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/road_cmd.cpp | 2 - src/road_func.h | 2 + src/station_cmd.cpp | 102 ++++++++++++++++++++++++++++++++++++++++------- src/table/sprites.h | 19 ++++++++- src/table/station_land.h | 64 +++++++++++++++++++++++++++++ src/unmovable_cmd.cpp | 2 +- 6 files changed, 173 insertions(+), 18 deletions(-) diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 7b34560f4..b4dd0d845 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -99,8 +99,6 @@ static const RoadBits _invalid_tileh_slopes_road[2][15] = { } }; -Foundation GetRoadFoundation(Slope tileh, RoadBits bits); - /** * Is it allowed to remove the given road bits from the given tile? * @param tile the tile to remove the road from diff --git a/src/road_func.h b/src/road_func.h index 4b96cd608..c9bfa43f0 100644 --- a/src/road_func.h +++ b/src/road_func.h @@ -163,4 +163,6 @@ RoadTypes GetCompanyRoadtypes(const CompanyID company); void UpdateLevelCrossing(TileIndex tile, bool sound = true); +Foundation GetRoadFoundation(Slope tileh, RoadBits bits); + #endif /* ROAD_FUNC_H */ 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); } diff --git a/src/table/sprites.h b/src/table/sprites.h index c9ca6c98d..9bf448236 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -207,7 +207,24 @@ enum Sprites { SPR_TRUCK_STOP_DT_Y_E = SPR_ROADSTOP_BASE + 5, SPR_TRUCK_STOP_DT_X_W = SPR_ROADSTOP_BASE + 6, SPR_TRUCK_STOP_DT_X_E = SPR_ROADSTOP_BASE + 7, - ROADSTOP_SPRITE_COUNT = 8, + // sprites for sloped graphics + SPR_BUS_STOP_DT_SE_W = SPR_ROADSTOP_BASE + 12, + SPR_BUS_STOP_DT_SE_E = SPR_ROADSTOP_BASE + 13, + SPR_BUS_STOP_DT_NE_E = SPR_ROADSTOP_BASE + 14, + SPR_BUS_STOP_DT_NE_W = SPR_ROADSTOP_BASE + 15, + SPR_BUS_STOP_DT_NW_W = SPR_ROADSTOP_BASE + 16, + SPR_BUS_STOP_DT_NW_E = SPR_ROADSTOP_BASE + 17, + SPR_BUS_STOP_DT_SW_E = SPR_ROADSTOP_BASE + 18, + SPR_BUS_STOP_DT_SW_W = SPR_ROADSTOP_BASE + 19, + SPR_TRUCK_STOP_DT_SE_W = SPR_ROADSTOP_BASE + 20, + SPR_TRUCK_STOP_DT_SE_E = SPR_ROADSTOP_BASE + 21, + SPR_TRUCK_STOP_DT_NE_E = SPR_ROADSTOP_BASE + 22, + SPR_TRUCK_STOP_DT_NE_W = SPR_ROADSTOP_BASE + 23, + SPR_TRUCK_STOP_DT_NW_W = SPR_ROADSTOP_BASE + 24, + SPR_TRUCK_STOP_DT_NW_E = SPR_ROADSTOP_BASE + 25, + SPR_TRUCK_STOP_DT_SW_E = SPR_ROADSTOP_BASE + 26, + SPR_TRUCK_STOP_DT_SW_W = SPR_ROADSTOP_BASE + 27, + ROADSTOP_SPRITE_COUNT = 28, /* Tramway sprites */ SPR_TRAMWAY_BASE = SPR_ROADSTOP_BASE + ROADSTOP_SPRITE_COUNT, diff --git a/src/table/station_land.h b/src/table/station_land.h index 5dfcddaf6..c705fbbac 100644 --- a/src/table/station_land.h +++ b/src/table/station_land.h @@ -1013,6 +1013,62 @@ static const DrawTileSeqStruct _station_display_datas_0171[] = { TILE_SEQ_END() }; +// drive-through bus stop SE slope +static const DrawTileSeqStruct _station_display_datas_0172[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_BUS_STOP_DT_SE_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_BUS_STOP_DT_SE_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + +// drive-through bus stop NE slope +static const DrawTileSeqStruct _station_display_datas_0173[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_BUS_STOP_DT_NE_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_BUS_STOP_DT_NE_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + +// drive-through bus stop NW slope +static const DrawTileSeqStruct _station_display_datas_0174[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_BUS_STOP_DT_NW_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_BUS_STOP_DT_NW_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + +// drive-through bus stop SW slope +static const DrawTileSeqStruct _station_display_datas_0175[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_BUS_STOP_DT_SW_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_BUS_STOP_DT_SW_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + +// drive-through truck stop SE slope +static const DrawTileSeqStruct _station_display_datas_0176[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_SE_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_SE_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + +// drive-through truck stop NE slope +static const DrawTileSeqStruct _station_display_datas_0177[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_NE_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_NE_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + +// drive-through truck stop NW slope +static const DrawTileSeqStruct _station_display_datas_0178[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_NW_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_NW_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + +// drive-through truck stop SW slope +static const DrawTileSeqStruct _station_display_datas_0179[] = { + TILE_SEQ_LINE( 0, 0, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_SW_W | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_LINE( 0, 13, 0, 16, 3, 16, SPR_TRUCK_STOP_DT_SW_E | (1 << PALETTE_MODIFIER_COLOUR)) + TILE_SEQ_END() +}; + #undef TILE_SEQ_END #undef TILE_SEQ_LINE #undef TILE_SEQ_LINE_PAL @@ -1189,6 +1245,10 @@ static const DrawTileSprites _station_display_datas_truck[] = { TILE_SPRITE_LINE(SPR_TRUCK_STOP_NW_GROUND | (1 << PALETTE_MODIFIER_COLOUR), _station_display_datas_70) TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_X, _station_display_datas_0168) TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0169) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_X, _station_display_datas_0176) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0177) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_X, _station_display_datas_0178) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0179) }; static const DrawTileSprites _station_display_datas_bus[] = { @@ -1198,6 +1258,10 @@ static const DrawTileSprites _station_display_datas_bus[] = { TILE_SPRITE_LINE(SPR_BUS_STOP_NW_GROUND | (1 << PALETTE_MODIFIER_COLOUR), _station_display_datas_74) TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_X, _station_display_datas_0170) TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0171) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_X, _station_display_datas_0172) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0173) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_X, _station_display_datas_0174) + TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0175) }; static const DrawTileSprites _station_display_datas_oilrig[] = { diff --git a/src/unmovable_cmd.cpp b/src/unmovable_cmd.cpp index 9bf26dc96..c4eed93c9 100644 --- a/src/unmovable_cmd.cpp +++ b/src/unmovable_cmd.cpp @@ -89,7 +89,7 @@ void UpdateCompanyHQ(Company *c, uint score) MarkTileDirtyByTile(tile + TileDiffXY(1, 1)); } -extern CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_clear = true); +extern CommandCost CheckFlatLandBelow(TileIndex tile, uint w, uint h, DoCommandFlag flags, uint invalid_dirs, StationID *station, bool check_facing_slope = false, bool check_clear = true); /** Build or relocate the HQ. This depends if the HQ is already built or not * @param tile tile where the HQ will be built or relocated to -- cgit v1.2.3-54-g00ecf