From 06f203a7e70d59f3a79bc2a2f19be890f0233a0a Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 5 Dec 2018 20:33:45 +0000 Subject: [PATCH 1/6] Implement surfaces, edges and stations as objects --- OpenRCT2.xcodeproj/project.pbxproj | 18 + data/language/en-GB.txt | 17 +- resources/g2/edge/brick.png | Bin 769 -> 0 bytes resources/g2/edge/brown_sandstone.png | Bin 783 -> 0 bytes resources/g2/edge/green_stucco.png | Bin 472 -> 0 bytes resources/g2/edge/grey_sandstone.png | Bin 566 -> 0 bytes resources/g2/edge/purple_stucco.png | Bin 472 -> 0 bytes resources/g2/edge/red_stucco.png | Bin 472 -> 0 bytes resources/g2/edge/rust.png | Bin 776 -> 0 bytes resources/g2/edge/skyscraper_a.png | Bin 1057 -> 0 bytes resources/g2/edge/skyscraper_b.png | Bin 943 -> 0 bytes resources/g2/edge/white_stucco.png | Bin 472 -> 0 bytes resources/g2/edge/yellow_stucco.png | Bin 472 -> 0 bytes resources/g2/sprites.json | 55 --- src/openrct2-ui/interface/LandTool.cpp | 92 ++-- src/openrct2-ui/interface/LandTool.h | 3 - .../windows/EditorObjectSelection.cpp | 4 + src/openrct2-ui/windows/Land.cpp | 45 +- src/openrct2-ui/windows/MapGen.cpp | 63 ++- src/openrct2-ui/windows/Ride.cpp | 94 ++-- src/openrct2/Editor.cpp | 16 + src/openrct2/EditorObjectSelectionSession.cpp | 6 +- src/openrct2/actions/RideCreateAction.hpp | 2 +- src/openrct2/drawing/Drawing.Sprite.cpp | 6 +- src/openrct2/drawing/Drawing.h | 14 +- src/openrct2/localisation/StringIds.h | 20 +- src/openrct2/object/Object.cpp | 11 + src/openrct2/object/Object.h | 10 +- src/openrct2/object/ObjectFactory.cpp | 18 + src/openrct2/object/ObjectJsonHelpers.cpp | 194 ++++++--- src/openrct2/object/ObjectJsonHelpers.h | 6 +- src/openrct2/object/ObjectLimits.h | 4 + src/openrct2/object/ObjectList.cpp | 10 +- src/openrct2/object/ObjectManager.cpp | 48 +++ src/openrct2/object/ObjectRepository.cpp | 11 - src/openrct2/object/RideObject.cpp | 46 +- src/openrct2/object/StationObject.cpp | 94 ++++ src/openrct2/object/StationObject.h | 41 ++ src/openrct2/object/TerrainEdgeObject.cpp | 54 +++ src/openrct2/object/TerrainEdgeObject.h | 32 ++ src/openrct2/object/TerrainSurfaceObject.cpp | 140 ++++++ src/openrct2/object/TerrainSurfaceObject.h | 68 +++ .../paint/tile_element/Paint.Entrance.cpp | 25 +- .../paint/tile_element/Paint.Surface.cpp | 407 ++++++------------ src/openrct2/rct1/Tables.cpp | 32 +- src/openrct2/ride/Ride.cpp | 13 + src/openrct2/ride/Ride.h | 22 +- src/openrct2/ride/RideData.cpp | 17 - src/openrct2/ride/RideData.h | 11 - src/openrct2/ride/TrackPaint.cpp | 78 ++-- src/openrct2/ride/TrackPaint.h | 11 +- src/openrct2/ride/Vehicle.cpp | 2 +- .../coaster/MultiDimensionRollerCoaster.cpp | 10 +- src/openrct2/ride/gentle/MiniGolf.cpp | 10 +- src/openrct2/ride/thrill/GoKarts.cpp | 10 +- src/openrct2/ride/transport/Chairlift.cpp | 12 +- src/openrct2/ride/water/BoatHire.cpp | 6 +- src/openrct2/ride/water/SubmarineRide.cpp | 6 +- src/openrct2/scenario/Scenario.cpp | 2 +- src/openrct2/sprites.h | 40 +- src/openrct2/world/Map.cpp | 30 +- src/openrct2/world/Map.h | 1 - src/openrct2/world/MapAnimation.cpp | 23 +- test/testpaint/Compat.cpp | 7 + test/testpaint/TestPaint.cpp | 4 +- test/testpaint/TestTrack.cpp | 2 +- 66 files changed, 1212 insertions(+), 811 deletions(-) delete mode 100644 resources/g2/edge/brick.png delete mode 100644 resources/g2/edge/brown_sandstone.png delete mode 100644 resources/g2/edge/green_stucco.png delete mode 100644 resources/g2/edge/grey_sandstone.png delete mode 100644 resources/g2/edge/purple_stucco.png delete mode 100644 resources/g2/edge/red_stucco.png delete mode 100644 resources/g2/edge/rust.png delete mode 100644 resources/g2/edge/skyscraper_a.png delete mode 100644 resources/g2/edge/skyscraper_b.png delete mode 100644 resources/g2/edge/white_stucco.png delete mode 100644 resources/g2/edge/yellow_stucco.png create mode 100644 src/openrct2/object/StationObject.cpp create mode 100644 src/openrct2/object/StationObject.h create mode 100644 src/openrct2/object/TerrainEdgeObject.cpp create mode 100644 src/openrct2/object/TerrainEdgeObject.h create mode 100644 src/openrct2/object/TerrainSurfaceObject.cpp create mode 100644 src/openrct2/object/TerrainSurfaceObject.h diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 8e3459f1c2..0358625205 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -72,6 +72,9 @@ 93CBA4CC20A7504500867D56 /* ImageImporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 93CBA4C820A7504500867D56 /* ImageImporter.h */; }; 93DE9751209C3C1000FB1CC8 /* GameState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93DE974E209C3C0F00FB1CC8 /* GameState.cpp */; }; 93DE9753209C3C1000FB1CC8 /* GameState.h in Headers */ = {isa = PBXBuildFile; fileRef = 93DE974F209C3C0F00FB1CC8 /* GameState.h */; }; + 93F6004C213DD7DD00EEB83E /* TerrainSurfaceObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F60049213DD7DC00EEB83E /* TerrainSurfaceObject.cpp */; }; + 93F6004D213DD7DD00EEB83E /* TerrainEdgeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F6004A213DD7DC00EEB83E /* TerrainEdgeObject.cpp */; }; + 93F60050213DD7E400EEB83E /* StationObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F6004F213DD7E300EEB83E /* StationObject.cpp */; }; 93F76EED20BFF6F900D4512C /* Drawing.Sprite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F76EEB20BFF6F900D4512C /* Drawing.Sprite.cpp */; }; 93F76EEE20BFF6F900D4512C /* Drawing.String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F76EEC20BFF6F900D4512C /* Drawing.String.cpp */; }; 93F76EF020BFF71700D4512C /* InteractiveConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93F76EEF20BFF71700D4512C /* InteractiveConsole.cpp */; }; @@ -1122,6 +1125,12 @@ 93CBA4C820A7504500867D56 /* ImageImporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageImporter.h; sourceTree = ""; }; 93DE974E209C3C0F00FB1CC8 /* GameState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameState.cpp; sourceTree = ""; }; 93DE974F209C3C0F00FB1CC8 /* GameState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameState.h; sourceTree = ""; }; + 93F60048213DD7DC00EEB83E /* TerrainSurfaceObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TerrainSurfaceObject.h; sourceTree = ""; }; + 93F60049213DD7DC00EEB83E /* TerrainSurfaceObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TerrainSurfaceObject.cpp; sourceTree = ""; }; + 93F6004A213DD7DC00EEB83E /* TerrainEdgeObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TerrainEdgeObject.cpp; sourceTree = ""; }; + 93F6004B213DD7DD00EEB83E /* TerrainEdgeObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TerrainEdgeObject.h; sourceTree = ""; }; + 93F6004E213DD7E300EEB83E /* StationObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StationObject.h; sourceTree = ""; }; + 93F6004F213DD7E300EEB83E /* StationObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StationObject.cpp; sourceTree = ""; }; 93F76EEB20BFF6F900D4512C /* Drawing.Sprite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.Sprite.cpp; sourceTree = ""; }; 93F76EEC20BFF6F900D4512C /* Drawing.String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.String.cpp; sourceTree = ""; }; 93F76EEF20BFF71700D4512C /* InteractiveConsole.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InteractiveConsole.cpp; sourceTree = ""; }; @@ -2645,8 +2654,14 @@ F76C842A1EC4E7CC00FA49E2 /* SceneryObject.h */, F76C842B1EC4E7CC00FA49E2 /* SmallSceneryObject.cpp */, F76C842C1EC4E7CC00FA49E2 /* SmallSceneryObject.h */, + 93F6004F213DD7E300EEB83E /* StationObject.cpp */, + 93F6004E213DD7E300EEB83E /* StationObject.h */, F76C842F1EC4E7CC00FA49E2 /* StringTable.cpp */, F76C84301EC4E7CC00FA49E2 /* StringTable.h */, + 93F6004A213DD7DC00EEB83E /* TerrainEdgeObject.cpp */, + 93F6004B213DD7DD00EEB83E /* TerrainEdgeObject.h */, + 93F60049213DD7DC00EEB83E /* TerrainSurfaceObject.cpp */, + 93F60048213DD7DC00EEB83E /* TerrainSurfaceObject.h */, F76C84311EC4E7CC00FA49E2 /* WallObject.cpp */, F76C84321EC4E7CC00FA49E2 /* WallObject.h */, F76C84331EC4E7CC00FA49E2 /* WaterObject.cpp */, @@ -3622,6 +3637,7 @@ 93CBA4C420A7502E00867D56 /* Imaging.cpp in Sources */, C6D2BEE61F9BAACE008B557C /* TrackList.cpp in Sources */, C666EE701F37ACB10061AA04 /* LandRights.cpp in Sources */, + 93F6004D213DD7DD00EEB83E /* TerrainEdgeObject.cpp in Sources */, C666EE781F37ACB10061AA04 /* ServerList.cpp in Sources */, C654DF341F69C0430040F43D /* NewCampaign.cpp in Sources */, F76C887D1EC5324E00FA49E2 /* CursorData.cpp in Sources */, @@ -3640,6 +3656,7 @@ C68313D51FDB4F4C006DB3D8 /* Graph.cpp in Sources */, C685E51D1F8907850090598F /* Research.cpp in Sources */, C64644FB1F3FA4120026AC2D /* EditorScenarioOptions.cpp in Sources */, + 93F60050213DD7E400EEB83E /* StationObject.cpp in Sources */, C654DF321F69C0430040F43D /* InstallTrack.cpp in Sources */, C64644FF1F3FA4120026AC2D /* StaffList.cpp in Sources */, 4C29DEB3218C6AE500E8707F /* RCT12.cpp in Sources */, @@ -3683,6 +3700,7 @@ C685E51A1F8907850090598F /* Staff.cpp in Sources */, F76C888C1EC5324E00FA49E2 /* UiContext.cpp in Sources */, C666EE7D1F37ACB10061AA04 /* TitleMenu.cpp in Sources */, + 93F6004C213DD7DD00EEB83E /* TerrainSurfaceObject.cpp in Sources */, 933CBDB520CB1ACD00134678 /* Widget.cpp in Sources */, 9308D9FE209908090079EE96 /* TileElement.cpp in Sources */, F76C888D1EC5324E00FA49E2 /* UiContext.Linux.cpp in Sources */, diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 4975b861e7..c4326152fb 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -2330,18 +2330,6 @@ STR_3074 :{RED}WARNING: Your park rating is still below 700 !{NEWLINE}You hav STR_3075 :{RED}WARNING: Your park rating is still below 700 !{NEWLINE}You have only 2 weeks to raise the park rating, or your park will be closed down STR_3076 :{RED}FINAL WARNING: Your park rating is still below 700 !{NEWLINE}In just 7 days your park will be closed down unless you can raise the rating STR_3077 :{RED}CLOSURE NOTICE: Your park has been closed down ! -STR_3078 :Plain entrance -STR_3079 :Wooden entrance -STR_3080 :Canvas tent entrance -STR_3081 :Castle entrance (grey) -STR_3082 :Castle entrance (brown) -STR_3083 :Jungle entrance -STR_3084 :Log cabin entrance -STR_3085 :Classical/Roman entrance -STR_3086 :Abstract entrance -STR_3087 :Snow/Ice entrance -STR_3088 :Pagoda entrance -STR_3089 :Space entrance STR_3090 :{SMALLFONT}{BLACK}Select style of entrance, exit, and station STR_3091 :You are not allowed to remove this section! STR_3092 :You are not allowed to move or modify the station for this ride! @@ -2989,7 +2977,6 @@ STR_5484 :{BLACK}({COMMA16} week remaining) STR_5485 :{SMALLFONT}{STRING} STR_5486 :{BLACK}{COMMA16} STR_5487 :{SMALLFONT}{BLACK}Show recent messages -STR_5488 :No entrance (OpenRCT2 only!) STR_5489 :{SMALLFONT}{BLACK}Show only tracked guests STR_5490 :Disable audio on focus loss STR_5491 :Inventions list @@ -3730,6 +3717,10 @@ STR_6266 :Open custom content folder STR_6267 :Open tile inspector STR_6268 :Advance to next tick STR_6269 :Invalid climate ID +STR_6270 :Terrain Surfaces +STR_6271 :Terrain Edges +STR_6272 :Stations +STR_6273 :Music ############# # Scenarios # diff --git a/resources/g2/edge/brick.png b/resources/g2/edge/brick.png deleted file mode 100644 index 33fafac33ca7b1ed68ce26d764e897c09b4f8bc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 769 zcmV+c1OEJpP)BqmzHTb5pyklfRc&%dciYqbKA#<YqizW z`G50^kT5tfBy?@468Sdq55JHCWI%jCs&R8-c4GMjU->;he#A;)VPj&UG0~ss9I+H< z3Bc1COL^A8?|tOOUG({{etG;gPIVWn1pt2lV!SQT3f$Ij00000NkvXXu0mjfSm-^o diff --git a/resources/g2/edge/brown_sandstone.png b/resources/g2/edge/brown_sandstone.png deleted file mode 100644 index 202475cd7086b0c95074c00fb43ed20128fe71e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 783 zcmV+q1MvKbP)+R$A{yqgXi0$=i9^YznAyVtM~82|J$SgL;#2d9Y_EG0u)I^K~y-6)l|`r93c$z&V+bqE+(+s zZvX#F`!KV2duo56NKrtT5E)|tAkJY|ey#J$0^WAs!vHvd0I&cI0LSNvf1$^P)D``_ znAku#h#dxpIZ)C%PGo#H@*~ z4oO%;0PZK6xY=ej8k^I|rZswh-e)b1z9zTPWjUMj0Zx)Pn(y?bj0mltnj@o*_|&h1Y;0t^3hy=4 zV~zT)*`*16>6bJoxzp&I^S0;sNad=>nyRV(UBAZ0^Bri;diGqQQICgI`leqeoou}H z!<;qM)l<@1L;Andn}`Y6D-k`r7I5`40zUBik0m1a1HT N002ovPDHLkV1hf|W9$F` diff --git a/resources/g2/edge/green_stucco.png b/resources/g2/edge/green_stucco.png deleted file mode 100644 index 08b966fd34e1930d628230bb17461ed015822dd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 472 zcmeAS@N?(olHy`uVBq!ia0vp^+CZ$p!VDxUx6CmBQk(@Ik;M!Q+`=Ht$S`Y;1W=H@ z#M9T6{Sl+6n4rj<@NKh!Lb9155hc#~xw)x%B|t6%gL6@8Vo7R>LV0FMhJw4NZ$OG( zDmzeIG{7gs6-fKH$0yG&uU_9h`S|knw-2BHd_UCGR1PS?SQ6wH%;50sMjD8dd2_I%oI$?*qqhoww{Ms>_szuvZYTH^ zMIH)V6L1RAJ7vO=8u-hn>uj3ASwqtmOQ-Dpk+9CDZ-3h zt8dWvH%|IW0Z)Rb)GYS0G=9P^JH6z@TBAE31Ew0?@lD;i=RT*X^HS+5)7thGMR^nQ zAExa!{no$x{JrP-Kc}TgTiHBzebFv*UeEnpdRh7I*&7yopL{~<*3=j39ek@((`A3v z&c1mq`Y5yF^t}={XMRflmnwhrmh|R~)`yuzzy>4^~m%OnJ4L%r3yNV(@hJ Kb6Mw<&;$VCP`qsb diff --git a/resources/g2/edge/grey_sandstone.png b/resources/g2/edge/grey_sandstone.png deleted file mode 100644 index df4a2bb9c990a17e79a5a373fc11d96d6905b56b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 566 zcmV-60?GY}P)L;#2d9Y_EG0c%M_K~yMHy^t|-!yphvH84Uh z6Q6()7r?t0NE6o-0i~o6i%S(2Ize*oEMR9Q7s#x>H2Sl={p>KvVQ3Pp@uBJnRG`6sa7X$=T zd@hBSEz~INBD)6R2t=@lRKHuV0k8aHd2_I%oI$?*qqhoww{Ms>_szuvZYTH^ zMIH)V6L1RAJ7vO=8u-hn>uj3ASwqtmOQ-Dpk+9CDZ-3h zt8dWvH%|IW0Z)Rb)GYS0G=9P^JH6z@TBAE31Ew0?@lD;i=RT*X^HS+5)7thGMR^nQ zAExa!{no$x{JrP-Kc}TgTiHBzebFv*UeEnpdRh7I*&7yopL{~<*3=j39ek@((`A3v z&c1mq`Y5yF^t}={XMRflmnwhrmh|R~)`yuzzy>4^~m%OnJ4L%r3yNV(@hJ Kb6Mw<&;$Uxo4qXn diff --git a/resources/g2/edge/red_stucco.png b/resources/g2/edge/red_stucco.png deleted file mode 100644 index c2f24b8f2fa3a8a1a64196d59198685702b004ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 472 zcmeAS@N?(olHy`uVBq!ia0vp^+CZ$p!VDxUx6CmBQk(@Ik;M!Q+`=Ht$S`Y;1W=H@ z#M9T6{Sl+6n2_qTB~O!pLb9155hc#~xw)x%B|t6%gL6@8Vo7R>LV0FMhJw4NZ$OG( zDmzeIG{7gs6-f81t1q^;-t6yxJU#t-ef{hC^D_cm)qxU>B|(0{3=Yq3q=7g|-tI08 z9jvk*K(?@_i(`mJ@ZNxvjV%T|+>L(}MOplrHwQb)8RXkPdaLkv`-W+A-&{Q4c7k6~ zr+6;hjNeyu5V3 z`UZV};mzD3Hy!M8d!UG`V) z?3>r3k1{Jx-z#x*=BMO;sq!~(NnfA1Tku|5{+xcFOZUoN-q`+c>C%d}FTePI>n(5k zb}UG=_`a}CjrQ|>kCXg;K1WP$OiyrSowWLQ#o_w}`zP1`U={VvlvkU{>;eoc22WQ% Jmvv4FO#u8iy59f* diff --git a/resources/g2/edge/rust.png b/resources/g2/edge/rust.png deleted file mode 100644 index 5381391c179f344d5dee4e219918cc035318864e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 776 zcmV+j1NZ!iP)k{&^BL0000TX;fHrLvL+uWo~o;00000Lvm$d zbY)~9cWHEJAV*0}P-HG;2LJ#7IZ#YgMF0Q*7b7DhGczwkLqAhfLn{YMV`Eo43tMkP zTXS=7OBZj0gKvjVe^(!amzR%YC!cdOvx7swmsh$tXn+6!00DGTPE!Ct=GbNc0004E zOGiWihy@);0006XNkl9tU`$1t88&;m&XXb7J=m_Cx-|c~nPu;t7F3v7itX1c5|j@J3>gAR3JU zfPsdi9s!FD*MhghJHa&QD0trs10>*L;3`lOE(UAD_Mmpb+D}yg1>)ga5^51*60|fj zoi^TV@bu;h@kouZ%fweLmm2GuYRfB0f3eZ`VMo;^wOqYQJ-94uvwfz$YwViSF$bQ$ zY?)Y1j7)`C8s}|qz9%g!tATyj8&H<3$JQM?+=AKs@Z%r0_iQ8qK(W9Ok65WJ3d1z$ z$!&YKzlv-l-XH)BO82T~sE4bmiKV5dH{1D~`uJhOfkk03%u1t5>Y=VCVoy(_aGO=33Z`Wh=xY%p=y_vm!gmG*)81`E?1k zRcbO-;$g|QnYX1+rPF@%`>02V#WvScZy)dcFpWCezxY)bTU=F?3>QmlzHHCbuC#Xk z-~2*7pgRz5U^YJd;KRm0{32pOSr7&^h~&nejaL!B`Nc*d;BeUa91gtx(3jz5lnjnV6P1Hd1q-5!9`SL^5i0000dGczX>04FO~FGE8wM|eLPfxeE-?ziVyK_^!tCPFG zbHA5Y$7g5DuW!rGi_e2&&%>+J)9=&U+t-(K+sB9FtApp;qvzYh@4uJt^Yj19hyUB7 zni+aC00001bW%=J06^y0W&i*H0b)x>L;#2d9Y_EG0=h{=K~y-6)s*3qqc#wP+hm0g z3kw8z$nKDpIVHEi+E@f+&X;@t=gJRj_imFXIQ{9Gs;*Jb)K>!lg!@Z_mO-EYqksu+ z0f2*(0c-(`!P&oe6aaMSTZh^J=m2~L-~e0zfZ(CQh><~~gn~eU0UcU2u+TWegTWAY zJH-NV9D&LSQW@}S@RA>J^%mB9-0%l*&sJs7F+nq)dj?Sp+jd z7!yUGL_w5gq@||O%+sG=+;FkKyX!E`FaUrfpcAWr#&I>xq03uv03qJZ+UKZyTyP7=jnl_9!0!h>fC1td?L`hX8S{7G#cFWBl zeOb42+YUeNw|&?|BGs%Elg?89=j@!HCV#TrKILzDfg@r)Y#ufuA~sgagowwJw^P?z zJ8{0t?|H+1by-InneI*9MWrYczF1o~&$abqx!XPeJq4=)h%zdLh%}dNRBjaUWV&tr z+>WE==Xt*N{X4$|(p4tXf^9A9jnKTBc3XF|oxbvPbq>=Heg$(}Wxr`#T4jVP%)s4K z`_fo@(O=HaUq13naU3O7PCKa#@oKu4{LoyzW$QhE;J4B-#hTf)avQ0Fj;1^0hi0&= z_dMK|&%ZXmkST!#fgTgA+~d11Fs=sw;}=Q_XwIM$2Jwh-GI0HZa+l*HzfgEU3PuKk zz!9%l;ILptjt+19!iIAs!x5-(59jW~papQ}mjEOHHsPpoIBX8U6zV+a{S84)&=EiW beAj;g-AiQy5U_;$00000NkvXXu0mjfOAgf> diff --git a/resources/g2/edge/skyscraper_b.png b/resources/g2/edge/skyscraper_b.png deleted file mode 100644 index 1204f9f6d6a7585dbdf26c637d72a8ed263f298d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 943 zcmV;g15o^lP)dGczYES1&_DFGnLYH)lIjD?dYb zKT}gnV>e4uX|@pgO`_!i@%S5YoDLbpRcc@ zlYh6j-?ziVyQ`DSuW!%8tJBl()7#tI$A{yqgXi0$=i9^YznAax^Y_oI|J&F9pm4^ZUWQ@jo)8f^S`U?1@z?i`w&Q^C2!rSmMZT^O z1HvL^#BHHvrd6hNCbkG0$y8H=a5yz?69}eA7bFgN&;^< z_?nM4vE#f=B1jWbSPU07eTCftIBrci^k30 z)CXfKUg|DNJRyKVokNd%y0zZyZ;g6eU8z(9Yt{ljSc`WH=fs9cZ@>Mm>w{~ZS^ELr z#Z+g7K6EEc`|!LsQ|nr-8`$=*rgf8anGAVD8);L0%e`%b^lOtLI_5Ryr=PHLV0FMhJw4NZ$OG( zDmzeIG{7gs6-Za7d-vC8FP>b#d-de=hgUzpefY1M|2v=rV@Z%-FoVOh8)+a;lDE4H zLkFv@2aql7>Ealo5xh6xWMhi~4|n4qMNt-i=FP#5at8VKkKQW$-M(Sk+&32wxSilv z6nQ9cO~5Hc@01BgYTz%QuCr+dXAMnPES<9VN5VRrzFo?U-hG?)PS$u3cX(&e880v0 zuf9Rw-#F1E}+XKz^WeewyZTT@@Cckr!FO_%*u zJNxFf=%dVv)Avf;ocSsFU#k4gThiAj?iRe4mOrQ8=hD5hmp8WmTe`HO?aMFz-+IfN zz8wn^Exs?TQ=|QS-{T~IpU)AK8`Be9StqUjU2*t+!T!nhKUhV5Gv(E0GP?l7iow&> K&t;ucLK6UA-o8Qr diff --git a/resources/g2/edge/yellow_stucco.png b/resources/g2/edge/yellow_stucco.png deleted file mode 100644 index 5309fc68cc1250e0132fea0ae766d99ef2fbef2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 472 zcmeAS@N?(olHy`uVBq!ia0vp^+CZ$p!VDxUx6CmBQk(@Ik;M!Q+`=Ht$S`Y;1W=H@ z#M9T6{Sl+6m=Lqc%7pnqA=%83h!W@g+}zZ>5+Ij>!MP|ku_QG`p**uBL&4qCHy}kX zl^rN98sHP+3Z&;38*grQ-akG3^!ohU$J?LZUc5&6F~~;7k|4ie28U-i(m*1|IW0xn%I2}_i*}LodhX}a%gT4p-mu{N diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 3ce6013081..83099a5d61 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -380,61 +380,6 @@ "x_offset": 0, "y_offset": 15 }, - { - "path": "edge/brick.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/rust.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/white_stucco.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/yellow_stucco.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/red_stucco.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/purple_stucco.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/green_stucco.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/brown_sandstone.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/grey_sandstone.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/skyscraper_a.png", - "x_offset": 2, - "y_offset": 2 - }, - { - "path": "edge/skyscraper_b.png", - "x_offset": 2, - "y_offset": 2 - }, { "path": "icons/eyedropper.png", "x_offset": 5, diff --git a/src/openrct2-ui/interface/LandTool.cpp b/src/openrct2-ui/interface/LandTool.cpp index e030700a39..d6029a8f09 100644 --- a/src/openrct2-ui/interface/LandTool.cpp +++ b/src/openrct2-ui/interface/LandTool.cpp @@ -11,11 +11,17 @@ #include #include #include +#include #include #include +#include +#include +#include #include #include +using namespace OpenRCT2; + // clang-format off static uint16_t toolSizeSpriteIndices[] = { @@ -28,40 +34,6 @@ static uint16_t toolSizeSpriteIndices[] = SPR_LAND_TOOL_SIZE_6, SPR_LAND_TOOL_SIZE_7, }; - -static uint32_t FloorTextureOrder[] = -{ - TERRAIN_SAND_DARK, TERRAIN_SAND_LIGHT, TERRAIN_DIRT, TERRAIN_GRASS_CLUMPS, TERRAIN_GRASS, - TERRAIN_ROCK, TERRAIN_SAND, TERRAIN_MARTIAN, TERRAIN_CHECKERBOARD, TERRAIN_ICE, - TERRAIN_GRID_RED, TERRAIN_GRID_YELLOW, TERRAIN_GRID_BLUE, TERRAIN_GRID_GREEN -}; - -uint32_t WallTextureOrder[] = -{ - TERRAIN_EDGE_ROCK, TERRAIN_EDGE_WOOD_RED, TERRAIN_EDGE_WOOD_BLACK, TERRAIN_EDGE_ICE, TERRAIN_EDGE_BRICK, - TERRAIN_EDGE_GREY, TERRAIN_EDGE_YELLOW, TERRAIN_EDGE_RED, TERRAIN_EDGE_PURPLE, TERRAIN_EDGE_GREEN, - TERRAIN_EDGE_IRON, TERRAIN_EDGE_STONE_BROWN, TERRAIN_EDGE_STONE_GREY, TERRAIN_EDGE_SKYSCRAPER_A, TERRAIN_EDGE_SKYSCRAPER_B, - 0, 0 -}; - -uint32_t WallTexturePreviews[] = -{ - SPR_WALL_TEXTURE_ROCK, - SPR_WALL_TEXTURE_WOOD_RED, - SPR_WALL_TEXTURE_WOOD_BLACK, - SPR_WALL_TEXTURE_ICE, - SPR_G2_WALL_TEXTURE_BRICK, - SPR_G2_WALL_TEXTURE_IRON, - SPR_G2_WALL_TEXTURE_GREY, - SPR_G2_WALL_TEXTURE_YELLOW, - SPR_G2_WALL_TEXTURE_RED, - SPR_G2_WALL_TEXTURE_PURPLE, - SPR_G2_WALL_TEXTURE_GREEN, - SPR_G2_WALL_TEXTURE_STONE_BROWN, - SPR_G2_WALL_TEXTURE_STONE_GREY, - SPR_G2_WALL_TEXTURE_SKYSCRAPER_A, - SPR_G2_WALL_TEXTURE_SKYSCRAPER_B, -}; // clang-format on uint16_t gLandToolSize; @@ -86,38 +58,58 @@ uint32_t land_tool_size_to_sprite_index(uint16_t size) void land_tool_show_surface_style_dropdown(rct_window* w, rct_widget* widget, uint8_t currentSurfaceType) { - uint8_t defaultIndex = 0; + auto& objManager = GetContext()->GetObjectManager(); - for (uint8_t i = 0; i < TERRAIN_COUNT_REGULAR; i++) + auto defaultIndex = 0; + auto itemIndex = 0; + for (size_t i = 0; i < MAX_TERRAIN_SURFACE_OBJECTS; i++) { - gDropdownItemsFormat[i] = DROPDOWN_FORMAT_LAND_PICKER; - gDropdownItemsArgs[i] = SPR_FLOOR_TEXTURE_GRASS + FloorTextureOrder[i]; - if (FloorTextureOrder[i] == currentSurfaceType) + const auto surfaceObj = static_cast(objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, i)); + if (surfaceObj != nullptr) { - defaultIndex = i; + gDropdownItemsFormat[itemIndex] = DROPDOWN_FORMAT_LAND_PICKER; + gDropdownItemsArgs[itemIndex] = surfaceObj->IconImageId; + if (surfaceObj->Colour != 255) + { + gDropdownItemsArgs[itemIndex] |= surfaceObj->Colour << 19 | IMAGE_TYPE_REMAP; + } + if (i == currentSurfaceType) + { + defaultIndex = itemIndex; + } + itemIndex++; } } + auto surfaceCount = itemIndex; window_dropdown_show_image( - w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[2], 0, TERRAIN_COUNT_REGULAR, 47, 36, - gAppropriateImageDropdownItemsPerRow[TERRAIN_COUNT_REGULAR]); + w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[2], 0, surfaceCount, 47, 36, + gAppropriateImageDropdownItemsPerRow[surfaceCount]); gDropdownDefaultIndex = defaultIndex; } void land_tool_show_edge_style_dropdown(rct_window* w, rct_widget* widget, uint8_t currentEdgeType) { - uint8_t defaultIndex = 0; - // Do not show RCT1 edge styles if the player does not have RCT1. - const uint8_t edgeCount = is_csg_loaded() ? TERRAIN_EDGE_COUNT : TERRAIN_EDGE_RCT2_COUNT; + auto& objManager = GetContext()->GetObjectManager(); - for (uint8_t i = 0; i < edgeCount; i++) + auto defaultIndex = 0; + auto itemIndex = 0; + for (size_t i = 0; i < MAX_TERRAIN_EDGE_OBJECTS; i++) { - gDropdownItemsFormat[i] = DROPDOWN_FORMAT_LAND_PICKER; - gDropdownItemsArgs[i] = WallTexturePreviews[WallTextureOrder[i]]; - if (WallTextureOrder[i] == currentEdgeType) - defaultIndex = i; + const auto edgeObj = static_cast(objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_EDGE, i)); + if (edgeObj != nullptr) + { + gDropdownItemsFormat[itemIndex] = DROPDOWN_FORMAT_LAND_PICKER; + gDropdownItemsArgs[itemIndex] = edgeObj->IconImageId; + if (i == currentEdgeType) + { + defaultIndex = itemIndex; + } + itemIndex++; + } } + auto edgeCount = itemIndex; window_dropdown_show_image( w->x + widget->left, w->y + widget->top, widget->bottom - widget->top, w->colours[2], 0, edgeCount, 47, 36, diff --git a/src/openrct2-ui/interface/LandTool.h b/src/openrct2-ui/interface/LandTool.h index 04e49ae25c..979ee421ff 100644 --- a/src/openrct2-ui/interface/LandTool.h +++ b/src/openrct2-ui/interface/LandTool.h @@ -26,9 +26,6 @@ extern uint8_t gLandToolTerrainEdge; extern money32 gWaterToolRaiseCost; extern money32 gWaterToolLowerCost; -extern uint32_t WallTextureOrder[]; -extern uint32_t WallTexturePreviews[]; - uint32_t land_tool_size_to_sprite_index(uint16_t size); void land_tool_show_surface_style_dropdown(rct_window* w, rct_widget* widget, uint8_t currentSurfaceType); void land_tool_show_edge_style_dropdown(rct_window* w, rct_widget* widget, uint8_t currentEdgeType); diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index aee0e23b92..e32af26171 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -98,6 +98,10 @@ static constexpr const ObjectPageDesc ObjectSelectionPages[OBJECT_TYPE_COUNT] = { STR_OBJECT_SELECTION_PARK_ENTRANCE, SPR_TAB_PARK, false }, { STR_OBJECT_SELECTION_WATER, SPR_TAB_WATER, false }, { STR_OBJECT_SELECTION_SCENARIO_DESCRIPTION, SPR_TAB_STATS, false }, + { STR_OBJECT_SELECTION_TERRAIN_SURFACES, SPR_G2_TAB_LAND, false }, + { STR_OBJECT_SELECTION_TERRAIN_EDGES, SPR_G2_TAB_LAND, false }, + { STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, false }, + { STR_OBJECT_SELECTION_MUSIC, SPR_TAB_MUSIC_0, false }, }; #pragma region Widgets diff --git a/src/openrct2-ui/windows/Land.cpp b/src/openrct2-ui/windows/Land.cpp index f409774bc9..887f7f4cb1 100644 --- a/src/openrct2-ui/windows/Land.cpp +++ b/src/openrct2-ui/windows/Land.cpp @@ -15,9 +15,14 @@ #include #include #include +#include +#include +#include #include #include +using namespace OpenRCT2; + // clang-format off enum WINDOW_LAND_WIDGET_IDX { WIDX_BACKGROUND, @@ -214,8 +219,7 @@ static void window_land_dropdown(rct_window* w, rct_widgetindex widgetIndex, int if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; - type = (dropdownIndex == -1) ? _selectedFloorTexture - : (uint32_t)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS; + type = (dropdownIndex == -1) ? _selectedFloorTexture : dropdownIndex; if (gLandToolTerrainSurface == type) { @@ -232,7 +236,7 @@ static void window_land_dropdown(rct_window* w, rct_widgetindex widgetIndex, int if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; - type = (dropdownIndex == -1) ? _selectedWallTexture : WallTextureOrder[dropdownIndex]; + type = (dropdownIndex == -1) ? _selectedWallTexture : dropdownIndex; if (gLandToolTerrainEdge == type) { @@ -290,6 +294,27 @@ static void window_land_update(rct_window* w) */ static void window_land_invalidate(rct_window* w) { + auto surfaceImage = (uint32_t)SPR_NONE; + auto edgeImage = (uint32_t)SPR_NONE; + + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _selectedFloorTexture)); + if (surfaceObj != nullptr) + { + surfaceImage = surfaceObj->IconImageId; + if (surfaceObj->Colour != 255) + { + surfaceImage |= surfaceObj->Colour << 19 | IMAGE_TYPE_REMAP; + } + } + const auto edgeObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_EDGE, _selectedWallTexture)); + if (edgeObj != nullptr) + { + edgeImage = edgeObj->IconImageId; + } + w->pressed_widgets = (1 << WIDX_PREVIEW); if (gLandToolTerrainSurface != 255) w->pressed_widgets |= (1 << WIDX_FLOOR); @@ -300,8 +325,8 @@ static void window_land_invalidate(rct_window* w) if (gLandPaintMode) w->pressed_widgets |= (1 << WIDX_PAINTMODE); - window_land_widgets[WIDX_FLOOR].image = SPR_FLOOR_TEXTURE_GRASS + _selectedFloorTexture; - window_land_widgets[WIDX_WALL].image = WallTexturePreviews[_selectedWallTexture]; + window_land_widgets[WIDX_FLOOR].image = surfaceImage; + window_land_widgets[WIDX_WALL].image = edgeImage; // Update the preview image (for tool sizes up to 7) window_land_widgets[WIDX_PREVIEW].image = land_tool_size_to_sprite_index(gLandToolSize); } @@ -349,7 +374,15 @@ static void window_land_paint(rct_window* w, rct_drawpixelinfo* dpi) numTiles = gLandToolSize * gLandToolSize; price = 0; if (gLandToolTerrainSurface != 255) - price += numTiles * TerrainPricing[gLandToolTerrainSurface]; + { + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, gLandToolTerrainSurface)); + if (surfaceObj != nullptr) + { + price += numTiles * surfaceObj->Price; + } + } if (gLandToolTerrainEdge != 255) price += numTiles * 100; diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index 8ea82cfdcb..39ee2ffa29 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -16,11 +16,16 @@ #include #include #include +#include +#include +#include #include #include #include #include +using namespace OpenRCT2; + // clang-format off enum { WINDOW_MAPGEN_PAGE_BASE, @@ -652,8 +657,7 @@ static void window_mapgen_base_dropdown(rct_window* w, rct_widgetindex widgetInd if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; - type = (dropdownIndex == -1) ? _floorTexture - : (uint32_t)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS; + type = (dropdownIndex == -1) ? _floorTexture : dropdownIndex; if (gLandToolTerrainSurface == type) { @@ -670,7 +674,7 @@ static void window_mapgen_base_dropdown(rct_window* w, rct_widgetindex widgetInd if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; - type = (dropdownIndex == -1) ? _wallTexture : WallTextureOrder[dropdownIndex]; + type = (dropdownIndex == -1) ? _wallTexture : dropdownIndex; if (gLandToolTerrainEdge == type) { @@ -730,14 +734,34 @@ static void window_mapgen_textinput(rct_window* w, rct_widgetindex widgetIndex, static void window_mapgen_base_invalidate(rct_window* w) { + auto surfaceImage = (uint32_t)SPR_NONE; + auto edgeImage = (uint32_t)SPR_NONE; + + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _floorTexture)); + if (surfaceObj != nullptr) + { + surfaceImage = surfaceObj->IconImageId; + if (surfaceObj->Colour != 255) + { + surfaceImage |= surfaceObj->Colour << 19 | IMAGE_TYPE_REMAP; + } + } + const auto edgeObj = static_cast(objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_EDGE, _wallTexture)); + if (edgeObj != nullptr) + { + edgeImage = edgeObj->IconImageId; + } + if (w->widgets != PageWidgets[WINDOW_MAPGEN_PAGE_BASE]) { w->widgets = PageWidgets[WINDOW_MAPGEN_PAGE_BASE]; window_init_scroll_widgets(w); } - w->widgets[WIDX_FLOOR_TEXTURE].image = SPR_FLOOR_TEXTURE_GRASS + _floorTexture; - w->widgets[WIDX_WALL_TEXTURE].image = WallTexturePreviews[_wallTexture]; + w->widgets[WIDX_FLOOR_TEXTURE].image = surfaceImage; + w->widgets[WIDX_WALL_TEXTURE].image = edgeImage; window_mapgen_set_pressed_tab(w); } @@ -965,8 +989,7 @@ static void window_mapgen_simplex_dropdown(rct_window* w, rct_widgetindex widget if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; - type = (dropdownIndex == -1) ? _floorTexture - : (uint32_t)gDropdownItemsArgs[dropdownIndex] - SPR_FLOOR_TEXTURE_GRASS; + type = (dropdownIndex == -1) ? _floorTexture : dropdownIndex; if (gLandToolTerrainSurface == type) { @@ -983,7 +1006,7 @@ static void window_mapgen_simplex_dropdown(rct_window* w, rct_widgetindex widget if (dropdownIndex == -1) dropdownIndex = gDropdownHighlightedIndex; - type = (dropdownIndex == -1) ? _wallTexture : WallTextureOrder[dropdownIndex]; + type = (dropdownIndex == -1) ? _wallTexture : dropdownIndex; if (gLandToolTerrainEdge == type) { @@ -1009,14 +1032,34 @@ static void window_mapgen_simplex_update(rct_window* w) static void window_mapgen_simplex_invalidate(rct_window* w) { + auto surfaceImage = (uint32_t)SPR_NONE; + auto edgeImage = (uint32_t)SPR_NONE; + + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, _floorTexture)); + if (surfaceObj != nullptr) + { + surfaceImage = surfaceObj->IconImageId; + if (surfaceObj->Colour != 255) + { + surfaceImage |= surfaceObj->Colour << 19 | IMAGE_TYPE_REMAP; + } + } + const auto edgeObj = static_cast(objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_EDGE, _wallTexture)); + if (edgeObj != nullptr) + { + edgeImage = edgeObj->IconImageId; + } + if (w->widgets != PageWidgets[WINDOW_MAPGEN_PAGE_SIMPLEX]) { w->widgets = PageWidgets[WINDOW_MAPGEN_PAGE_SIMPLEX]; window_init_scroll_widgets(w); } - w->widgets[WIDX_SIMPLEX_FLOOR_TEXTURE].image = SPR_FLOOR_TEXTURE_GRASS + _floorTexture; - w->widgets[WIDX_SIMPLEX_WALL_TEXTURE].image = WallTexturePreviews[_wallTexture]; + w->widgets[WIDX_SIMPLEX_FLOOR_TEXTURE].image = surfaceImage; + w->widgets[WIDX_SIMPLEX_WALL_TEXTURE].image = edgeImage; widget_set_checkbox_value(w, WIDX_SIMPLEX_RANDOM_TERRAIN_CHECKBOX, _randomTerrain != 0); widget_set_checkbox_value(w, WIDX_SIMPLEX_PLACE_TREES_CHECKBOX, _placeTrees != 0); diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index abf11263c6..b6bd3aa14b 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,8 @@ #include #include +using namespace OpenRCT2; + enum { WINDOW_RIDE_PAGE_MAIN, @@ -4225,14 +4228,6 @@ static void window_ride_maintenance_paint(rct_window* w, rct_drawpixelinfo* dpi) #pragma region Colour -static constexpr const uint8_t window_ride_entrance_style_list[] = { - RIDE_ENTRANCE_STYLE_PLAIN, RIDE_ENTRANCE_STYLE_CANVAS_TENT, RIDE_ENTRANCE_STYLE_WOODEN, - RIDE_ENTRANCE_STYLE_CASTLE_BROWN, RIDE_ENTRANCE_STYLE_CASTLE_GREY, RIDE_ENTRANCE_STYLE_LOG_CABIN, - RIDE_ENTRANCE_STYLE_JUNGLE, RIDE_ENTRANCE_STYLE_CLASSICAL_ROMAN, RIDE_ENTRANCE_STYLE_ABSTRACT, - RIDE_ENTRANCE_STYLE_SNOW_ICE, RIDE_ENTRANCE_STYLE_PAGODA, RIDE_ENTRANCE_STYLE_SPACE, - RIDE_ENTRANCE_STYLE_NONE -}; - static uint32_t window_ride_get_colour_button_image(int32_t colour) { return IMAGE_TYPE_TRANSPARENT | SPRITE_ID_PALETTE_COLOUR_1(colour) | SPR_PALETTE_BTN; @@ -4240,15 +4235,24 @@ static uint32_t window_ride_get_colour_button_image(int32_t colour) static int32_t window_ride_has_track_colour(Ride* ride, int32_t trackColour) { - uint16_t colourUse = RideEntranceDefinitions[ride->entrance_style].colour_use_flags; + // Get station flags (shops don't have them) + auto stationObjFlags = 0; + if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + { + auto stationObj = ride_get_station_object(ride); + if (stationObj != nullptr) + { + stationObjFlags = stationObj->Flags; + } + } switch (trackColour) { case 0: - return ((colourUse & 1) && !ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + return (stationObjFlags & STATION_OBJECT_FLAGS::HAS_PRIMARY_COLOUR) || ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_MAIN); case 1: - return ((colourUse & 2) && !ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP)) + return (stationObjFlags & STATION_OBJECT_FLAGS::HAS_SECONDARY_COLOUR) || ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_ADDITIONAL); case 2: return ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_TRACK_COLOUR_SUPPORTS); @@ -4352,7 +4356,7 @@ static void window_ride_colour_mousedown(rct_window* w, rct_widgetindex widgetIn vehicle_colour vehicleColour; rct_widget* dropdownWidget; rct_ride_entry* rideEntry; - int32_t i, numItems, checkedIndex; + int32_t i, numItems; rct_string_id stringId; ride = get_ride(w->number); @@ -4398,28 +4402,29 @@ static void window_ride_colour_mousedown(rct_window* w, rct_widgetindex widgetIn dropdown_set_checked(ride->track_colour_supports[colourSchemeIndex], true); break; case WIDX_ENTRANCE_STYLE_DROPDOWN: - checkedIndex = -1; - for (i = 0; i < (int32_t)std::size(window_ride_entrance_style_list); i++) + { + auto ddIndex = 0; + auto& objManager = GetContext()->GetObjectManager(); + for (i = 0; i < MAX_STATION_OBJECTS; i++) { - gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[i] = RideEntranceDefinitions[window_ride_entrance_style_list[i]].string_id; - - if (ride->entrance_style == window_ride_entrance_style_list[i]) + auto stationObj = static_cast(objManager.GetLoadedObject(OBJECT_TYPE_STATION, i)); + if (stationObj != nullptr) { - checkedIndex = i; + gDropdownItemsFormat[ddIndex] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[ddIndex] = stationObj->NameStringId; + if (ride->entrance_style == i) + { + gDropdownItemsFormat[ddIndex] = STR_DROPDOWN_MENU_LABEL_SELECTED; + } + ddIndex++; } } window_dropdown_show_text_custom_width( w->x + dropdownWidget->left, w->y + dropdownWidget->top, dropdownWidget->bottom - dropdownWidget->top + 1, - w->colours[1], 0, DROPDOWN_FLAG_STAY_OPEN, std::size(window_ride_entrance_style_list), - widget->right - dropdownWidget->left); - - if (checkedIndex != -1) - { - dropdown_set_checked(checkedIndex, true); - } + w->colours[1], 0, DROPDOWN_FLAG_STAY_OPEN, ddIndex, widget->right - dropdownWidget->left); break; + } case WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN: for (i = 0; i < 3; i++) { @@ -4502,10 +4507,24 @@ static void window_ride_colour_dropdown(rct_window* w, rct_widgetindex widgetInd 0, (4 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, w->ride_colour, 0); break; case WIDX_ENTRANCE_STYLE_DROPDOWN: - game_do_command( - 0, (6 << 8) | 1, 0, (window_ride_entrance_style_list[dropdownIndex] << 8) | w->number, - GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0); + { + auto ddIndex = 0; + auto& objManager = GetContext()->GetObjectManager(); + for (auto i = 0; i < MAX_STATION_OBJECTS; i++) + { + auto stationObj = static_cast(objManager.GetLoadedObject(OBJECT_TYPE_STATION, i)); + if (stationObj != nullptr) + { + if (ddIndex == dropdownIndex) + { + game_do_command(0, (6 << 8) | 1, 0, (ddIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0); + break; + } + ddIndex++; + } + } break; + } case WIDX_VEHICLE_COLOUR_SCHEME_DROPDOWN: game_do_command(0, (5 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_APPEARANCE, 0, 0); w->vehicleIndex = 0; @@ -4669,7 +4688,13 @@ static void window_ride_colour_invalidate(rct_window* w) window_ride_colour_widgets[WIDX_ENTRANCE_STYLE].type = WWT_DROPDOWN; window_ride_colour_widgets[WIDX_ENTRANCE_STYLE_DROPDOWN].type = WWT_BUTTON; - window_ride_colour_widgets[WIDX_ENTRANCE_STYLE].text = RideEntranceDefinitions[ride->entrance_style].string_id; + auto stringId = STR_NONE; + auto stationObj = ride_get_station_object(ride); + if (stationObj != nullptr) + { + stringId = stationObj->NameStringId; + } + window_ride_colour_widgets[WIDX_ENTRANCE_STYLE].text = stringId; } else { @@ -4861,18 +4886,17 @@ static void window_ride_colour_paint(rct_window* w, rct_drawpixelinfo* dpi) { gfx_clear(&clippedDpi, PALETTE_INDEX_12); - if (ride->entrance_style != RIDE_ENTRANCE_STYLE_NONE) + auto stationObj = ride_get_station_object(ride); + if (stationObj != nullptr && stationObj->BaseImageId != 0) { - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; - int32_t terniaryColour = 0; - if (entranceStyle->base_image_id & IMAGE_TYPE_TRANSPARENT) + if (stationObj->Flags & STATION_OBJECT_FLAGS::IS_TRANSPARENT) { terniaryColour = IMAGE_TYPE_TRANSPARENT | (GlassPaletteIds[trackColour.main] << 19); } int32_t spriteIndex = SPRITE_ID_PALETTE_COLOUR_2(trackColour.main, trackColour.additional); - spriteIndex += RideEntranceDefinitions[ride->entrance_style].sprite_index; + spriteIndex += stationObj->BaseImageId; // Back gfx_draw_sprite(&clippedDpi, spriteIndex, 34, 20, terniaryColour); diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index a894ad4fdf..31262d7d99 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -19,8 +19,10 @@ #include "audio/audio.h" #include "interface/Viewport.h" #include "localisation/Localisation.h" +#include "localisation/LocalisationService.h" #include "management/NewsItem.h" #include "object/ObjectManager.h" +#include "object/ObjectRepository.h" #include "peep/Staff.h" #include "rct1/RCT1.h" #include "scenario/Scenario.h" @@ -52,6 +54,20 @@ namespace Editor static bool ReadS6(const char* path); static void ClearMapForEditing(bool fromSave); + static void object_list_load() + { + // Scan objects if necessary + auto context = GetContext(); + const auto& localisationService = context->GetLocalisationService(); + auto& objectRepository = context->GetObjectRepository(); + objectRepository.LoadOrConstruct(localisationService.GetCurrentLanguage()); + + // Reset loaded objects to just defaults + auto& objectManager = context->GetObjectManager(); + objectManager.UnloadAll(); + objectManager.LoadDefaultObjects(); + } + /** * * rct2: 0x0066FFE1 diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index 8bab398e6f..6bec7ee4e7 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -105,12 +105,16 @@ static void setup_track_designer_objects() */ void setup_in_use_selection_flags() { + auto& objectMgr = OpenRCT2::GetContext()->GetObjectManager(); + for (uint8_t objectType = 0; objectType < OBJECT_TYPE_COUNT; objectType++) { for (int32_t i = 0; i < object_entry_group_counts[objectType]; i++) { Editor::ClearSelectedObject(objectType, i, OBJECT_SELECTION_FLAG_ALL); - if (object_entry_get_chunk(objectType, i) != nullptr) + + auto loadedObj = objectMgr.GetLoadedObject(objectType, i); + if (loadedObj != nullptr) { Editor::SetSelectedObject(objectType, i, OBJECT_SELECTION_FLAG_2); } diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index 770e04f1d7..7c7e638cb9 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -295,7 +295,7 @@ public: ride->income_per_hour = MONEY32_UNDEFINED; ride->profit = MONEY32_UNDEFINED; ride->connected_message_throttle = 0; - ride->entrance_style = RIDE_ENTRANCE_STYLE_PLAIN; + ride->entrance_style = 0; ride->num_block_brakes = 0; ride->guests_favourite = 0; diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index 84ff52b416..f72df68fd0 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -128,7 +128,7 @@ static void read_and_convert_gxdat(IStream* stream, size_t count, bool is_rctc, if (src.flags & G1_FLAG_HAS_ZOOM_SPRITE) { - elements[i].zoomed_offset = (uint16_t)(i - rctc_to_rct2_index(rctc - src.zoomed_offset)); + elements[i].zoomed_offset = (int32_t)(i - rctc_to_rct2_index(rctc - src.zoomed_offset)); } else { @@ -379,9 +379,9 @@ bool gfx_load_csg() { _csg.elements[i].offset += (uintptr_t)_csg.data; // RCT1 used zoomed offsets that counted from the beginning of the file, rather than from the current sprite. - if (_csg.elements[i].zoomed_offset != 0) + if (_csg.elements[i].flags & G1_FLAG_HAS_ZOOM_SPRITE) { - _csg.elements[i].zoomed_offset = i - (SPR_CSG_BEGIN + _csg.elements[i].zoomed_offset); + _csg.elements[i].zoomed_offset = i - _csg.elements[i].zoomed_offset; } } _csgLoaded = true; diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index b5e2fe4120..20b43b188b 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -20,13 +20,13 @@ namespace OpenRCT2 struct rct_g1_element { - uint8_t* offset; // 0x00 - int16_t width; // 0x04 - int16_t height; // 0x06 - int16_t x_offset; // 0x08 - int16_t y_offset; // 0x0A - uint16_t flags; // 0x0C - uint16_t zoomed_offset; // 0x0E + uint8_t* offset; // 0x00 + int16_t width; // 0x04 + int16_t height; // 0x06 + int16_t x_offset; // 0x08 + int16_t y_offset; // 0x0A + uint16_t flags; // 0x0C + int32_t zoomed_offset; // 0x0E }; struct rct_drawpixelinfo diff --git a/src/openrct2/localisation/StringIds.h b/src/openrct2/localisation/StringIds.h index 51f4320d8d..19b8af0ae6 100644 --- a/src/openrct2/localisation/StringIds.h +++ b/src/openrct2/localisation/StringIds.h @@ -556,7 +556,7 @@ enum STR_SELECT_VEHICLE_COLOUR_SCHEME_TIP = 1140, STR_SELECT_VEHICLE_TO_MODIFY_TIP = 1141, STR_DROPDOWN_MENU_LABEL = 1142, - // STR_1143 :{RIGHTGUILLEMET}{MOVE_X}{SMALLFONT}{STRINGID} + STR_DROPDOWN_MENU_LABEL_SELECTED = 1143, STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION = 1144, STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION = 1145, STR_ENTRANCE_NOT_YET_BUILT = 1146, @@ -2413,18 +2413,6 @@ enum STR_PARK_RATING_WARNING_2_WEEKS_REMAINING = 3075, STR_PARK_RATING_WARNING_1_WEEK_REMAINING = 3076, STR_PARK_HAS_BEEN_CLOSED_DOWN = 3077, - STR_PLAIN_ENTRANCE = 3078, - STR_WOODEN_ENTRANCE = 3079, - STR_CANVAS_TENT_ENTRANCE = 3080, - STR_CASTLE_ENTRANCE_GREY = 3081, - STR_CASTLE_ENTRANCE_BROWN = 3082, - STR_JUNGLE_ENTRANCE = 3083, - STR_LOG_CABIN_ENTRANCE = 3084, - STR_CLASSICAL_ROMAN_ENTRANCE = 3085, - STR_ABSTRACT_ENTRANCE = 3086, - STR_SNOW_ICE_ENTRANCE = 3087, - STR_PAGODA_ENTRANCE = 3088, - STR_SPACE_ENTRANCE = 3089, STR_SELECT_STYLE_OF_ENTRANCE_EXIT_STATION_TIP = 3090, STR_YOU_ARE_NOT_ALLOWED_TO_REMOVE_THIS_SECTION = 3091, STR_NOT_ALLOWED_TO_MODIFY_STATION = 3092, @@ -3084,7 +3072,6 @@ enum STR_BOTTOM_TOOLBAR_NEWS_TEXT = 5485, STR_LAND_TOOL_SIZE_VALUE = 5486, STR_SHOW_RECENT_MESSAGES_TIP = 5487, - STR_ENTRANCE_NONE = 5488, STR_TRACKED_GUESTS_ONLY_TIP = 5489, STR_AUDIO_FOCUS = 5490, STR_DEBUG_DROPDOWN_INVENTIONS_LIST = 5491, @@ -3899,6 +3886,11 @@ enum STR_INVALID_CLIMATE_ID = 6269, + STR_OBJECT_SELECTION_TERRAIN_SURFACES = 6270, + STR_OBJECT_SELECTION_TERRAIN_EDGES = 6271, + STR_OBJECT_SELECTION_STATIONS = 6272, + STR_OBJECT_SELECTION_MUSIC = 6273, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index d959b996d3..3487129001 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -16,6 +16,7 @@ #include "ObjectLimits.h" #include +#include Object::Object(const rct_object_entry& entry) { @@ -36,6 +37,16 @@ Object::~Object() Memory::Free(_identifier); } +void* Object::GetLegacyData() +{ + throw std::runtime_error("Not supported."); +} + +void Object::ReadLegacy(IReadObjectContext* context, IStream* stream) +{ + throw std::runtime_error("Not supported."); +} + std::string Object::GetOverrideString(uint8_t index) const { const char* identifier = GetIdentifier(); diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index a9cfdd3e81..39b2a44a19 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -30,6 +30,10 @@ enum OBJECT_TYPE OBJECT_TYPE_PARK_ENTRANCE, OBJECT_TYPE_WATER, OBJECT_TYPE_SCENARIO_TEXT, + OBJECT_TYPE_TERRAIN_SURFACE, + OBJECT_TYPE_TERRAIN_EDGE, + OBJECT_TYPE_STATION, + OBJECT_TYPE_MUSIC, OBJECT_TYPE_COUNT }; @@ -192,12 +196,12 @@ public: { return &_objectEntry; } - virtual void* GetLegacyData() abstract; + virtual void* GetLegacyData(); virtual void ReadJson(IReadObjectContext* /*context*/, const json_t* /*root*/) { } - virtual void ReadLegacy(IReadObjectContext* context, IStream* stream) abstract; + virtual void ReadLegacy(IReadObjectContext* context, IStream* stream); virtual void Load() abstract; virtual void Unload() abstract; @@ -245,8 +249,6 @@ enum OBJECT_ERROR : uint32_t extern int32_t object_entry_group_counts[]; extern int32_t object_entry_group_encoding[]; -void object_list_load(); - bool object_entry_is_empty(const rct_object_entry* entry); bool object_entry_compare(const rct_object_entry* a, const rct_object_entry* b); int32_t object_calculate_checksum(const rct_object_entry* entry, const void* data, size_t dataLength); diff --git a/src/openrct2/object/ObjectFactory.cpp b/src/openrct2/object/ObjectFactory.cpp index 6f9c805fb8..46421b2be8 100644 --- a/src/openrct2/object/ObjectFactory.cpp +++ b/src/openrct2/object/ObjectFactory.cpp @@ -31,6 +31,9 @@ #include "RideObject.h" #include "SceneryGroupObject.h" #include "SmallSceneryObject.h" +#include "StationObject.h" +#include "TerrainEdgeObject.h" +#include "TerrainSurfaceObject.h" #include "WallObject.h" #include "WaterObject.h" @@ -298,6 +301,15 @@ namespace ObjectFactory case OBJECT_TYPE_SCENARIO_TEXT: result = nullptr; break; + case OBJECT_TYPE_TERRAIN_SURFACE: + result = new TerrainSurfaceObject(entry); + break; + case OBJECT_TYPE_TERRAIN_EDGE: + result = new TerrainEdgeObject(entry); + break; + case OBJECT_TYPE_STATION: + result = new StationObject(entry); + break; default: throw std::runtime_error("Invalid object type"); } @@ -326,6 +338,12 @@ namespace ObjectFactory return OBJECT_TYPE_PARK_ENTRANCE; if (s == "water") return OBJECT_TYPE_WATER; + if (s == "terrain_surface") + return OBJECT_TYPE_TERRAIN_SURFACE; + if (s == "terrain_edge") + return OBJECT_TYPE_TERRAIN_EDGE; + if (s == "station") + return OBJECT_TYPE_STATION; return 0xFF; } diff --git a/src/openrct2/object/ObjectJsonHelpers.cpp b/src/openrct2/object/ObjectJsonHelpers.cpp index 26910e145a..3732578641 100644 --- a/src/openrct2/object/ObjectJsonHelpers.cpp +++ b/src/openrct2/object/ObjectJsonHelpers.cpp @@ -35,6 +35,59 @@ using namespace OpenRCT2::Drawing; namespace ObjectJsonHelpers { + /** + * Container for a G1 image, additional information and RAII. + */ + struct RequiredImage + { + rct_g1_element g1{}; + std::unique_ptr next_zoom; + + bool HasData() const + { + return g1.offset != nullptr; + } + + RequiredImage() = default; + RequiredImage(const RequiredImage&) = delete; + + RequiredImage(const rct_g1_element& orig) + { + auto length = g1_calculate_data_size(&orig); + g1 = orig; + g1.offset = (uint8_t*)std::malloc(length); + std::memcpy(g1.offset, orig.offset, length); + g1.flags &= ~G1_FLAG_HAS_ZOOM_SPRITE; + } + + RequiredImage(uint32_t idx, std::function getter) + { + auto orig = getter(idx); + if (orig != nullptr) + { + auto length = g1_calculate_data_size(orig); + g1 = *orig; + g1.offset = (uint8_t*)std::malloc(length); + std::memcpy(g1.offset, orig->offset, length); + if (g1.flags & G1_FLAG_HAS_ZOOM_SPRITE) + { + // Fetch image for next zoom level + next_zoom = std::make_unique((uint32_t)(idx - g1.zoomed_offset), getter); + if (!next_zoom->HasData()) + { + next_zoom = nullptr; + g1.flags &= ~G1_FLAG_HAS_ZOOM_SPRITE; + } + } + } + } + + ~RequiredImage() + { + std::free(g1.offset); + } + }; + bool GetBoolean(const json_t* obj, const std::string& name, bool defaultValue) { auto value = json_object_get(obj, name.c_str()); @@ -112,6 +165,46 @@ namespace ObjectJsonHelpers return result; } + colour_t ParseColour(const std::string_view& s, colour_t defaultValue) + { + static const std::unordered_map LookupTable{ + { "black", COLOUR_BLACK }, + { "grey", COLOUR_GREY }, + { "white", COLOUR_WHITE }, + { "dark_purple", COLOUR_DARK_PURPLE }, + { "light_purple", COLOUR_LIGHT_PURPLE }, + { "bright_purple", COLOUR_BRIGHT_PURPLE }, + { "dark_blue", COLOUR_DARK_BLUE }, + { "light_blue", COLOUR_LIGHT_BLUE }, + { "icy_blue", COLOUR_ICY_BLUE }, + { "teal", COLOUR_TEAL }, + { "aquamarine", COLOUR_AQUAMARINE }, + { "saturated_green", COLOUR_SATURATED_GREEN }, + { "dark_green", COLOUR_DARK_GREEN }, + { "moss_green", COLOUR_MOSS_GREEN }, + { "bright_green", COLOUR_BRIGHT_GREEN }, + { "olive_green", COLOUR_OLIVE_GREEN }, + { "dark_olive_green", COLOUR_DARK_OLIVE_GREEN }, + { "bright_yellow", COLOUR_BRIGHT_YELLOW }, + { "yellow", COLOUR_YELLOW }, + { "dark_yellow", COLOUR_DARK_YELLOW }, + { "light_orange", COLOUR_LIGHT_ORANGE }, + { "dark_orange", COLOUR_DARK_ORANGE }, + { "light_brown", COLOUR_LIGHT_BROWN }, + { "saturated_brown", COLOUR_SATURATED_BROWN }, + { "dark_brown", COLOUR_DARK_BROWN }, + { "salmon_pink", COLOUR_SALMON_PINK }, + { "bordeaux_red", COLOUR_BORDEAUX_RED }, + { "saturated_red", COLOUR_SATURATED_RED }, + { "bright_red", COLOUR_BRIGHT_RED }, + { "dark_pink", COLOUR_DARK_PINK }, + { "bright_pink", COLOUR_BRIGHT_PINK }, + { "light_pink", COLOUR_LIGHT_PINK }, + }; + auto result = LookupTable.find(s); + return (result != LookupTable.end()) ? result->second : defaultValue; + } + uint8_t ParseCursor(const std::string& s, uint8_t defaultValue) { static const std::unordered_map LookupTable{ @@ -215,10 +308,10 @@ namespace ObjectJsonHelpers return objectPath; } - static std::vector LoadObjectImages( + static std::vector> LoadObjectImages( IReadObjectContext* context, const std::string& name, const std::vector& range) { - std::vector result; + std::vector> result; auto objectPath = FindLegacyObject(name); auto obj = ObjectFactory::CreateObjectFromLegacyFile(context->GetObjectRepository(), objectPath.c_str()); if (obj != nullptr) @@ -231,17 +324,12 @@ namespace ObjectJsonHelpers { if (i >= 0 && i < numImages) { - auto& objg1 = images[i]; - auto length = g1_calculate_data_size(&objg1); - auto g1 = objg1; - g1.offset = (uint8_t*)std::malloc(length); - std::memcpy(g1.offset, objg1.offset, length); - result.push_back(g1); + result.push_back(std::make_unique( + (uint32_t)(i), [images](uint32_t idx) -> const rct_g1_element* { return &images[idx]; })); } else { - auto g1 = rct_g1_element{}; - result.push_back(g1); + result.push_back(std::make_unique()); placeHoldersAdded++; } } @@ -258,18 +346,20 @@ namespace ObjectJsonHelpers { std::string msg = "Unable to open '" + objectPath + "'"; context->LogWarning(OBJECT_ERROR_INVALID_PROPERTY, msg.c_str()); - result.resize(range.size()); + for (size_t i = 0; i < range.size(); i++) + { + result.push_back(std::make_unique()); + } } return result; } - static std::vector ParseImages(IReadObjectContext* context, std::string s) + static std::vector> ParseImages(IReadObjectContext* context, std::string s) { - std::vector result; + std::vector> result; if (s.empty()) { - rct_g1_element emptyg1 = {}; - result.push_back(emptyg1); + result.push_back(std::make_unique()); } else if (String::StartsWith(s, "$CSG")) { @@ -280,12 +370,9 @@ namespace ObjectJsonHelpers { for (auto i : range) { - auto& csg1 = *gfx_get_g1_element(SPR_CSG_BEGIN + i); - auto length = g1_calculate_data_size(&csg1); - auto g1 = csg1; - g1.offset = (uint8_t*)std::malloc(length); - std::memcpy(g1.offset, csg1.offset, length); - result.push_back(g1); + result.push_back(std::make_unique( + (uint32_t)(SPR_CSG_BEGIN + i), + [](uint32_t idx) -> const rct_g1_element* { return gfx_get_g1_element(idx); })); } } } @@ -297,20 +384,8 @@ namespace ObjectJsonHelpers { for (auto i : range) { - auto og1 = gfx_get_g1_element(i); - if (og1 == nullptr) - { - rct_g1_element g1{}; - result.push_back(g1); - } - else - { - auto length = g1_calculate_data_size(og1); - auto g1 = *og1; - g1.offset = (uint8_t*)std::malloc(length); - std::memcpy(g1.offset, og1->offset, length); - result.push_back(g1); - } + result.push_back(std::make_unique( + (uint32_t)(i), [](uint32_t idx) -> const rct_g1_element* { return gfx_get_g1_element(idx); })); } } } @@ -336,28 +411,27 @@ namespace ObjectJsonHelpers ImageImporter importer; auto importResult = importer.Import(image, 0, 0, ImageImporter::IMPORT_FLAGS::RLE); - result.push_back(importResult.Element); + result.push_back(std::make_unique(importResult.Element)); + std::free(importResult.Buffer); } catch (const std::exception& e) { auto msg = String::StdFormat("Unable to load image '%s': %s", s.c_str(), e.what()); context->LogWarning(OBJECT_ERROR_BAD_IMAGE_TABLE, msg.c_str()); - - rct_g1_element emptyg1 = {}; - result.push_back(emptyg1); + result.push_back(std::make_unique()); } } return result; } - static std::vector ParseImages(IReadObjectContext* context, json_t* el) + static std::vector> ParseImages(IReadObjectContext* context, json_t* el) { auto path = GetString(el, "path"); auto x = GetInteger(el, "x"); auto y = GetInteger(el, "y"); auto raw = (GetString(el, "format") == "raw"); - std::vector result; + std::vector> result; try { auto flags = ImageImporter::IMPORT_FLAGS::NONE; @@ -373,15 +447,14 @@ namespace ObjectJsonHelpers auto g1Element = importResult.Element; g1Element.x_offset = x; g1Element.y_offset = y; - result.push_back(g1Element); + result.push_back(std::make_unique(g1Element)); + std::free(importResult.Buffer); } catch (const std::exception& e) { auto msg = String::StdFormat("Unable to load image '%s': %s", path.c_str(), e.what()); context->LogWarning(OBJECT_ERROR_BAD_IMAGE_TABLE, msg.c_str()); - - rct_g1_element emptyg1 = {}; - result.push_back(emptyg1); + result.push_back(std::make_unique()); } return result; } @@ -434,7 +507,7 @@ namespace ObjectJsonHelpers json_t* el; json_array_foreach(jsonImages, i, el) { - std::vector images; + std::vector> images; if (json_is_string(el)) { auto s = json_string_value(el); @@ -444,10 +517,35 @@ namespace ObjectJsonHelpers { images = ParseImages(context, el); } - for (const auto& g1 : images) + for (const auto& img : images) { + const auto& g1 = img->g1; imageTable.AddImage(&g1); - std::free(g1.offset); + } + + // Add zoom images here + for (size_t j = 0; j < images.size(); j++) + { + const auto* img = images[j].get(); + if (img->next_zoom != nullptr) + { + img = img->next_zoom.get(); + + // Set old image zoom offset to zoom image which we are about to add + auto g1a = (rct_g1_element*)(&imageTable.GetImages()[j]); + g1a->zoomed_offset = (int32_t)j - (int32_t)imageTable.GetCount(); + + while (img != nullptr) + { + auto g1b = img->g1; + if (img->next_zoom != nullptr) + { + g1b.zoomed_offset = -1; + } + imageTable.AddImage(&g1b); + img = img->next_zoom.get(); + } + } } } } diff --git a/src/openrct2/object/ObjectJsonHelpers.h b/src/openrct2/object/ObjectJsonHelpers.h index 90c1eb233a..849a6df2c9 100644 --- a/src/openrct2/object/ObjectJsonHelpers.h +++ b/src/openrct2/object/ObjectJsonHelpers.h @@ -12,6 +12,7 @@ #include "../common.h" #include "../core/Json.hpp" #include "../drawing/Drawing.h" +#include "../interface/Colour.h" #include "../object/Object.h" #include "ImageTable.h" #include "StringTable.h" @@ -30,6 +31,7 @@ namespace ObjectJsonHelpers float GetFloat(const json_t* obj, const std::string& name, const float& defaultValue = 0); std::vector GetJsonStringArray(const json_t* arr); std::vector GetJsonIntegerArray(const json_t* arr); + colour_t ParseColour(const std::string_view& s, colour_t defaultValue = COLOUR_BLACK); uint8_t ParseCursor(const std::string& s, uint8_t defaultValue); rct_object_entry ParseObjectEntry(const std::string& s); void LoadStrings(const json_t* root, StringTable& stringTable); @@ -37,12 +39,12 @@ namespace ObjectJsonHelpers template static T GetFlags(const json_t* obj, std::initializer_list> list) { - T flags = 0; + T flags{}; for (const auto& item : list) { if (GetBoolean(obj, item.first)) { - flags |= item.second; + flags = (T)(flags | item.second); } } return flags; diff --git a/src/openrct2/object/ObjectLimits.h b/src/openrct2/object/ObjectLimits.h index df0ffe309d..26408d4c4d 100644 --- a/src/openrct2/object/ObjectLimits.h +++ b/src/openrct2/object/ObjectLimits.h @@ -20,5 +20,9 @@ #define MAX_PARK_ENTRANCE_OBJECTS 1 #define MAX_WATER_OBJECTS 1 #define MAX_SCENARIO_TEXT_OBJECTS 1 +#define MAX_TERRAIN_SURFACE_OBJECTS 14 +#define MAX_TERRAIN_EDGE_OBJECTS 255 +#define MAX_STATION_OBJECTS 255 +#define MAX_MUSIC_OBJECTS 0 #define DAT_NAME_LENGTH 8 diff --git a/src/openrct2/object/ObjectList.cpp b/src/openrct2/object/ObjectList.cpp index a622b7e631..f5573544bd 100644 --- a/src/openrct2/object/ObjectList.cpp +++ b/src/openrct2/object/ObjectList.cpp @@ -33,7 +33,11 @@ int32_t object_entry_group_counts[] = { MAX_SCENERY_GROUP_OBJECTS, // scenery sets MAX_PARK_ENTRANCE_OBJECTS, // park entrance MAX_WATER_OBJECTS, // water - MAX_SCENARIO_TEXT_OBJECTS // scenario text + MAX_SCENARIO_TEXT_OBJECTS, // scenario text + MAX_TERRAIN_SURFACE_OBJECTS, + MAX_TERRAIN_EDGE_OBJECTS, + MAX_STATION_OBJECTS, + MAX_MUSIC_OBJECTS, }; // 98DA2C @@ -98,10 +102,12 @@ bool find_object_in_entry_group(const rct_object_entry* entry, uint8_t* entry_ty return false; } + auto& objectMgr = OpenRCT2::GetContext()->GetObjectManager(); auto maxObjects = object_entry_group_counts[objectType]; for (int32_t i = 0; i < maxObjects; i++) { - if (object_entry_get_chunk(objectType, i) != nullptr) + auto loadedObj = objectMgr.GetLoadedObject(objectType, i); + if (loadedObj != nullptr) { auto thisEntry = object_entry_get_entry(objectType, i); if (object_entry_compare(thisEntry, entry)) diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index 52f43125f6..b3ae3b23d5 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -214,6 +214,54 @@ public: { // We currently will load new object types here that apply to all // loaded RCT1 and RCT2 save files. + + // Surfaces + LoadObject("#RCT2SGR"); + LoadObject("#RCT2SSY"); + LoadObject("#RCT2SDI"); + LoadObject("#RCT2SRO"); + LoadObject("#RCT2SMA"); + LoadObject("#RCT2SCH"); + LoadObject("#RCT2SGC"); + LoadObject("#RCT2SIC"); + LoadObject("#RCT2SIR"); + LoadObject("#RCT2SIY"); + LoadObject("#RCT2SIP"); + LoadObject("#RCT2SIG"); + LoadObject("#RCT2SSR"); + LoadObject("#RCT2SSA"); + + // Edges + LoadObject("#RCT2ERO"); + LoadObject("#RCT2EWR"); + LoadObject("#RCT2EWB"); + LoadObject("#RCT2EIC"); + LoadObject("#RCT1EBR"); + LoadObject("#RCT1EIR"); + LoadObject("#RCT1EGY"); + LoadObject("#RCT1EYE"); + LoadObject("#RCT1ERE"); + LoadObject("#RCT1EPU"); + LoadObject("#RCT1EGR"); + LoadObject("#RCT1ESN"); + LoadObject("#RCT1ESG"); + LoadObject("#RCT1ESA"); + LoadObject("#RCT1ESB"); + + // Stations + LoadObject("#RCT2STN"); + LoadObject("#RCT2STW"); + LoadObject("#RCT2STV"); + LoadObject("#RCT2ST3"); + LoadObject("#RCT2ST4"); + LoadObject("#RCT2STJ"); + LoadObject("#RCT2STL"); + LoadObject("#RCT2STC"); + LoadObject("#RCT2STA"); + LoadObject("#RCT2STS"); + LoadObject("#RCT2STP"); + LoadObject("#RCT2STE"); + LoadObject("#ORCT2SN"); } static rct_string_id GetObjectSourceGameString(const uint8_t sourceGame) diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index c0373e061a..57c8425242 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -643,17 +643,6 @@ const rct_object_entry* object_list_find(rct_object_entry* entry) return result; } -void object_list_load() -{ - auto context = GetContext(); - const auto& localisationService = context->GetLocalisationService(); - auto& objectRepository = context->GetObjectRepository(); - objectRepository.LoadOrConstruct(localisationService.GetCurrentLanguage()); - - auto& objectManager = context->GetObjectManager(); - objectManager.UnloadAll(); -} - void* object_repository_load_object(const rct_object_entry* objectEntry) { Object* object = nullptr; diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index c016b25593..322e9f6664 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -918,16 +918,16 @@ std::vector RideObject::ReadJsonColourConfiguration(const json_t auto colours = ObjectJsonHelpers::GetJsonStringArray(jColours); if (colours.size() >= 1) { - carColour.main = ParseColour(colours[0]); + carColour.main = ObjectJsonHelpers::ParseColour(colours[0]); carColour.additional_1 = carColour.main; carColour.additional_2 = carColour.main; if (colours.size() >= 2) { - carColour.additional_1 = ParseColour(colours[1]); + carColour.additional_1 = ObjectJsonHelpers::ParseColour(colours[1]); } if (colours.size() >= 3) { - carColour.additional_2 = ParseColour(colours[2]); + carColour.additional_2 = ObjectJsonHelpers::ParseColour(colours[2]); } } config.push_back(carColour); @@ -1097,43 +1097,3 @@ uint8_t RideObject::ParseShopItem(const std::string& s) auto result = LookupTable.find(s); return (result != LookupTable.end()) ? result->second : SHOP_ITEM_NONE; } - -colour_t RideObject::ParseColour(const std::string& s) -{ - static const std::unordered_map LookupTable{ - { "black", COLOUR_BLACK }, - { "grey", COLOUR_GREY }, - { "white", COLOUR_WHITE }, - { "dark_purple", COLOUR_DARK_PURPLE }, - { "light_purple", COLOUR_LIGHT_PURPLE }, - { "bright_purple", COLOUR_BRIGHT_PURPLE }, - { "dark_blue", COLOUR_DARK_BLUE }, - { "light_blue", COLOUR_LIGHT_BLUE }, - { "icy_blue", COLOUR_ICY_BLUE }, - { "teal", COLOUR_TEAL }, - { "aquamarine", COLOUR_AQUAMARINE }, - { "saturated_green", COLOUR_SATURATED_GREEN }, - { "dark_green", COLOUR_DARK_GREEN }, - { "moss_green", COLOUR_MOSS_GREEN }, - { "bright_green", COLOUR_BRIGHT_GREEN }, - { "olive_green", COLOUR_OLIVE_GREEN }, - { "dark_olive_green", COLOUR_DARK_OLIVE_GREEN }, - { "bright_yellow", COLOUR_BRIGHT_YELLOW }, - { "yellow", COLOUR_YELLOW }, - { "dark_yellow", COLOUR_DARK_YELLOW }, - { "light_orange", COLOUR_LIGHT_ORANGE }, - { "dark_orange", COLOUR_DARK_ORANGE }, - { "light_brown", COLOUR_LIGHT_BROWN }, - { "saturated_brown", COLOUR_SATURATED_BROWN }, - { "dark_brown", COLOUR_DARK_BROWN }, - { "salmon_pink", COLOUR_SALMON_PINK }, - { "bordeaux_red", COLOUR_BORDEAUX_RED }, - { "saturated_red", COLOUR_SATURATED_RED }, - { "bright_red", COLOUR_BRIGHT_RED }, - { "dark_pink", COLOUR_DARK_PINK }, - { "bright_pink", COLOUR_BRIGHT_PINK }, - { "light_pink", COLOUR_LIGHT_PINK }, - }; - auto result = LookupTable.find(s); - return (result != LookupTable.end()) ? result->second : COLOUR_BLACK; -} diff --git a/src/openrct2/object/StationObject.cpp b/src/openrct2/object/StationObject.cpp new file mode 100644 index 0000000000..d0d48eb874 --- /dev/null +++ b/src/openrct2/object/StationObject.cpp @@ -0,0 +1,94 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include "StationObject.h" + +#include "../core/IStream.hpp" +#include "../core/String.hpp" +#include "../drawing/Drawing.h" +#include "../localisation/Localisation.h" +#include "ObjectJsonHelpers.h" + +void StationObject::Load() +{ + GetStringTable().Sort(); + NameStringId = language_allocate_object_string(GetName()); + + auto numImages = GetImageTable().GetCount(); + if (numImages != 0) + { + BaseImageId = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount()); + + uint32_t shelterOffset = (Flags & STATION_OBJECT_FLAGS::IS_TRANSPARENT) ? 32 : 16; + if (numImages > shelterOffset) + { + ShelterImageId = BaseImageId + shelterOffset; + } + } +} + +void StationObject::Unload() +{ + language_free_object_string(NameStringId); + gfx_object_free_images(BaseImageId, GetImageTable().GetCount()); + + NameStringId = 0; + BaseImageId = 0; + ShelterImageId = 0; +} + +void StationObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const +{ + int32_t x = width / 2; + int32_t y = (height / 2) + 16; + + auto colour0 = COLOUR_LIGHT_BLUE; + auto colour1 = COLOUR_BORDEAUX_RED; + auto tcolour0 = GlassPaletteIds[colour0]; + + uint32_t imageId = BaseImageId; + uint32_t tImageId = BaseImageId + 16; + if (Flags & STATION_OBJECT_FLAGS::HAS_PRIMARY_COLOUR) + { + imageId |= (colour0 << 19) | IMAGE_TYPE_REMAP; + tImageId |= (GlassPaletteIds[tcolour0] << 19) | IMAGE_TYPE_TRANSPARENT; + } + if (Flags & STATION_OBJECT_FLAGS::HAS_SECONDARY_COLOUR) + { + imageId |= (colour1 << 24) | IMAGE_TYPE_REMAP_2_PLUS; + tImageId |= (colour1 << 24) | IMAGE_TYPE_REMAP_2_PLUS; + } + + gfx_draw_sprite(dpi, imageId + 0, x, y, 0); + if (Flags & STATION_OBJECT_FLAGS::IS_TRANSPARENT) + { + gfx_draw_sprite(dpi, tImageId, x, y, 0); + } + + gfx_draw_sprite(dpi, imageId + 4, x, y, 0); + if (Flags & STATION_OBJECT_FLAGS::IS_TRANSPARENT) + { + gfx_draw_sprite(dpi, tImageId + 4, x, y, 0); + } +} + +void StationObject::ReadJson(IReadObjectContext* context, const json_t* root) +{ + auto properties = json_object_get(root, "properties"); + Height = ObjectJsonHelpers::GetInteger(properties, "height", 0); + ScrollingMode = ObjectJsonHelpers::GetInteger(properties, "scrollingMode", 0xFF); + Flags = ObjectJsonHelpers::GetFlags( + properties, + { { "hasPrimaryColour", STATION_OBJECT_FLAGS::HAS_PRIMARY_COLOUR }, + { "hasSecondaryColour", STATION_OBJECT_FLAGS::HAS_SECONDARY_COLOUR }, + { "isTransparent", STATION_OBJECT_FLAGS::IS_TRANSPARENT } }); + + ObjectJsonHelpers::LoadStrings(root, GetStringTable()); + ObjectJsonHelpers::LoadImages(context, root, GetImageTable()); +} diff --git a/src/openrct2/object/StationObject.h b/src/openrct2/object/StationObject.h new file mode 100644 index 0000000000..85e4cd149a --- /dev/null +++ b/src/openrct2/object/StationObject.h @@ -0,0 +1,41 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "Object.h" + +namespace STATION_OBJECT_FLAGS +{ + const uint32_t HAS_PRIMARY_COLOUR = 1 << 0; + const uint32_t HAS_SECONDARY_COLOUR = 1 << 1; + const uint32_t IS_TRANSPARENT = 1 << 2; +} // namespace STATION_OBJECT_FLAGS + +class StationObject final : public Object +{ +public: + rct_string_id NameStringId{}; + uint32_t BaseImageId{}; + uint32_t ShelterImageId{}; + uint32_t Flags; + int32_t Height; + uint8_t ScrollingMode; + + explicit StationObject(const rct_object_entry& entry) + : Object(entry) + { + } + + void ReadJson(IReadObjectContext* context, const json_t* root) override; + void Load() override; + void Unload() override; + + void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override; +}; diff --git a/src/openrct2/object/TerrainEdgeObject.cpp b/src/openrct2/object/TerrainEdgeObject.cpp new file mode 100644 index 0000000000..7d0b1c8475 --- /dev/null +++ b/src/openrct2/object/TerrainEdgeObject.cpp @@ -0,0 +1,54 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include "TerrainEdgeObject.h" + +#include "../core/IStream.hpp" +#include "../core/String.hpp" +#include "../drawing/Drawing.h" +#include "../localisation/Localisation.h" +#include "ObjectJsonHelpers.h" + +void TerrainEdgeObject::Load() +{ + GetStringTable().Sort(); + NameStringId = language_allocate_object_string(GetName()); + IconImageId = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount()); + + // First image is icon followed by edge images + BaseImageId = IconImageId + 1; +} + +void TerrainEdgeObject::Unload() +{ + language_free_object_string(NameStringId); + gfx_object_free_images(IconImageId, GetImageTable().GetCount()); + + NameStringId = 0; + IconImageId = 0; + BaseImageId = 0; +} + +void TerrainEdgeObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const +{ + int32_t x = width / 2; + int32_t y = height / 2; + + uint32_t imageId = BaseImageId; + gfx_draw_sprite(dpi, imageId + 5, x + 8, y - 8, 0); + gfx_draw_sprite(dpi, imageId + 5, x + 8, y + 8, 0); +} + +void TerrainEdgeObject::ReadJson(IReadObjectContext* context, const json_t* root) +{ + // auto properties = json_object_get(root, "properties"); + + ObjectJsonHelpers::LoadStrings(root, GetStringTable()); + ObjectJsonHelpers::LoadImages(context, root, GetImageTable()); +} diff --git a/src/openrct2/object/TerrainEdgeObject.h b/src/openrct2/object/TerrainEdgeObject.h new file mode 100644 index 0000000000..55b6551285 --- /dev/null +++ b/src/openrct2/object/TerrainEdgeObject.h @@ -0,0 +1,32 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "Object.h" + +class TerrainEdgeObject final : public Object +{ +private: +public: + rct_string_id NameStringId{}; + uint32_t IconImageId{}; + uint32_t BaseImageId{}; + + explicit TerrainEdgeObject(const rct_object_entry& entry) + : Object(entry) + { + } + + void ReadJson(IReadObjectContext* context, const json_t* root) override; + void Load() override; + void Unload() override; + + void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override; +}; diff --git a/src/openrct2/object/TerrainSurfaceObject.cpp b/src/openrct2/object/TerrainSurfaceObject.cpp new file mode 100644 index 0000000000..a71ccba970 --- /dev/null +++ b/src/openrct2/object/TerrainSurfaceObject.cpp @@ -0,0 +1,140 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma warning(disable : 4706) // assignment within conditional expression + +#include "TerrainSurfaceObject.h" + +#include "../core/IStream.hpp" +#include "../core/String.hpp" +#include "../drawing/Drawing.h" +#include "../localisation/Localisation.h" +#include "ObjectJsonHelpers.h" + +void TerrainSurfaceObject::Load() +{ + GetStringTable().Sort(); + NameStringId = language_allocate_object_string(GetName()); + IconImageId = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount()); + if ((Flags & SMOOTH_WITH_SELF) || (Flags & SMOOTH_WITH_OTHER)) + { + PatternBaseImageId = IconImageId + 1; + EntryBaseImageId = PatternBaseImageId + 6; + } + else + { + EntryBaseImageId = IconImageId + 1; + } + NumEntries = (GetImageTable().GetCount() - EntryBaseImageId) / NUM_IMAGES_IN_ENTRY; +} + +void TerrainSurfaceObject::Unload() +{ + language_free_object_string(NameStringId); + gfx_object_free_images(IconImageId, GetImageTable().GetCount()); + + NameStringId = 0; + IconImageId = 0; + PatternBaseImageId = 0; + EntryBaseImageId = 0; + NumEntries = 0; +} + +void TerrainSurfaceObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const +{ + uint32_t imageId = GetImageId({}, 1, 0, 0, false, false); + if (Colour != 255) + { + imageId |= Colour << 19 | IMAGE_TYPE_REMAP; + } + + int32_t x0 = 0; + int32_t y = -16; + for (int32_t i = 0; i < 8; i++) + { + int32_t x = x0; + if (i % 2 == 0) + { + x -= 32; + } + for (int32_t j = 0; j < 4; j++) + { + gfx_draw_sprite(dpi, imageId, x, y, 0); + x += 64; + } + y += 16; + } +} + +void TerrainSurfaceObject::ReadJson(IReadObjectContext* context, const json_t* root) +{ + auto properties = json_object_get(root, "properties"); + Colour = ObjectJsonHelpers::ParseColour(ObjectJsonHelpers::GetString(properties, "colour"), 255); + Rotations = ObjectJsonHelpers::GetInteger(properties, "rotations", 1); + Price = ObjectJsonHelpers::GetInteger(properties, "price", 0); + Flags = ObjectJsonHelpers::GetFlags( + properties, + { { "smoothWithSelf", TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_SELF }, + { "smoothWithOther", TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_OTHER } }); + + auto jDefault = json_object_get(root, "default"); + if (json_is_object(jDefault)) + { + DefaultEntry = ObjectJsonHelpers::GetInteger(properties, "normal"); + DefaultGridEntry = ObjectJsonHelpers::GetInteger(properties, "grid"); + DefaultUndergroundEntry = ObjectJsonHelpers::GetInteger(properties, "underground"); + } + else + { + DefaultEntry = 0; + DefaultGridEntry = 1; + DefaultUndergroundEntry = 2; + } + + auto jSpecialArray = json_object_get(properties, "special"); + if (json_is_array(jSpecialArray)) + { + size_t i; + json_t* el; + json_array_foreach(jSpecialArray, i, el) + { + SpecialEntry entry; + entry.Index = ObjectJsonHelpers::GetInteger(el, "index"); + entry.Length = ObjectJsonHelpers::GetInteger(el, "length", -1); + entry.Rotation = ObjectJsonHelpers::GetInteger(el, "rotation", -1); + entry.Variation = ObjectJsonHelpers::GetInteger(el, "variation", -1); + entry.Grid = ObjectJsonHelpers::GetBoolean(el, "grid"); + entry.Underground = ObjectJsonHelpers::GetBoolean(el, "underground"); + SpecialEntries.push_back(std::move(entry)); + } + } + + ObjectJsonHelpers::LoadStrings(root, GetStringTable()); + ObjectJsonHelpers::LoadImages(context, root, GetImageTable()); +} + +uint32_t TerrainSurfaceObject::GetImageId( + const CoordsXY& position, int32_t length, int32_t rotation, int32_t offset, bool grid, bool underground) const +{ + uint32_t result = (underground ? DefaultUndergroundEntry : (grid ? DefaultGridEntry : DefaultEntry)); + + // Look for a matching special + auto variation = ((position.x << 1) & 0b10) | (position.y & 0b01); + for (const auto& special : SpecialEntries) + { + if ((special.Length == -1 || special.Length == length) && (special.Rotation == -1 || special.Rotation == rotation) + && (special.Variation == -1 || special.Variation == variation) && special.Grid == grid + && special.Underground == underground) + { + result = special.Index; + break; + } + } + return EntryBaseImageId + (result * NUM_IMAGES_IN_ENTRY) + offset; +} diff --git a/src/openrct2/object/TerrainSurfaceObject.h b/src/openrct2/object/TerrainSurfaceObject.h new file mode 100644 index 0000000000..cfe05c0f73 --- /dev/null +++ b/src/openrct2/object/TerrainSurfaceObject.h @@ -0,0 +1,68 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "../world/Location.hpp" +#include "Object.h" + +enum TERRAIN_SURFACE_FLAGS +{ + NONE = 0, + SMOOTH_WITH_SELF = 1 << 0, + SMOOTH_WITH_OTHER = 1 << 1, +}; + +class TerrainSurfaceObject final : public Object +{ +private: + struct SpecialEntry + { + uint32_t Index{}; + int32_t Length{}; + int32_t Rotation{}; + int32_t Variation{}; + bool Grid{}; + bool Underground{}; + }; + + static constexpr auto NUM_IMAGES_IN_ENTRY = 19; + +public: + rct_string_id NameStringId{}; + uint32_t IconImageId{}; + uint32_t PatternBaseImageId{}; + uint32_t EntryBaseImageId{}; + + uint32_t NumEntries{}; + uint32_t DefaultEntry{}; + uint32_t DefaultGridEntry{}; + uint32_t DefaultUndergroundEntry{}; + std::vector SpecialEntries; + std::vector SpecialEntryMap; + + colour_t Colour{}; + uint8_t Rotations{}; + money32 Price{}; + TERRAIN_SURFACE_FLAGS Flags{}; + + explicit TerrainSurfaceObject(const rct_object_entry& entry) + : Object(entry) + { + } + + void ReadJson(IReadObjectContext* context, const json_t* root) override; + void Load() override; + void Unload() override; + + void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override; + + uint32_t GetImageId( + const CoordsXY& position, int32_t length, int32_t rotation, int32_t offset, bool grid, bool underground) const; +}; diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index 38fc355d38..a07247f13d 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -12,6 +12,7 @@ #include "../../drawing/LightFX.h" #include "../../interface/Viewport.h" #include "../../localisation/Localisation.h" +#include "../../object/StationObject.h" #include "../../ride/RideData.h" #include "../../ride/TrackDesign.h" #include "../../world/Entrance.h" @@ -68,14 +69,15 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, #endif Ride* ride = get_ride(tile_element->AsEntrance()->GetRideIndex()); - if (ride->entrance_style == RIDE_ENTRANCE_STYLE_NONE) + auto stationObj = ride_get_station_object(ride); + if (stationObj == nullptr || stationObj->BaseImageId == 0) + { return; - - const rct_ride_entrance_definition* style = &RideEntranceDefinitions[ride->entrance_style]; + } uint8_t colour_1, colour_2; uint32_t transparant_image_id = 0, image_id = 0; - if (style->base_image_id & IMAGE_TYPE_TRANSPARENT) + if (stationObj->Flags & STATION_OBJECT_FLAGS::IS_TRANSPARENT) { colour_1 = GlassPaletteIds[ride->track_colour_main[0]]; transparant_image_id = (colour_1 << 19) | IMAGE_TYPE_TRANSPARENT; @@ -99,11 +101,11 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, if (is_exit) { - image_id |= style->sprite_index + direction + 8; + image_id |= stationObj->BaseImageId + direction + 8; } else { - image_id |= style->sprite_index + direction; + image_id |= stationObj->BaseImageId + direction; } // Format modified to stop repeated code @@ -122,11 +124,11 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, { if (is_exit) { - transparant_image_id |= style->sprite_index + direction + 24; + transparant_image_id |= stationObj->BaseImageId + direction + 24; } else { - transparant_image_id |= style->sprite_index + direction + 16; + transparant_image_id |= stationObj->BaseImageId + direction + 16; } sub_98199C(session, transparant_image_id, 0, 0, lengthX, lengthY, ah, height, 2, 2, height); @@ -154,7 +156,8 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, paint_util_push_tunnel_left(session, height, TUNNEL_6); } - if (!is_exit && !(tile_element->flags & TILE_ELEMENT_FLAG_GHOST) && tile_element->AsEntrance()->GetRideIndex() != 0xFF) + if (!is_exit && !(tile_element->flags & TILE_ELEMENT_FLAG_GHOST) && tile_element->AsEntrance()->GetRideIndex() != 0xFF + && stationObj->ScrollingMode != 0xFF) { set_format_arg(0, uint32_t, 0); set_format_arg(4, uint32_t, 0); @@ -185,8 +188,8 @@ static void ride_entrance_exit_paint(paint_session* session, uint8_t direction, uint16_t scroll = (gCurrentTicks / 2) % string_width; sub_98199C( - session, scrolling_text_setup(session, string_id, scroll, style->scrolling_mode), 0, 0, 0x1C, 0x1C, 0x33, - height + style->height, 2, 2, height + style->height); + session, scrolling_text_setup(session, string_id, scroll, stationObj->ScrollingMode), 0, 0, 0x1C, 0x1C, 0x33, + height + stationObj->Height, 2, 2, height + stationObj->Height); } image_id = _unk9E32BC; diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index a827a48b38..8c8fd07c65 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -10,12 +10,16 @@ #include "Paint.Surface.h" #include "../../Cheats.h" +#include "../../Context.h" #include "../../OpenRCT2.h" #include "../../config/Config.h" #include "../../core/Guard.hpp" #include "../../drawing/Drawing.h" #include "../../interface/Colour.h" #include "../../interface/Viewport.h" +#include "../../object/ObjectManager.h" +#include "../../object/TerrainEdgeObject.h" +#include "../../object/TerrainSurfaceObject.h" #include "../../paint/Paint.h" #include "../../peep/Staff.h" #include "../../ride/TrackDesign.h" @@ -203,220 +207,12 @@ static constexpr const uint8_t byte_97B5B0[TUNNEL_TYPE_COUNT] = { 16, 17, 18, 19, 20, 21, 22 }; -#define EDGE_SPRITE_TYPE_COUNT 4 - -#define DEFINE_EDGE_SPRITES(base) { \ - (base) + 0, \ - (base) + 20, \ - (base) + 10, \ - (base) + 30, \ -} -#define DEFINE_EDGE_TUNNEL_SPRITES(base) { \ - (base) + 36, \ - (base) + 40, \ - (base) + 44, \ - (base) + 48, \ - (base) + 52, \ - (base) + 56, \ - (base) + 60, \ - (base) + 64, \ - (base) + 68, \ - (base) + 72, \ - (base) + 76, \ - (base) + 80, \ - (base) + 36, \ - (base) + 48, \ - (base) + 60, \ - (base) + 72, \ - (base) + 36, \ - (base) + 36, \ - (base) + 36, \ - (base) + 36, \ - (base) + 36, \ - (base) + 36, \ - (base) + 36, \ -} - -#define DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(base) { \ - (base) + 36, \ - (base) + 40, \ - (base) + 44, \ - (base) + 48, \ - (base) + 52, \ - (base) + 56, \ - (base) + 60, \ - (base) + 64, \ - (base) + 68, \ - (base) + 72, \ - (base) + 76, \ - (base) + 80, \ - (base) + 36, \ - (base) + 48, \ - (base) + 60, \ - (base) + 72, \ - (base) + 76, \ - (base) + 80, \ - (base) + 84, \ - (base) + 88, \ - (base) + 92, \ - (base) + 96, \ - (base) + 100, \ -} - -static constexpr const uint32_t _terrainEdgeSpriteIds[][EDGE_SPRITE_TYPE_COUNT] = -{ - DEFINE_EDGE_SPRITES(SPR_EDGE_ROCK_BASE), - DEFINE_EDGE_SPRITES(SPR_EDGE_WOOD_RED_BASE), - DEFINE_EDGE_SPRITES(SPR_EDGE_WOOD_BLACK_BASE), - DEFINE_EDGE_SPRITES(SPR_EDGE_ICE_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_BRICK_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_IRON_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_GREY_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_YELLOW_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_RED_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_PURPLE_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_GREEN_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_STONE_BROWN_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_STONE_GREY_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_SKYSCRAPER_A_BASE), - DEFINE_EDGE_SPRITES(SPR_CSG_EDGE_SKYSCRAPER_B_BASE), -}; - -static constexpr const uint32_t _terrainEdgeTunnelSpriteIds[][TUNNEL_TYPE_COUNT] = -{ - DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_ROCK_BASE), - DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_WOOD_RED_BASE), - DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_WOOD_BLACK_BASE), - DEFINE_EDGE_TUNNEL_SPRITES(SPR_EDGE_ICE_BASE), - DEFINE_EDGE_TUNNEL_SPRITES(SPR_CSG_EDGE_BRICK_BASE), - DEFINE_EDGE_TUNNEL_SPRITES(SPR_CSG_EDGE_IRON_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_GREY_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_YELLOW_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_RED_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_PURPLE_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_GREEN_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_STONE_BROWN_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_STONE_GREY_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_SKYSCRAPER_A_BASE), - DEFINE_EDGE_TUNNEL_SPRITES_WITH_DOORS(SPR_CSG_EDGE_SKYSCRAPER_B_BASE), -}; - static constexpr const uint8_t byte_97B740[] = { 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 1, 4, 0 }; -static constexpr const uint32_t dword_97B750[][2] = -{ - { SPR_TERRAIN_GRASS, SPR_TERRAIN_GRASS_GRID }, - { SPR_TERRAIN_SAND_YELLOW, SPR_TERRAIN_SAND_YELLOW_GRID }, - { SPR_TERRAIN_DIRT, SPR_TERRAIN_DIRT_GRID }, - { SPR_TERRAIN_ROCK, SPR_TERRAIN_ROCK_GRID }, - { SPR_TERRAIN_MARTIAN, SPR_TERRAIN_MARTIAN_GRID }, - { SPR_TERRAIN_CHECKERBOARD, SPR_TERRAIN_CHECKERBOARD_GRID }, - { SPR_TERRAIN_GRASS_CLUMPS, SPR_TERRAIN_GRASS_CLUMPS_GRID }, - { SPR_TERRAIN_ICE, SPR_TERRAIN_ICE_GRID }, - { SPR_TERRAIN_GRID | COLOUR_BRIGHT_RED << 19 | IMAGE_TYPE_REMAP, SPR_TERRAIN_GRID_GRID | COLOUR_BRIGHT_RED << 19 | IMAGE_TYPE_REMAP }, - { SPR_TERRAIN_GRID | COLOUR_YELLOW << 19 | IMAGE_TYPE_REMAP, SPR_TERRAIN_GRID_GRID | COLOUR_YELLOW << 19 | IMAGE_TYPE_REMAP }, - { SPR_TERRAIN_GRID | COLOUR_BRIGHT_PURPLE << 19 | IMAGE_TYPE_REMAP, SPR_TERRAIN_GRID_GRID | COLOUR_BRIGHT_PURPLE << 19 | IMAGE_TYPE_REMAP }, - { SPR_TERRAIN_GRID | COLOUR_BRIGHT_GREEN << 19 | IMAGE_TYPE_REMAP, SPR_TERRAIN_GRID_GRID | COLOUR_BRIGHT_GREEN << 19 | IMAGE_TYPE_REMAP }, - { SPR_TERRAIN_SAND_RED, SPR_TERRAIN_SAND_RED_GRID }, - { SPR_TERRAIN_SAND, SPR_TERRAIN_SAND_GRID }, - { SPR_TERRAIN_CHECKERBOARD_INVERTED, SPR_TERRAIN_CHECKERBOARD_INVERTED_GRID }, -}; - -static constexpr const uint32_t dword_97B7C8[] = -{ - SPR_TERRAIN_GRASS_UNDERGROUND, - SPR_TERRAIN_SAND_YELLOW_UNDERGROUND, - SPR_TERRAIN_DIRT_UNDERGROUND, - SPR_TERRAIN_ROCK_UNDERGROUND, - SPR_TERRAIN_MARTIAN_UNDERGROUND, - SPR_TERRAIN_CHECKERBOARD_UNDERGROUND, - SPR_TERRAIN_GRASS_CLUMPS_UNDERGROUND, - SPR_TERRAIN_ICE_UNDERGROUND, - SPR_TERRAIN_GRID_UNDERGROUND | COLOUR_BRIGHT_RED << 19 | IMAGE_TYPE_REMAP, - SPR_TERRAIN_GRID_UNDERGROUND | COLOUR_YELLOW << 19 | IMAGE_TYPE_REMAP, - SPR_TERRAIN_GRID_UNDERGROUND | COLOUR_BRIGHT_PURPLE << 19 | IMAGE_TYPE_REMAP, - SPR_TERRAIN_GRID_UNDERGROUND | COLOUR_BRIGHT_GREEN << 19 | IMAGE_TYPE_REMAP, - SPR_TERRAIN_SAND_RED_UNDERGROUND, - SPR_TERRAIN_SAND_UNDERGROUND, - SPR_TERRAIN_CHECKERBOARD_INVERTED_UNDERGROUND, -}; - -static constexpr const uint32_t dword_97B804[] = -{ - SPR_TERRAIN_PATTERN_GRASS, - SPR_TERRAIN_PATTERN_SAND_YELLOW, - SPR_TERRAIN_PATTERN_DIRT, - SPR_TERRAIN_PATTERN_ROCK, - SPR_TERRAIN_PATTERN_MARTIAN, - SPR_TERRAIN_PATTERN_GRASS, - SPR_TERRAIN_PATTERN_GRASS_CLUMPS, - SPR_TERRAIN_PATTERN_ICE, - SPR_TERRAIN_PATTERN_GRASS, - SPR_TERRAIN_PATTERN_GRASS, - SPR_TERRAIN_PATTERN_GRASS, - SPR_TERRAIN_PATTERN_GRASS, - SPR_TERRAIN_PATTERN_SAND_RED, - SPR_TERRAIN_PATTERN_SAND -}; - -enum -{ - FLAG_DONT_SMOOTHEN = (1 << 0), - FLAG_DONT_SMOOTHEN_SELF = (1 << 1), -}; - -static constexpr const uint8_t byte_97B83C[] = -{ - 0, - 0, - 0, - FLAG_DONT_SMOOTHEN_SELF, - FLAG_DONT_SMOOTHEN_SELF, - FLAG_DONT_SMOOTHEN_SELF | FLAG_DONT_SMOOTHEN, - 0, - 0, - FLAG_DONT_SMOOTHEN_SELF | FLAG_DONT_SMOOTHEN, - FLAG_DONT_SMOOTHEN_SELF | FLAG_DONT_SMOOTHEN, - FLAG_DONT_SMOOTHEN_SELF | FLAG_DONT_SMOOTHEN, - FLAG_DONT_SMOOTHEN_SELF | FLAG_DONT_SMOOTHEN, - 0, - 0 -}; - -static constexpr const uint8_t byte_97B84A[] = -{ - 0, 1, 2, 3, 4, 14, 6, 7, 8, 9, - 10, 11, 12, 13 -}; - -static constexpr const uint32_t dword_97B858[][2] = -{ - { SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_1, SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_1_GRID }, - { SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_2, SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_2_GRID }, - { SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_3, SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_3_GRID }, - { SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_4, SPR_TERRAIN_GRASS_LENGTH_4_VARIANT_4_GRID }, -}; - -static constexpr const uint32_t dword_97B878[][2] = -{ - { SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_1, SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_1_GRID }, - { SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_2, SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_2_GRID }, - { SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_3, SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_3_GRID }, - { SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_4, SPR_TERRAIN_GRASS_LENGTH_6_VARIANT_4_GRID }, -}; - -static constexpr const uint32_t dword_97B898[][2] = -{ - { SPR_TERRAIN_GRASS_MOWED_90, SPR_TERRAIN_GRASS_MOWED_90_GRID }, - { SPR_TERRAIN_GRASS_MOWED, SPR_TERRAIN_GRASS_MOWED_GRID }, - { SPR_TERRAIN_GRASS_MOWED_90, SPR_TERRAIN_GRASS_MOWED_90_GRID }, - { SPR_TERRAIN_GRASS_MOWED, SPR_TERRAIN_GRASS_MOWED_GRID } -}; - struct tile_descriptor { TileCoordsXY tile_coords; @@ -495,14 +291,113 @@ static constexpr const tile_surface_boundary_data _tileSurfaceBoundaries[4] = }; // clang-format on +static const TerrainSurfaceObject* get_surface_object(size_t index) +{ + TerrainSurfaceObject* result{}; + auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); + auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, index); + if (obj != nullptr) + { + return static_cast(obj); + } + return result; +} + +static uint32_t get_surface_image( + const paint_session* session, uint8_t index, int32_t offset, uint8_t rotation, int32_t grassLength, bool grid, + bool underground) +{ + auto image = (uint32_t)SPR_NONE; + auto obj = get_surface_object(index); + if (obj != nullptr) + { + image = obj->GetImageId( + { session->MapPosition.x >> 5, session->MapPosition.y >> 5 }, grassLength, rotation, offset, grid, underground); + if (obj->Colour != 255) + { + image |= obj->Colour << 19 | IMAGE_TYPE_REMAP; + } + } + return image; +} + +static uint32_t get_surface_pattern(uint8_t index, int32_t offset) +{ + auto image = (uint32_t)SPR_NONE; + auto obj = get_surface_object(index); + if (obj != nullptr) + { + image = obj->PatternBaseImageId + offset; + if (obj->Colour != 255) + { + image |= obj->Colour << 19 | IMAGE_TYPE_REMAP; + } + } + return image; +} + +static bool surface_should_smooth_self(uint8_t index) +{ + auto obj = get_surface_object(index); + if (obj != nullptr) + { + return obj->Flags & TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_SELF; + } + return false; +} + +static bool surface_should_smooth(uint8_t index) +{ + auto obj = get_surface_object(index); + if (obj != nullptr) + { + return obj->Flags & TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_OTHER; + } + return false; +} + +static uint32_t get_edge_image_with_offset(uint8_t index, uint32_t offset) +{ + uint32_t result = 0; + auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); + auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_TERRAIN_EDGE, index); + if (obj != nullptr) + { + auto tobj = static_cast(obj); + return tobj->BaseImageId + offset; + } + return result; +} + static uint32_t get_edge_image(uint8_t index, uint8_t type) { - return _terrainEdgeSpriteIds[index][type]; + static constexpr uint32_t offsets[] = { + 0, + 20, + 10, + 30, + }; + + uint32_t result = 0; + if (type < std::size(offsets)) + { + result = get_edge_image_with_offset(index, offsets[type]); + } + return result; } static uint32_t get_tunnel_image(uint8_t index, uint8_t type) { - return _terrainEdgeTunnelSpriteIds[index][type]; + static constexpr uint32_t offsets[] = { + 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 36, 48, 60, 72, + }; + + uint32_t result = 0; + if (type < std::size(offsets)) + { + result = get_edge_image_with_offset(index, offsets[type]); + } + return result; } static uint8_t viewport_surface_paint_setup_get_relative_slope(const TileElement* tileElement, int32_t rotation) @@ -595,15 +490,15 @@ static void viewport_surface_smoothen_edge( if (cl == dh) return; - if (byte_97B83C[self.terrain] & FLAG_DONT_SMOOTHEN_SELF) + if (!surface_should_smooth_self(self.terrain)) return; } else { - if (byte_97B83C[self.terrain] & FLAG_DONT_SMOOTHEN) + if (!surface_should_smooth(self.terrain)) return; - if (byte_97B83C[neighbour.terrain] & FLAG_DONT_SMOOTHEN) + if (!surface_should_smooth(neighbour.terrain)) return; } @@ -613,7 +508,7 @@ static void viewport_surface_smoothen_edge( { attached_paint_struct* out = session->UnkF1AD2C; // set content and enable masking - out->colour_image_id = dword_97B804[neighbour.terrain] + cl; + out->colour_image_id = get_surface_pattern(neighbour.terrain, cl); out->flags |= PAINT_STRUCT_FLAG_IS_MASKED; } } @@ -1104,81 +999,30 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c { const bool showGridlines = (session->ViewFlags & VIEWPORT_FLAG_GRIDLINES); - int32_t branch = -1; - if (tileElement->AsSurface()->GetSurfaceStyle() == TERRAIN_GRASS) + auto grassLength = -1; + if (zoomLevel == 0) { - if (tileElement->GetDirection() == 0) + if ((session->ViewFlags & (VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE)) == 0) { - if (zoomLevel == 0) - { - if ((session->ViewFlags & (VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE)) == 0) - { - branch = tileElement->AsSurface()->GetGrassLength() & 0x7; - } - } + grassLength = tileElement->AsSurface()->GetGrassLength() & 0x7; } } assert(surfaceShape < std::size(byte_97B444)); const uint8_t image_offset = byte_97B444[surfaceShape]; - int32_t image_id; - uint32_t ebp = terrain_type; - switch (branch) + auto imageId = get_surface_image(session, terrain_type, image_offset, rotation, grassLength, showGridlines, false); + if (gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) { - case 0: - // loc_660C90 - image_id = dword_97B898[rotation][showGridlines ? 1 : 0] + image_offset; - break; - - case 1: - case 2: - case 3: - default: - // loc_660C9F - if (rotation & 1) - { - assert(ebp < std::size(byte_97B84A)); - ebp = byte_97B84A[ebp]; - } - assert(ebp < std::size(dword_97B750)); - image_id = dword_97B750[ebp][showGridlines ? 1 : 0] + image_offset; - - if (gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)) - { - image_id = SPR_TERRAIN_TRACK_DESIGNER; - } - - if (session->ViewFlags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE)) - { - image_id &= 0xDC07FFFF; // remove colour - image_id |= 0x41880000; - } - break; - - case 4: - case 5: - // loc_660C44 - case 6: - // loc_660C6A - { - const int16_t x = session->MapPosition.x & 0x20; - const int16_t y = session->MapPosition.y & 0x20; - const int32_t index = (y | (x << 1)) >> 5; - - if (branch == 6) - { - image_id = dword_97B878[index][showGridlines ? 1 : 0] + image_offset; - } - else - { - image_id = dword_97B858[index][showGridlines ? 1 : 0] + image_offset; - } - } - break; + imageId = SPR_TERRAIN_TRACK_DESIGNER; + } + if (session->ViewFlags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE)) + { + imageId &= 0xDC07FFFF; // remove colour + imageId |= 0x41880000; } - sub_98196C(session, image_id, 0, 0, 32, 32, -1, height); + sub_98196C(session, imageId, 0, 0, 32, 32, -1, height); has_surface = true; } @@ -1381,12 +1225,7 @@ void surface_paint(paint_session* session, uint8_t direction, uint16_t height, c && !(gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER))) { const uint8_t image_offset = byte_97B444[surfaceShape]; - uint32_t base_image = terrain_type; - if (rotation & 1) - { - base_image = byte_97B84A[terrain_type]; - } - const uint32_t image_id = dword_97B7C8[base_image] + image_offset; + const uint32_t image_id = get_surface_image(session, terrain_type, image_offset, rotation, 1, false, true); paint_attach_to_previous_ps(session, image_id, 0, 0); } diff --git a/src/openrct2/rct1/Tables.cpp b/src/openrct2/rct1/Tables.cpp index 9edb12d3f3..be5a7efa34 100644 --- a/src/openrct2/rct1/Tables.cpp +++ b/src/openrct2/rct1/Tables.cpp @@ -143,22 +143,22 @@ namespace RCT1 { static constexpr const uint8_t map[] = { - TERRAIN_EDGE_ROCK, - TERRAIN_EDGE_BRICK, - TERRAIN_EDGE_IRON, - TERRAIN_EDGE_WOOD_RED, - TERRAIN_EDGE_GREY, - TERRAIN_EDGE_YELLOW, - TERRAIN_EDGE_WOOD_BLACK, - TERRAIN_EDGE_RED, - TERRAIN_EDGE_ICE, - TERRAIN_EDGE_PURPLE, - TERRAIN_EDGE_GREEN, - TERRAIN_EDGE_STONE_BROWN, - TERRAIN_EDGE_STONE_GREY, - TERRAIN_EDGE_SKYSCRAPER_A, - TERRAIN_EDGE_SKYSCRAPER_B, - TERRAIN_EDGE_ROCK // Unused + TERRAIN_EDGE_ROCK, // #RCT2ERO + TERRAIN_EDGE_BRICK, // #RCT1EBR + TERRAIN_EDGE_IRON, // #RCT1EIR + TERRAIN_EDGE_WOOD_RED, // #RCT2EWR + TERRAIN_EDGE_GREY, // #RCT1EGY + TERRAIN_EDGE_YELLOW, // #RCT1EYE + TERRAIN_EDGE_WOOD_BLACK, // #RCT2EWB + TERRAIN_EDGE_RED, // #RCT1ERE + TERRAIN_EDGE_ICE, // #RCT2EIC + TERRAIN_EDGE_PURPLE, // #RCT2EIC + TERRAIN_EDGE_GREEN, // #RCT1EGR + TERRAIN_EDGE_STONE_BROWN, // #RCT1ESN + TERRAIN_EDGE_STONE_GREY, // #RCT1ESG + TERRAIN_EDGE_SKYSCRAPER_A, // #RCT1ESA + TERRAIN_EDGE_SKYSCRAPER_B, // #RCT1ESB + TERRAIN_EDGE_ROCK // #RCT2ERO (Unused) }; Guard::ArgumentInRange(terrainEdge, 0, std::size(map), "Unsupported RCT1 terrain edge."); return map[terrainEdge]; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index e351b06a62..305dc96b23 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -29,6 +29,7 @@ #include "../network/network.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" +#include "../object/StationObject.h" #include "../paint/VirtualFloor.h" #include "../peep/Peep.h" #include "../peep/Staff.h" @@ -8535,6 +8536,12 @@ bool ride_has_adjacent_station(Ride* ride) return found; } +bool ride_has_station_shelter(Ride* ride) +{ + auto stationObj = ride_get_station_object(ride); + return stationObj != nullptr && stationObj->BaseImageId != 0; +} + bool ride_has_ratings(const Ride* ride) { return ride->excitement != RIDE_RATING_UNDEFINED; @@ -8775,6 +8782,12 @@ int32_t ride_get_entry_index(int32_t rideType, int32_t rideSubType) return subType; } +StationObject* ride_get_station_object(const Ride* ride) +{ + auto& objManager = GetContext()->GetObjectManager(); + return static_cast(objManager.GetLoadedObject(OBJECT_TYPE_STATION, ride->entrance_style)); +} + LocationXY16 ride_get_rotated_coords(int16_t x, int16_t y, int16_t z) { LocationXY16 rotatedCoords = { 0, 0 }; diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 927c273de2..5446450fa6 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -19,6 +19,7 @@ #include "Vehicle.h" interface IObjectManager; +class StationObject; #define MAX_RIDE_TYPES_PER_RIDE_ENTRY 3 // The max number of different types of vehicle. @@ -732,25 +733,6 @@ enum VEHICLE_COLOUR_SCHEME_PER_VEHICLE }; -enum -{ - RIDE_ENTRANCE_STYLE_PLAIN, - RIDE_ENTRANCE_STYLE_WOODEN, - RIDE_ENTRANCE_STYLE_CANVAS_TENT, - RIDE_ENTRANCE_STYLE_CASTLE_GREY, - RIDE_ENTRANCE_STYLE_CASTLE_BROWN, - RIDE_ENTRANCE_STYLE_JUNGLE, - RIDE_ENTRANCE_STYLE_LOG_CABIN, - RIDE_ENTRANCE_STYLE_CLASSICAL_ROMAN, - RIDE_ENTRANCE_STYLE_ABSTRACT, - RIDE_ENTRANCE_STYLE_SNOW_ICE, - RIDE_ENTRANCE_STYLE_PAGODA, - RIDE_ENTRANCE_STYLE_SPACE, - RIDE_ENTRANCE_STYLE_NONE, - - RIDE_ENTRANCE_STYLE_COUNT -}; - enum { RIDE_INSPECTION_EVERY_10_MINUTES, @@ -1193,6 +1175,7 @@ money16 ride_get_price(Ride* ride); TileElement* get_station_platform(int32_t x, int32_t y, int32_t z, int32_t z_tolerance); bool ride_has_adjacent_station(Ride* ride); +bool ride_has_station_shelter(Ride* ride); bool ride_has_ratings(const Ride* ride); const char* ride_type_get_enum_name(int32_t rideType); @@ -1204,6 +1187,7 @@ void fix_invalid_vehicle_sprite_sizes(); bool ride_entry_has_category(const rct_ride_entry* rideEntry, uint8_t category); int32_t ride_get_entry_index(int32_t rideType, int32_t rideSubType); +StationObject* ride_get_station_object(const Ride* ride); void ride_action_modify(int32_t rideIndex, int32_t modifyType, int32_t flags); void ride_stop_peeps_queuing(int32_t rideIndex); diff --git a/src/openrct2/ride/RideData.cpp b/src/openrct2/ride/RideData.cpp index 6508268821..51a6b6d1fa 100644 --- a/src/openrct2/ride/RideData.cpp +++ b/src/openrct2/ride/RideData.cpp @@ -1105,23 +1105,6 @@ const uint8_t RideAvailableBreakdowns[] = { (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE) // 5a LIM Launched Roller Coaster }; -// rct2: 0x00993E7C and 0x00993E1C -const rct_ride_entrance_definition RideEntranceDefinitions[RIDE_ENTRANCE_STYLE_COUNT] = { - { 22664, 32, 2, 0x00000000, STR_PLAIN_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_PLAIN - { 22760, 31, 21, 0x000057A1, STR_WOODEN_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_WOODEN - { 22680, 43, 2, 0x800057AD, STR_CANVAS_TENT_ENTRANCE, 3, }, // RIDE_ENTRANCE_STYLE_CANVAS_TENT - { 22728, 43, 19, 0x000057B9, STR_CASTLE_ENTRANCE_GREY, 0, }, // RIDE_ENTRANCE_STYLE_CASTLE_GREY - { 22712, 43, 19, 0x000057C5, STR_CASTLE_ENTRANCE_BROWN, 0, }, // RIDE_ENTRANCE_STYLE_CASTLE_BROWN - { 22776, 33, 19, 0x000057D1, STR_JUNGLE_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_JUNGLE - { 22744, 32, 20, 0x000057DD, STR_LOG_CABIN_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_LOG_CABIN - { 22696, 34, 19, 0x000057E9, STR_CLASSICAL_ROMAN_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_CLASSICAL_ROMAN - { 22792, 40, 22, 0x400057F5, STR_ABSTRACT_ENTRANCE, 1, }, // RIDE_ENTRANCE_STYLE_ABSTRACT - { 22824, 35, 23, 0x0000580D, STR_SNOW_ICE_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_SNOW_ICE - { 22840, 33, 19, 0x00005819, STR_PAGODA_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_PAGODA - { 22856, 33, 2, 0x00005825, STR_SPACE_ENTRANCE, 0, }, // RIDE_ENTRANCE_STYLE_SPACE - { 0, 0, 2, 0x00000000, STR_ENTRANCE_NONE, 0, } // RIDE_ENTRANCE_STYLE_NONE -}; - // rct2: 0x0097D4F0, 0x0097D4F1, 0x0097D4F2, 0x0097D4F4, 0x0097D4F5 const rct_ride_data_4 RideData4[RIDE_TYPE_COUNT] = { { 20, 20, RIDE_TYPE_FLAG4_ALLOW_MUSIC | RIDE_TYPE_FLAG4_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG4_HAS_ENTRANCE_EXIT | RIDE_TYPE_FLAG4_HAS_AIR_TIME | RIDE_TYPE_FLAG4_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG4_SHOW_IN_TRACK_DESIGNER | RIDE_TYPE_FLAG4_INTERESTING_TO_LOOK_AT, MUSIC_STYLE_ROCK_STYLE_3, 0 }, // RIDE_TYPE_SPIRAL_ROLLER_COASTER diff --git a/src/openrct2/ride/RideData.h b/src/openrct2/ride/RideData.h index 0ca3715ea7..80442b2ed0 100644 --- a/src/openrct2/ride/RideData.h +++ b/src/openrct2/ride/RideData.h @@ -50,16 +50,6 @@ struct rct_ride_name_convention RIDE_COMPONENT_TYPE station; }; -struct rct_ride_entrance_definition -{ - uint32_t sprite_index; - uint16_t height; - uint16_t scrolling_mode; - uint32_t base_image_id; - rct_string_id string_id; - uint16_t colour_use_flags; -}; - struct rct_ride_data_4 { uint8_t price; @@ -138,7 +128,6 @@ extern const uint8_t RideAvailableModes[]; extern const uint8_t AllRideModesAvailable[]; extern const uint8_t RideAvailableBreakdowns[]; -extern const rct_ride_entrance_definition RideEntranceDefinitions[RIDE_ENTRANCE_STYLE_COUNT]; extern const rct_ride_lift_data RideLiftData[RIDE_TYPE_COUNT]; extern const rct_ride_data_4 RideData4[RIDE_TYPE_COUNT]; diff --git a/src/openrct2/ride/TrackPaint.cpp b/src/openrct2/ride/TrackPaint.cpp index 76a9718e2c..0e0f6e9a67 100644 --- a/src/openrct2/ride/TrackPaint.cpp +++ b/src/openrct2/ride/TrackPaint.cpp @@ -14,6 +14,7 @@ #include "../interface/Viewport.h" #include "../interface/Window.h" #include "../localisation/Localisation.h" +#include "../object/StationObject.h" #include "../paint/Paint.h" #include "../paint/Supports.h" #include "../paint/tile_element/Paint.TileElement.h" @@ -325,7 +326,7 @@ static void track_paint_util_draw_station_impl( { LocationXY16 position = session->MapPosition; Ride* ride = get_ride(rideIndex); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); const bool hasGreenLight = tileElement->AsTrack()->HasGreenLight(); bool hasFence; @@ -363,7 +364,7 @@ static void track_paint_util_draw_station_impl( } sub_98196C(session, imageId, 0, 0, 32, 8, 1, height + fenceOffsetA); // height -= 5 (height) - track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, entranceStyle, coverHeight); + track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, stationObj, coverHeight); // height += 5 (height + 5) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_END_STATION && direction == 0) @@ -412,7 +413,7 @@ static void track_paint_util_draw_station_impl( sub_98196C(session, imageId, 31, 23, 1, 8, 7, height + fenceOffsetB); } // height -= 7 (height) - track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, entranceStyle, coverHeight); + track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, stationObj, coverHeight); // height += 7 (height + 7) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_BEGIN_STATION && direction == 0) @@ -458,7 +459,7 @@ static void track_paint_util_draw_station_impl( } sub_98196C(session, imageId, 0, 0, 8, 32, 1, height + fenceOffsetA); // height -= 5 (height) - track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, entranceStyle, coverHeight); + track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, stationObj, coverHeight); // height += 5 (height + 5) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_END_STATION && direction == 3) @@ -508,7 +509,7 @@ static void track_paint_util_draw_station_impl( } // height -= 7 (height) - track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, entranceStyle, coverHeight); + track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, stationObj, coverHeight); // height += 7 (height + 7) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_BEGIN_STATION && direction == 3) @@ -530,7 +531,7 @@ void track_paint_util_draw_station_inverted( { LocationXY16 position = session->MapPosition; Ride* ride = get_ride(rideIndex); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); const bool hasGreenLight = tileElement->AsTrack()->HasGreenLight(); bool hasFence; @@ -568,7 +569,7 @@ void track_paint_util_draw_station_inverted( } sub_98196C(session, imageId, 0, 0, 32, 8, 1, height + 6); // height -= 5 (height) - track_paint_util_draw_station_covers_2(session, EDGE_NW, hasFence, entranceStyle, height, stationVariant); + track_paint_util_draw_station_covers_2(session, EDGE_NW, hasFence, stationObj, height, stationVariant); // height += 5 (height + 5) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_END_STATION && direction == 0) @@ -617,7 +618,7 @@ void track_paint_util_draw_station_inverted( sub_98196C(session, imageId, 31, 23, 1, 8, 7, height + 8); } // height -= 7 (height) - track_paint_util_draw_station_covers_2(session, EDGE_SE, hasFence, entranceStyle, height, stationVariant); + track_paint_util_draw_station_covers_2(session, EDGE_SE, hasFence, stationObj, height, stationVariant); // height += 7 (height + 7) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_BEGIN_STATION && direction == 0) @@ -663,7 +664,7 @@ void track_paint_util_draw_station_inverted( } sub_98196C(session, imageId, 0, 0, 8, 32, 1, height + 6); // height -= 5 (height) - track_paint_util_draw_station_covers_2(session, EDGE_NE, hasFence, entranceStyle, height, stationVariant); + track_paint_util_draw_station_covers_2(session, EDGE_NE, hasFence, stationObj, height, stationVariant); // height += 5 (height + 5) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_END_STATION && direction == 3) @@ -713,7 +714,7 @@ void track_paint_util_draw_station_inverted( } // height -= 7 (height) - track_paint_util_draw_station_covers_2(session, EDGE_SW, hasFence, entranceStyle, height, stationVariant); + track_paint_util_draw_station_covers_2(session, EDGE_SW, hasFence, stationObj, height, stationVariant); // height += 7 (height + 7) if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_BEGIN_STATION && direction == 3) @@ -730,15 +731,20 @@ void track_paint_util_draw_station_inverted( } bool track_paint_util_draw_station_covers( - paint_session* session, enum edge_t edge, bool hasFence, const rct_ride_entrance_definition* entranceStyle, uint16_t height) + paint_session* session, enum edge_t edge, bool hasFence, const StationObject* stationObject, uint16_t height) { - return track_paint_util_draw_station_covers_2(session, edge, hasFence, entranceStyle, height, STATION_VARIANT_BASIC); + return track_paint_util_draw_station_covers_2(session, edge, hasFence, stationObject, height, STATION_VARIANT_BASIC); } bool track_paint_util_draw_station_covers_2( - paint_session* session, enum edge_t edge, bool hasFence, const rct_ride_entrance_definition* entranceStyle, uint16_t height, + paint_session* session, enum edge_t edge, bool hasFence, const StationObject* stationObject, uint16_t height, uint8_t stationVariant) { + if (stationObject == nullptr) + { + return false; + } + if (!(session->Unk141E9DB & (G141E9DB_FLAG_1 | G141E9DB_FLAG_2))) { return false; @@ -751,7 +757,16 @@ bool track_paint_util_draw_station_covers_2( }; uint32_t imageId; - uint32_t baseImageId = entranceStyle->base_image_id; + uint32_t baseImageId = stationObject->ShelterImageId; + if (stationObject->Flags & STATION_OBJECT_FLAGS::HAS_SECONDARY_COLOUR) + { + baseImageId |= IMAGE_TYPE_REMAP_2_PLUS; + } + if (stationObject->Flags & STATION_OBJECT_FLAGS::IS_TRANSPARENT) + { + baseImageId |= IMAGE_TYPE_TRANSPARENT; + } + int32_t imageOffset = 0; LocationXYZ16 offset, bounds = { 0, 0, 0 }, boundsOffset = { 0, 0, 0 }; @@ -823,14 +838,14 @@ void track_paint_util_draw_station_platform( paint_session* session, Ride* ride, uint8_t direction, int32_t height, int32_t zOffset, const TileElement* tileElement) { LocationXY16 position = session->MapPosition; - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); if (direction & 1) { bool hasFence = track_paint_util_has_fence(EDGE_NE, position, tileElement, ride, session->CurrentRotation); uint32_t imageId = (hasFence ? SPR_STATION_NARROW_EDGE_FENCED_NE : SPR_STATION_NARROW_EDGE_NE) | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 0, 0, 8, 32, 1, height + zOffset); - track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, stationObj, height); imageId = SPR_STATION_NARROW_EDGE_SW | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 24, 0, 8, 32, 1, height + zOffset); @@ -841,7 +856,7 @@ void track_paint_util_draw_station_platform( imageId = SPR_STATION_FENCE_NW_SE | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 31, 0, 1, 32, 7, height + zOffset + 2); } - track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, stationObj, height); } else { @@ -849,7 +864,7 @@ void track_paint_util_draw_station_platform( uint32_t imageId = (hasFence ? SPR_STATION_NARROW_EDGE_FENCED_NW : SPR_STATION_NARROW_EDGE_NW) | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 0, 0, 32, 8, 1, height + zOffset); - track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, stationObj, height); imageId = SPR_STATION_NARROW_EDGE_SE | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 0, 24, 32, 8, 1, height + zOffset); @@ -860,13 +875,13 @@ void track_paint_util_draw_station_platform( imageId = SPR_STATION_FENCE_SW_NE | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 0, 31, 32, 1, 7, height + zOffset + 2); } - track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, stationObj, height); } } void track_paint_util_draw_pier( - paint_session* session, Ride* ride, const rct_ride_entrance_definition* entranceStyle, LocationXY16 position, - uint8_t direction, int32_t height, const TileElement* tileElement, uint8_t rotation) + paint_session* session, Ride* ride, const StationObject* stationObj, LocationXY16 position, uint8_t direction, + int32_t height, const TileElement* tileElement, uint8_t rotation) { bool hasFence; uint32_t imageId; @@ -877,7 +892,7 @@ void track_paint_util_draw_pier( imageId = (hasFence ? SPR_STATION_PIER_EDGE_NE_FENCED : SPR_STATION_PIER_EDGE_NE) | session->TrackColours[SCHEME_SUPPORTS]; sub_98197C(session, imageId, 0, 0, 6, 32, 1, height, 2, 0, height); - track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, stationObj, height); imageId = SPR_STATION_PIER_EDGE_SW | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 24, 0, 8, 32, 1, height); @@ -888,7 +903,7 @@ void track_paint_util_draw_pier( imageId = SPR_STATION_PIER_FENCE_SW | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 31, 0, 1, 32, 7, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, stationObj, height); } else { @@ -896,7 +911,7 @@ void track_paint_util_draw_pier( imageId = (hasFence ? SPR_STATION_PIER_EDGE_NW_FENCED : SPR_STATION_PIER_EDGE_NW) | session->TrackColours[SCHEME_SUPPORTS]; sub_98197C(session, imageId, 0, 0, 32, 6, 1, height, 0, 2, height); - track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, stationObj, height); imageId = SPR_STATION_PIER_EDGE_SE | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 0, 24, 32, 8, 1, height); @@ -907,7 +922,7 @@ void track_paint_util_draw_pier( imageId = SPR_STATION_PIER_FENCE_SE | session->TrackColours[SCHEME_SUPPORTS]; sub_98196C(session, imageId, 0, 31, 32, 1, 7, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, stationObj, height); } } @@ -2149,14 +2164,6 @@ void track_paint(paint_session* session, uint8_t direction, int32_t height, cons return; } - // HACK Set entrance style to plain if none to stop glitch until entrance track piece is implemented - bool isEntranceStyleNone = false; - if (ride->entrance_style == RIDE_ENTRANCE_STYLE_NONE) - { - isEntranceStyleNone = true; - ride->entrance_style = RIDE_ENTRANCE_STYLE_PLAIN; - } - rct_drawpixelinfo* dpi = session->DPI; if ((!gTrackDesignSaveMode || rideIndex == gTrackDesignSaveRideIndex) @@ -2212,9 +2219,4 @@ void track_paint(paint_session* session, uint8_t direction, int32_t height, cons } } } - - if (isEntranceStyleNone) - { - ride->entrance_style = RIDE_ENTRANCE_STYLE_NONE; - } } diff --git a/src/openrct2/ride/TrackPaint.h b/src/openrct2/ride/TrackPaint.h index 24d2dc5b26..28f0db6a7a 100644 --- a/src/openrct2/ride/TrackPaint.h +++ b/src/openrct2/ride/TrackPaint.h @@ -16,6 +16,8 @@ #include "../world/Map.h" #include "RideData.h" +class StationObject; + extern const uint8_t track_map_2x2[][4]; extern const uint8_t edges_2x2[]; @@ -284,10 +286,9 @@ void track_paint_util_paint_fences( paint_session* session, uint8_t edges, LocationXY16 position, const TileElement* tileElement, Ride* ride, uint32_t colourFlags, uint16_t height, const uint32_t fenceSprites[4], uint8_t rotation); bool track_paint_util_draw_station_covers( - paint_session* session, enum edge_t edge, bool hasFence, const rct_ride_entrance_definition* entranceStyle, - uint16_t height); + paint_session* session, enum edge_t edge, bool hasFence, const StationObject* stationObject, uint16_t height); bool track_paint_util_draw_station_covers_2( - paint_session* session, enum edge_t edge, bool hasFence, const rct_ride_entrance_definition* entranceStyle, uint16_t height, + paint_session* session, enum edge_t edge, bool hasFence, const StationObject* stationObject, uint16_t height, uint8_t stationVariant); void track_paint_util_draw_station_platform( paint_session* session, Ride* ride, uint8_t direction, int32_t height, int32_t zOffset, const TileElement* tileElement); @@ -304,8 +305,8 @@ void track_paint_util_draw_station_inverted( uint8_t stationVariant); bool track_paint_util_should_paint_supports(LocationXY16 position); void track_paint_util_draw_pier( - paint_session* session, Ride* ride, const rct_ride_entrance_definition* entranceStyle, LocationXY16 position, - uint8_t direction, int32_t height, const TileElement* tileElement, uint8_t rotation); + paint_session* session, Ride* ride, const StationObject* stationObject, LocationXY16 position, uint8_t direction, + int32_t height, const TileElement* tileElement, uint8_t rotation); void track_paint_util_draw_station_metal_supports(paint_session* session, uint8_t direction, uint16_t height, uint32_t colour); void track_paint_util_draw_station_metal_supports_2( paint_session* session, uint8_t direction, uint16_t height, uint32_t colour, uint8_t type); diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index 278557286f..30996d81ec 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -7282,7 +7282,7 @@ static void vehicle_update_additional_animation(rct_vehicle* vehicle) if (al != ah) { Ride* ride = get_ride(vehicle->ride); - if (ride->entrance_style == RIDE_ENTRANCE_STYLE_PLAIN + if (!ride_has_station_shelter(ride) || (vehicle->status != VEHICLE_STATUS_MOVING_TO_END_OF_STATION && vehicle->status != VEHICLE_STATUS_ARRIVING)) { diff --git a/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp b/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp index 83e8eae378..7676250a83 100644 --- a/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp +++ b/src/openrct2/ride/coaster/MultiDimensionRollerCoaster.cpp @@ -132,28 +132,28 @@ static void multi_dimension_rc_track_station( track_paint_util_draw_station_metal_supports_2(session, direction, height, session->TrackColours[SCHEME_SUPPORTS], 11); Ride* ride = get_ride(rideIndex); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); bool hasFence; if (direction == 0 || direction == 2) { hasFence = track_paint_util_has_fence(EDGE_NW, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, stationObj, height); } else { hasFence = track_paint_util_has_fence(EDGE_NE, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, stationObj, height); } if (direction == 0 || direction == 2) { hasFence = track_paint_util_has_fence(EDGE_SE, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, stationObj, height); } else { hasFence = track_paint_util_has_fence(EDGE_SW, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, stationObj, height); } paint_util_push_tunnel_rotated(session, direction, height, TUNNEL_6); diff --git a/src/openrct2/ride/gentle/MiniGolf.cpp b/src/openrct2/ride/gentle/MiniGolf.cpp index 6b4d0bda30..8e059a3998 100644 --- a/src/openrct2/ride/gentle/MiniGolf.cpp +++ b/src/openrct2/ride/gentle/MiniGolf.cpp @@ -675,7 +675,7 @@ static void paint_mini_golf_station( { LocationXY16 position = session->MapPosition; Ride* ride = get_ride(rideIndex); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); uint32_t imageId; bool hasFence; @@ -698,8 +698,8 @@ static void paint_mini_golf_station( sub_98197C(session, imageId, 10, 0, 1, 32, 7, height, 31, 0, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, entranceStyle, height); - track_paint_util_draw_station_covers(session, EDGE_SW, hasSWFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, stationObj, height); + track_paint_util_draw_station_covers(session, EDGE_SW, hasSWFence, stationObj, height); // Was leftwards tunnel in game, seems odd paint_util_push_tunnel_right(session, height, TUNNEL_6); @@ -720,8 +720,8 @@ static void paint_mini_golf_station( sub_98197C(session, imageId, 0, 10, 32, 1, 7, height, 0, 31, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, entranceStyle, height); - track_paint_util_draw_station_covers(session, EDGE_SE, hasSEFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, stationObj, height); + track_paint_util_draw_station_covers(session, EDGE_SE, hasSEFence, stationObj, height); paint_util_push_tunnel_left(session, height, TUNNEL_6); } diff --git a/src/openrct2/ride/thrill/GoKarts.cpp b/src/openrct2/ride/thrill/GoKarts.cpp index 41c61f08f5..5cb842b2c5 100644 --- a/src/openrct2/ride/thrill/GoKarts.cpp +++ b/src/openrct2/ride/thrill/GoKarts.cpp @@ -349,7 +349,7 @@ static void paint_go_karts_station( { LocationXY16 position = session->MapPosition; Ride* ride = get_ride(rideIndex); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); bool hasFence; uint32_t imageId; @@ -373,12 +373,12 @@ static void paint_go_karts_station( if (direction == 0 || direction == 2) { hasFence = track_paint_util_has_fence(EDGE_NW, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, stationObj, height); } else { hasFence = track_paint_util_has_fence(EDGE_NE, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, stationObj, height); } imageId = sprites[direction][1] | session->TrackColours[SCHEME_TRACK]; @@ -398,12 +398,12 @@ static void paint_go_karts_station( if (direction == 0 || direction == 2) { hasFence = track_paint_util_has_fence(EDGE_SE, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, stationObj, height); } else { hasFence = track_paint_util_has_fence(EDGE_SW, position, tileElement, ride, session->CurrentRotation); - track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, stationObj, height); } if (tileElement->AsTrack()->GetTrackType() == TRACK_ELEM_END_STATION) diff --git a/src/openrct2/ride/transport/Chairlift.cpp b/src/openrct2/ride/transport/Chairlift.cpp index 06ca31dac9..16fd764788 100644 --- a/src/openrct2/ride/transport/Chairlift.cpp +++ b/src/openrct2/ride/transport/Chairlift.cpp @@ -184,7 +184,7 @@ static void chairlift_paint_station_ne_sw( ; bool isEnd = chairlift_paint_util_is_last_track(rideIndex, tileElement, pos, trackType); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); wooden_a_supports_paint_setup(session, 0, 0, height, session->TrackColours[SCHEME_MISC], nullptr); @@ -203,7 +203,7 @@ static void chairlift_paint_station_ne_sw( imageId = SPR_FENCE_METAL_NW | session->TrackColours[SCHEME_TRACK]; sub_98199C(session, imageId, 0, 0, 32, 1, 7, height, 0, 2, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NW, hasFence, stationObj, height); if ((direction == 2 && isStart) || (direction == 0 && isEnd)) { @@ -217,7 +217,7 @@ static void chairlift_paint_station_ne_sw( imageId = SPR_FENCE_METAL_SE | session->TrackColours[SCHEME_TRACK]; sub_98197C(session, imageId, 0, 0, 32, 1, 27, height, 0, 30, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SE, hasFence, stationObj, height); bool drawFrontColumn = true; bool drawBackColumn = true; @@ -275,7 +275,7 @@ static void chairlift_paint_station_se_nw( ; bool isEnd = chairlift_paint_util_is_last_track(rideIndex, tileElement, pos, trackType); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); wooden_a_supports_paint_setup(session, 1, 0, height, session->TrackColours[SCHEME_MISC], nullptr); @@ -294,7 +294,7 @@ static void chairlift_paint_station_se_nw( imageId = SPR_FENCE_METAL_NE | session->TrackColours[SCHEME_TRACK]; sub_98199C(session, imageId, 0, 0, 1, 32, 7, height, 2, 0, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_NE, hasFence, stationObj, height); if ((direction == 1 && isStart) || (direction == 3 && isEnd)) { @@ -308,7 +308,7 @@ static void chairlift_paint_station_se_nw( imageId = SPR_FENCE_METAL_SW | session->TrackColours[SCHEME_TRACK]; sub_98197C(session, imageId, 0, 0, 1, 32, 27, height, 30, 0, height + 2); } - track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, entranceStyle, height); + track_paint_util_draw_station_covers(session, EDGE_SW, hasFence, stationObj, height); bool drawRightColumn = true; bool drawLeftColumn = true; diff --git a/src/openrct2/ride/water/BoatHire.cpp b/src/openrct2/ride/water/BoatHire.cpp index ae23b6fea5..8380e4b3ab 100644 --- a/src/openrct2/ride/water/BoatHire.cpp +++ b/src/openrct2/ride/water/BoatHire.cpp @@ -65,19 +65,19 @@ static void paint_boat_hire_station( { LocationXY16 position = session->MapPosition; Ride* ride = get_ride(rideIndex); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); if (direction & 1) { paint_util_push_tunnel_right(session, height, TUNNEL_6); track_paint_util_draw_pier( - session, ride, entranceStyle, position, direction, height, tileElement, session->CurrentRotation); + session, ride, stationObj, position, direction, height, tileElement, session->CurrentRotation); } else { paint_util_push_tunnel_left(session, height, TUNNEL_6); track_paint_util_draw_pier( - session, ride, entranceStyle, position, direction, height, tileElement, session->CurrentRotation); + session, ride, stationObj, position, direction, height, tileElement, session->CurrentRotation); } paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0); diff --git a/src/openrct2/ride/water/SubmarineRide.cpp b/src/openrct2/ride/water/SubmarineRide.cpp index c957dd5832..f21f326571 100644 --- a/src/openrct2/ride/water/SubmarineRide.cpp +++ b/src/openrct2/ride/water/SubmarineRide.cpp @@ -80,7 +80,7 @@ static void submarine_ride_paint_track_station( { LocationXY16 position = session->MapPosition; Ride* ride = get_ride(rideIndex); - const rct_ride_entrance_definition* entranceStyle = &RideEntranceDefinitions[ride->entrance_style]; + auto stationObj = ride_get_station_object(ride); int32_t heightLower = height - 16; uint32_t imageId; @@ -91,7 +91,7 @@ static void submarine_ride_paint_track_station( paint_util_push_tunnel_right(session, height, TUNNEL_6); track_paint_util_draw_pier( - session, ride, entranceStyle, position, direction, height, tileElement, session->CurrentRotation); + session, ride, stationObj, position, direction, height, tileElement, session->CurrentRotation); } else { @@ -100,7 +100,7 @@ static void submarine_ride_paint_track_station( paint_util_push_tunnel_left(session, height, TUNNEL_6); track_paint_util_draw_pier( - session, ride, entranceStyle, position, direction, height, tileElement, session->CurrentRotation); + session, ride, stationObj, position, direction, height, tileElement, session->CurrentRotation); } paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0); diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 49255f52b9..422930d0d1 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -159,7 +159,7 @@ void scenario_begin() park_calculate_size(); map_count_remaining_land_rights(); staff_reset_stats(); - gLastEntranceStyle = RIDE_ENTRANCE_STYLE_PLAIN; + gLastEntranceStyle = 0; memset(gMarketingCampaignDaysLeft, 0, 20); gParkRatingCasualtyPenalty = 0; diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 084e5eb9e4..397c05e8b4 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -826,21 +826,9 @@ enum SPR_G2_SELECTION_EDGE_SW = SPR_G2_BEGIN + 110, SPR_G2_SELECTION_EDGE_SE = SPR_G2_BEGIN + 111, - SPR_G2_WALL_TEXTURE_BRICK = SPR_G2_BEGIN + 112, - SPR_G2_WALL_TEXTURE_IRON = SPR_G2_BEGIN + 113, - SPR_G2_WALL_TEXTURE_GREY = SPR_G2_BEGIN + 114, - SPR_G2_WALL_TEXTURE_YELLOW = SPR_G2_BEGIN + 115, - SPR_G2_WALL_TEXTURE_RED = SPR_G2_BEGIN + 116, - SPR_G2_WALL_TEXTURE_PURPLE = SPR_G2_BEGIN + 117, - SPR_G2_WALL_TEXTURE_GREEN = SPR_G2_BEGIN + 118, - SPR_G2_WALL_TEXTURE_STONE_BROWN = SPR_G2_BEGIN + 119, - SPR_G2_WALL_TEXTURE_STONE_GREY = SPR_G2_BEGIN + 120, - SPR_G2_WALL_TEXTURE_SKYSCRAPER_A = SPR_G2_BEGIN + 121, - SPR_G2_WALL_TEXTURE_SKYSCRAPER_B = SPR_G2_BEGIN + 122, + SPR_G2_EYEDROPPER = SPR_G2_BEGIN + 112, - SPR_G2_EYEDROPPER = SPR_G2_BEGIN + 123, - - SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 124, + SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 113, SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN, SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1, @@ -938,30 +926,6 @@ enum // of the last possible range of image ID values that is large enough to fit all csg1 sprites. SPR_CSG_BEGIN = 393216, - SPR_CSG_EDGE_BRICK_BASE = SPR_CSG_BEGIN + 40506, - SPR_CSG_EDGE_IRON_BASE = SPR_CSG_BEGIN + 40590, - SPR_CSG_EDGE_RED_BASE = SPR_CSG_BEGIN + 40926, - SPR_CSG_EDGE_YELLOW_BASE = SPR_CSG_BEGIN + 41030, - SPR_CSG_EDGE_GREY_BASE = SPR_CSG_BEGIN + 41134, - SPR_CSG_EDGE_PURPLE_BASE = SPR_CSG_BEGIN + 41238, - SPR_CSG_EDGE_GREEN_BASE = SPR_CSG_BEGIN + 41342, - SPR_CSG_EDGE_STONE_BROWN_BASE = SPR_CSG_BEGIN + 41446, - SPR_CSG_EDGE_STONE_GREY_BASE = SPR_CSG_BEGIN + 41550, - SPR_CSG_EDGE_SKYSCRAPER_A_BASE = SPR_CSG_BEGIN + 41654, - SPR_CSG_EDGE_SKYSCRAPER_B_BASE = SPR_CSG_BEGIN + 41758, - - SPR_CSG_WALL_TEXTURE_BRICK = SPR_CSG_BEGIN + 47365, - SPR_CSG_WALL_TEXTURE_IRON = SPR_CSG_BEGIN + 47366, - SPR_CSG_WALL_TEXTURE_GREY = SPR_CSG_BEGIN + 47368, - SPR_CSG_WALL_TEXTURE_YELLOW = SPR_CSG_BEGIN + 47369, - SPR_CSG_WALL_TEXTURE_RED = SPR_CSG_BEGIN + 47371, - SPR_CSG_WALL_TEXTURE_PURPLE = SPR_CSG_BEGIN + 47373, - SPR_CSG_WALL_TEXTURE_GREEN = SPR_CSG_BEGIN + 47374, - SPR_CSG_WALL_TEXTURE_STONE_BROWN = SPR_CSG_BEGIN + 47375, - SPR_CSG_WALL_TEXTURE_STONE_GREY = SPR_CSG_BEGIN + 47376, - SPR_CSG_WALL_TEXTURE_SKYSCRAPER_A = SPR_CSG_BEGIN + 47377, - SPR_CSG_WALL_TEXTURE_SKYSCRAPER_B = SPR_CSG_BEGIN + 47378, - SPR_CSG_ICE_CREAM_STALL_BEGIN = SPR_CSG_BEGIN + 60625, SPR_CSG_TOILETS_BEGIN = SPR_CSG_BEGIN + 61289, diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 73ccfbfa30..ded1c443cb 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -25,6 +25,8 @@ #include "../localisation/Localisation.h" #include "../management/Finance.h" #include "../network/network.h" +#include "../object/ObjectManager.h" +#include "../object/TerrainSurfaceObject.h" #include "../ride/RideData.h" #include "../ride/Track.h" #include "../ride/TrackData.h" @@ -47,6 +49,8 @@ #include #include +using namespace OpenRCT2; + /** * Replaces 0x00993CCC, 0x00993CCE */ @@ -56,24 +60,6 @@ const CoordsXY CoordsDirectionDelta[] = { { -32, 0 }, { 0, +32 }, { +32, 0 } const TileCoordsXY TileDirectionDelta[] = { { -1, 0 }, { 0, +1 }, { +1, 0 }, { 0, -1 }, { -1, +1 }, { +1, +1 }, { +1, -1 }, { -1, -1 } }; -/** rct2: 0x0097B8B8 */ -const money32 TerrainPricing[] = { - 300, // TERRAIN_GRASS - 100, // TERRAIN_SAND - 80, // TERRAIN_DIRT - 120, // TERRAIN_ROCK - 100, // TERRAIN_MARTIAN - 100, // TERRAIN_CHECKERBOARD - 110, // TERRAIN_GRASS_CLUMPS - 130, // TERRAIN_ICE - 110, // TERRAIN_GRID_RED - 110, // TERRAIN_GRID_YELLOW - 110, // TERRAIN_GRID_BLUE - 110, // TERRAIN_GRID_GREEN - 110, // TERRAIN_SAND_DARK - 110, // TERRAIN_SAND_LIGHT -}; - uint16_t gMapSelectFlags; uint16_t gMapSelectType; LocationXY16 gMapSelectPositionA; @@ -1309,11 +1295,13 @@ static money32 map_change_surface_style( // Prevent network-originated value of surfaceStyle from causing // invalid access. uint8_t style = surfaceStyle & 0x1F; - if (style >= std::size(TerrainPricing)) + auto& objManager = GetContext()->GetObjectManager(); + const auto surfaceObj = static_cast( + objManager.GetLoadedObject(OBJECT_TYPE_TERRAIN_SURFACE, style)); + if (surfaceObj != nullptr) { - return MONEY32_UNDEFINED; + surfaceCost += surfaceObj->Price; } - surfaceCost += TerrainPricing[style]; if (flags & GAME_COMMAND_FLAG_APPLY) { diff --git a/src/openrct2/world/Map.h b/src/openrct2/world/Map.h index 63d50a0674..1ffda16807 100644 --- a/src/openrct2/world/Map.h +++ b/src/openrct2/world/Map.h @@ -81,7 +81,6 @@ enum extern const CoordsXY CoordsDirectionDelta[]; extern const TileCoordsXY TileDirectionDelta[]; -extern const money32 TerrainPricing[]; extern uint16_t gWidePathTileLoopX; extern uint16_t gWidePathTileLoopY; diff --git a/src/openrct2/world/MapAnimation.cpp b/src/openrct2/world/MapAnimation.cpp index ef475fe7e4..0bb0e2b180 100644 --- a/src/openrct2/world/MapAnimation.cpp +++ b/src/openrct2/world/MapAnimation.cpp @@ -9,8 +9,10 @@ #include "MapAnimation.h" +#include "../Context.h" #include "../Game.h" #include "../interface/Viewport.h" +#include "../object/StationObject.h" #include "../ride/Ride.h" #include "../ride/RideData.h" #include "../ride/Track.h" @@ -103,11 +105,7 @@ void map_animation_invalidate_all() */ static bool map_animation_invalidate_ride_entrance(int32_t x, int32_t y, int32_t baseZ) { - TileElement* tileElement; - Ride* ride; - const rct_ride_entrance_definition* entranceDefinition; - - tileElement = map_get_first_element_at(x >> 5, y >> 5); + auto tileElement = map_get_first_element_at(x >> 5, y >> 5); do { if (tileElement->base_height != baseZ) @@ -117,11 +115,16 @@ static bool map_animation_invalidate_ride_entrance(int32_t x, int32_t y, int32_t if (tileElement->AsEntrance()->GetEntranceType() != ENTRANCE_TYPE_RIDE_ENTRANCE) continue; - ride = get_ride(tileElement->AsEntrance()->GetRideIndex()); - entranceDefinition = &RideEntranceDefinitions[ride->entrance_style]; - - int32_t height = (tileElement->base_height * 8) + entranceDefinition->height + 8; - map_invalidate_tile_zoom1(x, y, height, height + 16); + auto ride = get_ride(tileElement->AsEntrance()->GetRideIndex()); + if (ride != nullptr) + { + auto stationObj = ride_get_station_object(ride); + if (stationObj != nullptr) + { + int32_t height = (tileElement->base_height * 8) + stationObj->Height + 8; + map_invalidate_tile_zoom1(x, y, height, height + 16); + } + } return false; } while (!(tileElement++)->IsLastForTile()); diff --git a/test/testpaint/Compat.cpp b/test/testpaint/Compat.cpp index c922614e46..c84d7c5535 100644 --- a/test/testpaint/Compat.cpp +++ b/test/testpaint/Compat.cpp @@ -20,6 +20,8 @@ #include #include +class StationObject; + #define gRideEntries RCT2_ADDRESS(0x009ACFA4, rct_ride_entry*) #define gTileElementTilePointers RCT2_ADDRESS(0x013CE9A4, TileElement*) rct_sprite* sprite_list = RCT2_ADDRESS(0x010E63BC, rct_sprite); @@ -418,3 +420,8 @@ uint8_t PathElement::GetEdges() const { return edges & 0xF; } + +StationObject* ride_get_station_object(const Ride* ride) +{ + return nullptr; +} diff --git a/test/testpaint/TestPaint.cpp b/test/testpaint/TestPaint.cpp index d65266bb82..97c72195d5 100644 --- a/test/testpaint/TestPaint.cpp +++ b/test/testpaint/TestPaint.cpp @@ -47,7 +47,7 @@ namespace TestPaint { Ride ride = {}; - ride.entrance_style = RIDE_ENTRANCE_STYLE_PLAIN; + ride.entrance_style = 0; static rct_ride_entry rideEntry = {}; rct_ride_entry_vehicle vehicleEntry{}; vehicleEntry.base_image_id = 0x70000; @@ -57,7 +57,7 @@ namespace TestPaint } { rct2_ride ride = {}; - ride.entrance_style = RIDE_ENTRANCE_STYLE_PLAIN; + ride.entrance_style = 0; RCT2_Rides[0] = ride; } diff --git a/test/testpaint/TestTrack.cpp b/test/testpaint/TestTrack.cpp index 86eb8aa508..13617be7dd 100644 --- a/test/testpaint/TestTrack.cpp +++ b/test/testpaint/TestTrack.cpp @@ -167,7 +167,7 @@ public: int Variations(uint8_t rideType, uint8_t trackType) override { - return RIDE_ENTRANCE_STYLE_COUNT - 1; + return 12; } std::string VariantName(uint8_t rideType, uint8_t trackType, int variant) override From ef57f1a4030b8a70b57afa9c615d95095e337e99 Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 5 Dec 2018 21:59:35 +0000 Subject: [PATCH 2/6] Fix zoomed out images --- src/openrct2/object/ObjectJsonHelpers.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/openrct2/object/ObjectJsonHelpers.cpp b/src/openrct2/object/ObjectJsonHelpers.cpp index 3732578641..c32f21c0f8 100644 --- a/src/openrct2/object/ObjectJsonHelpers.cpp +++ b/src/openrct2/object/ObjectJsonHelpers.cpp @@ -517,6 +517,8 @@ namespace ObjectJsonHelpers { images = ParseImages(context, el); } + + auto imagesStartIndex = imageTable.GetCount(); for (const auto& img : images) { const auto& g1 = img->g1; @@ -526,14 +528,15 @@ namespace ObjectJsonHelpers // Add zoom images here for (size_t j = 0; j < images.size(); j++) { + const auto tableIndex = imagesStartIndex + j; const auto* img = images[j].get(); if (img->next_zoom != nullptr) { img = img->next_zoom.get(); // Set old image zoom offset to zoom image which we are about to add - auto g1a = (rct_g1_element*)(&imageTable.GetImages()[j]); - g1a->zoomed_offset = (int32_t)j - (int32_t)imageTable.GetCount(); + auto g1a = (rct_g1_element*)(&imageTable.GetImages()[tableIndex]); + g1a->zoomed_offset = (int32_t)tableIndex - (int32_t)imageTable.GetCount(); while (img != nullptr) { From 74793a3931107be97d9f06be1f706d61a7c4f123 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 9 Dec 2018 23:06:50 +0000 Subject: [PATCH 3/6] Update objects version --- CMakeLists.txt | 4 ++-- OpenRCT2.xcodeproj/project.pbxproj | 2 +- openrct2.proj | 4 ++-- src/openrct2-android/app/build.gradle | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c799cb740..e4307598c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,8 +21,8 @@ set(CMAKE_MACOSX_RPATH 1) set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2/title-sequence-v0.1.2.zip") set(TITLE_SEQUENCE_SHA1 "1136ef92bfb05cd1cba9831ba6dc4a653d87a246") -set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.6/objects.zip") -set(OBJECTS_SHA1 "61c70237814dc0f5aee5e9219f2ff232ea1a6111") +set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.7/objects.zip") +set(OBJECTS_SHA1 "c9acbbd16c649d8a9fc308ee5b02ecb7f89c8565") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 0358625205..1ea1b2361a 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -3447,7 +3447,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "version=\"1.0.6\"\nzipname=\"objects.zip\"\nliburl=\"https://github.com/OpenRCT2/objects/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/object\" || ! -e \"${SRCROOT}/objectsversion\" || $(head -n 1 \"${SRCROOT}/objectsversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/object\" ]]; then rm -r \"${SRCROOT}/data/object\"; fi\nmkdir -p \"${SRCROOT}/data/object\"\n\ncurl -L -o \"${SRCROOT}/data/object/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/object\" \"${SRCROOT}/data/object/$zipname\"\nrm \"${SRCROOT}/data/object/$zipname\"\n\necho $version > \"${SRCROOT}/objectsversion\"\nfi"; + shellScript = "version=\"1.0.7\"\nzipname=\"objects.zip\"\nliburl=\"https://github.com/OpenRCT2/objects/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/data/object\" || ! -e \"${SRCROOT}/objectsversion\" || $(head -n 1 \"${SRCROOT}/objectsversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/data/object\" ]]; then rm -r \"${SRCROOT}/data/object\"; fi\nmkdir -p \"${SRCROOT}/data/object\"\n\ncurl -L -o \"${SRCROOT}/data/object/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/data/object\" \"${SRCROOT}/data/object/$zipname\"\nrm \"${SRCROOT}/data/object/$zipname\"\n\necho $version > \"${SRCROOT}/objectsversion\"\nfi"; }; C68B2D471EC790710020651C /* Download Libraries */ = { isa = PBXShellScriptBuildPhase; diff --git a/openrct2.proj b/openrct2.proj index 14ce00377b..f53ec88b4b 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -70,8 +70,8 @@ 058b9df80244c03f1633cb06e9f70471a29ebb8e https://github.com/OpenRCT2/title-sequences/releases/download/v0.1.2/title-sequence-v0.1.2.zip 1136ef92bfb05cd1cba9831ba6dc4a653d87a246 - https://github.com/OpenRCT2/objects/releases/download/v1.0.6/objects.zip - 61c70237814dc0f5aee5e9219f2ff232ea1a6111 + https://github.com/OpenRCT2/objects/releases/download/v1.0.7/objects.zip + c9acbbd16c649d8a9fc308ee5b02ecb7f89c8565 diff --git a/src/openrct2-android/app/build.gradle b/src/openrct2-android/app/build.gradle index beeed98a4a..1837308c3b 100644 --- a/src/openrct2-android/app/build.gradle +++ b/src/openrct2-android/app/build.gradle @@ -98,7 +98,7 @@ android.applicationVariants.all { variant -> into "$variant.mergeAssets.outputDir/data/title" } download { - src 'https://github.com/OpenRCT2/objects/releases/download/v1.0.6/objects.zip' + src 'https://github.com/OpenRCT2/objects/releases/download/v1.0.7/objects.zip' dest new File(buildDir, 'objects.zip') } copy { From 4b77d763036abf10474759c9980c72f14aef4dcf Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 9 Dec 2018 23:09:42 +0000 Subject: [PATCH 4/6] Hide new object tabs until we have new save format --- .../windows/EditorObjectSelection.cpp | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index e32af26171..a40da0050a 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -86,7 +86,7 @@ struct ObjectPageDesc bool IsAdvanced; }; -static constexpr const ObjectPageDesc ObjectSelectionPages[OBJECT_TYPE_COUNT] = { +static constexpr const ObjectPageDesc ObjectSelectionPages[] = { { STR_OBJECT_SELECTION_RIDE_VEHICLES_ATTRACTIONS, SPR_TAB_RIDE_16, false }, { STR_OBJECT_SELECTION_SMALL_SCENERY, SPR_TAB_SCENERY_TREES, true }, { STR_OBJECT_SELECTION_LARGE_SCENERY, SPR_TAB_SCENERY_URBAN, true }, @@ -97,11 +97,15 @@ static constexpr const ObjectPageDesc ObjectSelectionPages[OBJECT_TYPE_COUNT] = { STR_OBJECT_SELECTION_SCENERY_GROUPS, SPR_TAB_SCENERY_STATUES, false }, { STR_OBJECT_SELECTION_PARK_ENTRANCE, SPR_TAB_PARK, false }, { STR_OBJECT_SELECTION_WATER, SPR_TAB_WATER, false }, - { STR_OBJECT_SELECTION_SCENARIO_DESCRIPTION, SPR_TAB_STATS, false }, - { STR_OBJECT_SELECTION_TERRAIN_SURFACES, SPR_G2_TAB_LAND, false }, - { STR_OBJECT_SELECTION_TERRAIN_EDGES, SPR_G2_TAB_LAND, false }, - { STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, false }, - { STR_OBJECT_SELECTION_MUSIC, SPR_TAB_MUSIC_0, false }, + + // No longer supported: + // { STR_OBJECT_SELECTION_SCENARIO_DESCRIPTION, SPR_TAB_STATS, false }, + + // Currently hidden until new save format arrives: + // { STR_OBJECT_SELECTION_TERRAIN_SURFACES, SPR_G2_TAB_LAND, false }, + // { STR_OBJECT_SELECTION_TERRAIN_EDGES, SPR_G2_TAB_LAND, false }, + // { STR_OBJECT_SELECTION_STATIONS, SPR_TAB_PARK, false }, + // { STR_OBJECT_SELECTION_MUSIC, SPR_TAB_MUSIC_0, false }, }; #pragma region Widgets @@ -782,7 +786,7 @@ static void window_editor_object_selection_scroll_mouseover(rct_window* w, int32 */ static void window_editor_object_selection_tooltip(rct_window* w, rct_widgetindex widgetIndex, rct_string_id* stringId) { - if (widgetIndex >= WIDX_TAB_1 && widgetIndex < WIDX_TAB_1 + OBJECT_TYPE_COUNT) + if (widgetIndex >= WIDX_TAB_1 && widgetIndex < WIDX_TAB_1 + std::size(ObjectSelectionPages)) { set_format_arg(0, rct_string_id, ObjectSelectionPages[(widgetIndex - WIDX_TAB_1)].Caption); } @@ -842,7 +846,7 @@ static void window_editor_object_selection_invalidate(rct_window* w) // Align tabs, hide advanced ones bool advancedMode = (w->list_information_type & 1) != 0; int32_t x = 3; - for (int32_t i = 0; i < OBJECT_TYPE_COUNT; i++) + for (int32_t i = 0; i < std::size(ObjectSelectionPages); i++) { auto widget = &w->widgets[WIDX_TAB_1 + i]; if (!advancedMode && ObjectSelectionPages[i].IsAdvanced) @@ -956,7 +960,7 @@ static void window_editor_object_selection_paint(rct_window* w, rct_drawpixelinf window_draw_widgets(w, dpi); // Draw tabs - for (i = 0; i < OBJECT_TYPE_COUNT; i++) + for (i = 0; i < std::size(ObjectSelectionPages); i++) { widget = &w->widgets[WIDX_TAB_1 + i]; if (widget->type != WWT_EMPTY) From 253409b64ceaf82e6039f122ecb4fa63fa720761 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sun, 9 Dec 2018 23:15:11 +0000 Subject: [PATCH 5/6] Update changelog --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 5030ad561b..f61e7a3915 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -13,6 +13,7 @@ - Feature: [#8190] Allow building footpaths on 'corner down' terrain. - Feature: [#8191] Allow building on-ride photos and water S-bends on the Water Coaster. - Feature: [#8259] Add say command to in-game console. +- Change: [#7961] Add new object types: station, terrain surface, and terrain edge. - Change: [#8222] The climate setting has been moved from objective options to scenario options. - Fix: [#6191] OpenRCT2 fails to run when the path has an emoji in it. - Fix: [#7439] Placement messages have mixed strings From 9dc860b526479fd213992d78b41fb3dc7190efc6 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 10 Dec 2018 00:26:12 +0000 Subject: [PATCH 6/6] Fix compile errors --- src/openrct2-ui/windows/EditorObjectSelection.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index a40da0050a..370ea02d83 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -786,7 +786,7 @@ static void window_editor_object_selection_scroll_mouseover(rct_window* w, int32 */ static void window_editor_object_selection_tooltip(rct_window* w, rct_widgetindex widgetIndex, rct_string_id* stringId) { - if (widgetIndex >= WIDX_TAB_1 && widgetIndex < WIDX_TAB_1 + std::size(ObjectSelectionPages)) + if (widgetIndex >= WIDX_TAB_1 && (size_t)widgetIndex < WIDX_TAB_1 + std::size(ObjectSelectionPages)) { set_format_arg(0, rct_string_id, ObjectSelectionPages[(widgetIndex - WIDX_TAB_1)].Caption); } @@ -846,7 +846,7 @@ static void window_editor_object_selection_invalidate(rct_window* w) // Align tabs, hide advanced ones bool advancedMode = (w->list_information_type & 1) != 0; int32_t x = 3; - for (int32_t i = 0; i < std::size(ObjectSelectionPages); i++) + for (size_t i = 0; i < std::size(ObjectSelectionPages); i++) { auto widget = &w->widgets[WIDX_TAB_1 + i]; if (!advancedMode && ObjectSelectionPages[i].IsAdvanced) @@ -953,14 +953,14 @@ static void window_editor_object_selection_invalidate(rct_window* w) */ static void window_editor_object_selection_paint(rct_window* w, rct_drawpixelinfo* dpi) { - int32_t i, x, y, width; + int32_t x, y, width; rct_widget* widget; rct_string_id stringId; window_draw_widgets(w, dpi); // Draw tabs - for (i = 0; i < std::size(ObjectSelectionPages); i++) + for (size_t i = 0; i < std::size(ObjectSelectionPages); i++) { widget = &w->widgets[WIDX_TAB_1 + i]; if (widget->type != WWT_EMPTY) @@ -981,7 +981,7 @@ static void window_editor_object_selection_paint(rct_window* w, rct_drawpixelinf // Draw ride tabs if (get_selected_object_type(w) == OBJECT_TYPE_RIDE) { - for (i = 0; i < 7; i++) + for (int32_t i = 0; i < 7; i++) { widget = &w->widgets[WIDX_FILTER_RIDE_TAB_ALL + i]; if (widget->type == WWT_EMPTY)