From 49b595f952647a19dd97214e5dce9e019d196236 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Mon, 19 Nov 2018 09:37:23 +0100 Subject: sloped stations applied --- src/station_cmd.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 14 deletions(-) (limited to 'src/station_cmd.cpp') diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 2d97c2fd2..e6302d704 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -706,10 +706,11 @@ static CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags); * @param flags operation to perform * @param invalid_dirs prohibited directions (set of DiagDirections) * @param station StationID to be queried and returned if available + * @param bool check_facing_slope to check which stations are allowed to build on slopes facing the slope * @param check_clear if clearing tile should be performed (in wich case, cost will be added) * @return the cost in case of success, or an error code if it failed. */ -CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_clear = true) +CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_facing_slope = false, bool check_clear = true) { CommandCost cost(EXPENSES_CONSTRUCTION); int allowed_z = -1; @@ -735,13 +736,16 @@ CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag fla int flat_z = z; if (tileh != SLOPE_FLAT) { - /* need to check so the entrance to the station is not pointing at a slope. + /* Do not allow road bays to be build facing on slopes, but allow all other kinds of stations. + * Need to check so the entrance to the station is not pointing at a slope. * This must be valid for all station tiles, as the user can remove single station tiles. */ - if ((HasBit(invalid_dirs, DIAGDIR_NE) && !(tileh & SLOPE_NE)) || - (HasBit(invalid_dirs, DIAGDIR_SE) && !(tileh & SLOPE_SE)) || - (HasBit(invalid_dirs, DIAGDIR_SW) && !(tileh & SLOPE_SW)) || - (HasBit(invalid_dirs, DIAGDIR_NW) && !(tileh & SLOPE_NW))) { - return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); + if (check_facing_slope) { + if ((HasBit(invalid_dirs, DIAGDIR_NE) && !(tileh & SLOPE_NE)) || + (HasBit(invalid_dirs, DIAGDIR_SE) && !(tileh & SLOPE_SE)) || + (HasBit(invalid_dirs, DIAGDIR_SW) && !(tileh & SLOPE_SW)) || + (HasBit(invalid_dirs, DIAGDIR_NW) && !(tileh & SLOPE_NW))) { + return_cmd_error(STR_0007_FLAT_LAND_REQUIRED); + } } cost.AddCost(_price.terraform); flat_z += TILE_HEIGHT; @@ -1454,7 +1458,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin rts |= cur_rts; } - CommandCost cost = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL, !build_over_road); + CommandCost cost = CheckFlatLandBelow(tile, 1, 1, flags, is_drive_through ? 5 << p1 : 1 << p1, NULL, !HasBit(p2, 1), !build_over_road); if (CmdFailed(cost)) return cost; uint roadbits_to_build = CountBits(rts) * 2 - num_roadbits; cost.AddCost(_price.build_road * roadbits_to_build); @@ -2309,15 +2313,33 @@ const DrawTileSprites *GetStationTileLayout(StationType st, byte gfx) return &_station_display_datas[st][gfx]; } +/* these two arrays are copied from rail/road_cmd.cpp, I should find a way to + * duplicate less code + */ +const byte _road_sloped_sprites[14] = { + 0, 0, 2, 0, + 0, 1, 0, 0, + 3, 0, 0, 0, + 0, 0 +}; + +const byte _track_sloped_sprites[14] = { + 14, 15, 22, 13, + 0, 21, 17, 12, + 23, 0, 18, 20, + 19, 16 +}; + static void DrawTile_Station(TileInfo *ti) { const DrawTileSprites *t = NULL; RoadTypes roadtypes; int32 total_offset; int32 custom_ground_offset; + const RailtypeInfo *rti; if (IsRailwayStation(ti->tile)) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + rti = GetRailTypeInfo(GetRailType(ti->tile)); roadtypes = ROADTYPES_NONE; total_offset = rti->total_offset; custom_ground_offset = rti->custom_ground_offset; @@ -2339,8 +2361,8 @@ static void DrawTile_Station(TileInfo *ti) palette = PALETTE_TO_GREY; } - /* don't show foundation for docks */ - if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile)) + /* always draw leveled foundations only for airports and road bays! */ + if (ti->tileh != SLOPE_FLAT && (IsAirport(ti->tile) || IsStandardRoadStopTile(ti->tile))) DrawFoundation(ti, FOUNDATION_LEVELED); if (IsCustomStationSpecIndex(ti->tile)) { @@ -2388,14 +2410,55 @@ static void DrawTile_Station(TileInfo *ti) image += GetCustomStationGroundRelocation(statspec, st, ti->tile); image += custom_ground_offset; } else { - image += total_offset; + /* It's a sloped rail/road station? */ + if (ti->tileh != SLOPE_FLAT && (IsRailwayStation(ti->tile) || IsRoadStop(ti->tile))) { + Foundation rf = FOUNDATION_NONE; + if (IsRoadStop(ti->tile)) { + /* Roadstops without foundation on a slope + * and on Slopes with one corner raised */ + rf = GetRoadFoundation(ti->tileh, AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(ti->tile)))); + DrawFoundation(ti, rf); + /* Draws the sloped road */ + if (ti->tileh != SLOPE_FLAT) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F; + } else { + /* sloped rail station */ + TrackBits track = AxisToTrackBits(GetRailStationAxis(ti->tile)); + rf = GetRailFoundation(ti->tileh, track); + DrawFoundation(ti, rf); + if (rf != FOUNDATION_LEVELED) { + image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; + } else { + (image = rti->base_sprites.track_y, track == TRACK_BIT_Y ) || (image++, track == TRACK_BIT_X); + } + } + } else { + /* It is not a slope */ + image += total_offset; + } } DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette)); /* PBS debugging, draw reserved tracks darker */ if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && IsRailwayStation(ti->tile) && GetRailwayStationReservation(ti->tile)) { - const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); - DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_y : rti->base_sprites.single_x, PALETTE_CRASH); + TrackBits pbs = AxisToTrackBits(GetRailStationAxis(ti->tile)); + if (pbs & TRACK_BIT_X) { + if (ti->tileh == SLOPE_FLAT || ti->tileh == SLOPE_ELEVATED) { + DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); + } else { + DrawGroundSprite(_track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.single_sloped - 20, PALETTE_CRASH); + } + } + if (pbs & TRACK_BIT_Y) { + if (ti->tileh == SLOPE_FLAT || ti->tileh == SLOPE_ELEVATED) { + DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH); + } else { + DrawGroundSprite(_track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.single_sloped - 20, PALETTE_CRASH); + } + } + if (pbs & TRACK_BIT_UPPER) AddSortableSpriteToDraw(rti->base_sprites.single_n, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_N ? 8 : 0)); + if (pbs & TRACK_BIT_LOWER) AddSortableSpriteToDraw(rti->base_sprites.single_s, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_S ? 8 : 0)); + if (pbs & TRACK_BIT_LEFT) AddSortableSpriteToDraw(rti->base_sprites.single_w, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_W ? 8 : 0)); + if (pbs & TRACK_BIT_RIGHT) AddSortableSpriteToDraw(rti->base_sprites.single_e, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + (ti->tileh & SLOPE_E ? 8 : 0)); } } @@ -2464,6 +2527,17 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro static uint GetSlopeZ_Station(TileIndex tile, uint x, uint y) { + Axis axis; + uint z; + Slope tileh = GetTileSlope(tile, &z); + + /* this code makes vehicles and trains follow the slope on sloped stations */ + if (IsRailwayStation(tile) || IsRoadStopTile(tile) && !IsStandardRoadStopTile(tile)) { + axis = IsRailwayStation(tile)?GetRailStationAxis(tile):DiagDirToAxis(GetRoadStopDir(tile)); + z += ApplyFoundationToSlope(GetRailFoundation(tileh,AxisToTrackBits(axis)), &tileh); + return z + GetPartialZ(x & 0xF, y & 0xF, tileh); + } + return GetTileMaxZ(tile); } -- cgit v1.2.3-54-g00ecf