From 6caed5f15e7eec01a20fdc2e0781af6a9787a5a6 Mon Sep 17 00:00:00 2001 From: Francis Herne Date: Mon, 26 Dec 2022 21:06:21 +0100 Subject: [PATCH] Add: Slope-aware and roadtype-specific one-way sprites. (#10282) --- media/baseset/openttd.grf | Bin 508716 -> 509868 bytes media/baseset/openttd/oneway.nfo | 28 +++++++++++++++++++++------- media/baseset/openttd/oneway.png | Bin 1222 -> 7846 bytes src/newgrf.cpp | 10 +++++++++- src/road.h | 1 + src/road_cmd.cpp | 12 +++++++++++- src/table/sprites.h | 6 ++++-- 7 files changed, 46 insertions(+), 11 deletions(-) diff --git a/media/baseset/openttd.grf b/media/baseset/openttd.grf index e3ebf2dd675589b31cdab66116ae5db1d72520bf..9e08fb17c3a801a57391f8f6656f9240f5e3d2f0 100644 GIT binary patch delta 798 zcmZ9KPe>F|9LHyzx0$7o?&{9y#_`@J?@jpYMD>?@ix`PT!3Z zB6x4Ekr5(}kg5?PJtt%)wy6Q4xJ4G0y%lwjNuuh<7}+5$dOy|XIGK~ad&}ylI5{S+ zo%SV2w^&kRtt6;gpGBfhB}h+=k67g2azxAU`IqL^>&;b*;(RAH9SeE zWUv}mr*CAkpQC6p6g`O^Eo((Ezy^^kbV1ec;b}34*V?>VpQ#RQw$Jl!pH-vB@%#*UtUPl?r8bPl07Dnmm`xkv;$@}%sXQ38ypwicsxYNc! z*{MCD7(v!NCR=T8Ck{BB2y0>F^-;Wpf%o`|5+yW9. // -1 * 0 0C "One way road graphics" - -1 * 3 05 09 06 - -1 sprites/oneway.png 8bpp 34 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 66 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 98 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 130 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 162 8 24 16 -12 -8 normal - -1 sprites/oneway.png 8bpp 194 8 24 16 -12 -8 normal + -1 * 3 05 09 12 + -1 sprites/oneway.png 8bpp 34 8 24 16 -10 -9 normal + -1 sprites/oneway.png 8bpp 66 8 24 16 -13 -7 normal + -1 sprites/oneway.png 8bpp 98 8 24 16 -12 -8 normal + -1 sprites/oneway.png 8bpp 130 8 24 16 -15 -10 normal + -1 sprites/oneway.png 8bpp 162 8 24 16 -12 -9 normal + -1 sprites/oneway.png 8bpp 194 8 24 16 -11 -8 normal + + -1 sprites/oneway.png 8bpp 34 40 24 16 -13 -10 normal + -1 sprites/oneway.png 8bpp 66 40 24 16 -12 -8 normal + -1 sprites/oneway.png 8bpp 98 40 24 16 -12 -9 normal + -1 sprites/oneway.png 8bpp 130 40 24 16 -11 -8 normal + -1 sprites/oneway.png 8bpp 162 40 24 16 -9 -10 normal + -1 sprites/oneway.png 8bpp 194 40 24 16 -10 -9 normal + + -1 sprites/oneway.png 8bpp 34 72 24 16 -8 -11 normal + -1 sprites/oneway.png 8bpp 66 72 24 16 -11 -5 normal + -1 sprites/oneway.png 8bpp 98 72 24 16 -12 -8 normal + -1 sprites/oneway.png 8bpp 130 72 24 16 -12 -5 normal + -1 sprites/oneway.png 8bpp 162 72 24 16 -14 -10 normal + -1 sprites/oneway.png 8bpp 194 72 24 16 -12 -8 normal diff --git a/media/baseset/openttd/oneway.png b/media/baseset/openttd/oneway.png index 15542af8563cdcc8870d2a251d01ae0a8daf9e83..843747677fc0296025e49b4fc7b70c3a789c465f 100644 GIT binary patch literal 7846 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 ZAS}Ca8E5c8FFe42yPLP`1!ubKe*k#%zwZD5 delta 433 zcmV;i0Z#s=J;n);7Z)H10{{R3-A3%k00001b5ch_0Itp)>9e>O4g-GybV)=(RCwC$ znq6+fFc1d!N)K&x%wyJG9@x?P&%OY_#R{LSKIYHx zSbRnP+5rAWxSb$&`LSMrQ3Hg@0n~!jO3-3)i+3m-f&B_%*Zjz~0=G&KLEw&ikV*kt zJs#bI#5x#2Q$YX#K>&Z+2x1P85(n6sAbDi%{Ao0Tz>5fy^XI^NL8jpuLEr@h8QZ~j zK?+?2LEz~G`EetAf*b}4g3R**f*j6sBM9tJkl*ex)VeqSQjo!_QWx1O2pt3-Vu>}k zf@M6VV=4%8KFK12O!*N6?jgux7wr^qo-2J(!0Gh<(WR0gqauH6^Jh;GCqIB*kQN2p zcW>Rv5u}BHPJRHjAdQwl$G%U|Q>y=#a8rH+f!hiq-bAYp0RW_ev^<85-g8`Yj0_+b zM0t^?zK8_S3nF|9qJGK(pcO>?m{9!~55#dCK+5CA|B00aR*5C8-LKo9@~0YDId br{WtE&P^u))G`fc00000NkvXXu0mjfMRc?2 diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 5f1991ae6e..692ef30850 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -6274,9 +6274,17 @@ static void GraphicsNew(ByteReader *buf) if (offset <= depot_no_track_offset && offset + num > depot_no_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NO_TRACK; } + /* If the baseset or grf only provides sprites for flat tiles (pre #10282), duplicate those for use on slopes. */ + bool dup_oneway_sprites = ((type == 0x09) && (offset + num <= SPR_ONEWAY_SLOPE_N_OFFSET)); + for (; num > 0; num--) { _cur.nfo_line++; - LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, *_cur.file, _cur.nfo_line); + int load_index = (replace == 0 ? _cur.spriteid++ : replace++); + LoadNextSprite(load_index, *_cur.file, _cur.nfo_line); + if (dup_oneway_sprites) { + DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_N_OFFSET); + DupSprite(load_index, load_index + SPR_ONEWAY_SLOPE_S_OFFSET); + } } _cur.skip_sprites = skip_num; diff --git a/src/road.h b/src/road.h index c34579b5bb..c3fcc30ca9 100644 --- a/src/road.h +++ b/src/road.h @@ -66,6 +66,7 @@ enum RoadTypeSpriteGroup { ROTSG_DEPOT, ///< Optional: Depot images ROTSG_reserved3, ///< Placeholder, if we add road fences (for highways). ROTSG_ROADSTOP, ///< Required: Drive-in stop surface + ROTSG_ONEWAY, ///< Optional: One-way indicator images ROTSG_END, }; diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index dda2f2fa2a..94b4423a15 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1606,7 +1606,17 @@ static void DrawRoadBits(TileInfo *ti) if (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)); + SpriteID oneway = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_ONEWAY); + + if (oneway == 0) oneway = SPR_ONEWAY_BASE; + + if ((ti->tileh == SLOPE_NE) || (ti->tileh == SLOPE_NW)) { + oneway += SPR_ONEWAY_SLOPE_N_OFFSET; + } else if ((ti->tileh == SLOPE_SE) || (ti->tileh == SLOPE_SW)) { + oneway += SPR_ONEWAY_SLOPE_S_OFFSET; + } + + DrawGroundSpriteAt(oneway + drd - 1 + ((road == ROAD_X) ? 0 : 3), PAL_NONE, 8, 8, GetPartialPixelZ(8, 8, ti->tileh)); } } diff --git a/src/table/sprites.h b/src/table/sprites.h index b0e61b5d02..407a7a2d87 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.h @@ -290,8 +290,10 @@ static const SpriteID SPR_TRAMWAY_DEPOT_NO_TRACK = SPR_TRAMWAY_BASE + 113; static const uint16 TRAMWAY_SPRITE_COUNT = 119; /** One way road sprites */ -static const SpriteID SPR_ONEWAY_BASE = SPR_TRAMWAY_BASE + TRAMWAY_SPRITE_COUNT; -static const uint16 ONEWAY_SPRITE_COUNT = 6; +static const SpriteID SPR_ONEWAY_BASE = SPR_TRAMWAY_BASE + TRAMWAY_SPRITE_COUNT; +static const SpriteID SPR_ONEWAY_SLOPE_N_OFFSET = 6; +static const SpriteID SPR_ONEWAY_SLOPE_S_OFFSET = 12; +static const uint16 ONEWAY_SPRITE_COUNT = 18; /** Tunnel sprites with grass only for custom railtype tunnel. */ static const SpriteID SPR_RAILTYPE_TUNNEL_BASE = SPR_ONEWAY_BASE + ONEWAY_SPRITE_COUNT;