From 264b9408cc0e4fb2334a3c378b906926a8282fb2 Mon Sep 17 00:00:00 2001 From: Richard Wheeler <2762690+zephyris@users.noreply.github.com> Date: Sat, 22 Nov 2025 21:47:49 +0000 Subject: [PATCH] Feature: Add bridge deck overlays Fixes #219. Uses a uniform width of sprites across infrastructure types, notably rail and maglev are not narrower than road and monorail, which is unlike openttd.grf. --- baseset/nml/extra/extra-bridge-decks.pnml | 37 +++++++++++++++++++ baseset/ogfx2e_extra.pnml | 1 + .../256/bridgeramps_deckonly_32bpp.pdn | 3 ++ .../256/bridgeramps_deckonly_32bpp.png | 3 ++ .../bridges/64/bridgeramps_deckonly_32bpp.pdn | 3 ++ .../bridges/64/bridgeramps_deckonly_32bpp.png | 3 ++ .../bridges/bridge_infrastructureoverlay.py | 2 + templates/zoom-sensitive.pnml | 21 +++++++++++ 8 files changed, 73 insertions(+) create mode 100644 baseset/nml/extra/extra-bridge-decks.pnml create mode 100644 graphics/bridges/256/bridgeramps_deckonly_32bpp.pdn create mode 100644 graphics/bridges/256/bridgeramps_deckonly_32bpp.png create mode 100644 graphics/bridges/64/bridgeramps_deckonly_32bpp.pdn create mode 100644 graphics/bridges/64/bridgeramps_deckonly_32bpp.png diff --git a/baseset/nml/extra/extra-bridge-decks.pnml b/baseset/nml/extra/extra-bridge-decks.pnml new file mode 100644 index 00000000..4bc44c42 --- /dev/null +++ b/baseset/nml/extra/extra-bridge-decks.pnml @@ -0,0 +1,37 @@ +// Bridge decks for overlay on NewGRF bridges +if (climate != CLIMATE_TOYLAND) { + replacenew bridge_decks_spr0(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_rail_8bpp.png", 0) { template_bridgedeckoverlay_general(0, 0, 1) } + #ez alternative_sprites(bridge_decks_spr0, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_rail_8bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + #32 alternative_sprites(bridge_decks_spr0, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_rail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_spr0, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_rail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + replacenew bridge_decks_spr6(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_monorail_8bpp.png", 6) { template_bridgedeckoverlay_general(0, 0, 1) } + #ez alternative_sprites(bridge_decks_spr6, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_monorail_8bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + #32 alternative_sprites(bridge_decks_spr6, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_monorail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_spr6, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_monorail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + replacenew bridge_decks_spr12(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_maglev_8bpp.png", 12) { template_bridgedeckoverlay_general(0, 0, 1) } + #ez alternative_sprites(bridge_decks_spr12, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_maglev_8bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + #32 alternative_sprites(bridge_decks_spr12, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_maglev_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_spr12, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_maglev_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + replacenew bridge_decks_spr18(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_road_8bpp.png", 18) { template_bridgedeckoverlay_road(0, 0, 1) } + #ez alternative_sprites(bridge_decks_spr18, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_road_8bpp.png") { template_bridgedeckoverlay_road(0, 0, 4) } + #32 alternative_sprites(bridge_decks_spr18, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_road_bt32bpp.png") { template_bridgedeckoverlay_road(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_spr18, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_road_bt32bpp.png") { template_bridgedeckoverlay_road(0, 0, 4) } +} +if (climate == CLIMATE_TOYLAND) { + replacenew bridge_decks_toyland_spr0(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_rail_8bpp.png", 0) { template_bridgedeckoverlay_general(0, 0, 1) } + #ez alternative_sprites(bridge_decks_toyland_spr0, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_rail_8bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + #32 alternative_sprites(bridge_decks_toyland_spr0, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_rail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_toyland_spr0, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_rail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + replacenew bridge_decks_toyland_spr6(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_monorail_8bpp.png", 6) { template_bridgedeckoverlay_general(0, 0, 1) } + #ez alternative_sprites(bridge_decks_toyland_spr6, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_monorail_8bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + #32 alternative_sprites(bridge_decks_toyland_spr6, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_monorail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_toyland_spr6, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_monorail_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + replacenew bridge_decks_toyland_spr12(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_maglev_8bpp.png", 12) { template_bridgedeckoverlay_general(0, 0, 1) } + #ez alternative_sprites(bridge_decks_toyland_spr12, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_maglev_8bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + #32 alternative_sprites(bridge_decks_toyland_spr12, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_maglev_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_toyland_spr12, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_maglev_bt32bpp.png") { template_bridgedeckoverlay_general(0, 0, 4) } + replacenew bridge_decks_toyland_spr18(BRIDGE_DECKS, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_road_8bpp.png", 18) { template_bridgedeckoverlay_road(0, 0, 1) } + #ez alternative_sprites(bridge_decks_toyland_spr18, ZOOM_LEVEL_IN_4X, BIT_DEPTH_8BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_road_8bpp.png") { template_bridgedeckoverlay_road(0, 0, 4) } + #32 alternative_sprites(bridge_decks_toyland_spr18, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "../graphics/bridges/64/pygen/ramps_deckonly_toyland_road_bt32bpp.png") { template_bridgedeckoverlay_road(0, 0, 1) } + #32 #ez alternative_sprites(bridge_decks_toyland_spr18, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "../graphics/bridges/256/pygen/ramps_deckonly_toyland_road_bt32bpp.png") { template_bridgedeckoverlay_road(0, 0, 4) } +} diff --git a/baseset/ogfx2e_extra.pnml b/baseset/ogfx2e_extra.pnml index d67026d7..070864b7 100644 --- a/baseset/ogfx2e_extra.pnml +++ b/baseset/ogfx2e_extra.pnml @@ -17,6 +17,7 @@ #include "nml/extra/extra-tram-tracks.pnml" #include "nml/extra/extra-road-waypoints.pnml" #include "nml/extra/extra-overlay-rocks.pnml" +#include "nml/extra/extra-bridge-decks.pnml" // OpenTTD-specific additional sprite sets #include "nml/extra/extra-openttd-airport.pnml" diff --git a/graphics/bridges/256/bridgeramps_deckonly_32bpp.pdn b/graphics/bridges/256/bridgeramps_deckonly_32bpp.pdn new file mode 100644 index 00000000..11d95773 --- /dev/null +++ b/graphics/bridges/256/bridgeramps_deckonly_32bpp.pdn @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eece347ec1df4a703ad651d586470169f9b858cae65996aef38e06b508c26827 +size 17320 diff --git a/graphics/bridges/256/bridgeramps_deckonly_32bpp.png b/graphics/bridges/256/bridgeramps_deckonly_32bpp.png new file mode 100644 index 00000000..2c588d86 --- /dev/null +++ b/graphics/bridges/256/bridgeramps_deckonly_32bpp.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:97c0a53e4777c1c91f33c9a5c31991d2637c075afd17817edaea1da74b186979 +size 822 diff --git a/graphics/bridges/64/bridgeramps_deckonly_32bpp.pdn b/graphics/bridges/64/bridgeramps_deckonly_32bpp.pdn new file mode 100644 index 00000000..316f66b4 --- /dev/null +++ b/graphics/bridges/64/bridgeramps_deckonly_32bpp.pdn @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcd792fafbf637dab5bec20e956c5316cb8132f7d70c70889fd0f558e7480c29 +size 6058 diff --git a/graphics/bridges/64/bridgeramps_deckonly_32bpp.png b/graphics/bridges/64/bridgeramps_deckonly_32bpp.png new file mode 100644 index 00000000..1c49911f --- /dev/null +++ b/graphics/bridges/64/bridgeramps_deckonly_32bpp.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ef9e06564ab9780374b4ea11a9651ecf406e090c7f9d1fa2fd26dc636263b5b +size 510 diff --git a/graphics/bridges/bridge_infrastructureoverlay.py b/graphics/bridges/bridge_infrastructureoverlay.py index f5ef0017..ec7fa729 100644 --- a/graphics/bridges/bridge_infrastructureoverlay.py +++ b/graphics/bridges/bridge_infrastructureoverlay.py @@ -115,12 +115,14 @@ def infrastructure_bridge_infrastructureoverlay(scale, mode, base_path=".", verb "ramps_general": "bridgeramps_general_32bpp.png", "ramps_norecolour": "bridgeramps_norecolour_32bpp.png", "ramps_wood": "bridgeramps_wood_32bpp.png", + "ramps_deckonly": "bridgeramps_deckonly_32bpp.png", } elif mode == "roadramps_toyland" or mode == "railramps_toyland": bridge_list = { "ramps_general_toyland": "bridgeramps_general_toyland_32bpp.png", "ramps_norecolour_toyland": "bridgeramps_norecolour_32bpp.png", "ramps_wood_toyland": "bridgeramps_wood_toyland_32bpp.png", + "ramps_deckonly_toyland": "bridgeramps_deckonly_32bpp.png", } bridgemask = "bridgeramps_deckmask.png" composite_over = False diff --git a/templates/zoom-sensitive.pnml b/templates/zoom-sensitive.pnml index 50ed4703..0acbad7a 100644 --- a/templates/zoom-sensitive.pnml +++ b/templates/zoom-sensitive.pnml @@ -709,6 +709,27 @@ template template_bridgeramps_wood(x, y, z) { [ 1*z+x*z, 1*z+y*z, 64*z, 47*z-1, -31*z, -24*z ] } +// Template bridges: extra deck overlays +template template_bridgedeckoverlay_general(x, y, z) { + [ 1*z+x*z, 1*z+y*z, 64*z, 47*z-1, -31*z, -16*z ] + [ 131*z+x*z, 1*z+y*z, 64*z, 47*z-1, -31*z, -16*z ] + + [ 261*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] + [ 456*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] + [ 326*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] + [ 391*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] +} + +template template_bridgedeckoverlay_road(x, y, z) { + [ 131*z+x*z, 1*z+y*z, 64*z, 47*z-1, -31*z, -16*z ] + [ 1*z+x*z, 1*z+y*z, 64*z, 47*z-1, -31*z, -16*z ] + + [ 261*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] + [ 456*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] + [ 326*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] + [ 391*z+x*z, 1*z+y*z, 64*z, 55*z-1, -31*z, -24*z ] +} + // Template bridges: simple/core bridges template template_bridge_single_rear(x, y, z) { [ 1*z+x*z, 1*z+y*z, 64*z, 128*z-1, -31*z, -84*z ]