From 80f61fca5e7384e35f752b99e2cee07aaaa3e4ce Mon Sep 17 00:00:00 2001 From: X123M3-256 Date: Thu, 19 Sep 2024 23:51:32 +0200 Subject: [PATCH] Add LSM Launched Roller Coaster Co-authored-by: karst --- data/language/en-GB.txt | 4 +- distribution/changelog.txt | 2 + resources/g2/sprites.json | 152 +++++++++++- .../block_brake_alt_closed_1.png | Bin 0 -> 1245 bytes .../block_brake_alt_closed_2.png | Bin 0 -> 1233 bytes .../block_brake_alt_closed_3.png | Bin 0 -> 1243 bytes .../block_brake_alt_closed_4.png | Bin 0 -> 1234 bytes .../block_brake_alt_open_1.png | Bin 0 -> 1231 bytes .../block_brake_alt_open_2.png | Bin 0 -> 1243 bytes .../block_brake_alt_open_3.png | Bin 0 -> 1238 bytes .../block_brake_alt_open_4.png | Bin 0 -> 1242 bytes .../track/lattice_triangle/booster_alt_1.png | Bin 0 -> 1237 bytes .../track/lattice_triangle/booster_alt_2.png | Bin 0 -> 1215 bytes .../track/lattice_triangle/booster_alt_3.png | Bin 0 -> 1233 bytes .../track/lattice_triangle/booster_alt_4.png | Bin 0 -> 1215 bytes .../lattice_triangle/brake_alt_closed_1.png | Bin 0 -> 1237 bytes .../lattice_triangle/brake_alt_closed_2.png | Bin 0 -> 1211 bytes .../lattice_triangle/brake_alt_closed_3.png | Bin 0 -> 1232 bytes .../lattice_triangle/brake_alt_closed_4.png | Bin 0 -> 1209 bytes .../lattice_triangle/brake_alt_open_1.png | Bin 0 -> 1218 bytes .../lattice_triangle/brake_alt_open_2.png | Bin 0 -> 1222 bytes .../lattice_triangle/brake_alt_open_3.png | Bin 0 -> 1215 bytes .../lattice_triangle/brake_alt_open_4.png | Bin 0 -> 1213 bytes .../track/lattice_triangle/drive_tyre_1.png | Bin 0 -> 1227 bytes .../track/lattice_triangle/drive_tyre_2.png | Bin 0 -> 1232 bytes .../track/lattice_triangle/drive_tyre_3.png | Bin 0 -> 1242 bytes .../track/lattice_triangle/drive_tyre_4.png | Bin 0 -> 1241 bytes .../track/lattice_triangle/liftbooster_1.png | Bin 1140 -> 1262 bytes .../track/lattice_triangle/liftbooster_2.png | Bin 1149 -> 1140 bytes .../track/lattice_triangle/liftbooster_3.png | Bin 1274 -> 1149 bytes .../track/lattice_triangle/liftbooster_4.png | Bin 0 -> 1274 bytes ...iftbooster_0.png => liftbooster_alt_1.png} | Bin 1262 -> 1252 bytes .../lattice_triangle/liftbooster_alt_2.png | Bin 0 -> 1168 bytes .../lattice_triangle/liftbooster_alt_3.png | Bin 0 -> 1164 bytes .../lattice_triangle/liftbooster_alt_4.png | Bin 0 -> 1260 bytes src/openrct2-ui/windows/NewRide.cpp | 1 + src/openrct2/libopenrct2.vcxproj | 2 + .../track/coaster/LatticeTriangleTrack.cpp | 2 +- .../track/coaster/LatticeTriangleTrackAlt.cpp | 217 ++++++++++++++++++ src/openrct2/park/ParkFile.h | 2 +- src/openrct2/ride/Ride.h | 1 + src/openrct2/ride/RideData.cpp | 2 + src/openrct2/ride/RideData.h | 1 + src/openrct2/ride/RideStringIds.h | 2 + src/openrct2/ride/TrackPaint.h | 1 + src/openrct2/ride/rtd/coaster/GigaCoaster.h | 4 +- .../rtd/coaster/LSMLaunchedRollerCoaster.h | 90 ++++++++ src/openrct2/sprites.h | 30 ++- 48 files changed, 503 insertions(+), 10 deletions(-) create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_closed_1.png create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_closed_2.png create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_closed_3.png create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_closed_4.png create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_open_1.png create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_open_2.png create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_open_3.png create mode 100644 resources/g2/track/lattice_triangle/block_brake_alt_open_4.png create mode 100644 resources/g2/track/lattice_triangle/booster_alt_1.png create mode 100644 resources/g2/track/lattice_triangle/booster_alt_2.png create mode 100644 resources/g2/track/lattice_triangle/booster_alt_3.png create mode 100644 resources/g2/track/lattice_triangle/booster_alt_4.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_closed_1.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_closed_2.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_closed_3.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_closed_4.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_open_1.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_open_2.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_open_3.png create mode 100644 resources/g2/track/lattice_triangle/brake_alt_open_4.png create mode 100644 resources/g2/track/lattice_triangle/drive_tyre_1.png create mode 100644 resources/g2/track/lattice_triangle/drive_tyre_2.png create mode 100644 resources/g2/track/lattice_triangle/drive_tyre_3.png create mode 100644 resources/g2/track/lattice_triangle/drive_tyre_4.png create mode 100644 resources/g2/track/lattice_triangle/liftbooster_4.png rename resources/g2/track/lattice_triangle/{liftbooster_0.png => liftbooster_alt_1.png} (66%) create mode 100644 resources/g2/track/lattice_triangle/liftbooster_alt_2.png create mode 100644 resources/g2/track/lattice_triangle/liftbooster_alt_3.png create mode 100644 resources/g2/track/lattice_triangle/liftbooster_alt_4.png create mode 100644 src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp create mode 100644 src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 15cf329813..0e69146f78 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -99,6 +99,7 @@ STR_0094 :Single Rail Roller Coaster STR_0095 :Alpine Coaster STR_0096 :Classic Wooden Roller Coaster STR_0097 :Classic Stand-up Roller Coaster +STR_0098 :LSM Launched Roller Coaster STR_0512 :A compact roller coaster with a spiral lift hill and smooth, twisting drops. STR_0513 :A looping roller coaster where the riders ride in a standing position STR_0514 :Trains suspended beneath the roller coaster track swing out to the side around corners @@ -183,6 +184,7 @@ STR_0604 :Riders ride single file on a narrow monorail track, as they race th STR_0605 :Riders toboggan down a meandering steel track, braking to control their speed STR_0606 :An older-style wooden roller coaster with a fast and rough ride, with plenty of air-time, some lateral G’s, and designed to feel ‘out-of-control’ STR_0607 :An intense, older-style steel looping roller coaster where the riders ride in a standing position +STR_0608 :Roller coaster trains are accelerated by linear synchronous motors, speeding through tight twists and turns STR_0767 :Guest {INT32} STR_0768 :Handyman {INT32} STR_0769 :Mechanic {INT32} @@ -3610,7 +3612,7 @@ STR_6537 :Allow using regular paths as queue STR_6538 :Shows regular paths in the queues dropdown of the Footpaths window. STR_6539 :Brake Closed STR_6540 :{WINDOW_COLOUR_2}Special thanks to the following companies for allowing their likeness: -STR_6541 :{WINDOW_COLOUR_2}Rocky Mountain Construction Group, Josef Wiegand GmbH & Co. KG +STR_6541 :{WINDOW_COLOUR_2}Rocky Mountain Construction Group, Josef Wiegand GmbH & Co. KG, Intamin Amusement Rides Int. Corp. Est. STR_6542 :Contributors STR_6543 :Contributors… STR_6544 :Loan cannot be negative! diff --git a/distribution/changelog.txt b/distribution/changelog.txt index cc81bb8a0c..b149ee2a7b 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,8 +1,10 @@ 0.4.16 (in development) ------------------------------------------------------------------------ +- Feature: [#20810] New ride type: LSM Launched Roller Coaster. - Improved: [#22937] Add banked sloped turns and many other pieces to the Corkscrew, Hypercoaster and Lay-down Roller Coaster. - Improved: [#22967] Add medium and large half loops to the Wooden and Classic Wooden Roller Coasters. - Improved: [#23010] Make AppImage compatible with Ubuntu 22.04 and Debian Bookworm again. +- Change: [#20810] Giga Coaster boosters and launched lift hill track pieces are now locked behind cheats. - Fix: [#21221] Trains use unbanked sprites on flat to gentle diagonal banked track pieces. - Fix: [#22615] Crash when drawing Space Rings with an invalid ride entry. - Fix: [#22633] Crash when drawing loading screen with an outdated g2.dat. diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 4282107096..7105f9b22a 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -2711,6 +2711,106 @@ "x": -22, "y": -5 }, + { + "path": "track/lattice_triangle/booster_alt_1.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/booster_alt_2.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/booster_alt_3.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/booster_alt_4.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_closed_1.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_closed_2.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_closed_3.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_closed_4.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_open_1.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_open_2.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_open_3.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/block_brake_alt_open_4.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_closed_1.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_closed_2.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_closed_3.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_closed_4.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_open_1.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_open_2.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_open_3.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/brake_alt_open_4.png", + "x": -22, + "y": -4 + }, { "path": "track/lattice_triangle/brake_horizontal_background_open.png", "x": -32, @@ -2748,25 +2848,69 @@ "palette": "keep" }, { - "path": "track/lattice_triangle/liftbooster_0.png", + "path": "track/lattice_triangle/drive_tyre_1.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/drive_tyre_2.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/drive_tyre_3.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/drive_tyre_4.png", + "x": -22, + "y": -4 + }, + { + "path": "track/lattice_triangle/liftbooster_1.png", "x": -21, "y": -20, "palette": "keep" }, { - "path": "track/lattice_triangle/liftbooster_1.png", + "path": "track/lattice_triangle/liftbooster_2.png", "x": -21, "y": -4, "palette": "keep" }, { - "path": "track/lattice_triangle/liftbooster_2.png", + "path": "track/lattice_triangle/liftbooster_3.png", "x": -22, "y": -4, "palette": "keep" }, { - "path": "track/lattice_triangle/liftbooster_3.png", + "path": "track/lattice_triangle/liftbooster_4.png", + "x": -22, + "y": -20, + "palette": "keep" + }, + { + "path": "track/lattice_triangle/liftbooster_alt_1.png", + "x": -21, + "y": -20, + "palette": "keep" + }, + { + "path": "track/lattice_triangle/liftbooster_alt_2.png", + "x": -21, + "y": -4, + "palette": "keep" + }, + { + "path": "track/lattice_triangle/liftbooster_alt_3.png", + "x": -22, + "y": -4, + "palette": "keep" + }, + { + "path": "track/lattice_triangle/liftbooster_alt_4.png", "x": -22, "y": -20, "palette": "keep" diff --git a/resources/g2/track/lattice_triangle/block_brake_alt_closed_1.png b/resources/g2/track/lattice_triangle/block_brake_alt_closed_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b0a15201b8f186adbd371466f2e32e566b3ad54c GIT binary patch literal 1245 zcmWlYe{2(F7{_1MZ8sRB(*_D2T1ZU}J)oKkIkIAI>{!Y?-N6o5SX~MpU4aYU;Fc6D zrb2~EI=q--iWI5w)c#SoMuuEM)gomUZ18{?yLgyJtJE+^6B@0KnAeg#&+~cyc=CLc z=g09)y^gkdPs{@VwDoM<&{yZmx?5Td^_V*zX_-5BuGwm} z5`>MWDUM@!-X%$5Fc^$Rw~CB8;Izm*7MF;LAf1Ui^C?l!h03~8t7IK0aO1#70hvP*B9aLk3kg#- zkHWGIR^9NS3}My^01JQ{K}4f5fTA*nDR%n=%jUe^LLe{`kHbs`B}`VzY-25UH|7v= zXMo^kyA-2?NhXr!l)PKjy%rL+IjnXLXL!;j(qf1W#ocjLRJA}>k7(sYv6eAXz{CNw z7g+oNlMym*cBC*@h7vVrxF{(VISVIP+{BZp&w+=X_5@F-B~A%hn#~T2mBVek-7Ya~$X##dPlY47L`u(U)glGl3?gyHfZHMqc+5{F zLtHxM%_RecOsrhUR;x3R0>BA?1b|#W7XWeqln?;x#?sI)!K4E90*e8W01*nP4xqCD zasY~E7$%^?LREnI5Y!d$Xz?UqXy9ZKfj0+yctmz26h55}YFe^f)?i%=^#a1*O37wc zvA9)C)a`P`m8|;GwP^mKT7-oPW&)%IaoCJ5$|7)t-^<7WL5T#?$%vLsmh~*G7DljBSd= z%T6nFTVMc#F#@U-)EEfidy>if=m$pndO6T}XL_if5A|$VzvaNsCr{@4v&-5$x6wB~ z`3q(?zTEK7^0V{h<*S!Ayt!>xX{G=5h}}H!-PzGw_pbhZ;?|u5hxE|tw-@|J-T0BsF&kgkzWA48t2;|Wv*&K^b=p2{|M2&&7rQc}rw6{+_|~T7Ys>rn zdkin6Ce_VoM}O03$Nb4JOE!AZVsv~ecdQTGY<+()Iz8+;-(PE6edV`~%jYi54zKd& z2U^~}Uism6%bB0_}KRTfti2b7^9zQPoMAKH~G$@KbvOH+%FMduTmaAgmoWp zy3#yM9^L!Vgq-?g!L;e_CF`F1aOttO#ZQ`tFB-0`X$JEP4c@iC{`ktpdmUY`u4??s zvHSA(pXXL27-u88M?L&}Eqm(e+cRUhGQMbL#lai9AM6^l*aj1Kv?J@bj)2;r@YLa^ z%g@&FE#j^WEU^Ty50=ZY{oPS?P>?T-jjs`=PkfeE!?O#wgU)S7;RUYOQy)L*>F(Vy I-nIS6|F8}rkN^Mx literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/block_brake_alt_closed_2.png b/resources/g2/track/lattice_triangle/block_brake_alt_closed_2.png new file mode 100644 index 0000000000000000000000000000000000000000..5e58c90853d125847a5bdf36de18114f32c44733 GIT binary patch literal 1233 zcmWkte{2(V6#woAyN)>vHd=yl8{(U(Mg7WEy;WD^ZDcDeUi_6 z@7=ZC?)K>&(*XeOU8`61)bXi$+D%RMs+=t?s>AG|&J9B>KQJWrzvc%kxAI&3^STE6 z1O6U=|JFBlUGXmipb4yfXy9-@t>tznN{;?SgkjYO!N?8#?%V>DVZQj=B9Z38|h5J@1hNSa4-F>^6(spW03 z;(|3FoRT2a8~`u?_z;9Qo5MDngrX^e7-5*vK%f{7-%ciBE@#6m4$|sk?1T?>^G;6~ z<0L{zP!WZWXW3NVry2n}ZgaUE1nZD58S@Znj>-zG9^s0zP*x(-LKHKxST32=Rkc(oRI618Y&<|^1WTK#tc}e(10^b2_NFRgwkj2B znaWgg61F+bX54CZ+a0Xa#Sw%+Gf`iCSSS;VkESz*rq@a&@X?6Cn!`T36m%v+q!MMb ziNL55F6I)IqE@Tjh9m$U00aP}`ndow3P2eFupSHrLjqJ%&?qt};4u&N)RgarL~LdFvxCdy?YpT`p)QC=?_4053mkGUeaOC~Xe!g92$z&I-& z2lUxt7=;N8swC8D2;m{Y61e{ZLp|Lrcy8k7fjaN&TD5ZB>*MbqzJBo1ycsWiKCrns z89ugt$3^^))+L?8&o0=ttv_}8#H&dK4QBI6UMe52AGq-#_8xkkit5@5#wIkHupN!C-bxia# z?+pLBAoT5l_cq>~esbc-)w>(cxCVCGPD~tG?w3vv=u3LBf6<+T^Dhj*hT+ju+rs%R^8o-0+n(FfS;IB8G-)-p8oN?lSA%8!tvmZ!VSm4;=a36*?iKdAR<<4J z;a#1sp5E8`zH@B?Km$6qb+y)->+0(2>+3ZdO+!ONV`JmIdGini(Q36#O-%-~*^FUU ziXvH-<~WBa3Vy#o9FD}}iF7(wC{(Id%nC>XFm$uSp?AAY976HvPk z<0L|qDSwO(C0QlwOcZz%ZnWCW1dGxf?hq&;zyu=BNJ2=czH}j^mZQa)l#T>?78rP7 z@&b#5;1Po@ZgHeYLA3{qqEeC4aD+ki9B%a3(4d`&a#T`eRX>*xi=~*qk_ykLF<46L z^tc7JV>nMz9+nMqob2($gTYiJq9zi>T&_~7KwuPrC5&KE9hEe)S(GnQfs#Whdy*9? zSB;nF@-wg*)#-49!DceEsFfoKk!AwU+AwcC7|KNBg|u2NlE6tLBCGQ`O_Cdxy<{xF zCS^Vo^W{@=IiIdpry&V|9RLvksdg>^WB@230M>$`pjU)31s3v*1qc`jksx6M1qMJC zK*0cm7*rUTaKmf>78LMc@i?F$rdKX*-9>dg z`X}^lXEWFTd;9zJ*n(Y47WAEOS)yKl_wdP|uAN>xE-xFHB$UCA|DC!&l-n>UPmN0N zPi_3LoLh9_@=!GA*syrd`qgJ?;e7q>i<-ZmQjYuE+85d{bmiN=8rp69hj{vnZr7o+ zvrp{!IeT&KhIPO1+`W3dZ}Z&f*kq|CyKm`~@$w=P+q?dgU(W5}FE!oX`Poo+xAz>c zb>yj24{yJ+YH8hDzv`m{(=E*}_pPdbWGnZ>U!$6X0~aoT`B12F!jvmP5? zeQjdX*VRk6+^*$b*}LKv+_tU-Kl>Y587JW Lw_JMmg*W~Om2)OO literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/block_brake_alt_closed_4.png b/resources/g2/track/lattice_triangle/block_brake_alt_closed_4.png new file mode 100644 index 0000000000000000000000000000000000000000..6613d0e06530a915da4c06ef74b9cb1a6555a01e GIT binary patch literal 1234 zcmWkte~i;~6#w22==~5EoibpNkxXb{K#^jK8CalP#@WkCuE3Om1gDF0Dwu|t5)_laBd?lZ7q!|e^p-4fT{kjSN*Ke=MQY&?g7iU2yb|1bZ_14 z_4Il+ZyD(S-m?UN7O=W!O;@A2si~>Cxw)mKrM0zn!h{JECr(5Vq^+&3y}jLJwOVl; zqbQPPX`XkBq7V*;aoIZs+7xnGBpywQcs5Mstq7CVPJ1e+^_ z^O9XmP+^&l<=9k-Q*^I|Fk=p@owdQV|q2RM2B;HC-Od8%SVefyoOj zL4ZmKku*6ns5?&zsw-L+Q#Gjovy9Ei6Xt-!7IoRvJe3n!HOy;qu_A|S`S_SB!%D$m zBv6|RC%hyTVA&|oCjx;?G@4H)RYfU}jMQp12+RUN;|QKMP&qSOvU$r?q~cCh1G$-RLnut(P$8j8LkJIvM(^Vv@b@}du^=~l@yxPEw_i99 zXYTlHav!pBx%p^x8@|W1b_PX%a2Bf!4lF$<51gER{MMDxOysS~{Aa=IJ4=g^joP_M_s7rtP}%xV z#y9uhE7<+7_Z+02-VZ$w7mU1T$Oca=D81AE-z8e$ko=axOZ zvGJCC>Da9Cqx0T<@hXzP>pa_g=#$;|^vTmbp9X%!M&<`abYI<@o!tlrWnZA zMw`1f1Zocoec%0kDmSPVFJ}GHu}w#uJAb|T9Jk^N?ar*}=iSnx$?Bbx_Tk-gUShs{ zV))>->vJyeo&SF1;PA9{2NK(do;?1b$_zGv&mC{hdl;6KhUcKW%enIOicNd|2UuS# A-v9sr literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/block_brake_alt_open_1.png b/resources/g2/track/lattice_triangle/block_brake_alt_open_1.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff47adf7b80e790da06b798da46c138ed70a8c6 GIT binary patch literal 1231 zcmWktacmQH6#i{v+{QE|X;^_`ZdmjTh17WB5sDme%(5KoksW#q9jWywMNU2NCWSQE zu_}$$pKTGo7`@TP3-j{su zy$`n9ZI91eJP!cyc-!Vp9aUUWO|+q|T9X$F&sJekcWY-iEAHy{y54q!4Lilx+%0Wy zx;*X%nYHMrj>gwjqnNwe1KX>k21VI`a8X6lL4JMNb z$1M~^vMkN>4oMONfj}e@OQn=dW>nM4l?rYFq!lo9lf$7G1k~%Z1Vh$Hlu4wVX;sSR zLWN?SG9#R|Nu&*a4wZQMkXa-lB5FvNPv|RI zBP>~9#R+F+2s0)C7yz6IBI&o2DKW?dW6qc&Dmi~f3+GCS!i=gTfu02h z4?ukYlMy0ju%$4EN{TryRFL9jIRgh6vz{l6UYj|@Sra^!me^c?&qt(UGEi0{Gr1%z zW^{T2GjllMAt^7*hIl^e^`=50H5SV$N?~-gTrNXk6af}N@Pv*^8`-ScQ=o!HN4(@s zm*vq)sx+IQflX$ejxZQ(sEIXOc&k;SnV_>e%$Ev`y1dxlFR8WniU1 z&@@y4)BuE_s)YzUF*#@q_z=NOL?cA>c(hoQvRNW}f^s-mLEwEp5w`>gON7Le6t2>i zQN~>2Owfr!KL(>XR7jYkA%uOB-t*`Ox;yMFSU-MmSCx0RZQ8Kyz}V5FKXqJddF-XZ zBftJzc_`i=Yn}|OZr{A|%DvnBcW_tF4*qe{WnZ^$&&^YfBTG)rPfR?srk!2#@Noal zN_Oet^Pk^+V!ffS>-JNjt^eI=ZaDOD@2$_m-*=we{`>m-SEN(QEnjQl!6 z52ntnys)~tCT;H=dDt&_(Eb+=H?KK4-aGlrpCj-8@XoE3+>YdI&$WZzX;;7NOzE4{ zvAs^Z<;35s+F#DUXt7U5CcHd^ehE>5DU$7cLuq_tNHyUB{dlQQnBM)yZ`%isWOh&dymWHKw_s}U>-RdoG7VP^2W_qPP3Jbg+WS9N CCM?$g literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/block_brake_alt_open_2.png b/resources/g2/track/lattice_triangle/block_brake_alt_open_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6022dff8b88c962d3432b71822d348850f5b2867 GIT binary patch literal 1243 zcmWktacmQH6#k8}-C$sel~gI&2~{t8Ldi}!wdjGzDD%h;cVLAEk9ivnspi02I81{j z)L7(z3luF_rLtlg(@0@p4sy{ND^x7lxSG`LR>~|`4MIaosL3EdOY+|PzCT{xmwfNN zk5~7)W=@|o9RM)1XXWy~CO+FtwB6LK$us3eO?Ygm`^_Ov+%zQjzc&b$4Tx_KKHl?g zzjv^2uz%qFtrrKE0AK>ESFP!8Hn+62OqnvpWHL>iI<>X6wXLlUL6G+L_G#0mS?zW^ zK{#ld;y6YSJdz{^gTY87mP%=vOu;Z}^*Z4IloPN_hsR^_`B2&K2r14;lue{~JuT(( zO1ToJam4NH5E*O0jj93`lZewnIvsK6QlgO!RgHL~mT}ntj{}(kDu*OQB(0c>2}?a^ zgH;Et^KepyFk=UR1%O8o(QFRbY$}GuozBxNoAr8&fxwMe45rgI!eXba4iPnP{k9k%6d&L z)Kk^TVgq*IW;1EEx==fZI|QdwV%QMh9Oh3c;cOyhWb*Yg1$YLLICFqURUaPpQ^^pg zN4?o(pqP$UiPo}~T@U8-$!awZn_4z6Ap9MaYGvan zuVJF$RBN7OUDg|s+@w~9#TsS-B#O8kW)Fq>IKuB`)POG@4(Q2nK9j5(8CWlq3ObywBe#AFOMk8eOaI{j9ayc@3g!XtipHJ}nMZysz9TAF1(nOkZ6j;3K zwnH9;0Srb7s8KM_KnM>=7Vm=}80zcgz|z0|*wo|$J=Skmtm%MYEPpmJTSB z{K3AHXHD)ekKK9xxpUn5y(>DehaTOZnK-^cs3mLbZeJHi9?4!kd2`Q}8QhKwOrev_ z?)%75^DmEH+(7!y_U-@s{C)F( zg&*dQY#xr?yWn|xAHg)Z&yN-_tsVb<;)(b-ql@Lhti9u=g!hYkJ-sjdhL$#8-fs3V zZw!4l|ATE>yMZtH6D=)cPipd&(s#RKvo{8k3rbsu(Za-2NA*IZb?kU{=vMEUnNKEq z4$WI18p(vV4AcLdS}|{jW8I4jbNw&v9=*x$Yyo?UhsS>T{oKP%^FdE{@A4C`Zrt@h DDu6IU literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/block_brake_alt_open_3.png b/resources/g2/track/lattice_triangle/block_brake_alt_open_3.png new file mode 100644 index 0000000000000000000000000000000000000000..a5d3af10a5cb25a761ade0cf69f9acb9da61b25f GIT binary patch literal 1238 zcmWkte{2(V6#woA+{OlV)}(_fMGG|Xz(P(vOw|K!vn;0^?vSo)q=Q>2?gFRWpkSjN z6l}0Arxa76LK9EYm}V5+NYSzsC~lZePTW{=7p&OCZcHtq!o(?GOY+|PeExWOpXBr2 zJGgGGdG@S%vj70Io7OZmmvBibbyXFm8tuz2E5Y2(#+FWo-_q&Yw8H^bwey=D3!1iV zayptFo7(rh^_}B+04l(`m)AFzn#;<{%FD|uDk>@~D`(7@F>~fj1VO5*s;aB2HF~`s z!;BY1s)Ucuyibc!_2os>G8ksx5zPut$6;fs`u%p050Fgl=Jd*UQG7)t# zt%Z3bEZX6;2w_SO01bd0L3owQqt%KAgJd%G()6Iynelig!(o_AYB9B*&=_f*$!;+7 zsKtY^qDcsm-Y6AFFjCqcSDZRrYc%Uk3`()MjVE~@?F-w(aXv14Qc6J1N3v5%6#>)? z&^Uq44GbcJhc)Jy!ImU=+2YR%QbA0?UK&-ixYlJx{T5S%B@+T8d)Z7-$VI({WN=E3 z!dyzF#toP$O$H2^8(Kmxj4x{=i@)rljOzmH>7N5g3)nt`j*l z< z2vI{zI(yu}D<-jEixyppsbG3Ko`so$K@D&nVm7L5gpOk{x04b*oD}dRq5(M-%_}Kb z%;FRU;{YlELQv8|xORi+(|X+q=fFcjJoHH@mlM)yJamM#*%*#v-EJN;dU0crz@j9U zq>RHfnz!hoT?ah|7{XwjfHDOk{76tcAN)XP^I8V1{O#J761O)stXjW&>~LV!j?{wM zMyq$C@A7~A$jI_D$VAJ-YdT*&b?nR=ZNGL*-1CO#>rNd1pm=k91@Vem8h-j-n)oa) zf$jdgk;s*cOAa;Pq{sH(K2hD)J<-y3oO)#IUkAQ8-*J0u&({q--(Qi3MmAqfU)vaJ z4>GnZ3x|%qyJxcJ*@o>0=j;UdLpA+J%e(r@Yr9W>6FbtiVf2>`qt*^E*?Q{Iq3)fR zURv&TmOfwsvVz?A-X-soXor>T{Q$;;dsW*821C&mZrxf2_P8 zwpwxPhrM;s}grrenpUORt*_|5Minw%v~|n#+uJmV5_I MjcXfDu5R1+KeO~L1ONa4 literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/block_brake_alt_open_4.png b/resources/g2/track/lattice_triangle/block_brake_alt_open_4.png new file mode 100644 index 0000000000000000000000000000000000000000..2791fb047497fea09ec57a475aafc3aa93c4aa1b GIT binary patch literal 1242 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 Z!0B_L?bTP8CF`ad7QB0K;9 literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/brake_alt_closed_3.png b/resources/g2/track/lattice_triangle/brake_alt_closed_3.png new file mode 100644 index 0000000000000000000000000000000000000000..1fa69a9ab65e563e13bfd43313419b6bdc26a40a GIT binary patch literal 1232 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/brake_alt_open_2.png b/resources/g2/track/lattice_triangle/brake_alt_open_2.png new file mode 100644 index 0000000000000000000000000000000000000000..fccd9c9db3ef1238c36fbfb332d5c3d2345f4a3c GIT binary patch literal 1222 zcmWktag5V+6#l{Pt_K$w$&3RA&SWtS6dhWyCRHl-&T;fykrHbxGR`tavS>Lw9A<&FQ>ILrI(4eWV(IAU=gqxeq`SL&+O%nQm&=9Y zZknbzjuAycmZexMrmE?DUMrPG4a01;a5tbxz%o68U<(GF;fOn)Ak`F`&HD;PxvVE@ z^$d+6JlP{L_9*XEL^Lhq!!f$3^5wi_jKmv8X2L9a9KeTxFa;D2$x28uVXb6st+E3) z+_2??lL~|-7XT~(J_M1h)~LgwplF69hgo(c5U50>B_pXfvbBk#l>#;n*aN^B z0jPoyX}c$n3PnoN`9w|5m`Vu_vzSdJ9AOWZ;K{5=7i3P4i4|3@=VE42ozQczUb5N< z6ytFsK+$22ONe4B9L^^a#dKQNwA$#XX_^o?B!H?2p0&~i2Uo@dH9B4wGL3M-R7P9* z#$;sz_Fz^kVYhpnE)H{xBq=j&+}9o!$tRK{*}PHGTQv&!7)0i*QJ+%@VyOs~i*tok zU?dl<6jO~#snr^X6aYK`G5|{ZTmTpWppF384wi-y8Rjz3sIVxIaFC>c<^cu^AP1mi zhY1{JSf~YIIS!2sxVLx$Ff`yRA%Mk#0q=!=MY{u!+ zP{|+_Q^>W#g$cDhsnuY`L~Vd@A|AI@pqxPtj|3Pc8q6f4g_hj%WX)i-(W?W-{Q z>z?;cvtM}KbaJ@oz=5?t_dL4j%;}ZF{&jri;AQO3fd!8&IQ#v>Cm))T9lo=)QopwM z6!x_@uw_@O*&LDwPwu;ZcKvU+f9da=!>+sa__F`xM#mwLzcN()=v&)%^eFkm^X4&O zd`rsTJd9qh?yDc)?Z0yCZ}0p2=ia=JxOAg5L=}ctbyw$)@nhdy`O#FH%hZFvFT8u? zxj296`pi%$&lkprcKGd|HBXsMYP5CEaf!a&+yja`j=&1XyH>AW5za*VTt9#^2qLdMw}Gc2UxdN9b4 z34<&+O~s+ptGdJmhbi0=G0w1rsTEGLKgwl+nkzEMB0J@9;KWmo_;n=jz0c>5m-k6N z@4XX!8@+R9FPseknA^L4ZGRKHo9XIkX;$^?%CaUb81C6N%!#{(!vjMBux3zvJ+QcU z&p6o9i5$>4!7G) z5I9X!9LETPPm;t~ES5^8bGf{xl})qWXb?D{Jb-1aKA$}la)l#!JmEZ7zk59=8&w26caWhYj2dC zu!h5iAI``SYHk2n0Q?9d+H6s$Q%2E@$8(-#$AUp48oirN!(!1%*xi%^XI&mY>J>3Q zN(iz?Qs|hkZV!hs0_hWJG0w)*{&Zf<>ru^2>a}cTx@e<-odb>_ za76$rBV^j)&7r;`CF*>lB4z5b2G6sYT_BxdFP7jvS%EG{oE{U5lvGt?^^QVa=BiwL*NtvnnH-IjV?I35*Dn`@v1LV3m58g zxsj{Q7}L;-*=(f4;dQw=3>Q2eiDBdZ=CDXEksQnBOigc8DBx!hiL*uhE;)oL5lW47 z1tmD9MvbCUGqgtIE~Eh90gwQYo96<+7ywlSz-F*Cj7U(;K+|ARAQB)+fxH)(EPxz< zq5~!fm|g+ff%)mlx5O)X~-5D_aSJJ^iN zpGQU0BiDUuBV3qHm1go4Xw*?VAYF(TxA`bnh$A9FMvjIu$!I}M>Y7?JHQ1<-3yDWjjor7~2)vDaNeM9**=DBca+lQISuet{wAuAWnzu$Hb7st=+?h>Z( zEK$SvSg7|Go(-)#a_7BIw@?1~&UYi@qs-*;H+L6a*g5s6ykfsOy7c9V7tL^%I9a*+ zz{XGPIJy5w*UGt=<=*I2*tj;aV;~W@v~NSt;_HRyj6>Z&40X2+HISw6j{dgotxH?x z@BDkov48iqe|DjN?-uUZ{Z))sJBQ6T=2_=qtMTKT`i+@6x6WawD{pi>uD;Ya#DA-= z-oM<^_vIYo)yofWuRPk*I{y0&X85Pwzx*{h(oP?Gc;YI5GyQ>f{o3i#GZ!C>EUSF6 z|mB#>nzT>l#zf eetxm-8Swb{_$OzX@>J7c(A%?d?dU5zkNywHXdQ?E literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/brake_alt_open_4.png b/resources/g2/track/lattice_triangle/brake_alt_open_4.png new file mode 100644 index 0000000000000000000000000000000000000000..a33b1018b2d606614efa176ed97bad154e72f054 GIT binary patch literal 1213 zcmWktacmQH6n<=s+Za%^#)>7Lq{N04sL7EOQ{n-~tnn-7jwHZQ{yi;_a=?nz>khwh2puU421T+!+k**z1E0{o)(Gr@MFU z@cVjwJNn<;^OJ8KKr3v1c}rKbdCr_UEiEmrt*vwC&TVUJn>TMBhGFgP?HwH*7MsmR z5Kf9BS(X+AuOx}lXf&BjWwTnLFlHFFdYy0r=>~@G^m@&K03HfEV{vyi3r-k*QP)mg^FhAM2=O9yk_`um(}U9xmgD-xV$1I#+X=&Pidm2M+!zlucph5yom%e3l=}% zVX(`XD`oLy?cO{o>Rh}msWrKPMi_@#a9KkhN1St~1u7@8dQ>PSrAj7R%O@Lp22~0s zv&-(_2$!FvLM$5>1SJ&8#^d=^O4qdV*jTMrLtqubp2Uc>iON~oqQhUNVim7i4drU` zSUp>vDK${1!(?(U870OJA^`~!G!GaIAQq5l zL2&}94AKIq7(<2%4;SwOngWi&0)izHawKF=S`~7+sIF(KRUI|8tbQQEouq7GRGioB zqT!Zn-b_7|Yb1*^S{apUb~Cte%;Pk9Nj$(3VLvTL0%{_X%OvzdrfL*Wz3ifCqyaJj zA!ur0fquIjvqr;Mz~@quF6D$$sYu15OF2n-y=)*Lgu^1?jJljjlE_d*o_3Bgjw)wE zJdPrEq!36WkxnCoj!I_#!ygFt_OP)2pWk*i`3v2fHf$OG{qS+)LiFjy(0K5KfKcMq zs~gF#ZGBshjSOeby!O}S6NjhzAA{?@1^wB(*S}ipxq0Tw_s=bQ@4s`(%;eG=(fWeH zc%Xjo*Vd(nf{oyTWj6KVirKT6tWo#R{d{loN(X*u|E<}f)k1!)d%Yf<*nOV6vyyFj z^p(A%gDZtcKK^K&-ovaJ9lW_a92@7}9hiRm_U={twrfND*Z9P@=Z~zrxwR4dGBw0i zApXJQjkC8NOzodN`N_`jE}t4Wx}r4QhfiET_RGxl>Y?n^t#o5p{lcbAK0ixz&wlo2 zc=*@`@oIK_j5J^44sJ!uE!%Ft)!1|YUhk@xe%KY#Ey}V9Wx8!qGVH(e)bUG;#eIKY zI~61Dc-o-v=_R&dNy6y`1-;B0rmhW^#A|> literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/drive_tyre_1.png b/resources/g2/track/lattice_triangle/drive_tyre_1.png new file mode 100644 index 0000000000000000000000000000000000000000..ae2bb9065a535d54d8943cb1a4464d9d18bb06fd GIT binary patch literal 1227 zcmWktacmQH6#i{v+{PHy6m4c*4y>e-o9Xa`GgQ6dZIp3lhr3CQ)tzuF7t`nkZd&z> zMGGl<>ctdNW`!Cq(&#a6W{d(AiYZ}WF{hcXKqXb1P~(OrY2ru*{w&FR@B99Ed0+Cq z_deXz=V@K^z#;%ZYww2c{u*}F5^ZXzRsC48vj%O$JueKi;nE26k#aVBYS>5P;! zm10SwFvRO_5ouekacA>rd;DiibO46!g7DHpW4O4efs90r0UP+24?A{oV!Pg<)v zJ1o0km4ovtgjojw3;-O0h!#u8ZdaX7&Fvm%m`Op%he9)n1k7aYxYa@0Tny^woE{PL zhHzeWOK~c!)6q1m<+xNqKnc6c<8ZSW%@aP65+h6`!6i~+$_!--QL~&Z&Sfklu(H4= z08|D}6(JHfkKy!XNYV5vMMaJIK0gOrFpGt-**vI&#az7GEzwMbs|}M4B|4cj3R$ySBmqYw5^D)@s2afHGO0({ zbX=I!L-|a+oX=LPGmr$p3xEWGT00j2CIKiR0M>$`pe#XMgM~cf1R@TiBuIHcfdP;O zP_#h>hZ+M@0ho)xf(Gs`o&YojybKcHZJ{6*RXs_KPp8ACsh7(ptZCT=fXgkUYGX8% zOF6}YTdnx?YA`()%gv{XFkf+60f8bOm&He-0T!19S`7uXXeg~m&8%K7WMQ>P&@@Z| zSO5@$nidima;gz~SVjVVA|4~+`{SjOl*YDLg~FrWma3 zbwCbh7f)xS%telFx=nAg0AbAx7GMSZ}+-^x32DuUhCi0xp=+YdPJ+h zjY^jfJ-56!`upyc)7~j zTl4Zex7sdT!Os5t{-tjgFMH_`e8;D8ug5+EPAwZ-Dw_)B`|%UPsK0RLR`*|yV&dW5 zzv}yDKl&3hnybZubC3V_-86b|`x7g676<7EXD@GUG*&F>`{IYemgwH?)wNH(mm4~F ppYfIc?e&T7)}(e)PWC727X!4CPrAq2n`>r+-k!ehqtCqZ!T)J6Ah7@d literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/drive_tyre_2.png b/resources/g2/track/lattice_triangle/drive_tyre_2.png new file mode 100644 index 0000000000000000000000000000000000000000..69daa700dba148d113fb57f60d81024e9c471597 GIT binary patch literal 1232 zcmWkte{2(V6#v55Zex-nO(~6EDb5p@Iy~H<)TL@TIJBHovTZcMw&rfAtjl~vV1Mcd++o4mE@;ep}7p?7^h40i+20Q$FW-%@X0uwcQ$g$o-R8Wt^D)Y#bA)YOC^NON;@OG}Hz zX0zeAgQh8tV+6r1Nn$7zip3I{jH2uLVzFAQ;SNBNfMr_UZnM{m`U8$|gp9@6REAeI zDQ84V$|ZBWQuLsN)#0>}oShK}w@8a&Hk{xSil`Vty%;qrsnV=wqJWtL z77suJ0Fx0SVR2?Kw?>JED^ik@Rau7@Si4yutbV6G;v!Q5txB8`5(+V?oDNmB*sPI; zW!+>ZFuMyUJQVHcxQHOc{r*fOq9qcBqLlLaYPAZ1RRmZJ!BZw$wQ@PTr$mR#?qtQU zR^@yxQ<*Ew!dAP4PS7&3nIi&;(Rm=JWO4qHP3#5+vHV?_L9yj+%YIU+tryWO1ED+B@}?g$Z%7=@>4Tw@%0 z)?RVhAdkWz2IDwXC}=Pc!sC+J^XLag2l_bBb7x{#oxj?xBk+G@t(cWBV7CA)35wq z$afw`DlNB`5mS2Y=OZ17kz;*B`+s{lUjDBC`;*<%!ofp(viH@F$ey0|ne5a1uAwiS z`l90|x520Uac}F;s!bH#eEXP>zqWeAv#R#V>ZP9!bnjL|`XOK9*7)36^~;Ib`MX#C zy%IKkb@xAP#21?x*rlnTH|-c5^d)lNT%F1rqho)b4>YIMn`^F4otxCpEZLTs2_8An zwMRlu@1Ow-5so}yiL5^`h+QV zdgNol%~LylOa#xjo4z{w7|VSytl zShQe`r*u$e#l}?9Vdt7L@g$8o$r%O|y@UaUmC%La8Z)Jl25N%(wIuJo&->%$eUi`n zad^#Y$E+E1X8-_Zb-voMwt@>Qj@H#wV&c2pixqgfclr8WR@l<(?b_K5mTeX`bvJiz z@A7o7?e5yV=iQ6lO97|>YgVmWUMa4ss;aK8uBoY+Hf`GU>C^pbWD5lC;Rq8?x>Kr{ z)`PixjKUD7y+NQ&J|`-3)~JY&_$f8)OeclxXrPddm5Z9g4BQy-l0asWxPYiZLndx4 zrOmKlgC#e7BtxiK0AK)cBZy!y_{?V6YK__LBMdX@@nn3ysc00csu?$0NRy30?QW|> zz??pulkH-J@+as}ijAe+O4frCW}CxeXEB;1TmmHom_XDWRRl%%Y1xooi08_xfdobt zm^=WLfK^6_sL7GEx>Qoooxz+KE6N%iVK5^{n7s}x=(NWn`)Mahkg6^lg(%mT265j<|7Qf4-dd2&=B?}`>+)W>PX38jUBjnqJD0z)d3}Yw)>Ina3g$ znFz3{h-Wn6%czk;Mk|%3APImI01*JWvMvCO0+2@ltQbQ`D&^PpM4_O=3YXafaH)Zm zO-u}RD^?+Emy51M$(t&N(~p!K%oMFgK%j`jW^j=x&*GAYmVJCI#k~gZ63aB{fSE(uv1?QJfQmb4t{@OS>LrjmvsH|k{kI2 ze+;4`jRu6FJw(VbX_EOunmc93XZo4`> z1MA`HKkfhZC35(QJ%f!4dj?xT$S`k}{OqBp0)E^K={COjVs6YHhv#Ry>nhwer@*GrJZ)+`0XAt%tvNdr?NI{GL3#h8~)_|9eGy(7Akd K$IvSq-~S&|x+xF< literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/drive_tyre_4.png b/resources/g2/track/lattice_triangle/drive_tyre_4.png new file mode 100644 index 0000000000000000000000000000000000000000..b5fdfbe782f200cb18551cc37c669c1db5f3fdf3 GIT binary patch literal 1241 zcmWkte{2(V6#s66-F}Egnpm}9kw#BaLnXI(YBe`FpezSF*r6qyc#d0lY9j~Uq>iG8 zG_GL51Bxkfk`imyKqHOWMunnyOS;5O&iQR0 zbqdZ7XJ=RM*590O08j_ktXj9c+FVmpQ(IeGS64S<#*CRWXV%x(BM8#a(9qb}XfT`2 z7-l6&f?+70XC+DWdcDD5C>D#SQkh(?R4!vyK-d6HHM6YVva&oG3c+O3i0RFQ!AhHK9BLOW z4jJPWo1~K7C>2OB;WQV|2`1cVwVQ2>h2n8mBt;+X3vr>i7}w-fE}#`7`ASkp06hZ? z0x)?1svvmCV2`0}k`OhAKQDz#N(v6p7Cny}-FA!LVT_*fE&vPzP(T2z22Dbb1fyY?%hD(iF%Td?+zxUy zfDC}50s1i*reWL#(>|CBgGY1by_>y0bjRlcch*^+gij_p0P_MmtEV|~4S z?IpQ?w`BiZV66$9-FKtw{?_r{@z=L>j=Fx_w|M$0b$N5&Yx^%h{CpdC zTRnEZb?(r(I6D14+bA^$7Vq4Bg#B`G-bHWIsV-CP{uPH>_uP76s#MeeylwxIcg~7O z?mXN7!3M!ly72q$wGXG%ujNK++nvV`H?4-LE2sN?JMT{%9hkhc85=(~}9H~-h1`tN;D-TJV5&Pe=^ z&t4S1oA}24MP};K*put8jU`q+aO}9g@qA(OYHu(7_Sgs#xjS+6hnt1lv$gTl#3E|= z-nF9>hh3ZXjj5Ku&!l}@`=x(}E-qk->)xEY+4<}4k-O+Qu&8iqKsQ&}Rka?pEpK0T Ja_M`!{s)dSHuV4i literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/liftbooster_1.png b/resources/g2/track/lattice_triangle/liftbooster_1.png index 62aadbb3972d1bb3dac11d82531d24a404f75246..1ffc4de8c9863a960ba4bda5a59356aa93e2d626 100644 GIT binary patch delta 422 zcmV;X0a^a^2<{1x7YZu~0{{R3)`Nlau^~VMe*t$%L_t(|+LYDFa)U4o08rn9fwKJn z7bUHiL(hCcYAku-Qe$YE%+yP{0S}F&kp&_7i%C*@F)8`KXkSa;$v7|dbRN2DI`vMRn6tS(y&(^E!^dQNgGC>fIPdK%Hd)U^=Qc zG1ui1qrR`1$wGb7_@Uo;n%;1yieBQpfBMY4it}(E^D4rV3L58?$xL6pKPhA>xe5XL z`4}eWl@N4~sK=qyNlJ(|-MBBJV`bRYu*{Of&$qDN7IVz2$Wfw^_AR9!p;<;smS41B zE^TAnO&D9E0b5H@gTXQlDO&>CfT*BETcOV delta 299 zcmV+`0o4BP3G@h%7YYyv0{{R3xIT8Au^~VMe*pbSL_t(|+H8D}46>v3fBG*TFfUx%i27$3w`CUCQ8Pc6arr%~c%um4uO$a|gP#3HE;z{Nwd5p5V0F6W`vIbC3s^0UMxic+s@ xl#o7t!2GjRxo$0KrSm8D^3OL~jQtm26#yxBX0U@q>j3}&002ovPDHLkV1m1Ni6j63 diff --git a/resources/g2/track/lattice_triangle/liftbooster_2.png b/resources/g2/track/lattice_triangle/liftbooster_2.png index 01f342f00f097e7d994cb8d02d2bcf68aa135fac..62aadbb3972d1bb3dac11d82531d24a404f75246 100644 GIT binary patch delta 311 zcmV-70m%OS2=oY$P6Ge{0I^a10)LTn6K4Pb00DGTPE!Ct=GbNc008|-L_t(|+H8

D}46>v3fBG*TFfUx%i27$3w`CU4P2pWp;P< zrp;LH?E56*?sXett7EbuI}FHLA|XkLAOTtI4wY2XAE>c%um4uO$a|gP#3HE;z{Nwd5p5V0F6W`v zIbC3s^0UMxic+s@l#o7tz$pB)RJm>~X{GZg_VUj+T8#Y{U;rt1X0U@q>j3}&002ov JPDHLkV1n7`jfemM delta 320 zcmV-G0l)tA2>l3 za>OtQM7cpKp2__$#ZNM2}+1d!X*;*6Uqubr-9a za;R)|@8;pv*i|ieuUpkM_Fs@Vi7psJ<-7YZu~0{{R3)`Nlau^~YNe}hRxK~#9!jMYn$gCGzFU=E-o__+Ul zCKC{4Gh0s(6BG=jYIvxbO&VN(_1o3mwg{b%7*W>KAY*wRZo206G+DT5yRK1|rm=aI zwa3*Zh0QpcuZZs{O!+vX+Z6D8VM79oaV?9z3>Zu1U%X?aKrA2su{L1q9*f7@6fxEi zf4*w%urNE;7JtUqWnF!;^|)uKu9+^6&<*@f1~7AF3_@h#Q1cLy>kO=xSjJv62D>38J+PnP%s~83 zb`wOqea2yedWEo*5f^dmHv0tof6RQADUN-Hu+siR5@)iZ&^|ArN_*f7*o}et zn$`ZLpac#ps*4=V$B-<`cx2EI)H)t_19{xG0khB7NS?T9F>x3;T~dZ_m~tY76!59t zS5(Zm->OPoaEBL%`7{^lbARPZF~+v6KMv)qX4>Tao@lRZu0?d+Os;h+Y6Qy08~hx? bp8x{@zbuo-rt~PZ00000NkvXXu0mjfcD2jc diff --git a/resources/g2/track/lattice_triangle/liftbooster_4.png b/resources/g2/track/lattice_triangle/liftbooster_4.png new file mode 100644 index 0000000000000000000000000000000000000000..8a56a1bdc662ccb70fe58a6d20c8ef2fc070dec9 GIT binary patch literal 1274 zcmWkuacmQH6#i`;yN!)?+QkAT6m6g`hZb^#BNn;AZ7JjCZtO^ksnE?^sZik@H!QQv z6Dm}5=n<+EXry3~DkbY+LKmwxv1Sc+ri*ne;UL9KXv{PvRx-(upCx(k``%yg`{R4x z`>>70Dn$t=-3R|J(Sp8~t$hr)qtDsB*9O-2aIf2zwC?V< z+d6ICJ^j7cZEFEgfR45;EfB)8va<5>a)m-sQBg5x&Ya51N(4cws;a81tJON44#Ny2 zNiYn>vKF4_+-|qe7l=fni9|-03&kR40E7|HRE@==ayYb3m%$?%eSSI=vBu(jDlO)w zf+UKVjWryl7R*|S)dzTN*iFWL=2V1}lb*aBoGBzs8em0%lK>Kfgg7KFDzhO~F{Ocd z11wtMtOQ{~2LKI#6+t+qQqX85y*_9(4%2kfZqEwBbRYoZaSf)@5o!aiHCpv14mArH zD;aq|=?+ug7!yocqq1F#YYZlxkwGaIw{Rrqp*;a>Aj(D4LPGYY^P${KTuA^G1Jrh) zbpgGE-~qKMqPN5eE^QWbe6S!T;4qDYp`zIsV#yfKq}^=R$4`abg}84f9fng0 zr3%-hW(>Czq?2Jpmi0TG5mAf>0_kWpm&p_g1qd`8(EAW9q$Fb+CWYE_q-V+!%sXQR zDN~H(XR|Y~230C?wc4cBF{ptx8hMKLSWC-X5z(6rMdU=fm?MCdLU=|gShbP^^}C3$ zhl%;^$*_=(`}5gEu{aG00L%dJ07w9Y0Z0Ncg#cJ8nuIPMhJ#Sf(t5yQz)OIr3CJ{n z41k;(iWm&iFzSFQ50r!8iSam~NMNQB2dfsGs8=$Df^012PN&29d>WRtG7RA$1`vXh7UJm9OCF8eg*a@u--r88`lqJ&R0{W>A}toi;b2`Z4l}rMgO9+%Bo?O( z85+%-b`jFZm@qgmUwfh!M2b~_GLzvmjQF|V)QvbmVcQ>sZy>^MHyBpqd^Y{PG vyb*bGu%+*I+u%NQSH(}Gj~4w9DE+4Ra&Pj&KhJ+%@&>fFv^NiK=sNU2Q#Ce_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/liftbooster_0.png b/resources/g2/track/lattice_triangle/liftbooster_alt_1.png similarity index 66% rename from resources/g2/track/lattice_triangle/liftbooster_0.png rename to resources/g2/track/lattice_triangle/liftbooster_alt_1.png index 1ffc4de8c9863a960ba4bda5a59356aa93e2d626..53fcd60e5deb85091ec0b68f3a08b393e4e47130 100644 GIT binary patch delta 397 zcmV;80doHC3FHZ|Vgr9|Nkl)B^3`W_fizLncZ zXuaQM0`m{N=QoQ6)oBSj)s3tR?>Y@Lvsiw%DLpt ztM=v+GODX)vv}j6wpRXXB)~Xn`rZ@?23lP?+*5)8F+c6{a)j8JO1z* zsKi~b?-$qdnsfI`6s-~D?zQ(iFaZ2)hp?C^vj}e^K(f8&loGE7Zpls-XkJRMTIyn= z30Ud1Y8m8JG~9pEz51{#YdwZ6TC98ZaUZS6@4TXkx@!n{cmp2iRR_QB{gu}%?4r&! zQ}vlwN$ibFjHJ7Y9YzW%AKOpkdW70R{l^vkhc_Z_;D{0000%+7`HM+Xdod~bzi3}e-^n;H^>iM(YC82_g(9D5d$-vl!^_S2Nbgja zCqkao80G(gPFG~*?*l_>=002ovPDHLkV1jKk B$6EjZ diff --git a/resources/g2/track/lattice_triangle/liftbooster_alt_2.png b/resources/g2/track/lattice_triangle/liftbooster_alt_2.png new file mode 100644 index 0000000000000000000000000000000000000000..8a3dbf41cfe7c54e285282749a8f6af4e3602f23 GIT binary patch literal 1168 zcmWktacC2F6n<@5ueE9>aRv<|vM2{T-3^a<$jzPZT4Rapm7X-)@<-IOW?d$?dEGJz zEW_yH$mHsRi*m9IZkml_MhWg<(S?y==fXT#)Tp;DVAPCN4J=|6slP>d?|t7NkN3g% z-urBL$UA@T(zyUIe{fU(NE?ZEF6^gw+9o-=0-hG9KDJ-xlXPLIb! zQ6$H)g5VRyfGkV#cs!lX6y>s+ ztkpG+!2C>~D_JSCk*&=X?JPJ1aE8Dg z1zf@CjMJOL14ULc{mGiFHI)*|^MpgBT@f#l^fOtJE69Qw7prNxuE(3j^o*&addcpf zal%j0A(o2>LQ)jfNF7qR-e{Ppt>p><742gcC$G7K1}<5Q z(hTUWNMR;jer(iGwTU}`c4J=B9$?*Jfr^HFN-V6UVg)^Amh^^ILaiF@^C1I}1qeY~ z3k&bSm4quE#lmB>nx@qwYP~L(%d~ow3j~C4Sd2y`ij31_nx%A(D*DI@Pc-}<6m+8) zj#LU6EHZrvp+mAG^z;WNMur4ffBWjrHeWK>zhTQq*WaCdeRpZuy#3d*$u)Op$(xJb zyP9UUAUUh%@!;L-rPyHLd-1y)d@0CjaBrqKc;)YO4LmH%2C^v}w3||1d8e9QF=;G zJwpR-*Iw7a;E}^uU9SVwK;N7Dx~s$M)~#E=etk_%O>J#$U0q#$eLaR@4Gj$&Hf%7M z&1RCcFbvJ}tROffN%Z^u;czsWOl7lknpUnvM(OVKFGWQ?TVOdBkm$?C*y zB4L+FL9t2^#-CtAX+D;7rZl&SGFohAD^IWjM~z47@CPEwX9kx(BNb-iPy?5+TJFj|u6tUsV&Ol8UNcMmLbYCR#CY zF_SZei<(s_I}#OddL^7&O%+hSjO&3iVK$4-L7O~0>2tG+?1_csbRwi?6D2K+Dg}yV zQ3{X-2tm~g^9;ov)Kly>-y}dkiF8p?|syFs@?cDdtow3uir^mK5k4>qE zZtYlFrB9*%wzjwbar02kHxnbPoj)y;8~Jh9MReuBKW)!FzVYbOwP(5=^SSr7Pi||Q zzH(=IExvX5*2fPoOnJ~MAEUH!-Y2j!#&ga7~l literal 0 HcmV?d00001 diff --git a/resources/g2/track/lattice_triangle/liftbooster_alt_4.png b/resources/g2/track/lattice_triangle/liftbooster_alt_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ddbf0414f86df8fedefd2fec99594b6d7b4602d3 GIT binary patch literal 1260 zcmWktacmQH82ycIyTRNF7U`hT4jXbImr>*rE~J=ayJ0swIM@+7QbV`hM%98hxseK0 z3pAlh#gkMlTCyqy3OQWW8mk=8&1O`sa*34{JVMbbC7>2*aD}c<gwv6nwr|$S_DDr>gs0BoT)V!3^;D2 zD3W0;ENkO=&g=CCgW*^#kxFG1rBp8CMnIYXZK=1}G)|}9~KreKJU#_Up(&&d9K zAwpq@)l|<}v>vNoV9_v-$GucCXwAepCG9IJk*QM3tOIroxJV!{NR&g8eswOYDQ9%B zXoO`uoE9KV833RGuprHml%wbj! z&I%?zM0rI^Kw=^pdqQ#O37yewFfo{gC2SnU`DkC*9!_ux*^^QNaxt2pN~%eqVSv^F z^lpF(2octrW2h}ja-cPVF{hfjQOpmC`(B^BYW9gkS~bdQZhIti?EPV zYX}sx;)H{wTnyu9*^tW>^ZS$Gu$)Nbv)NLq1c8nNXb{1pYD&^E8O)KVd<9#i=#ol8 zwj3)?=cZsirdAVLtyyniFe7U+@fO-=ub8=G{y;h!Q&Ms{PXfCI;Tg5Zt{0qG$W4kq zMhZF7q9>OO6?3U_`8Fg0umZpXAOIi&kOrWD09YBCf^Hs)5vb&76mU2QkRV|O3Jo9w zAg6_X97brEaKelaDiQFgcmh}`V5Jc!tM$0BfMAYBSV{8AvREw2u#%;70NhBLR;j2IQ1jR8p{4cZa0S;y@WAH;v$77EygU3 z6|Dwn*Fz5qLpV&3P_{q_5AqtvqaPUVUdw=0H!g3f=pCKyts7qZ^_@d&wx^mOd+v%! zhn|CbKC12dan0=J*&~a|1Nf#5V;4t=@I+v&?MUXY{_X20152MYA6)7?CFC|-TS%15H z{rCAR?(ga8Wwu>?_vU-$heOwLf4u(9==hb6BWKblC?k7s4|yrcOrIY zW4!m&-}9*ZSsckUoF{uP#)rSU($O$FqEU(67qU&KhwgQqK2tk2XUFn6u_b4fmKO(9 ztNv>k-MjDB$BU%Q{+%b6eErYP@e_^DBC4~Y$B+0|d_HpNCBqGGk6d-Tby>>_L;GZ$ z|MZ6!`gYGnyvJVt=@a*bQ*$OZUl@yDvn~5lW!wC4=+xx+eh1a_x=xaKr+1m literal 0 HcmV?d00001 diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index ef4043e3d9..b17e59929c 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -105,6 +105,7 @@ namespace OpenRCT2::Ui::Windows RIDE_TYPE_HYBRID_COASTER, RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER, RIDE_TYPE_ALPINE_COASTER, + RIDE_TYPE_LSM_LAUNCHED_ROLLER_COASTER, // Gentle rides RIDE_TYPE_MONORAIL_CYCLES, diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index b88e708d96..7323e94289 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -449,6 +449,7 @@ + @@ -920,6 +921,7 @@ + diff --git a/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp b/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp index 2e8ecaacc3..84f425a21f 100644 --- a/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp +++ b/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp @@ -10341,7 +10341,7 @@ static void LatticeTriangleTrackPoweredLift( const TrackElement& trackElement, SupportType supportType) { PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_0 + direction), + session, direction, session.TrackColours.WithIndex(SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_1 + direction), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) diff --git a/src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp b/src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp new file mode 100644 index 0000000000..f2623d6649 --- /dev/null +++ b/src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp @@ -0,0 +1,217 @@ +/***************************************************************************** + * Copyright (c) 2014-2024 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 "../../../drawing/Drawing.h" +#include "../../../interface/Viewport.h" +#include "../../../ride/RideData.h" +#include "../../../ride/TrackData.h" +#include "../../../ride/TrackPaint.h" +#include "../../../sprites.h" +#include "../../../world/Map.h" +#include "../../../world/tile_element/TrackElement.h" +#include "../../Paint.h" +#include "../../support/MetalSupports.h" +#include "../../tile_element/Paint.TileElement.h" +#include "../../tile_element/Segment.h" +#include "../../track/Segment.h" +#include "../../track/Support.h" + +using namespace OpenRCT2; + +static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; + +static constexpr uint32_t _LatticeTriangleAltBrakeImages[kNumOrthogonalDirections][2] = { + { SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_NE_SW, SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_NE_SW }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_NW_SE, SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_NW_SE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_SW_NE, SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_SW_NE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_SE_NW, SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_SE_NW }, +}; + +static constexpr uint32_t _LatticeTriangleAltBlockBrakeImages[kNumOrthogonalDirections][2] = { + { SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_NE_SW, SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_NE_SW }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_NW_SE, SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_NW_SE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_SW_NE, SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_SW_NE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_SE_NW, SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_SE_NW }, +}; + +static void LatticeTriangleTrackAltStation( + PaintSession& session, const Ride& ride, [[maybe_unused]] uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + if (ride.mode == RideMode::PoweredLaunch || ride.mode == RideMode::PoweredLaunchBlockSectioned + || ride.mode == RideMode::PoweredLaunchPasstrough) + { + static constexpr uint32_t imageIds[4][2] = { + { SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_NE_SW, SPR_STATION_BASE_A_SW_NE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_NW_SE, SPR_STATION_BASE_A_NW_SE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_SW_NE, SPR_STATION_BASE_A_SW_NE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_SE_NW, SPR_STATION_BASE_A_NW_SE }, + }; + + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(imageIds[direction][0]), { 0, 0, height }, + { { 0, 6, height + 3 }, { 32, 20, 1 } }); + + PaintAddImageAsParentRotated( + session, direction, GetStationColourScheme(session, trackElement).WithIndex(imageIds[direction][1]), + { 0, 0, height }, { 32, 32, 1 }); + } + else + { + static constexpr uint32_t imageIds[4][2] = { + { SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_NE_SW, SPR_STATION_BASE_A_SW_NE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_NW_SE, SPR_STATION_BASE_A_NW_SE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_SW_NE, SPR_STATION_BASE_A_SW_NE }, + { SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_SE_NW, SPR_STATION_BASE_A_NW_SE }, + }; + if (trackElement.GetTrackType() == TrackElemType::EndStation) + { + bool isClosed = trackElement.IsBrakeClosed(); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(_LatticeTriangleAltBlockBrakeImages[direction][isClosed]), + { 0, 0, height }, { { 0, 6, height + 3 }, { 32, 20, 1 } }); + } + else + { + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(imageIds[direction][0]), { 0, 0, height }, + { { 0, 6, height + 3 }, { 32, 20, 1 } }); + } + + PaintAddImageAsParentRotated( + session, direction, GetStationColourScheme(session, trackElement).WithIndex(imageIds[direction][1]), + { 0, 0, height }, { 32, 32, 1 }); + } + DrawSupportsSideBySide(session, direction, height, session.SupportColours, supportType.metal); + TrackPaintUtilDrawStation2(session, ride, direction, height, trackElement, 9, 11); + TrackPaintUtilDrawStationTunnel(session, direction, height); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + +static void LatticeTriangleTrackAltBrakes( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + bool isClosed = trackElement.IsBrakeClosed(); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(_LatticeTriangleAltBrakeImages[direction][isClosed]), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, MetalSupportType::Tubes, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + +static void LatticeTriangleTrackAltBlockBrakes( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + bool isClosed = trackElement.IsBrakeClosed(); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(_LatticeTriangleAltBlockBrakeImages[direction][isClosed]), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, MetalSupportType::Tubes, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + +static void LatticeTriangleTrackAltBooster( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_NE_SW), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_NW_SE), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_SW_NE), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_SE_NW), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, MetalSupportType::Tubes, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + +static void LatticeTriangleTrackAltPoweredLift( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_ALT_1 + direction), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + else + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::SlopeEnd); + } + PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); +} + +TRACK_PAINT_FUNCTION GetTrackPaintFunctionLatticeTriangleTrackAlt(TrackElemType trackType) +{ + switch (trackType) + { + case TrackElemType::EndStation: + case TrackElemType::BeginStation: + case TrackElemType::MiddleStation: + return LatticeTriangleTrackAltStation; + case TrackElemType::Brakes: + return LatticeTriangleTrackAltBrakes; + case TrackElemType::BlockBrakes: + return LatticeTriangleTrackAltBlockBrakes; + case TrackElemType::Booster: + return LatticeTriangleTrackAltBooster; + case TrackElemType::PoweredLift: + return LatticeTriangleTrackAltPoweredLift; + + default: + return GetTrackPaintFunctionLatticeTriangleTrack(trackType); + } +} diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index 0dc6c046d0..61c19360ed 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -14,7 +14,7 @@ namespace OpenRCT2 constexpr uint32_t PARK_FILE_CURRENT_VERSION = 42; // The minimum version that is forwards compatible with the current version. - constexpr uint32_t PARK_FILE_MIN_VERSION = 40; + constexpr uint32_t PARK_FILE_MIN_VERSION = 42; // The minimum version that is backwards compatible with the current version. // If this is increased beyond 0, uncomment the checks in ParkFile.cpp and Context.cpp! diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 214cba38b6..882807edbb 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -619,6 +619,7 @@ enum RIDE_TYPE_ALPINE_COASTER, RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER, RIDE_TYPE_CLASSIC_STAND_UP_ROLLER_COASTER, + RIDE_TYPE_LSM_LAUNCHED_ROLLER_COASTER, RIDE_TYPE_COUNT }; diff --git a/src/openrct2/ride/RideData.cpp b/src/openrct2/ride/RideData.cpp index bf428be178..e503a233b4 100644 --- a/src/openrct2/ride/RideData.cpp +++ b/src/openrct2/ride/RideData.cpp @@ -49,6 +49,7 @@ #include "rtd/coaster/InvertedRollerCoaster.h" #include "rtd/coaster/JuniorRollerCoaster.h" #include "rtd/coaster/LIMLaunchedRollerCoaster.h" +#include "rtd/coaster/LSMLaunchedRollerCoaster.h" #include "rtd/coaster/LayDownRollerCoaster.h" #include "rtd/coaster/LoopingRollerCoaster.h" #include "rtd/coaster/MineRide.h" @@ -352,6 +353,7 @@ constexpr RideTypeDescriptor RideTypeDescriptors[RIDE_TYPE_COUNT] = { /* RIDE_TYPE_ALPINE_COASTER */ AlpineCoasterRTD, /* RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER */ ClassicWoodenRollerCoasterRTD, /* RIDE_TYPE_CLASSIC_STAND_UP_ROLLER_COASTER */ ClassicStandUpRollerCoasterRTD, + /* RIDE_TYPE_LSM_LAUNCHED_ROLLER_COASTER */ LSMLaunchedRollerCoasterRTD, }; bool RideTypeDescriptor::HasFlag(RtdFlag flag) const diff --git a/src/openrct2/ride/RideData.h b/src/openrct2/ride/RideData.h index 083ee615db..f82759026c 100644 --- a/src/openrct2/ride/RideData.h +++ b/src/openrct2/ride/RideData.h @@ -561,6 +561,7 @@ constexpr std::string_view MUSIC_OBJECT_SUMMER = "rct2.music.summer"; constexpr std::string_view MUSIC_OBJECT_TECHNO = "rct2.music.techno"; constexpr std::string_view MUSIC_OBJECT_WATER = "rct2.music.water"; constexpr std::string_view MUSIC_OBJECT_WILD_WEST = "rct2.music.wildwest"; +constexpr std::string_view MUSIC_OBJECT_MODERN = "rct2.music.modern"; constexpr const RideComponentName& GetRideComponentName(const RideComponentType type) { diff --git a/src/openrct2/ride/RideStringIds.h b/src/openrct2/ride/RideStringIds.h index 03855eba37..928ab36163 100644 --- a/src/openrct2/ride/RideStringIds.h +++ b/src/openrct2/ride/RideStringIds.h @@ -37,6 +37,7 @@ enum : StringId STR_RIDE_NAME_JUNIOR_ROLLER_COASTER = 6, STR_RIDE_NAME_LAY_DOWN_ROLLER_COASTER = 64, STR_RIDE_NAME_LIM_LAUNCHED_ROLLER_COASTER = 92, + STR_RIDE_NAME_LSM_LAUNCHED_ROLLER_COASTER = 98, STR_RIDE_NAME_LOOPING_ROLLER_COASTER = 17, STR_RIDE_NAME_MINE_RIDE = 90, STR_RIDE_NAME_MINE_TRAIN_COASTER = 19, @@ -79,6 +80,7 @@ enum : StringId STR_RIDE_DESCRIPTION_JUNIOR_ROLLER_COASTER = 516, STR_RIDE_DESCRIPTION_LAY_DOWN_ROLLER_COASTER = 574, STR_RIDE_DESCRIPTION_LIM_LAUNCHED_ROLLER_COASTER = 602, + STR_RIDE_DESCRIPTION_LSM_LAUNCHED_ROLLER_COASTER = 608, STR_RIDE_DESCRIPTION_LOOPING_ROLLER_COASTER = 527, STR_RIDE_DESCRIPTION_MINE_RIDE = 600, STR_RIDE_DESCRIPTION_MINE_TRAIN_COASTER = 529, diff --git a/src/openrct2/ride/TrackPaint.h b/src/openrct2/ride/TrackPaint.h index 9519baab66..9fdfbb9f85 100644 --- a/src/openrct2/ride/TrackPaint.h +++ b/src/openrct2/ride/TrackPaint.h @@ -607,6 +607,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionReverserRC(OpenRCT2::TrackElemType tra TRACK_PAINT_FUNCTION GetTrackPaintFunctionHeartlineTwisterRC(OpenRCT2::TrackElemType trackType); TRACK_PAINT_FUNCTION GetTrackPaintFunctionMiniGolf(OpenRCT2::TrackElemType trackType); TRACK_PAINT_FUNCTION GetTrackPaintFunctionLatticeTriangleTrack(OpenRCT2::TrackElemType trackType); +TRACK_PAINT_FUNCTION GetTrackPaintFunctionLatticeTriangleTrackAlt(OpenRCT2::TrackElemType trackType); TRACK_PAINT_FUNCTION GetTrackPaintFunctionRotoDrop(OpenRCT2::TrackElemType trackType); TRACK_PAINT_FUNCTION GetTrackPaintFunctionFlyingSaucers(OpenRCT2::TrackElemType trackType); TRACK_PAINT_FUNCTION GetTrackPaintFunctionCrookedHouse(OpenRCT2::TrackElemType trackType); diff --git a/src/openrct2/ride/rtd/coaster/GigaCoaster.h b/src/openrct2/ride/rtd/coaster/GigaCoaster.h index 135fde8d2e..fdb2ae56d1 100644 --- a/src/openrct2/ride/rtd/coaster/GigaCoaster.h +++ b/src/openrct2/ride/rtd/coaster/GigaCoaster.h @@ -22,8 +22,8 @@ constexpr RideTypeDescriptor GigaCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionLatticeTriangleTrack, .supportType = MetalSupportType::Tubes, - .enabledTrackGroups = {TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::liftHillCable, TrackGroup::booster, TrackGroup::poweredLift, TrackGroup::slopeCurveBanked, TrackGroup::slopeCurveLarge, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeVertical, TrackGroup::curveVertical}, - .extraTrackGroups = {TrackGroup::barrelRoll, TrackGroup::quarterLoop, TrackGroup::halfLoop, TrackGroup::halfLoopMedium, TrackGroup::halfLoopLarge, TrackGroup::verticalLoop, TrackGroup::corkscrew, TrackGroup::corkscrewLarge, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge}, + .enabledTrackGroups = {TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::liftHillCable, TrackGroup::slopeCurveBanked, TrackGroup::slopeCurveLarge, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeVertical, TrackGroup::curveVertical}, + .extraTrackGroups = {TrackGroup::barrelRoll, TrackGroup::quarterLoop, TrackGroup::halfLoop, TrackGroup::halfLoopMedium, TrackGroup::halfLoopLarge, TrackGroup::verticalLoop, TrackGroup::corkscrew, TrackGroup::corkscrewLarge, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge, TrackGroup::booster, TrackGroup::poweredLift}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | diff --git a/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h b/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h new file mode 100644 index 0000000000..75c8103dbe --- /dev/null +++ b/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h @@ -0,0 +1,90 @@ +/***************************************************************************** + * Copyright (c) 2014-2024 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 "../../../sprites.h" +#include "../../RideData.h" +#include "../../ShopItem.h" +#include "../../Track.h" + +// clang-format off +constexpr RideTypeDescriptor LSMLaunchedRollerCoasterRTD = +{ + .Category = RIDE_CATEGORY_ROLLERCOASTER, + .StartTrackPiece = OpenRCT2::TrackElemType::EndStation, + .TrackPaintFunctions = TrackDrawerDescriptor({ + .Drawer = GetTrackPaintFunctionLatticeTriangleTrackAlt, + .supportType = MetalSupportType::Tubes, + .enabledTrackGroups = {TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::flatRollBanking, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::slopeCurveBanked, TrackGroup::slopeCurveLarge, TrackGroup::slopeCurveLargeBanked, TrackGroup::booster, TrackGroup::poweredLift, TrackGroup::slopeVertical, TrackGroup::curveVertical, TrackGroup::barrelRoll, TrackGroup::quarterLoop, TrackGroup::halfLoop, TrackGroup::halfLoopMedium, TrackGroup::halfLoopLarge, TrackGroup::verticalLoop, TrackGroup::corkscrew, TrackGroup::corkscrewLarge, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge }, + .extraTrackGroups = {TrackGroup::liftHill, TrackGroup::liftHillCable}, + }), + .InvertedTrackPaintFunctions = {}, + .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | + EnumsToFlags(RtdFlag::hasLeaveWhenAnotherVehicleArrivesAtStation, RtdFlag::checkGForces, + RtdFlag::allowMultipleCircuits, RtdFlag::allowCableLiftHill, RtdFlag::allowReversedTrains), + .RideModes = EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned, RideMode::PoweredLaunch, RideMode::PoweredLaunchBlockSectioned), + .DefaultMode = RideMode::ContinuousCircuit, + .OperatingSettings = { 2, 10 }, + .TrackSpeedSettings = { 60, 60 }, + .BoosterSettings = { 17, 68 }, + .LegacyBoosterSettings = { 17, 68, 2 }, + .Naming = { STR_RIDE_NAME_LSM_LAUNCHED_ROLLER_COASTER, STR_RIDE_DESCRIPTION_LSM_LAUNCHED_ROLLER_COASTER }, + .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, + .EnumName = "RIDE_TYPE_LSM_LAUNCHED_ROLLER_COASTER", + .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), + .Heights = { 33, 24, 9, 11, }, + .MaxMass = 31, + .LiftData = { OpenRCT2::Audio::SoundId::LiftClassic, 5, 5 }, + .RatingsMultipliers = { 51, 32, 10 }, + .UpkeepCosts = { 10, 20, 80, 12, 3, 40 }, + .BuildCosts = { 57.00_GBP, 2.50_GBP, 55, }, + .DefaultPrices = { 20, 20 }, + .DefaultMusic = MUSIC_OBJECT_MODERN, + .PhotoItem = ShopItem::Photo, + .BonusValue = 120, + .ColourPresets = TRACK_COLOUR_PRESETS( + { COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_BLACK}, // Taiga + { COLOUR_BRIGHT_GREEN, COLOUR_BRIGHT_GREEN, COLOUR_YELLOW}, // Cheetah Hunt + { COLOUR_BRIGHT_RED, COLOUR_BRIGHT_RED, COLOUR_DULL_BROWN_LIGHT}, // Maverick + { COLOUR_BLACK, COLOUR_BLACK, COLOUR_DULL_BROWN_DARK}, // Taron + ), + .ColourPreview = { SPR_RIDE_DESIGN_PREVIEW_GIGA_RC, SPR_RIDE_DESIGN_PREVIEW_GIGA_RC_SUPPORTS }, + .ColourKey = RideColourKey::Ride, + .Name = "lsm_rc", + .RatingsData = + { + RatingsCalculationType::Normal, + { RIDE_RATING(3, 85), RIDE_RATING(0, 40), RIDE_RATING(0, 35) }, + 14, + -1, + false, + { + { RatingsModifierType::BonusLength, 6000, 764, 0, 0 }, + { RatingsModifierType::BonusSynchronisation, 0, RIDE_RATING(0, 40), RIDE_RATING(0, 05), 0 }, + { RatingsModifierType::BonusTrainLength, 0, 187245, 0, 0 }, + { RatingsModifierType::BonusMaxSpeed, 0, 44281, 88562, 35424 }, + { RatingsModifierType::BonusAverageSpeed, 0, 291271, 436906, 0 }, + { RatingsModifierType::BonusDuration, 150, 26214, 0, 0 }, + { RatingsModifierType::BonusGForces, 0, 24576, 35746, 49648 }, + { RatingsModifierType::BonusTurns, 0, 26749, 34767, 45749 }, + { RatingsModifierType::BonusDrops, 0, 29127, 46811, 49152 }, + { RatingsModifierType::BonusSheltered, 0, 15420, 32768, 35108 }, + { RatingsModifierType::BonusReversedTrains, 0, 2, 15, 20 }, + { RatingsModifierType::BonusProximity, 0, 20130, 0, 0 }, + { RatingsModifierType::BonusScenery, 0, 6693, 0, 0 }, + { RatingsModifierType::RequirementDropHeight, 10, 2, 2, 2 }, + { RatingsModifierType::RequirementMaxSpeed, 0xA0000, 2, 2, 2 }, + { RatingsModifierType::RequirementNegativeGs, 10, 2, 2, 2 }, + { RatingsModifierType::RequirementNumDrops, 2, 2, 2, 2 }, + { RatingsModifierType::PenaltyLateralGs, 0, 24576, 35746, 49648 }, + }, + }, +}; +// clang-format on diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index e827e024d1..a51ea9ca72 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1226,11 +1226,39 @@ enum : ImageIndex SPR_G2_LATTICE_TRIANGLE_TRACK_BEGIN = SPR_G2_JUNIOR_RC_END, SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_NE_SW = SPR_G2_LATTICE_TRIANGLE_TRACK_BEGIN, SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_NW_SE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_NE_SW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_NW_SE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_SW_NE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BOOSTER_ALT_SE_NW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_NE_SW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_NW_SE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_SW_NE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_CLOSED_SE_NW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_NE_SW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_NW_SE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_SW_NE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BLOCK_BRAKE_ALT_OPEN_SE_NW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_NE_SW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_NW_SE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_SW_NE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_CLOSED_SE_NW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_NE_SW, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_NW_SE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_SW_NE, + SPR_G2_LATTICE_TRIANGLE_TRACK_BRAKE_ALT_OPEN_SE_NW, SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BRAKES, - SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_0 = SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BRAKES + 6, + SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_NE_SW = SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BRAKES + 6, + SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_NW_SE, + SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_SW_NE, + SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_SE_NW, SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_1, SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_2, SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_3, + SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_4, + SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_ALT_1, + SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_ALT_2, + SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_ALT_3, + SPR_G2_LATTICE_TRIANGLE_TRACK_POWERED_LIFT_ALT_4, SPR_G2_LATTICE_TRIANGLE_TRACK_VERTICAL, SPR_G2_LATTICE_TRIANGLE_TRACK_VERTICAL_TWIST = SPR_G2_LATTICE_TRIANGLE_TRACK_VERTICAL + 12, SPR_G2_LATTICE_TRIANGLE_TRACK_BARREL_ROLL = SPR_G2_LATTICE_TRIANGLE_TRACK_VERTICAL_TWIST + 12,