summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/road_func.h2
-rw-r--r--src/station_cmd.cpp99
-rw-r--r--src/table/sprites.h21
-rw-r--r--src/table/station_land.h64
4 files changed, 177 insertions, 9 deletions
diff --git a/src/road_func.h b/src/road_func.h
index 937646057..aa8bb2a26 100644
--- a/src/road_func.h
+++ b/src/road_func.h
@@ -159,4 +159,6 @@ void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count);
struct TileInfo;
void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rit, uint road_offset, uint tram_offset);
+Foundation GetRoadFoundation(Slope tileh, RoadBits bits);
+
#endif /* ROAD_FUNC_H */
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index a58c7b1f2..560563292 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -814,9 +814,9 @@ CommandCost CheckBuildableTile(TileIndex tile, uint invalid_dirs, int &allowed_z
cost.AddCost(_price[PR_BUILD_FOUNDATION]);
}
- /* The level of this tile must be equal to allowed_z. */
- if (allowed_z < 0) {
- /* First tile. */
+ /* get corresponding flat level and make sure that all parts of the station have the same level. */
+ if (allowed_z == -1) {
+ /* first tile */
allowed_z = flat_z;
} else if (allowed_z != flat_z) {
return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
@@ -855,6 +855,7 @@ static CommandCost CheckFlatLandAirport(AirportTileTableIterator tile_iter, DoCo
* @param flags Operation to perform.
* @param axis Rail station axis.
* @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 rt The rail type to check for (overbuilding rail stations over rail).
* @param affected_vehicles List of trains with PBS reservations on the tiles
* @param spec_class Station class.
@@ -863,7 +864,7 @@ static CommandCost CheckFlatLandAirport(AirportTileTableIterator tile_iter, DoCo
* @param numtracks Number of platforms.
* @return The cost in case of success, or an error code if it failed.
*/
-static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, std::vector<Train *> &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks)
+static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, bool check_facing_slope, RailType rt, std::vector<Train *> &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks)
{
CommandCost cost(EXPENSES_CONSTRUCTION);
int allowed_z = -1;
@@ -953,6 +954,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags
{
CommandCost cost(EXPENSES_CONSTRUCTION);
int allowed_z = -1;
+// TODO: possibly needs some checks for slope, too?
for (TileIndex cur_tile : tile_area) {
CommandCost ret = CheckBuildableTile(cur_tile, invalid_dirs, allowed_z, !is_drive_through);
@@ -2812,6 +2814,9 @@ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrack
return true;
}
+extern const byte _road_sloped_sprites[14];
+extern const byte _track_sloped_sprites[14];
+
static void DrawTile_Station(TileInfo *ti)
{
const NewGRFSpriteLayout *layout = nullptr;
@@ -2824,8 +2829,9 @@ static void DrawTile_Station(TileInfo *ti)
BaseStation *st = nullptr;
const StationSpec *statspec = nullptr;
uint tile_layout = 0;
+ RailtypeInfo *rti;
- if (HasStationRail(ti->tile)) {
+ if (IsRailwayStation(ti->tile) || IsRailWaypoint(ti->tile)) {
rti = GetRailTypeInfo(GetRailType(ti->tile));
total_offset = rti->GetRailtypeSpriteOffset();
@@ -2898,6 +2904,32 @@ static void DrawTile_Station(TileInfo *ti)
palette = PALETTE_TO_GREY;
}
+ /* 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)) {
+ /* look for customization */
+ st = BaseStation::GetByTile(ti->tile);
+ statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec;
+
+ if (statspec != nullptr) {
+ uint tile = GetStationGfx(ti->tile);
+
+ relocation = GetCustomStationRelocation(statspec, st, ti->tile);
+
+ if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) {
+ uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
+ if (callback != CALLBACK_FAILED) tile = (callback & ~1) + GetRailStationAxis(ti->tile);
+ }
+
+ /* Ensure the chosen tile layout is valid for this custom station */
+ if (statspec->renderdata != nullptr) {
+ t = &statspec->renderdata[tile < statspec->tiles ? tile : (uint)GetRailStationAxis(ti->tile)];
+ }
+ }
+ }
+
if (layout == nullptr && (t == nullptr || t->seq == nullptr)) t = GetStationTileLayout(GetStationType(ti->tile), gfx);
/* don't show foundation for docks */
@@ -3023,13 +3055,53 @@ draw_default_foundation:
}
} else {
image += HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE) ? ground_relocation : total_offset;
- if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) pal += ground_relocation;
+ if (HasBit(pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
+ pal += ground_relocation;
+ } else if (ti->tileh != SLOPE_FLAT && (IsRailwayStation(ti->tile) || IsRoadStop(ti->tile))) {
+ /* It's a sloped rail/road station? */
+ 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);
+ }
+ }
DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
/* PBS debugging, draw reserved tracks darker */
if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationRail(ti->tile) && HasStationReservation(ti->tile)) {
- const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
- DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH);
+ TrackBits pbs = AxisToTrackBits(GetRailStationAxis(ti->tile));
+ // TODO: possibly inverted in 7b136d1fddbb2d0840076dfe2ddbe666b29fee8d
+ 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));
}
}
}
@@ -3123,6 +3195,17 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro
static int GetSlopePixelZ_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 GetTileMaxPixelZ(tile);
}
diff --git a/src/table/sprites.h b/src/table/sprites.h
index b7bb91020..732a2dae7 100644
--- a/src/table/sprites.h
+++ b/src/table/sprites.h
@@ -266,7 +266,26 @@ static const SpriteID SPR_TRUCK_STOP_DT_Y_W = SPR_ROADSTOP_BASE + 4;
static const SpriteID SPR_TRUCK_STOP_DT_Y_E = SPR_ROADSTOP_BASE + 5;
static const SpriteID SPR_TRUCK_STOP_DT_X_W = SPR_ROADSTOP_BASE + 6;
static const SpriteID SPR_TRUCK_STOP_DT_X_E = SPR_ROADSTOP_BASE + 7;
-static const uint16 ROADSTOP_SPRITE_COUNT = 8;
+
+/* sprites for sloped graphics */
+static const SpriteID SPR_BUS_STOP_DT_SE_W = SPR_ROADSTOP_BASE + 12;
+static const SpriteID SPR_BUS_STOP_DT_SE_E = SPR_ROADSTOP_BASE + 13;
+static const SpriteID SPR_BUS_STOP_DT_NE_E = SPR_ROADSTOP_BASE + 14;
+static const SpriteID SPR_BUS_STOP_DT_NE_W = SPR_ROADSTOP_BASE + 15;
+static const SpriteID SPR_BUS_STOP_DT_NW_W = SPR_ROADSTOP_BASE + 16;
+static const SpriteID SPR_BUS_STOP_DT_NW_E = SPR_ROADSTOP_BASE + 17;
+static const SpriteID SPR_BUS_STOP_DT_SW_E = SPR_ROADSTOP_BASE + 18;
+static const SpriteID SPR_BUS_STOP_DT_SW_W = SPR_ROADSTOP_BASE + 19;
+static const SpriteID SPR_TRUCK_STOP_DT_SE_W = SPR_ROADSTOP_BASE + 20;
+static const SpriteID SPR_TRUCK_STOP_DT_SE_E = SPR_ROADSTOP_BASE + 21;
+static const SpriteID SPR_TRUCK_STOP_DT_NE_E = SPR_ROADSTOP_BASE + 22;
+static const SpriteID SPR_TRUCK_STOP_DT_NE_W = SPR_ROADSTOP_BASE + 23;
+static const SpriteID SPR_TRUCK_STOP_DT_NW_W = SPR_ROADSTOP_BASE + 24;
+static const SpriteID SPR_TRUCK_STOP_DT_NW_E = SPR_ROADSTOP_BASE + 25;
+static const SpriteID SPR_TRUCK_STOP_DT_SW_E = SPR_ROADSTOP_BASE + 26;
+static const SpriteID SPR_TRUCK_STOP_DT_SW_W = SPR_ROADSTOP_BASE + 27;
+
+static const uint16 ROADSTOP_SPRITE_COUNT = 28;
/** Tramway sprites */
static const SpriteID SPR_TRAMWAY_BASE = SPR_ROADSTOP_BASE + ROADSTOP_SPRITE_COUNT;
diff --git a/src/table/station_land.h b/src/table/station_land.h
index 53a69e1e2..2b6deecd0 100644
--- a/src/table/station_land.h
+++ b/src/table/station_land.h
@@ -775,6 +775,62 @@ static const DrawTileSeqStruct _station_display_datas_waypoint_Y[] = {
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
@@ -944,6 +1000,10 @@ static const DrawTileSprites _station_display_datas_truck[] = {
TILE_SPRITE_LINE(SPR_TRUCK_STOP_NW_GROUND | (1U << 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[] = {
@@ -953,6 +1013,10 @@ static const DrawTileSprites _station_display_datas_bus[] = {
TILE_SPRITE_LINE(SPR_BUS_STOP_NW_GROUND | (1U << 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[] = {