From c3c55db02be262aa2e86915df63a675adef48845 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 26 Jan 2022 21:46:09 +0000 Subject: [PATCH] Implement road ground types for road waypoints --- docs/landscape.html | 17 +++++++++++++++ docs/landscape_grid.html | 19 +++++++++++------ src/road_cmd.cpp | 46 +++++++++++++++++++++++----------------- src/station_cmd.cpp | 40 ++++++++++++++++++++++++++++++++++ src/station_map.h | 43 +++++++++++++++++++++++++++++++++++++ src/tunnelbridge_cmd.cpp | 4 ++-- 6 files changed, 140 insertions(+), 29 deletions(-) diff --git a/docs/landscape.html b/docs/landscape.html index 2e3d82313b..bd6cc4b5c8 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -907,6 +907,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
    +
  • m3 bits 1..0: bits to disallow vehicles to go a specific direction (drive-through road stop) @@ -1037,6 +1053,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 14..12: Road cached one way state
  • m8 bits 11..6: Tramtype
  • m8 bits 5..0: track type for railway stations/waypoints
  • diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index e7aae85d5f..c70a18eef0 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -185,10 +185,10 @@ the array so you can quickly see what is used and what is not. - + - - + + @@ -203,12 +203,17 @@ the array so you can quickly see what is used and what is not. - - - - + + + + + + + + + diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index d7b7bdffa6..d767717b64 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1865,13 +1865,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)); } @@ -2064,11 +2064,11 @@ void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *roa * @param offset Road sprite offset * @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, PaletteID *pal, bool snow_or_desert) { /* 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); } @@ -2082,7 +2082,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) { @@ -2100,11 +2100,9 @@ static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const * Draw ground sprite and road pieces * @param ti TileInfo */ -void DrawRoadBits(TileInfo *ti) +void DrawRoadBits(TileInfo *ti, RoadBits road, RoadBits tram, Roadside roadside, bool snow_or_desert) { - const bool is_bridge = IsTileType(ti->tile, MP_TUNNELBRIDGE); - RoadBits road = is_bridge ? GetCustomBridgeHeadRoadBits(ti->tile, RTT_ROAD) : GetRoadBits(ti->tile, RTT_ROAD); - RoadBits tram = is_bridge ? GetCustomBridgeHeadRoadBits(ti->tile, RTT_TRAM) : GetRoadBits(ti->tile, RTT_TRAM); + const bool is_road_tile = IsTileType(ti->tile, MP_ROAD); RoadType road_rt = GetRoadTypeRoad(ti->tile); RoadType tram_rt = GetRoadTypeTram(ti->tile); @@ -2112,8 +2110,8 @@ void DrawRoadBits(TileInfo *ti) const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); if (ti->tileh != SLOPE_FLAT) { - DrawFoundation(ti, is_bridge ? FOUNDATION_LEVELED : GetRoadFoundation(ti->tileh, road | tram)); - /* DrawFoundation() modifies ti. */ + DrawFoundation(ti, !is_road_tile ? FOUNDATION_LEVELED : GetRoadFoundation(ti->tileh, road | tram)); + /* DrawFoundation() is_road_tile ti. */ } /* Determine sprite offsets */ @@ -2121,23 +2119,21 @@ void DrawRoadBits(TileInfo *ti) uint tram_offset = GetRoadSpriteOffset(ti->tileh, tram); /* Draw baseset underlay */ - Roadside roadside = is_bridge ? ROADSIDE_PAVED : GetRoadside(ti->tile); - PaletteID pal = PAL_NONE; - SpriteID image = GetRoadGroundSprite(ti, roadside, road_rti, road == ROAD_NONE ? tram_offset : road_offset, &pal); + SpriteID image = GetRoadGroundSprite(ti, roadside, road_rti, road == ROAD_NONE ? tram_offset : road_offset, &pal, snow_or_desert); DrawGroundSprite(image, pal); DrawRoadOverlays(ti, pal, road_rti, tram_rti, road_offset, tram_offset); /* Draw one way */ - if (!is_bridge && road_rti != nullptr) { + if (is_road_tile && road_rti != nullptr) { DisallowedRoadDirections drd = GetDisallowedRoadDirections(ti->tile); if (drd != DRD_NONE) { DrawGroundSpriteAt(SPR_ONEWAY_BASE + drd - 1 + ((road == ROAD_X) ? 0 : 3), PAL_NONE, 8, 8, GetPartialPixelZ(8, 8, ti->tileh)); } } - if (!is_bridge && HasRoadWorks(ti->tile)) { + if (is_road_tile && HasRoadWorks(ti->tile)) { /* Road works */ DrawGroundSprite((road | tram) & ROAD_X ? SPR_EXCAVATION_X : SPR_EXCAVATION_Y, PAL_NONE); return; @@ -2171,6 +2167,16 @@ void DrawRoadBits(TileInfo *ti) } } +void DrawRoadBitsRoad(TileInfo *ti) +{ + DrawRoadBits(ti, GetRoadBits(ti->tile, RTT_ROAD), GetRoadBits(ti->tile, RTT_TRAM), GetRoadside(ti->tile), IsOnSnow(ti->tile)); +} + +void DrawRoadBitsTunnelBridge(TileInfo *ti) +{ + DrawRoadBits(ti, GetCustomBridgeHeadRoadBits(ti->tile, RTT_ROAD), GetCustomBridgeHeadRoadBits(ti->tile, RTT_TRAM), ROADSIDE_PAVED, false); +} + /** Tile callback function for rendering a road tile to the screen */ static void DrawTile_Road(TileInfo *ti, DrawTileProcParams params) { @@ -2178,7 +2184,7 @@ static void DrawTile_Road(TileInfo *ti, DrawTileProcParams params) switch (GetRoadTileType(ti->tile)) { case ROAD_TILE_NORMAL: - DrawRoadBits(ti); + DrawRoadBitsRoad(ti); break; case ROAD_TILE_CROSSING: { @@ -2200,7 +2206,7 @@ static void DrawTile_Road(TileInfo *ti, DrawTileProcParams params) 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) { @@ -2216,7 +2222,7 @@ static void DrawTile_Road(TileInfo *ti, DrawTileProcParams params) 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/station_cmd.cpp b/src/station_cmd.cpp index 31fea176da..9da37895ec 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3360,6 +3360,12 @@ draw_default_foundation: DrawClearLandTile(ti, 3); } } + } else if (IsRoadWaypointTile(ti->tile)) { + RoadBits bits = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? ROAD_X : ROAD_Y; + extern void DrawRoadBits(TileInfo *ti, RoadBits road, RoadBits tram, Roadside roadside, bool snow_or_desert); + DrawRoadBits(ti, GetRoadTypeRoad(ti->tile) != INVALID_ROADTYPE ? bits : ROAD_NONE, + GetRoadTypeTram(ti->tile) != INVALID_ROADTYPE ? bits : ROAD_NONE, + GetRoadWaypointRoadside(ti->tile), IsRoadWaypointOnSnowOrDesert(ti->tile)); } else { if (layout != nullptr) { /* Sprite layout which needs preprocessing */ @@ -3684,6 +3690,40 @@ 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, VMDF_NOT_MAP_MODE); + } + break; + + case LT_TROPIC: + if (GetTropicZone(tile) == TROPICZONE_DESERT && !IsRoadWaypointOnSnowOrDesert(tile)) { + ToggleRoadWaypointOnSnowOrDesert(tile); + MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE); + } + break; + } + + HouseZonesBits grp = HZB_TOWN_EDGE; + const Town *t = ClosestTownFromTile(tile, UINT_MAX); + if (t != nullptr) { + grp = GetTownRadiusGroup(t, tile); + } + + /* Adjust road ground type depending on 'grp' (grp is the distance to the center) */ + Roadside new_rs = grp > 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, VMDF_NOT_MAP_MODE); + } + break; + } + default: break; } } diff --git a/src/station_map.h b/src/station_map.h index 98ef3236e3..2b8978c3c8 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -301,6 +301,49 @@ static inline void SetDriveThroughStopDisallowedRoadDirections(TileIndex t, Disa SB(_m[t].m3, 0, 2, drd); } +/** + * Get the decorations of a road waypoint. + * @param tile The tile to query. + * @return The road decoration of the tile. + */ +static inline Roadside GetRoadWaypointRoadside(TileIndex tile) +{ + assert_tile(IsRoadWaypointTile(tile), tile); + return (Roadside)GB(_m[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(TileIndex tile, Roadside s) +{ + assert_tile(IsRoadWaypointTile(tile), tile); + SB(_m[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(TileIndex t) +{ + assert_tile(IsRoadWaypointTile(t), t); + return HasBit(_me[t].m8, 15); +} + +/** + * Toggle the snow/desert state of a road waypoint tile. + * @param t The tile to change. + */ +static inline void ToggleRoadWaypointOnSnowOrDesert(TileIndex t) +{ + assert_tile(IsRoadWaypointTile(t), t); + ToggleBit(_me[t].m8, 15); +} + /** * Get the station graphics of this airport tile * @param t the tile to query diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 59502a7d63..e5ecd4003a 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -63,7 +63,7 @@ TileIndex _build_tunnel_endtile; ///< The end of a tunnel; as hidden return from static const int BRIDGE_Z_START = 3; extern void DrawTrackBits(TileInfo *ti, TrackBits track); -extern void DrawRoadBits(TileInfo *ti); +extern void DrawRoadBitsTunnelBridge(TileInfo *ti); extern const RoadBits _invalid_tileh_slopes_road[2][15]; extern CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statspec, byte layout, TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height, @@ -2124,7 +2124,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti, DrawTileProcParams params) DrawBridgeMiddle(ti); } else { // IsBridge(ti->tile) if (transport_type == TRANSPORT_ROAD && IsRoadCustomBridgeHead(ti->tile)) { - DrawRoadBits(ti); + DrawRoadBitsTunnelBridge(ti); DrawBridgeMiddle(ti); return; }
    OOOO OOOO OOOO OOOO
    55 rail stationOXX XXXXXXXXX XXXX XXXX XXXXOXX XXXXXXXXX XXXX XXXX XXXX XXXX OOOO XXXX XXXX XXXX XXXX
    road stop XXXX OOPPOOXX XXXXOOOO OXXXOPXXX OOOOOOX XXXXOOXX XXXXOOOO OXXXOPXXX OOOOOOX XXXX OPPP XXXX XXOO OOOO
    road waypointXXXX PP PPP PPP XXXX XXOO OOOO
    airport XXXX OOOO