From 72ee11a7c63211a3ffe34c834d7ca579d83af1f4 Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 11 Jul 2010 17:28:19 +0000 Subject: (svn r20126) -Fix [FS#3883]: Make railtype Terrain Type variable aware of RAIL_GROUND_HALF_SNOW. That is, resolve the sprites for upper and lower part of the foundation independently. --- src/elrail.cpp | 36 +++++++++++++++++++++++++++++------- src/newgrf_commons.cpp | 5 +++-- src/newgrf_commons.h | 2 +- src/newgrf_railtype.cpp | 11 ++++++----- src/newgrf_railtype.h | 2 +- src/newgrf_spritegroup.h | 1 + src/rail_cmd.cpp | 7 +++++-- 7 files changed, 46 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/elrail.cpp b/src/elrail.cpp index 1474ff932..757790312 100644 --- a/src/elrail.cpp +++ b/src/elrail.cpp @@ -165,20 +165,20 @@ static TrackBits MaskWireBits(TileIndex t, TrackBits tracks) /** * Get the base wire sprite to use. */ -static inline SpriteID GetWireBase(TileIndex tile) +static inline SpriteID GetWireBase(TileIndex tile, bool upper_halftile = false) { const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); - SpriteID wires = GetCustomRailSprite(rti, tile, RTSG_WIRES); + SpriteID wires = GetCustomRailSprite(rti, tile, RTSG_WIRES, upper_halftile); return wires == 0 ? SPR_WIRE_BASE : wires; } /** * Get the base pylon sprite to use. */ -static inline SpriteID GetPylonBase(TileIndex tile) +static inline SpriteID GetPylonBase(TileIndex tile, bool upper_halftile = false) { const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); - SpriteID pylons = GetCustomRailSprite(rti, tile, RTSG_PYLONS); + SpriteID pylons = GetCustomRailSprite(rti, tile, RTSG_PYLONS, upper_halftile); return pylons == 0 ? SPR_PYLON_BASE : pylons; } @@ -274,7 +274,11 @@ static void DrawCatenaryRailway(const TileInfo *ti) /* Half tile slopes coincide only with horizontal/vertical track. * Faking a flat slope results in the correct sprites on positions. */ - if (IsHalftileSlope(tileh[TS_HOME])) tileh[TS_HOME] = SLOPE_FLAT; + Corner halftile_corner = CORNER_INVALID; + if (IsHalftileSlope(tileh[TS_HOME])) { + halftile_corner = GetHighestSlopeCorner(tileh[TS_HOME]); + tileh[TS_HOME] = SLOPE_FLAT; + } TLG tlg = GetTLG(ti->tile); byte PCPstatus = 0; @@ -295,9 +299,17 @@ static void DrawCatenaryRailway(const TileInfo *ti) AdjustTileh(ti->tile, &tileh[TS_HOME]); - SpriteID pylon_base = GetPylonBase(ti->tile); + SpriteID pylon_normal = GetPylonBase(ti->tile); + SpriteID pylon_halftile = (halftile_corner != CORNER_INVALID) ? GetPylonBase(ti->tile, true) : pylon_normal; for (DiagDirection i = DIAGDIR_BEGIN; i < DIAGDIR_END; i++) { + static const uint edge_corners[] = { + 1 << CORNER_N | 1 << CORNER_E, // DIAGDIR_NE + 1 << CORNER_S | 1 << CORNER_E, // DIAGDIR_SE + 1 << CORNER_S | 1 << CORNER_W, // DIAGDIR_SW + 1 << CORNER_N | 1 << CORNER_W, // DIAGDIR_NW + }; + SpriteID pylon_base = (halftile_corner != CORNER_INVALID && HasBit(edge_corners[i], halftile_corner)) ? pylon_halftile : pylon_normal; TileIndex neighbour = ti->tile + TileOffsByDiagDir(i); Foundation foundation = FOUNDATION_NONE; byte elevation = GetPCPElevation(ti->tile, i); @@ -426,11 +438,21 @@ static void DrawCatenaryRailway(const TileInfo *ti) if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return; } - SpriteID wire_base = GetWireBase(ti->tile); + SpriteID wire_normal = GetWireBase(ti->tile); + SpriteID wire_halftile = (halftile_corner != CORNER_INVALID) ? GetWireBase(ti->tile, true) : wire_normal; + Track halftile_track; + switch (halftile_corner) { + case CORNER_W: halftile_track = TRACK_LEFT; break; + case CORNER_S: halftile_track = TRACK_LOWER; break; + case CORNER_E: halftile_track = TRACK_RIGHT; break; + case CORNER_N: halftile_track = TRACK_UPPER; break; + default: halftile_track = INVALID_TRACK; break; + } /* Drawing of pylons is finished, now draw the wires */ Track t; FOR_EACH_SET_TRACK(t, wireconfig[TS_HOME]) { + SpriteID wire_base = (t == halftile_track) ? wire_halftile : wire_normal; byte PCPconfig = HasBit(PCPstatus, PCPpositions[t][0]) + (HasBit(PCPstatus, PCPpositions[t][1]) << 1); diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index ec4810461..821d1362d 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -280,9 +280,10 @@ void IndustryTileOverrideManager::SetEntitySpec(const IndustryTileSpec *its) /** Function used by houses (and soon industries) to get information * on type of "terrain" the tile it is queries sits on. * @param tile TileIndex of the tile been queried + * @param upper_halftile If true, query upper halftile in case of rail tiles. * @return value corresponding to the grf expected format: * Terrain type: 0 normal, 1 desert, 2 rainforest, 4 on or above snowline */ -uint32 GetTerrainType(TileIndex tile) +uint32 GetTerrainType(TileIndex tile, bool upper_halftile) { switch (_settings_game.game_creation.landscape) { case LT_TROPIC: return GetTropicZone(tile); @@ -295,7 +296,7 @@ uint32 GetTerrainType(TileIndex tile) case MP_RAILWAY: { RailGroundType ground = GetRailGroundType(tile); - has_snow = (ground == RAIL_GROUND_ICE_DESERT); + has_snow = (ground == RAIL_GROUND_ICE_DESERT || (upper_halftile && ground == RAIL_GROUND_HALF_SNOW)); break; } diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index d5b9d9901..a30390603 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -123,7 +123,7 @@ extern IndustryTileOverrideManager _industile_mngr; extern AirportOverrideManager _airport_mngr; extern AirportTileOverrideManager _airporttile_mngr; -uint32 GetTerrainType(TileIndex tile); +uint32 GetTerrainType(TileIndex tile, bool upper_halftile = false); TileIndex GetNearbyTile(byte parameter, TileIndex tile); uint32 GetNearbyTileInformation(TileIndex tile); diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 53894dca7..114f31b7c 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -49,7 +49,7 @@ static uint32 RailTypeGetVariable(const ResolverObject *object, byte variable, b } switch (variable) { - case 0x40: return GetTerrainType(tile); + case 0x40: return GetTerrainType(tile, object->u.routes.upper_halftile); case 0x41: return 0; case 0x42: return IsLevelCrossingTile(tile) && IsCrossingBarred(tile); case 0x43: @@ -70,7 +70,7 @@ static const SpriteGroup *RailTypeResolveReal(const ResolverObject *object, cons return NULL; } -static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile) +static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile, bool upper_halftile) { res->GetRandomBits = &RailTypeGetRandomBits; res->GetTriggers = &RailTypeGetTriggers; @@ -79,6 +79,7 @@ static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile) res->ResolveReal = &RailTypeResolveReal; res->u.routes.tile = tile; + res->u.routes.upper_halftile = upper_halftile; res->callback = CBID_NO_CALLBACK; res->callback_param1 = 0; @@ -89,7 +90,7 @@ static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile) res->count = 0; } -SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg) +SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, bool upper_halftile) { assert(rtsg < RTSG_END); @@ -98,7 +99,7 @@ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSp const SpriteGroup *group; ResolverObject object; - NewRailTypeResolver(&object, tile); + NewRailTypeResolver(&object, tile, upper_halftile); group = SpriteGroup::Resolve(rti->group[rtsg], &object); if (group == NULL || group->GetNumResults() == 0) return 0; @@ -128,5 +129,5 @@ uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile) */ void GetRailTypeResolver(ResolverObject *ro, uint index) { - NewRailTypeResolver(ro, index); + NewRailTypeResolver(ro, index, false); } diff --git a/src/newgrf_railtype.h b/src/newgrf_railtype.h index 8dcd4fed0..40f772c03 100644 --- a/src/newgrf_railtype.h +++ b/src/newgrf_railtype.h @@ -5,7 +5,7 @@ #include "rail.h" -SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg); +SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, bool upper_halftile = false); uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile); diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 4ee77a29a..ed8eac529 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -343,6 +343,7 @@ struct ResolverObject { } generic; struct { TileIndex tile; + bool upper_halftile; ///< Are we resolving sprites for the upper halftile? } routes; struct { const struct Station *st; diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 0bcae1a66..ab3444cbd 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1791,8 +1791,9 @@ static void DrawTrackFence_WE_2(const TileInfo *ti, SpriteID base_image) static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti) { - /* Base sprite for track fences. */ - SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES); + /* Base sprite for track fences. + * Note: Halftile slopes only have fences on the upper part. */ + SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES, IsHalftileSlope(ti->tileh)); if (base_image == 0) base_image = SPR_TRACK_FENCE_FLAT_X; switch (GetRailGroundType(ti->tile)) { @@ -1951,6 +1952,8 @@ static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeIn if (IsValidCorner(halftile_corner)) { DrawFoundation(ti, HalftileFoundation(halftile_corner)); + overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY, true); + ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND, true); /* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */ Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner)); -- cgit v1.2.3-54-g00ecf