Implement road ground types for road waypoints

pull/363/head
Jonathan G Rennison 2 years ago
parent 7ff885fc96
commit c3c55db02b

@ -907,6 +907,22 @@
<li>m2: index into the array of stations</li>
<li>m3 bits 7..4: persistent random data for railway stations/waypoints and airports)</li>
<li>m3 bits 7..4: <a href="#OwnershipInfo">owner</a> of tram tracks (road stop)</li>
<li style="color: blue">m3 bits 3..2: ground type (road waypoints)
<table>
<tr>
<td><tt>0</tt>&nbsp; </td>
<td>on bare land</td>
</tr>
<tr>
<td><tt>1</tt>&nbsp; </td>
<td>on grass</td>
</tr>
<tr>
<td><tt>2</tt>&nbsp; </td>
<td>paved</td>
</tr>
</table>
</li>
<li style="color: blue">m3 bits 1..0: bits to disallow vehicles to go a specific direction (drive-through road stop)
<table>
<tr>
@ -1037,6 +1053,7 @@
<li>m7 bits 4..0: <a href="#OwnershipInfo">owner</a> of road (road stops)</li>
<li>m7: animation frame (railway stations/waypoints, airports)</li>
<li style="color: blue">m8 bit 15: Snow or desert present (road waypoints)</li>
<li style="color: blue">m8 bits 14..12: <a href="#RoadCachedOneWayState">Road cached one way state</a></li>
<li>m8 bits 11..6: <a href="#TramType">Tramtype</a></li>
<li>m8 bits 5..0: <a href="#TrackType">track type</a> for railway stations/waypoints</li>

@ -185,10 +185,10 @@ the array so you can quickly see what is used and what is not.
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
</tr>
<tr>
<td rowspan=7>5</td>
<td rowspan=8>5</td>
<td class="caption">rail station</td>
<td class="bits" rowspan=7><span class="free">O</span><span class="used" title="Water class">XX</span> <span class="used" title="Owner">XXXXX</span></td>
<td class="bits" rowspan=7><span class="pool" title="Station index on pool">XXXX XXXX XXXX XXXX</span></td>
<td class="bits" rowspan=8><span class="free">O</span><span class="used" title="Water class">XX</span> <span class="used" title="Owner">XXXXX</span></td>
<td class="bits" rowspan=8><span class="pool" title="Station index on pool">XXXX XXXX XXXX XXXX</span></td>
<td class="bits" rowspan=2><span class="used" title="Random bits">XXXX</span> <span class="free">OOOO</span></td>
<td class="bits" rowspan=2><span class="used" title="Custom station specifications ID">XXXX XXXX</span></td>
<td class="bits"><span class="used" title="Graphics index">XXXX XXXX</span></td>
@ -203,12 +203,17 @@ the array so you can quickly see what is used and what is not.
<tr>
<td class="caption">road stop</td>
<td class="bits"><span class="used" title="Owner of tram">XXXX</span> <span class="free">OO</span><span class="patch" title="Disallow vehicles to go a specific direction (drive-through road stop)">PP</span></td>
<td class="bits"><span class="free">OO</span><span class="used" title="Roadtype for road stop">XX XXXX</span></td>
<td class="bits"><span class="usable" title="Graphics index">OOOO O</span><span class="used" title="Graphics index: 00 (exit towards NE), 01 (exit towards SE), 02 (exit towards SW), 03 (exit towards NW), 04 (drive through X), 05 (drive through Y)">XXX</span></td>
<td class="bits" rowspan=5><span class="free">O<span class="patch" title="Station type (extra bit)">P</span></span><span class="used" title="Station type">XXX</span> <span class="free">OOO</span></td>
<td class="bits"><span class="free">OOO</span><span class="used" title="Owner of road">X XXXX</span></td>
<td class="bits" rowspan=2><span class="free">OO</span><span class="used" title="Roadtype for road stop">XX XXXX</span></td>
<td class="bits" rowspan=2><span class="usable" title="Graphics index">OOOO O</span><span class="used" title="Graphics index: 00 (exit towards NE), 01 (exit towards SE), 02 (exit towards SW), 03 (exit towards NW), 04 (drive through X), 05 (drive through Y)">XXX</span></td>
<td class="bits" rowspan=6><span class="free">O<span class="patch" title="Station type (extra bit)">P</span></span><span class="used" title="Station type">XXX</span> <span class="free">OOO</span></td>
<td class="bits" rowspan=2><span class="free">OOO</span><span class="used" title="Owner of road">X XXXX</span></td>
<td class="bits"><span class="free">O</span><span class="patch" title="Road cached one way state">PPP</span> <span class="used" title="Tram type">XXXX XX<span class="free">OO OOOO</span></td>
</tr>
<tr>
<td class="caption">road waypoint</td>
<td class="bits"><span class="used" title="Owner of tram">XXXX</span> <span class="patch" title="Pavement type">PP</span> <span class="patch" title="Disallow vehicles to go a specific direction (drive-through road stop)">PP</span></td>
<td class="bits"><span class="patch" title="Snow/desert present">P</span> <span class="patch" title="Road cached one way state">PPP</span> <span class="used" title="Tram type">XXXX XX<span class="free">OO OOOO</span></td>
</tr>
<tr>
<td class="caption">airport</td>
<td class="bits"><span class="used" title="Random bits">XXXX</span> <span class="free">OOOO</span></td>

@ -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) {

@ -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;
}
}

@ -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

@ -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;
}

Loading…
Cancel
Save