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