diff --git a/docs/landscape.html b/docs/landscape.html
index 3971c151c5..c48aedcebc 100644
--- a/docs/landscape.html
+++ b/docs/landscape.html
@@ -876,6 +876,22 @@
m2: index into the array of stations
m3 bits 7..4: persistent random data for railway stations/waypoints and airports)
m3 bits 7..4: owner of tram tracks (road stop)
+ m3 bits 3..2: ground type (road waypoints)
+
+
+ 0 |
+ on bare land |
+
+
+ 1 |
+ on grass |
+
+
+ 2 |
+ paved |
+
+
+
m4: custom station id; 0 means standard graphics
m4: Roadtype for road stops
m5: graphics index (range from 0..255 for each station type):
@@ -997,6 +1013,7 @@
m7 bits 4..0: owner of road (road stops)
m7: animation frame (railway stations/waypoints, airports)
+ m8 bit 15: Snow or desert present (road waypoints)
m8 bits 11..6: Tramtype
m8 bits 5..0: track type for railway stations/waypoints
m8 bits 5..0: custom road stop id; 0 means standard graphics
diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html
index 5db1bbdd05..11e5952777 100644
--- a/docs/landscape_grid.html
+++ b/docs/landscape_grid.html
@@ -181,10 +181,10 @@ the array so you can quickly see what is used and what is not.
OOOO OOOO OOOO OOOO |
- 5 |
+ 5 |
rail station |
- OXX XXXXX |
- XXXX XXXX XXXX XXXX |
+ OXX XXXXX |
+ XXXX XXXX XXXX XXXX |
XXXX OOOO |
XXXX XXXX |
XXXX XXXX |
@@ -199,12 +199,17 @@ the array so you can quickly see what is used and what is not.
road stop |
XXXX OOOO |
- OOXX XXXX |
- OOOO OXXX |
- OXXX XOOO |
- OOOX XXXX |
+ OOXX XXXX |
+ OOOO OXXX |
+ OXXX XOOO |
+ OOOX XXXX |
OOOO XXXX XX XXXXXX |
+
+ road waypoint |
+ XXXX XXOO |
+ XOOO XXXX XXOO OOOO |
+
airport |
XXXX OOOO |
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
index cd94e30a81..e4489c8621 100644
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -1359,13 +1359,13 @@ static uint GetRoadSpriteOffset(Slope slope, RoadBits bits)
* By default, roads are always drawn as unpaved if they are on desert or
* above the snow line, but NewGRFs can override this for desert.
*
- * @param tile The tile the road is on
+ * @param snow_or_desert Is snowy or desert tile
* @param roadside What sort of road this is
* @return True if snow/desert road sprites should be used.
*/
-static bool DrawRoadAsSnowDesert(TileIndex tile, Roadside roadside)
+static bool DrawRoadAsSnowDesert(bool snow_or_desert, Roadside roadside)
{
- return (IsOnSnow(tile) &&
+ return (snow_or_desert &&
!(_settings_game.game_creation.landscape == LT_TROPIC && HasGrfMiscBit(GMB_DESERT_PAVED_ROADS) &&
roadside != ROADSIDE_BARREN && roadside != ROADSIDE_GRASS && roadside != ROADSIDE_GRASS_ROAD_WORKS));
}
@@ -1556,13 +1556,14 @@ void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *roa
* @param roadside Road side type
* @param rti Road type info
* @param offset Road sprite offset
+ * @param snow_or_desert Whether to get snow/desert ground sprite
* @param[out] pal Palette to draw.
*/
-static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const RoadTypeInfo *rti, uint offset, PaletteID *pal)
+static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const RoadTypeInfo *rti, uint offset, bool snow_or_desert, PaletteID *pal)
{
/* Draw bare ground sprite if no road or road uses overlay system. */
if (rti == nullptr || rti->UsesOverlay()) {
- if (DrawRoadAsSnowDesert(ti->tile, roadside)) {
+ if (DrawRoadAsSnowDesert(snow_or_desert, roadside)) {
return SPR_FLAT_SNOW_DESERT_TILE + SlopeToSpriteOffset(ti->tileh);
}
@@ -1577,7 +1578,7 @@ static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const
/* Draw original road base sprite */
SpriteID image = SPR_ROAD_Y + offset;
- if (DrawRoadAsSnowDesert(ti->tile, roadside)) {
+ if (DrawRoadAsSnowDesert(snow_or_desert, roadside)) {
image += 19;
} else {
switch (roadside) {
@@ -1591,6 +1592,30 @@ static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const
return image;
}
+/**
+ * Draw road ground sprites.
+ * @param ti TileInfo
+ * @param road Road bits
+ * @param tram Tram bits
+ * @param road_rti Road road type information
+ * @param tram_rti Tram road type information
+ * @param roadside Roadside type
+ * @param snow_or_desert Whether to draw snow/desert ground sprites
+ */
+void DrawRoadGroundSprites(const TileInfo *ti, RoadBits road, RoadBits tram, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, Roadside roadside, bool snow_or_desert)
+{
+ /* Determine sprite offsets */
+ uint road_offset = GetRoadSpriteOffset(ti->tileh, road);
+ uint tram_offset = GetRoadSpriteOffset(ti->tileh, tram);
+
+ /* Draw baseset underlay */
+ PaletteID pal = PAL_NONE;
+ SpriteID image = GetRoadGroundSprite(ti, roadside, road_rti, road == ROAD_NONE ? tram_offset : road_offset, snow_or_desert, &pal);
+ DrawGroundSprite(image, pal);
+
+ DrawRoadOverlays(ti, pal, road_rti, tram_rti, road_offset, tram_offset);
+}
+
/**
* Draw ground sprite and road pieces
* @param ti TileInfo
@@ -1610,18 +1635,7 @@ static void DrawRoadBits(TileInfo *ti)
/* DrawFoundation() modifies ti. */
}
- /* Determine sprite offsets */
- uint road_offset = GetRoadSpriteOffset(ti->tileh, road);
- uint tram_offset = GetRoadSpriteOffset(ti->tileh, tram);
-
- /* Draw baseset underlay */
- Roadside roadside = GetRoadside(ti->tile);
-
- PaletteID pal = PAL_NONE;
- SpriteID image = GetRoadGroundSprite(ti, roadside, road_rti, road == ROAD_NONE ? tram_offset : road_offset, &pal);
- DrawGroundSprite(image, pal);
-
- DrawRoadOverlays(ti, pal, road_rti, tram_rti, road_offset, tram_offset);
+ DrawRoadGroundSprites(ti, road, tram, road_rti, tram_rti, GetRoadside(ti->tile), IsOnSnow(ti->tile));
/* Draw one way */
if (road_rti != nullptr) {
@@ -1654,6 +1668,7 @@ static void DrawRoadBits(TileInfo *ti)
if (!HasBit(_display_opt, DO_FULL_DETAIL) || _cur_dpi->zoom > ZOOM_LVL_DETAIL) return;
/* Do not draw details (street lights, trees) under low bridge */
+ Roadside roadside = GetRoadside(ti->tile);
if (IsBridgeAbove(ti->tile) && (roadside == ROADSIDE_TREES || roadside == ROADSIDE_STREET_LIGHTS)) {
int height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
int minz = GetTileMaxZ(ti->tile) + 2;
@@ -1712,7 +1727,7 @@ static void DrawTile_Road(TileInfo *ti)
SpriteID image = SPR_ROAD_Y + axis;
Roadside roadside = GetRoadside(ti->tile);
- if (DrawRoadAsSnowDesert(ti->tile, roadside)) {
+ if (DrawRoadAsSnowDesert(IsOnSnow(ti->tile), roadside)) {
image += 19;
} else {
switch (roadside) {
@@ -1728,7 +1743,7 @@ static void DrawTile_Road(TileInfo *ti)
if (IsCrossingBarred(ti->tile)) image += 2;
Roadside roadside = GetRoadside(ti->tile);
- if (DrawRoadAsSnowDesert(ti->tile, roadside)) {
+ if (DrawRoadAsSnowDesert(IsOnSnow(ti->tile), roadside)) {
image += 8;
} else {
switch (roadside) {
diff --git a/src/road_func.h b/src/road_func.h
index 7c73597b9f..ed3e3db6d0 100644
--- a/src/road_func.h
+++ b/src/road_func.h
@@ -159,6 +159,8 @@ void UpdateAdjacentLevelCrossingTilesOnLevelCrossingRemoval(TileIndex tile, Axis
void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count);
struct TileInfo;
+enum Roadside : uint8_t;
void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rit, uint road_offset, uint tram_offset, bool draw_underlay = true);
+void DrawRoadGroundSprites(const TileInfo *ti, RoadBits road, RoadBits tram, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, Roadside roadside, bool snow_or_desert);
#endif /* ROAD_FUNC_H */
diff --git a/src/road_map.h b/src/road_map.h
index 9179579b4c..06c000384c 100644
--- a/src/road_map.h
+++ b/src/road_map.h
@@ -474,7 +474,7 @@ inline void ToggleSnow(Tile t)
/** The possible road side decorations. */
-enum Roadside {
+enum Roadside : uint8_t {
ROADSIDE_BARREN = 0, ///< Road on barren land
ROADSIDE_GRASS = 1, ///< Road on grass
ROADSIDE_PAVED = 2, ///< Road with paved sidewalks
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 7f0f0fc8f1..5916075b4c 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -66,6 +66,7 @@
#include "timer/timer_game_economy.h"
#include "timer/timer_game_tick.h"
#include "cheat_type.h"
+#include "road_func.h"
#include "widgets/station_widget.h"
@@ -3254,6 +3255,20 @@ draw_default_foundation:
DrawClearLandTile(ti, 3);
}
}
+ } else if (IsRoadWaypointTile(ti->tile)) {
+ RoadBits bits = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? ROAD_X : ROAD_Y;
+ RoadType road_rt = GetRoadTypeRoad(ti->tile);
+ RoadType tram_rt = GetRoadTypeTram(ti->tile);
+ RoadBits road = (road_rt != INVALID_ROADTYPE) ? bits : ROAD_NONE;
+ RoadBits tram = (tram_rt != INVALID_ROADTYPE) ? bits : ROAD_NONE;
+ const RoadTypeInfo *road_rti = (road_rt != INVALID_ROADTYPE) ? GetRoadTypeInfo(road_rt) : nullptr;
+ const RoadTypeInfo *tram_rti = (tram_rt != INVALID_ROADTYPE) ? GetRoadTypeInfo(tram_rt) : nullptr;
+
+ if (ti->tileh != SLOPE_FLAT) {
+ DrawFoundation(ti, FOUNDATION_LEVELED);
+ }
+
+ DrawRoadGroundSprites(ti, road, tram, road_rti, tram_rti, GetRoadWaypointRoadside(ti->tile), IsRoadWaypointOnSnowOrDesert(ti->tile));
} else {
if (layout != nullptr) {
/* Sprite layout which needs preprocessing */
@@ -3601,6 +3616,42 @@ static void TileLoop_Station(TileIndex tile)
TileLoop_Water(tile);
break;
+ case STATION_ROADWAYPOINT: {
+ switch (_settings_game.game_creation.landscape) {
+ case LT_ARCTIC:
+ if (IsRoadWaypointOnSnowOrDesert(tile) != (GetTileZ(tile) > GetSnowLine())) {
+ ToggleRoadWaypointOnSnowOrDesert(tile);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ case LT_TROPIC:
+ if (GetTropicZone(tile) == TROPICZONE_DESERT && !IsRoadWaypointOnSnowOrDesert(tile)) {
+ ToggleRoadWaypointOnSnowOrDesert(tile);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+
+ default: break;
+ }
+
+ HouseZonesBits new_zone = HZB_TOWN_EDGE;
+ const Town *t = ClosestTownFromTile(tile, UINT_MAX);
+ if (t != nullptr) {
+ new_zone = GetTownRadiusGroup(t, tile);
+ }
+
+ /* Adjust road ground type depending on 'new_zone' */
+ Roadside new_rs = new_zone > HZB_TOWN_EDGE ? ROADSIDE_PAVED : ROADSIDE_GRASS;
+ Roadside cur_rs = GetRoadWaypointRoadside(tile);
+
+ if (new_rs != cur_rs) {
+ SetRoadWaypointRoadside(tile, cur_rs == ROADSIDE_BARREN ? new_rs : ROADSIDE_BARREN);
+ MarkTileDirtyByTile(tile);
+ }
+ break;
+ }
+
default: break;
}
}
diff --git a/src/station_map.h b/src/station_map.h
index d4cc0ef039..906ad6193b 100644
--- a/src/station_map.h
+++ b/src/station_map.h
@@ -280,6 +280,49 @@ inline bool IsDriveThroughStopTile(Tile t)
StationGfx GetTranslatedAirportTileID(StationGfx gfx);
+/**
+ * Get the decorations of a road waypoint.
+ * @param tile The tile to query.
+ * @return The road decoration of the tile.
+ */
+static inline Roadside GetRoadWaypointRoadside(Tile tile)
+{
+ assert(IsRoadWaypointTile(tile));
+ return (Roadside)GB(tile.m3(), 2, 2);
+}
+
+/**
+ * Set the decorations of a road waypoint.
+ * @param tile The tile to change.
+ * @param s The new road decoration of the tile.
+ */
+static inline void SetRoadWaypointRoadside(Tile tile, Roadside s)
+{
+ assert(IsRoadWaypointTile(tile));
+ SB(tile.m3(), 2, 2, s);
+}
+
+/**
+ * Check if a road waypoint tile has snow/desert.
+ * @param t The tile to query.
+ * @return True if the tile has snow/desert.
+ */
+static inline bool IsRoadWaypointOnSnowOrDesert(Tile t)
+{
+ assert(IsRoadWaypointTile(t));
+ return HasBit(t.m8(), 15);
+}
+
+/**
+ * Toggle the snow/desert state of a road waypoint tile.
+ * @param t The tile to change.
+ */
+static inline void ToggleRoadWaypointOnSnowOrDesert(Tile t)
+{
+ assert(IsRoadWaypointTile(t));
+ ToggleBit(t.m8(), 15);
+}
+
/**
* Get the station graphics of this airport tile
* @param t the tile to query