Implement road ground types for road waypoints
This commit is contained in:
@@ -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> </td>
|
||||
<td>on bare land</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>1</tt> </td>
|
||||
<td>on grass</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>2</tt> </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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user