From ab64191f899014d04450480df9fb26823ebf8b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 3 Nov 2024 19:54:36 +0100 Subject: [PATCH 001/139] Start v0.4.17 --- distribution/changelog.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 11e195689c..ad73d6d1a6 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,3 +1,6 @@ +0.4.17 (in development) +------------------------------------------------------------------------ + 0.4.16 (2024-11-03) ------------------------------------------------------------------------ - Feature: [#20810] New ride type: LSM Launched Roller Coaster. From 4234035402ab96d3e3afa1beda30ba195b6fe5b1 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Tue, 5 Nov 2024 04:02:06 +0000 Subject: [PATCH 002/139] Merge Localisation/master into OpenRCT2/develop --- data/language/ko-KR.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/language/ko-KR.txt b/data/language/ko-KR.txt index 4d2497d80b..00f2dc0d4a 100644 --- a/data/language/ko-KR.txt +++ b/data/language/ko-KR.txt @@ -99,6 +99,7 @@ STR_0094 :모노레일 롤러코스터 STR_0095 :알파인 코스터 STR_0096 :클래식 우든 롤러코스터 STR_0097 :클래식 스탠드 업 롤러코스터 +STR_0098 :LSM 발진 롤러코스터 STR_0512 :나선형 리프트 힐과 부드럽게 꼬인 낙하를 가진 알찬 구성의 롤러코스터입니다. STR_0513 :일어선 자세로 탑승하는 루핑 롤러코스터입니다. STR_0514 :코너를 돌 때 롤러코스터 트랙 아래에 매달린 차량이 좌우로 흔들리는 열차입니다. @@ -183,6 +184,7 @@ STR_0604 :탑승객들은 폭이 좁은 모노레일 트랙 위에 한 줄로 STR_0605 :탑승객들이 구불구불한 철제 트랙을 따라 썰매 모양의 차량을 타고 스스로 속력을 조절하며 내려오는 놀이기구입니다. STR_0606 :빠르고 거친 승차감과 충분한 에어 타임, 약간의 측면 중력이 있으며 '통제되지 않는 느낌'을 느낄 수 있도록 설계된 구식 목재 롤러코스터입니다. STR_0607 :탑승객들이 일어선 자세로 탑승하는, 격렬한 구식 스타일의 철제 루핑 롤러코스터입니다. +STR_0608 :선형 동기 모터로 가속되어 급커브와 커브를 빠르게 도는 롤러코스터 열차입니다. STR_0767 :손님 {INT32} STR_0768 :미화원 {INT32} STR_0769 :정비기술자 {INT32} @@ -3612,7 +3614,7 @@ STR_6537 :일반 보도를 대기줄로 사용 STR_6538 :보도 창의 대기줄 메뉴 밑에 일반 보도를 표시합니다. STR_6539 :브레이크 닫힘 STR_6540 :{WINDOW_COLOUR_2}외관 사용을 허락해주신 다음 회사에도 감사를 드립니다: -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 :기여하신 분들 STR_6543 :기여하신 분들… STR_6544 :대출은 음수일 수 없습니다! From 3b0a67cf97caefada77af36c18ec9f614eff0cfd Mon Sep 17 00:00:00 2001 From: Michael Steenbeek <1478678+Gymnasiast@users.noreply.github.com> Date: Tue, 5 Nov 2024 18:28:38 +0100 Subject: [PATCH 003/139] Fix #23126: Set correct PR for LSM LC --- distribution/changelog.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index ad73d6d1a6..95bab8f7f2 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -3,7 +3,7 @@ 0.4.16 (2024-11-03) ------------------------------------------------------------------------ -- Feature: [#20810] New ride type: LSM Launched Roller Coaster. +- Feature: [#22797] 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. From ff12d31926d31613b1cee10f7ad6e8438ce7054f Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Wed, 6 Nov 2024 04:02:14 +0000 Subject: [PATCH 004/139] Merge Localisation/master into OpenRCT2/develop --- data/language/eo-ZZ.txt | 4 +- data/language/it-IT.txt | 72 ++- data/language/pl-PL.txt | 956 ++++++++++++++++++++++++---------------- 3 files changed, 638 insertions(+), 394 deletions(-) diff --git a/data/language/eo-ZZ.txt b/data/language/eo-ZZ.txt index e7781e3c11..4174d3d7c3 100644 --- a/data/language/eo-ZZ.txt +++ b/data/language/eo-ZZ.txt @@ -99,6 +99,7 @@ STR_0094 :Onda Fervojo kun Unuopa Relo STR_0095 :Alpa Onda Fervojo STR_0096 :Klasika Ligna Onda Fervojo STR_0097 :Klasika Staranta Onda Fervojo +STR_0098 :Onda Fervojo Lanĉita per Linearaj Sinkronaj Motoroj STR_0512 :Onda fervojo kompakta kun helikforma lifto kaj glataj kurboplenaj malleviĝoj. STR_0513 :Onda fervojo kun lopoj, sur kiun la rajdantoj rajdas starante STR_0514 :Trajnoj penditaj sub la trako de la onda fervojo svingiĝas flanken ĉe anguloj @@ -183,6 +184,7 @@ STR_0604 :Rajdantoj rajdas anservice sur mallarĝa monorela trako, dum ili ve STR_0605 :Rajdantoj toboganas malsupren serpentuman ŝtalan trakon, bremsante por regi ilian rapidecon. STR_0606 :Maljuna-stila ligna onda fervojo kun rapida kaj malglata rajdo, kun sufiĉe da ‘en-aeraj periodoj’, kelka flanka graviteco, kaj desegnita sentiĝi ‘nedirektebla’ STR_0607 :Intensa, malnovstila ŝtala onda fervojo kun lopoj, sur kiun la rajdantoj rajdas starante +STR_0608 :Linearaj sinkronaj motoroj plirapidigas la trajnojn de la onda fervojo, kiuj tiam trapasas krutajn inversigojn kaj kurbiĝojn STR_0767 :Gasto {INT32} STR_0768 :Faktoto {INT32} STR_0769 :Mekanikisto {INT32} @@ -3609,7 +3611,7 @@ STR_6537 :Permesi uzante regulajn trotuarojn kiel atendovico STR_6538 :Montras regulajn trotuarojn en la atendovicoj-fallisto de la Trotuaroj-fenestro. STR_6539 :Bremso Fermita STR_6540 :{WINDOW_COLOUR_2}Specialan dankon al la sekvantaj firmaoj por permesi ilian similecon: -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 :Kontribuantoj STR_6543 :Kontribuantoj… STR_6544 :Prunto ne povas esti negativa! diff --git a/data/language/it-IT.txt b/data/language/it-IT.txt index eb8810cfee..f435208bb7 100644 --- a/data/language/it-IT.txt +++ b/data/language/it-IT.txt @@ -99,6 +99,7 @@ STR_0094 :Ottovolante a binario singolo STR_0095 :Ottovolante Alpino STR_0096 :Ottovolante di legno classico STR_0097 :Ottovolante in piedi classico +STR_0098 :Ottovolante a lancio LSM STR_0512 :Un ottovolante compatto con una salita a spirale e cadute fluide e tortuose. STR_0513 :Un ottovolante con giro della morte dove i passeggeri si trovano in una posizione eretta STR_0514 :I treni, sospesi sotto l’ottovolante, durante le curve oscillano lateralmente @@ -183,6 +184,7 @@ STR_0604 :I visitatori viaggiano lungo un sottile tracciato da monorotaia, at STR_0605 :I visitatori scendono lungo una rotaia piena di curve, frenando per controllare la velocità del loro vagone STR_0606 :Un ottovolante di legno vecchio stile con un percorso veloce e turbolento, con molto air-time, G laterali, progettato per farti sentire “fuori controllo” STR_0607 :Un intenso ottovolante d’acciaio vecchio stile, nel quale i passeggeri sono in posizione eretta +STR_0608 :I treni dell’ottovolante sono lanciati da motori sincroni lineari e corrono attraverso curve e avvitamenti stretti STR_0767 :Visitatore {INT32} STR_0768 :Tuttofare {INT32} STR_0769 :Meccanico {INT32} @@ -1913,11 +1915,11 @@ STR_2670 :Scorr STR_2680 :Tutte le ricerche sono completate STR_2684 :Fa arrivare una folla di visitatori STR_2685 :Simplex Noise Parameters -STR_2686 :Basso: -STR_2687 :Alto: -STR_2688 :Frequenza Base: -STR_2689 :Ottavi: -STR_2690 :Generazione Mappa +STR_2686 :Altezza min. terreno: +STR_2687 :Altezza max. terreno: +STR_2688 :Frequenza base: +STR_2689 :Ottave: +STR_2690 :Generazione mappa STR_2691 :Base height: STR_2692 :Livello acqua: STR_2693 :Terreno: @@ -3168,19 +3170,19 @@ STR_6038 :Se RCT1 è installato, selezionarne la cartella per caricarne gli s STR_6039 :Demolizione veloce percorso STR_6040 :Modifica opzioni scenario STR_6041 :{BLACK}Non è stato assunto alcun meccanico! -STR_6042 :Carica heightmap -STR_6043 :Seleziona heightmap -STR_6044 :Ammorbidisci heightmap -STR_6045 :Forza -STR_6046 :Normalizza heightmap -STR_6047 :Ammorbidisci celle -STR_6048 :Errore nella heightmap +STR_6042 :Carica mappa altimetrica +STR_6043 :Seleziona mappa altimetrica +STR_6044 :Ammorbidisci mappa altimetrica +STR_6045 :Forza: +STR_6046 :Normalizza mappa altimetrica +STR_6047 :Ammorbidisci bordi celle +STR_6048 :Errore nella mappa altimetrica STR_6049 :Errore nella lettura del PNG STR_6050 :Errore nella lettura della bitmap -STR_6052 :La heightmap è troppo grande e sarà tagliata -STR_6053 :La heightmap non può essere normalizzata +STR_6052 :La mappa altimetrica è troppo grande e sarà tagliata +STR_6053 :La mappa altimetrica non può essere normalizzata STR_6054 :Sono supportate solo le bitmap a 24 bit -STR_6055 :File di heightmap di OpenRCT2 +STR_6055 :File mappa altimetrica di OpenRCT2 STR_6056 :Muto STR_6057 :Mostra un bottone separato per l’opzione Muto nella barra degli strumenti STR_6058 :Muto @@ -3615,7 +3617,7 @@ STR_6537 :Usa sentieri normali come code STR_6538 :Mostra i percorsi regolari nel menu a cascata della finestra dei Sentieri. STR_6539 :Freno chiuso STR_6540 :{WINDOW_COLOUR_2}Un ringraziamento speciale alle seguenti aziende per aver concesso l'utilizzo della loro immagine: -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 :Collaboratori STR_6543 :Collaboratori… STR_6544 :I prestiti non posso essere negativi! @@ -3748,3 +3750,41 @@ STR_6669 :Mostra i trucchi sul personale STR_6670 :Comportamento visitatori STR_6671 :Mostra i “veri” nomi del personale STR_6672 :Alterna tra i nomi “veri” del personale e i loro numeri +STR_6673 :Trasparente +STR_6674 :{MONTH}, anno {COMMA16} +STR_6675 :Nomi visitatori +STR_6676 :È necessario selezionare almeno un oggetto nomi visitatori +STR_6677 :Aggiungi spiagge attorno agli specchi d’acqua +STR_6678 :Fonte mappa altimetrica: +STR_6679 :Pianura +STR_6680 :Rumore Simplex +STR_6681 :File mappa altimetrica +STR_6682 :Generatore mappa - Generatore +STR_6683 :Generatore mappa - Terreno +STR_6684 :Generatore mappa - Acqua +STR_6685 :Generatore mappa - Foreste +STR_6686 :Rapporto alberi/terreno: +STR_6687 :Altitudine min. alberi: +STR_6688 :Altitudine max. alberi: +STR_6689 :{UINT16}% +STR_6690 :Altezza terreno minima +STR_6691 :Inserisci un’altezza min. terreno tra {COMMA16} e {COMMA16} +STR_6692 :Altezza terreno massima +STR_6693 :Inserisci un’altezza max. terreno tra {COMMA16} e {COMMA16} +STR_6694 :Altitudine minima alberi +STR_6695 :Inserisci altitudine min. alberi tra {COMMA16} e {COMMA16} +STR_6696 :Altitudine massima alberi +STR_6697 :Inserisci altitudine max. alberi tra {COMMA16} e {COMMA16} +STR_6698 :Rapporto alberi/terreno +STR_6699 :Inserisci un rapporto alberi/terreno tra {COMMA16} e {COMMA16} +STR_6700 :Frequenza di base Simplex +STR_6701 :Inserisci una frequenza di base tra {COMMA2DP32} e {COMMA2DP32} +STR_6702 :Ottave Simplex +STR_6703 :Inserisci ottave tra {COMMA16} e {COMMA16} +STR_6704 :{COMMA2DP32} +STR_6705 :Sfoglia… +STR_6706 :{WINDOW_COLOUR_2}File immagine attuale: {BLACK}{STRING} +STR_6707 :(nessuno selezionato) +STR_6708 :Forza addolcimento +STR_6709 :Inserisci una forza addolcimento tra {COMMA16} e {COMMA16} + diff --git a/data/language/pl-PL.txt b/data/language/pl-PL.txt index 0c6df46c26..ba8a0f27fe 100644 --- a/data/language/pl-PL.txt +++ b/data/language/pl-PL.txt @@ -3,33 +3,33 @@ # Use # at the beginning of a line to leave a comment. STR_0000 : STR_0001 :{STRINGID} {COMMA16} -STR_0002 :Spiralna kolejka górska -STR_0003 :Stojąca kolejka górska +STR_0002 :Pajęcza jazda +STR_0003 :Stojąca kolejka STR_0004 :Podwieszana kolejka górska -STR_0005 :Odwrócona kolejka górska +STR_0005 :Kolejka odwrotna STR_0006 :Dziecięca kolejka górska STR_0007 :Miniaturowa kolejka STR_0008 :Kolejka jednotorowa -STR_0009 :Podwieszana mini kolejka +STR_0009 :Podwieszana minikolejka STR_0010 :Łódki -STR_0011 :Drewniana Zwariowana Mysz -STR_0012 :Tor Przeszkód -STR_0013 :Przejażdżka Autami +STR_0011 :Drewniana szalona mysz +STR_0012 :Bieg z przeszkodami +STR_0013 :Przejażdżka autami STR_0014 :Wystrzałowa spadajka -STR_0015 :Bobsleje +STR_0015 :Kolejka bobslejowa STR_0016 :Wieża obserwacyjna -STR_0017 :Pętlowa kolejka górska -STR_0018 :Zjeżdżalnia wodna +STR_0017 :Pętlowa kolejka +STR_0018 :Ślizg pontonowy STR_0019 :Kolejka kopalniana STR_0020 :Wyciąg krzesełkowy -STR_0021 :Kolejka górska korkociąg +STR_0021 :Kolejka korkociągowa STR_0022 :Labirynt -STR_0023 :Spiralna zjeżdżalnia +STR_0023 :Spiralny zjazd STR_0024 :Gokarty -STR_0025 :Zjazd na kłodach -STR_0026 :Katarakty rzeczne -STR_0027 :Samochodziki -STR_0028 :Statek piracki +STR_0025 :Jazda flisacka +STR_0026 :Przełomy Dunajca +STR_0027 :Unikajki +STR_0028 :Okręt piracki STR_0029 :Morska huśtawka STR_0030 :Budka z jedzeniem STR_0031 :Nieznane stoisko (1D) @@ -41,64 +41,67 @@ STR_0036 :Nieznane stoisko (22) STR_0037 :Punkt informacyjny STR_0038 :Toalety STR_0039 :Diabelski młyn -STR_0040 :Symulator -STR_0041 :Kino 3D +STR_0040 :Symulator ruchu +STR_0041 :Kino trójwymiarowe STR_0042 :Wirówka STR_0043 :Kosmiczne pierścienie -STR_0044 :Reverse Freefall Coaster +STR_0044 :Kolejka o swobodnym spadku STR_0045 :Winda -STR_0046 :Vertical Drop Roller Coaster +STR_0046 :Pionospadajka STR_0047 :Bankomat STR_0048 :Twist STR_0049 :Nawiedzony dom STR_0050 :Punkt pierwszej pomocy STR_0051 :Cyrk STR_0052 :Pociąg widmo -STR_0053 :Twister Roller Coaster +STR_0053 :Zwijka STR_0054 :Drewniana kolejka górska -STR_0055 :Side-Friction Roller Coaster -STR_0056 :Stalowa Zwariowana Mysz -STR_0057 :Multi-Dimension Roller Coaster +STR_0055 :Tarcie Boczne +STR_0056 :Stalowa szalona mysz +STR_0057 :Kolejka wielowymiarowa STR_0058 :Nieznana atrakcja (38) -STR_0059 :Latająca kolejka górska +STR_0059 :Latająca kolejka STR_0060 :Nieznana atrakcja (3A) -STR_0061 :Kołowrotek Virginia -STR_0062 :Chlapiące łódki +STR_0061 :W Koło Macieju +STR_0062 :Pluskołódki STR_0063 :Mini helikoptery -STR_0064 :Lay-down Roller Coaster -STR_0065 :Suspended Monorail +STR_0064 :Leżąca kolejka +STR_0065 :Kolejka podwieszana STR_0066 :Nieznana atrakcja (40) -STR_0067 :Reverser Roller Coaster -STR_0068 :Heartline Twister Coaster -STR_0069 :Mini golf -STR_0070 :Giga Coaster -STR_0071 :Roto-Drop +STR_0067 :Kolejka nawracająca +STR_0068 :Wagoniki zwijki +STR_0069 :Minigolf +STR_0070 :Gigajazda +STR_0071 :Obrotospad STR_0072 :Latające spodki STR_0073 :Krzywy dom -STR_0074 :Monorail Cycles -STR_0075 :Compact Inverted Coaster -STR_0076 :Wodna kolejka -STR_0077 :Air Powered Vertical Coaster -STR_0078 :Inverted Hairpin Coaster -STR_0079 :Magiczny Dywan -STR_0080 :Submarine Ride -STR_0081 :Tratwy +STR_0074 :Rowery jednotorowe +STR_0075 :Mała kolejka odwrócona +STR_0076 :Kolejka łódkowa +STR_0077 :Pneumatyczna kolejka pionowa +STR_0078 :Kolejka serpentynowa +STR_0079 :Latający dywan +STR_0080 :Podwodna podróż +STR_0081 :Tratwy rzeczne STR_0082 :Nieznana atrakcja (50) -STR_0083 :Enterprise +STR_0083 :Krynolina STR_0084 :Nieznana atrakcja (52) STR_0085 :Nieznana atrakcja (53) STR_0086 :Nieznana atrakcja (54) STR_0087 :Nieznana atrakcja (55) -STR_0088 :Inverted Impulse Coaster +STR_0088 :Zawracajka STR_0089 :Mini kolejka górska -STR_0090 :Kolejka kopalniana +STR_0090 :Przejażdżka kopalniana STR_0091 :Nieznana atrakcja (59) -STR_0092 :LIM Launched Roller Coaster +STR_0092 :Kolejka z napędem indukcyjnym liniowym STR_0093 :Kolejka hybrydowa STR_0094 :Kolejka jednotorowa STR_0095 :Tor saneczkowy +STR_0096 :Klasyczna drewniana kolejka górska +STR_0097 :Klasyczna stojąca kolejka górska +STR_0098 :Kolejka z napędem synchronicznym liniowym STR_0512 :Kolejka górska ze spiralnym podjazdem i łagodnymi pokręconymi zjazdami -STR_0513 :Kolejka górska z pętlą, klienci jadą w niej na stojąco +STR_0513 :Kolejka górska z pętlą, gdzie pasażerowie jadą na stojąco STR_0514 :Wagony podczepione są pod tor kolejki górskiej i bujają się na zakrętach STR_0515 :Stalowa kolejka górska z podczepionymi wagonikami z wieloma złożonymi i pokręconymi elementami STR_0516 :Łagodna kolejka górska dla ludzi, którzy nie mają jeszcze dość odwagi aby wsiąść na wyższe kolejki @@ -175,10 +178,13 @@ STR_0593 :Obrotowe koło z zawieszonymi pasażerami, na początku zaczyna si STR_0598 :Odwrócona kolejka górska, której wagoniki są rozpędzane na stacji, aby wjechać pionowym torem na szczyt toru, potem z powrotem przez stację, aby jechać odwrotnie na kolejny szczyt toru STR_0599 :Kolejka górska z indywidualnymi pojazdami i łagodnymi zakręcanymi zjazdami STR_0600 :Zasilane kopalniane wagoniki jeżdżące przez łagodne i pokręcone tory -STR_0602 :Kolejka górska, której wagoniki są rozpędzane na stacji liniowymi silnikami indukcyjnymi, aby pokonać zakręcone inwersje +STR_0602 :Kolejka górska, której wagoniki są rozpędzane na stacji liniowymi silnikami indukcyjnymi, aby szybko pokonywać zakręcone inwersje STR_0603 :Drewniana kolejka górska ze stalowymi torami pozwalającymi na strome zjazdy i inwersje -STR_0604 :Goście jadą pojedynczymi wagonikami po wąskim torze, ścigając się po ostrych zakrętach i zmianach kieruków. -STR_0605 :Saneczkarze zjeżdżają po wijącym się stalowym torze, hamując, aby kontrolować prędkość. +STR_0604 :Goście jadą pojedynczymi wagonikami po wąskim torze, ścigając się po ostrych zakrętach i zmianach kieruków +STR_0605 :Saneczkarze zjeżdżają po wijącym się stalowym torze, hamując, aby kontrolować prędkość +STR_0606 :Drewniana kolejka górska w starszym stylu, oferująca szybką i twardą jazdę z licznymi wzniesieniami i przeciążeniami bocznymi, co daje poczucie braku kontroli nad przejazdem +STR_0607 :Intensywna kolejka w starym stylu ze stalowymi torami, gdzie pasażerowie jadą na stojąco +STR_0608 :Kolejka górska, której wagoniki napędzane są synchronicznymi silnikami liniowymi, aby szybko pokonywać ciasne zakręty i inwersje STR_0767 :Gość {INT32} STR_0768 :Dozorca {INT32} STR_0769 :Mechanik {INT32} @@ -275,12 +281,12 @@ STR_0883 :Zapisz grę STR_0884 :Wczytaj krajobraz STR_0885 :Zapisz krajobraz STR_0887 :Wyjdź z edytora scenariuszy -STR_0888 :Wyjdź z Projektanta Kolejek -STR_0889 :Wyjdź z Menadżera Projektów Tras +STR_0888 :Wyjdź z projektanta kolejek +STR_0889 :Wyjdź z menadżera projektów tras STR_0891 :Zrzut ekranu STR_0892 :Zrzut ekranu zapisany jako „{STRINGID}” STR_0893 :Zrzut ekranu nieudany! -STR_0894 :Obszar danych krajobrazu jest pełny ! +STR_0894 :Obszar danych krajobrazu jest pełny! STR_0895 :Nie można wybudować częściowo nad i pod ziemią STR_0896 :{POP16}{POP16}{STRINGID} Budowanie STR_0897 :Kierunek @@ -295,7 +301,7 @@ STR_0905 :Zakręt w prawo (duży promień) STR_0906 :Prosto STR_0907 :Nachylenie STR_0908 :Nachylenie boczne -STR_0909 :Seat Rot. +STR_0909 :Obr. siedzenia STR_0910 :Nachylenie lewostronne STR_0911 :Nachylenie prawostronne STR_0912 :Prosto @@ -304,11 +310,11 @@ STR_0914 :Przejdź do następnego elementu STR_0915 :Wybuduj wybrany element STR_0916 :Usuń podświetlony element STR_0917 :Pionowo w dół -STR_0918 :Ostre w dół +STR_0918 :Ostro w dół STR_0919 :Zjazd w dół STR_0920 :Poziom STR_0921 :Podjazd w górę -STR_0922 :Ostre w górę +STR_0922 :Ostro w górę STR_0923 :Pionowo w górę STR_0924 :Spirala w dół STR_0925 :Spirala w górę @@ -420,7 +426,7 @@ STR_1031 :Nie można wybudować tego pod wodą! STR_1032 :Można wybudować to tylko na wodzie! STR_1033 :Można wybudować to tylko nad ziemią! STR_1034 :Można wybudować to tylko na ziemi! -STR_1035 :Władze lokalne zabraniają budowę ponad koronę drzew! +STR_1035 :Władze lokalne zabraniają budowy ponad koronę drzew! STR_1036 :Wczytaj grę STR_1037 :Wczytaj krajobraz STR_1038 :Przekonwertuj zapis gry do scenariusza @@ -437,7 +443,7 @@ STR_1048 :Zapis scenariusza nieudany! STR_1049 :Zapis krajobrazu nieudany! STR_1050 :Nie udało się wczytać…{NEWLINE}Plik zawiera błędne dane! STR_1051 :Przezroczyste wsporniki -STR_1052 :Przezroczyści ludzie +STR_1052 :Przezroczyści goście STR_1053 :Atrakcje w parku STR_1054 :Nazwy atrakcji STR_1055 :Nazwy osób @@ -456,7 +462,7 @@ STR_1067 :Start w górę STR_1068 :Tryb obrotowego podnoszenia STR_1069 :Tryb od stacji do stacji STR_1070 :Pojedynczy przejazd na wstęp -STR_1071 :Nieograniczone przejazdy za wstęp +STR_1071 :Nieograniczone przejazdy na wstęp STR_1072 :Tryb labiryntu STR_1073 :Tryb wyścigowy STR_1074 :Tryb zbijaków @@ -465,14 +471,14 @@ STR_1076 :Tryb stoiska sklepowego STR_1077 :Tryb obrotowy STR_1078 :Obroty do przodu STR_1079 :Obroty do tyłu -STR_1080 :Film: ”Mściwi lotnicy” -STR_1081 :3D film: ”Mysie ogonki” +STR_1080 :Film: „Mściwi lotnicy” +STR_1081 :Film 3D: „Mysie ogonki” STR_1082 :Tryb gwiezdnych pierścieni STR_1083 :Tryb początkującego -STR_1084 :LIM-powered launch -STR_1085 :Film: ”Thrill riders” -STR_1086 :3D film: ”Storm chasers” -STR_1087 :3D film: ”Kosmiczni jeźdźcy” +STR_1084 :Tryb napędu LIM +STR_1085 :Film: „Poszukiwacze mocnych wrażeń” +STR_1086 :Film 3D: „Łowcy burz” +STR_1087 :Film 3D: „Kosmiczni jeźdźcy” STR_1088 :Tryb intensywny STR_1089 :Tryb berserk STR_1090 :Tryb nawiedzonego domu @@ -482,7 +488,7 @@ STR_1093 :Tryb krzywego domu STR_1094 :Tryb wolnego spadku STR_1095 :Sekcyjny tryb pracy ciągłej STR_1096 :Rozpędzany start (bez przejeżdżania przez stację) -STR_1097 :Rozpędzany start zablokowany tryb sekcyjny +STR_1097 :Rozpędzany start w trybie sekcyjnym STR_1098 :Przemieszcza się na koniec {POP16}{STRINGID} STR_1099 :Oczekiwania na pasażerów w {POP16}{STRINGID} STR_1100 :Oczekuje na odjazd {POP16}{STRINGID} @@ -556,7 +562,7 @@ STR_1167 :Nie można tu podnieść poziomu wody… STR_1168 :Opcje STR_1169 :(Brak) STR_1170 :{STRING} -STR_1171 :{RED}Zamknięte - - +STR_1171 :{RED}Zamknięte STR_1172 :{YELLOW}{STRINGID} STR_1173 :Budowa chodników STR_1174 :Baner blokuje @@ -588,14 +594,14 @@ STR_1199 :{COMMA16} osoba korzysta STR_1200 :{COMMA16} osób korzysta STR_1201 :Kolejka pusta STR_1202 :1 osoba w kolejce -STR_1203 :{COMMA16} osób w kolejce +STR_1203 :{COMMA16} - liczba osób w kolejce STR_1204 :{COMMA16} minuta czekania STR_1205 :{COMMA16} minut czekania STR_1206 :{WINDOW_COLOUR_2}Czekaj na: STR_1207 :{WINDOW_COLOUR_2}Wyrusz, gdy inna kolejka trafi na tą samą stację STR_1208 :{WINDOW_COLOUR_2}Wyrusz, gdy inna łódka trafi na tą samą stację STR_1209 :Ustal, czy pojazdy powinny czekać na pasażerów przed wyruszeniem ze stacji -STR_1210 :Ustal, czy pojazdy powinny wyruszać ze stacj gdy tylko inny pojazd dotrze do tej samej stacji +STR_1210 :Ustal, czy pojazdy powinny wyruszać ze stacji gdy tylko inny pojazd dotrze do tej samej stacji STR_1211 :{WINDOW_COLOUR_2}Min. czas oczekiwania: STR_1212 :{WINDOW_COLOUR_2}Maks. czas oczekiwania: STR_1213 :Wybierz minimalny czas oczekiwania na stacji przed wyruszeniem @@ -720,9 +726,9 @@ STR_1331 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{VEL STR_1332 :{VELOCITY} STR_1333 :{STRINGID} - {STRINGID}{POP16} STR_1334 :{STRINGID} - {STRINGID} {COMMA16} -STR_1335 :{STRINGID} - Wjazd{POP16}{POP16} +STR_1335 :{STRINGID} - Wejście{POP16}{POP16} STR_1336 :{STRINGID} - Wjazd {POP16}{COMMA16} do stacji -STR_1337 :{STRINGID} - Opuszczanie{POP16}{POP16} +STR_1337 :{STRINGID} - Wyjście{POP16}{POP16} STR_1338 :{STRINGID} - Opuszczanie {POP16}{COMMA16} stacji STR_1339 :{BLACK}Oczekiwanie na rezultaty testu… STR_1340 :{WINDOW_COLOUR_2}Maks. prędkość: {BLACK}{VELOCITY} @@ -788,9 +794,9 @@ STR_1399 :Wykresy STR_1400 :Wejście STR_1401 :Wyjście STR_1402 :Wybuduj lub przesuń wejście do atrakcji -STR_1403 :Wybuduj lub przesuń wyjście z atrakcji -STR_1404 :Obrót o° -STR_1405 :Zdjęcie lustrzane +STR_1403 :Wybuduj lub przesuń wyjście z atrakcji +STR_1404 :Obrót o 90° +STR_1405 :Odbicie lustrzane STR_1406 :Włącz/wyłącz scenerię (jeśli dostępne w motywie) STR_1407 :{WINDOW_COLOUR_2}Wybuduj to… STR_1408 :{WINDOW_COLOUR_2}Koszt: {BLACK}{CURRENCY} @@ -841,13 +847,13 @@ STR_1452 :Imię gościa STR_1453 :Nowe imię dla gościa: STR_1454 :Nie można tak nazwać gościa… STR_1455 :Niewłaściwe imię dla gościa -STR_1456 :{WINDOW_COLOUR_2}Wydał: {BLACK}{CURRENCY2DP} -STR_1457 :{WINDOW_COLOUR_2}Pieniędzy w kieszeni: {BLACK}{CURRENCY2DP} +STR_1456 :{WINDOW_COLOUR_2}Wydane pieniądze: {BLACK}{CURRENCY2DP} +STR_1457 :{WINDOW_COLOUR_2}Posiadane pieniądze: {BLACK}{CURRENCY2DP} STR_1458 :{WINDOW_COLOUR_2}Czas w parku: {BLACK}{REALTIME} STR_1459 :Styl trasy STR_1460 :Otwarta trasa typu „U” STR_1461 :Zamknięta trasa typu „O” -STR_1462 :Too steep for lift hill +STR_1462 :Zbyt stromy podjazd na wyciągarkę STR_1463 :Goście STR_1464 :Spirala w górę (mała) STR_1465 :Spirala w górę (duża) @@ -865,131 +871,131 @@ STR_1476 :{WINDOW_COLOUR_2}Ocena intensywności: {BLACK}Jeszcze nie dostępna STR_1477 :{WINDOW_COLOUR_2}Ocena intensywności: {OUTLINE}{RED}{COMMA2DP32} ({STRINGID}) STR_1478 :{WINDOW_COLOUR_2}Ocena mdłości: {BLACK}{COMMA2DP32} ({STRINGID}) STR_1479 :{WINDOW_COLOUR_2}Ocena mdłości: {BLACK}Jeszcze nie dostępna -STR_1480 :“Nie mogę sobie pozwolić na {STRINGID}” -STR_1481 :“Wydałem wszystkie swoje pieniądze” -STR_1482 :“Niedobrze mi” -STR_1483 :“Zaraz zwymiotuję” -STR_1484 :“Chcę pójść na coś bardziej intensywnego niż {STRINGID}” -STR_1485 :“{STRINGID} wygląda zbyt intensywne dla mnie” -STR_1486 :“Nie skończyłem {STRINGID} jeszcze” -STR_1487 :“Od samego patrzenia na {STRINGID} robi mi się niedobrze” -STR_1488 :“Nie zapłacę tyle za {STRINGID}” -STR_1489 :“Chcę już do domu” -STR_1490 :“{STRINGID} ma naprawdę dobrą cenę” -STR_1491 :“Mam już {STRINGID}” -STR_1492 :“Nie mogę sobie pozwolić na {STRINGID}” -STR_1493 :“Nie jestem głodny” -STR_1494 :“Nie jestem spragniony” -STR_1495 :“Pomocy! Tonę!” -STR_1496 :“Zgubiłem się!” -STR_1497 :“Na atrakcji {STRINGID} było świetnie” -STR_1498 :“Czekam już wieki w kolejce na {STRINGID}” -STR_1499 :“Jestem zmęczony” -STR_1500 :“Jestem głodny” -STR_1501 :“Jestem spragniony” -STR_1502 :“Muszę do toalety” -STR_1503 :“Nie mogę znaleźć {STRINGID}” -STR_1504 :“Nie zapłacę tyle za {STRINGID}” -STR_1505 :“Nie pójdę na {STRINGID} dopóki pada” -STR_1506 :“Ścieżki tutaj są okropne” -STR_1507 :“Nie mogę znaleźć wyjścia z parku” -STR_1508 :“Muszę odpocząć od {STRINGID}” -STR_1509 :“Chcę już wyjść z {STRINGID}” -STR_1510 :“Nie pójdę na {STRINGID} - nie wygląda za bezpiecznie” -STR_1511 :“Ta ścieżka jest obrzydliwa” -STR_1512 :“Tutaj jest zdecydowanie za tłoczno” -STR_1513 :“Wandalizm stanowi tutaj duży problem” -STR_1514 :“Świetna sceneria!” -STR_1515 :“Ten park jest naprawdę czysty” -STR_1516 :“Ta skaczą fontanna jest świetna” -STR_1517 :“Leci tutaj miła muzyka” -STR_1518 :“Ten balon z {STRINGID} był naprawdę opłacalny” -STR_1519 :“Ta przytulanka z {STRINGID} była naprawdę opłacalna” -STR_1520 :“Ta mapa parku z {STRINGID} była naprawdę opłacalna” -STR_1521 :“To zdjęcie z przejazdu na {STRINGID} było naprawdę opłacalne” -STR_1522 :“Ta parasolka z {STRINGID} była naprawdę opłacalna” -STR_1523 :“Ten napój z {STRINGID} był naprawdę opłacalny” -STR_1524 :“Ten burger z {STRINGID} był naprawdę opłacalny” -STR_1525 :“Te frytki z {STRINGID} były naprawdę opłacalne” -STR_1526 :“Te lody z {STRINGID} były naprawdę opłacalne” -STR_1527 :“Ta wata cukrowa {STRINGID} była naprawdę opłacalna” +STR_1480 :„Nie mogę sobie pozwolić na {STRINGID}” +STR_1481 :„Wydałem wszystkie swoje pieniądze” +STR_1482 :„Niedobrze mi” +STR_1483 :„Zaraz zwymiotuję” +STR_1484 :„Chcę pójść na coś ciekawszego niż {STRINGID}” +STR_1485 :„{STRINGID} wygląda zbyt intensywne dla mnie” +STR_1486 :„Nie skończyłem jeszcze {STRINGID}” +STR_1487 :„{STRINGID} - od samego patrzenia robi mi się niedobrze” +STR_1488 :„Nie zapłacę tyle za {STRINGID}” +STR_1489 :„Chcę już do domu” +STR_1490 :„{STRINGID} ma naprawdę dobrą cenę” +STR_1491 :„Mam już {STRINGID}” +STR_1492 :„Nie mogę sobie pozwolić na {STRINGID}” +STR_1493 :„Nie chce mi się jeść” +STR_1494 :„Nie chce mi się pić” +STR_1495 :„Pomocy! Tonę!” +STR_1496 :„Zgubiłem się!” +STR_1497 :„Na atrakcji {STRINGID} było świetnie” +STR_1498 :„{STRINGID}… Już wieki stoję w kolejce do tej atrakcji” +STR_1499 :„Opadam z sił” +STR_1500 :„Chce mi się jeść” +STR_1501 :„Chce mi się pić” +STR_1502 :„Muszę do łazienki” +STR_1503 :„Nie mogę znaleźć {STRINGID}” +STR_1504 :„Nie zapłacę tyle za {STRINGID}” +STR_1505 :„Nie pójdę na {STRINGID} dopóki pada” +STR_1506 :„Ścieżki tutaj są okropne” +STR_1507 :„Nie mogę znaleźć wyjścia z parku” +STR_1508 :„Muszę odpocząć od {STRINGID}” +STR_1509 :„Chcę już wyjść z {STRINGID}” +STR_1510 :„Nie pójdę na {STRINGID} - nie wygląda za bezpiecznie” +STR_1511 :„Ta ścieżka jest obrzydliwa” +STR_1512 :„Tutaj jest zdecydowanie za tłoczno” +STR_1513 :„Wandalizm stanowi tutaj duży problem” +STR_1514 :„Wspaniały krajobraz!” +STR_1515 :„W tym parku jest naprawdę czysto i porządnie” +STR_1516 :„Ta skacząca fontanna jest świetna” +STR_1517 :„Leci tutaj miła muzyka” +STR_1518 :„Ten balon z {STRINGID} był naprawdę opłacalny” +STR_1519 :„Ta przytulanka z {STRINGID} była naprawdę opłacalna” +STR_1520 :„Ta mapa parku z {STRINGID} była naprawdę opłacalna” +STR_1521 :„To zdjęcie z przejazdu na {STRINGID} było naprawdę opłacalne” +STR_1522 :„Ta parasolka z {STRINGID} była naprawdę opłacalna” +STR_1523 :„Ten napój z {STRINGID} był naprawdę opłacalny” +STR_1524 :„Ten burger z {STRINGID} był naprawdę opłacalny” +STR_1525 :„Te frytki z {STRINGID} były naprawdę opłacalne” +STR_1526 :„Te lody z {STRINGID} były naprawdę opłacalne” +STR_1527 :„Ta wata cukrowa {STRINGID} była naprawdę opłacalna” STR_1528 : STR_1529 : STR_1530 : -STR_1531 :“Ta pizza z {STRINGID} była naprawdę opłacalna” +STR_1531 :„Ta pizza z {STRINGID} była naprawdę opłacalna” STR_1532 : -STR_1533 :“Ten popcorn z {STRINGID} był naprawdę opłacalny” -STR_1534 :“Ten hotdog z {STRINGID} był naprawdę opłacalny” -STR_1535 :“Ta ośmiorniczka z {STRINGID} była naprawdę opłacalna” -STR_1536 :“Ten kapelusz {STRINGID} był naprawdę opłacalny” -STR_1537 :“To kandyzowane jabłko z {STRINGID} było naprawdę opłacalne” -STR_1538 :“Ten t-shirt z {STRINGID} był naprawdę opłacalny” -STR_1539 :“Ten pączek z {STRINGID} był naprawdę opłacalny” -STR_1540 :“Ta kawa z {STRINGID} była naprawdę opłacalna” +STR_1533 :„Ten popcorn z {STRINGID} był naprawdę opłacalny” +STR_1534 :„Ten hotdog z {STRINGID} był naprawdę opłacalny” +STR_1535 :„Ta ośmiorniczka z {STRINGID} była naprawdę opłacalna” +STR_1536 :„Ten kapelusz {STRINGID} był naprawdę opłacalny” +STR_1537 :„To kandyzowane jabłko z {STRINGID} było naprawdę opłacalne” +STR_1538 :„Ten t-shirt z {STRINGID} był naprawdę opłacalny” +STR_1539 :„Ten pączek z {STRINGID} był naprawdę opłacalny” +STR_1540 :„Ta kawa z {STRINGID} była naprawdę opłacalna” STR_1541 : -STR_1542 :“Ten smażony kurczak z {STRINGID} był naprawdę opłacalny” -STR_1543 :“Ta lemoniada z {STRINGID} była naprawdę opłacalna” +STR_1542 :„Ten smażony kurczak z {STRINGID} był naprawdę opłacalny” +STR_1543 :„Ta lemoniada z {STRINGID} była naprawdę opłacalna” STR_1544 : STR_1545 : STR_1546 : STR_1547 : STR_1548 : STR_1549 : -STR_1550 :“Świetnie!” -STR_1551 :“Mam dziwne uczucie jakby mnie ktoś podglądał” -STR_1552 :“Nie zapłacę tyle za balona z {STRINGID}” -STR_1553 :“Nie zapłacę tyle za przytulankę z {STRINGID}” -STR_1554 :“Nie zapłacę tyle za mapę parku z {STRINGID}” -STR_1555 :“Nie zapłacę tyle za zdjęcie z przejażdżki z {STRINGID}” -STR_1556 :“Nie zapłacę tyle za parasol z {STRINGID}” -STR_1557 :“Nie zapłacę tyle za napój z {STRINGID}” -STR_1558 :“Nie zapłacę tyle za burgera z {STRINGID}” -STR_1559 :“Nie zapłacę tyle za frytki z {STRINGID}” -STR_1560 :“Nie zapłacę tyle za lody z {STRINGID}” -STR_1561 :“Nie zapłacę tyle za watę cukrową z {STRINGID}” +STR_1550 :„Świetnie!” +STR_1551 :„Mam dziwne uczucie jakby mnie ktoś podglądał” +STR_1552 :„Nie zapłacę tyle za balona z {STRINGID}” +STR_1553 :„Nie zapłacę tyle za przytulankę z {STRINGID}” +STR_1554 :„Nie zapłacę tyle za mapę parku z {STRINGID}” +STR_1555 :„Nie zapłacę tyle za zdjęcie z przejażdżki z {STRINGID}” +STR_1556 :„Nie zapłacę tyle za parasol z {STRINGID}” +STR_1557 :„Nie zapłacę tyle za napój z {STRINGID}” +STR_1558 :„Nie zapłacę tyle za burgera z {STRINGID}” +STR_1559 :„Nie zapłacę tyle za frytki z {STRINGID}” +STR_1560 :„Nie zapłacę tyle za lody z {STRINGID}” +STR_1561 :„Nie zapłacę tyle za watę cukrową z {STRINGID}” STR_1562 : STR_1563 : STR_1564 : -STR_1565 :“Nie zapłacę tyle za pizzę z {STRINGID}” +STR_1565 :„Nie zapłacę tyle za pizzę z {STRINGID}” STR_1566 : -STR_1567 :“Nie zapłacę tyle za popcorn z {STRINGID}” -STR_1568 :“Nie zapłacę tyle za hotdoga z {STRINGID}” -STR_1569 :“Nie zapłacę tyle za ośmiorniczkę z {STRINGID}” -STR_1570 :“Nie zapłacę tyle za kapelusz z {STRINGID}” -STR_1571 :“Nie zapłacę tyle za kandyzowane jabłko z {STRINGID}” -STR_1572 :“Nie zapłacę tyle za koszulkę z {STRINGID}” -STR_1573 :“Nie zapłacę tyle za pączka z {STRINGID}” -STR_1574 :“Nie zapłacę tyle za kawę z {STRINGID}” +STR_1567 :„Nie zapłacę tyle za popcorn z {STRINGID}” +STR_1568 :„Nie zapłacę tyle za hotdoga z {STRINGID}” +STR_1569 :„Nie zapłacę tyle za ośmiorniczkę z {STRINGID}” +STR_1570 :„Nie zapłacę tyle za kapelusz z {STRINGID}” +STR_1571 :„Nie zapłacę tyle za kandyzowane jabłko z {STRINGID}” +STR_1572 :„Nie zapłacę tyle za koszulkę z {STRINGID}” +STR_1573 :„Nie zapłacę tyle za pączka z {STRINGID}” +STR_1574 :„Nie zapłacę tyle za kawę z {STRINGID}” STR_1575 : -STR_1576 :“Nie zapłacę tyle za kurczaka z {STRINGID}” -STR_1577 :“Nie zapłacę tyle za lemoniadę z {STRINGID}” +STR_1576 :„Nie zapłacę tyle za kurczaka z {STRINGID}” +STR_1577 :„Nie zapłacę tyle za lemoniadę z {STRINGID}” STR_1578 : STR_1579 : STR_1580 : STR_1581 : STR_1582 : STR_1583 : -STR_1584 :“To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” -STR_1585 :“To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” -STR_1586 :“To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” -STR_1587 :“Ten precel z {STRINGID} był naprawdę opłacalny” -STR_1588 :“Ta gorąca czekolada z {STRINGID} była naprawdę opłacalna” -STR_1589 :“Ta mrożona herbata z {STRINGID} była naprawdę opłacalna” -STR_1590 :“Ten precel z {STRINGID} był naprawdę opłacalny” -STR_1591 :“Te okulary przeciwsłoneczne z {STRINGID} były naprawdę opłacalne” -STR_1592 :“Ten makaron z wołowiną z {STRINGID} był naprawdę opłacalny” -STR_1593 :“Ten smażony makaron z {STRINGID} był naprawdę opłacalny” -STR_1594 :“Ta zupa wonton z {STRINGID} była naprawdę opłacalna” -STR_1595 :“Ta zupa z klopsikami z {STRINGID} była naprawdę opłacalna” -STR_1596 :“Ten sok owocowy z {STRINGID} był naprawdę opłacalny” -STR_1597 :“Te mleko sojowe z {STRINGID} było naprawdę opłacalne” -STR_1598 :“Ta sujongkwa z {STRINGID} była naprawdę opłacalna” -STR_1599 :“Ta kanapka z {STRINGID} była naprawdę opłacalna” -STR_1600 :“To ciasteczko z {STRINGID} było naprawdę opłacalne” +STR_1584 :„To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” +STR_1585 :„To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” +STR_1586 :„To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” +STR_1587 :„Ten precel z {STRINGID} był naprawdę opłacalny” +STR_1588 :„Ta gorąca czekolada z {STRINGID} była naprawdę opłacalna” +STR_1589 :„Ta mrożona herbata z {STRINGID} była naprawdę opłacalna” +STR_1590 :„Ten precel z {STRINGID} był naprawdę opłacalny” +STR_1591 :„Te okulary przeciwsłoneczne z {STRINGID} były naprawdę opłacalne” +STR_1592 :„Ten makaron z wołowiną z {STRINGID} był naprawdę opłacalny” +STR_1593 :„Ten smażony makaron z {STRINGID} był naprawdę opłacalny” +STR_1594 :„Ta zupa wonton z {STRINGID} była naprawdę opłacalna” +STR_1595 :„Ta zupa z klopsikami z {STRINGID} była naprawdę opłacalna” +STR_1596 :„Ten sok owocowy z {STRINGID} był naprawdę opłacalny” +STR_1597 :„Te mleko sojowe z {STRINGID} było naprawdę opłacalne” +STR_1598 :„Ta sujongkwa z {STRINGID} była naprawdę opłacalna” +STR_1599 :„Ta kanapka z {STRINGID} była naprawdę opłacalna” +STR_1600 :„To ciasteczko z {STRINGID} było naprawdę opłacalne” STR_1601 : STR_1602 : STR_1603 : -STR_1604 :“Ta grillowana kiełbasa z {STRINGID} była naprawdę opłacalna” +STR_1604 :„Ta grillowana kiełbasa z {STRINGID} była naprawdę opłacalna” STR_1605 : STR_1606 : STR_1607 : @@ -1001,27 +1007,27 @@ STR_1612 : STR_1613 : STR_1614 : STR_1615 : -STR_1616 :“Nie zapłacę tyle za zdjęcie z przejażdżki na {STRINGID}” -STR_1617 :“Nie zapłacę tyle za zdjęcie z przejażdżki na {STRINGID}” -STR_1618 :“Nie zapłacę tyle za zdjęcie z przejażdżki na {STRINGID}” -STR_1619 :“Nie zapłacę tyle za precla z {STRINGID}” -STR_1620 :“Nie zapłacę tyle za gorącą czekoladę z {STRINGID}” -STR_1621 :“Nie zapłacę tyle za mrożoną herbatę z {STRINGID}” -STR_1622 :“Nie zapłacę tyle za chrusta z {STRINGID}” -STR_1623 :“Nie zapłacę tyle za okulary przeciwsłoneczne z {STRINGID}” -STR_1624 :“Nie zapłacę tyle za makaron z wołowiną z {STRINGID}” -STR_1625 :“Nie zapłacę tyle za smażony makaron ryżowy z {STRINGID}” -STR_1626 :“Nie zapłacę tyle za zupę wonton z {STRINGID}” -STR_1627 :“Nie zapłacę tyle za zupę z klopsikami z {STRINGID}” -STR_1628 :“Nie zapłacę tyle za sok owocowy z {STRINGID}” -STR_1629 :“Nie zapłacę tyle za mleko sojowe z {STRINGID}” -STR_1630 :“Nie zapłacę tyle za sujongkwa z {STRINGID}” -STR_1631 :“Nie zapłacę tyle za kanapkę z {STRINGID}” -STR_1632 :“Nie zapłacę tyle za ciasteczko z {STRINGID}” +STR_1616 :„Nie zapłacę tyle za zdjęcie z przejażdżki na {STRINGID}” +STR_1617 :„Nie zapłacę tyle za zdjęcie z przejażdżki na {STRINGID}” +STR_1618 :„Nie zapłacę tyle za zdjęcie z przejażdżki na {STRINGID}” +STR_1619 :„Nie zapłacę tyle za precla z {STRINGID}” +STR_1620 :„Nie zapłacę tyle za gorącą czekoladę z {STRINGID}” +STR_1621 :„Nie zapłacę tyle za mrożoną herbatę z {STRINGID}” +STR_1622 :„Nie zapłacę tyle za chrusta z {STRINGID}” +STR_1623 :„Nie zapłacę tyle za okulary przeciwsłoneczne z {STRINGID}” +STR_1624 :„Nie zapłacę tyle za makaron z wołowiną z {STRINGID}” +STR_1625 :„Nie zapłacę tyle za smażony makaron ryżowy z {STRINGID}” +STR_1626 :„Nie zapłacę tyle za zupę wonton z {STRINGID}” +STR_1627 :„Nie zapłacę tyle za zupę z klopsikami z {STRINGID}” +STR_1628 :„Nie zapłacę tyle za sok owocowy z {STRINGID}” +STR_1629 :„Nie zapłacę tyle za mleko sojowe z {STRINGID}” +STR_1630 :„Nie zapłacę tyle za sujongkwa z {STRINGID}” +STR_1631 :„Nie zapłacę tyle za kanapkę z {STRINGID}” +STR_1632 :„Nie zapłacę tyle za ciasteczko z {STRINGID}” STR_1633 : STR_1634 : STR_1635 : -STR_1636 :“Nie zapłacę tyle za grillowaną kiełbasę z {RINGID}” +STR_1636 :„Nie zapłacę tyle za grillowaną kiełbasę z {RINGID}” STR_1637 : STR_1638 : STR_1639 : @@ -1033,10 +1039,10 @@ STR_1644 : STR_1645 : STR_1646 : STR_1647 : -STR_1648 :“Pomocy! Puść mnie!” -STR_1649 :“Kończą mi się pieniądze!” -STR_1650 :“Świetnie! Budują nową atrakcję!” -STR_1653 :“…i teraz jesteśmy na {STRINGID}!” +STR_1648 :„Pomocy! Puść mnie!” +STR_1649 :„Kończą mi się pieniądze!” +STR_1650 :„Świetnie! Budują nową atrakcję!” +STR_1653 :„…i teraz jesteśmy na {STRINGID}!” STR_1654 :{WINDOW_COLOUR_2}Ostatnie myśli: STR_1655 :Buduj ścieżki na ziemi STR_1656 :Buduj ścieżki w powietrzu lub pod ziemią @@ -1056,7 +1062,7 @@ STR_1669 :{WINDOW_COLOUR_2}Zadowolenie: {BLACK}{COMMA16}% STR_1670 :{WINDOW_COLOUR_2}Wszystkich klientów: {BLACK}{COMMA32} STR_1671 :{WINDOW_COLOUR_2}Całkowity zysk: {BLACK}{CURRENCY2DP} STR_1672 :Hamulce -STR_1673 :Spinning Control Toggle Track +STR_1673 :Tor opcji blokowania obrotów STR_1674 :Prędkość hamowania STR_1675 :{POP16}{VELOCITY} STR_1676 :Ustaw limit prędkości hamowania @@ -1094,7 +1100,7 @@ STR_1707 :Za dużo pracowników w grze STR_1708 :Wyznacz teren patrolowania dla pracownika STR_1709 :Zwolnij pracownika STR_1710 :Tak -STR_1711 :{WINDOW_COLOUR_1}Czy jesteś pewny że chcesz zwolnić {STRINGID}? +STR_1711 :{WINDOW_COLOUR_1}Jesteś pewien, że chcesz zwolnić {STRINGID}? STR_1712 :{INLINE_SPRITE}{247}{19}{00}{00}{WINDOW_COLOUR_2}Zamiatanie ścieżek STR_1713 :{INLINE_SPRITE}{248}{19}{00}{00}{WINDOW_COLOUR_2}Podlewanie kwiatów STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}Opróżnianie kubłów @@ -1113,7 +1119,7 @@ STR_1726 :Teren nie jest na sprzedaż! STR_1727 :Prawa do budowy nie są na sprzedaż! STR_1728 :Nie można tu kupić praw do budowy… STR_1729 :Teren nie należy do parku! -STR_1730 :{RED}Zamknięte - - +STR_1730 :{RED}Zamknięte STR_1731 :{WHITE}{STRINGID} - - STR_1732 :Buduj STR_1733 :Tryb @@ -1143,7 +1149,7 @@ STR_1759 :Tryb przenoszenia STR_1760 :Tryb wypełnienia STR_1761 :Buduj labirynt w tym kierunku STR_1762 :Wodospady -STR_1763 :Katarakty rzeczne +STR_1763 :Przełomy Dunajca STR_1764 :Pniowe odbijaki STR_1765 :Sekcja fotograficzna STR_1766 :Odwrotna obrotnica @@ -1398,7 +1404,7 @@ STR_2023 :Frytki STR_2024 :Lody STR_2025 :Wata cukrowa STR_2026 :Puste puszki -STR_2027 :Śmiecie +STR_2027 :Śmieci STR_2028 :Puste pudełka po hamburgerach STR_2029 :Pizze STR_2030 :Kupony @@ -1443,11 +1449,11 @@ STR_2068 :Kurczak STR_2069 :trochę lemoniady STR_2070 :puste pudełko STR_2071 :pustą butelkę -STR_2072 :“{STRINGID}” Balon -STR_2073 :“{STRINGID}” Przytulanka +STR_2072 :Balon {STRINGID} +STR_2073 :Przytulanka {STRINGID} STR_2074 :Plan {STRINGID} -STR_2075 :Zdjęcie z przejażdżki {STRINGID} -STR_2076 :“{STRINGID}” Parasol +STR_2075 :Zdjęcie z przejażdżki na {STRINGID} +STR_2076 :Parasol {STRINGID} STR_2077 :Napój STR_2078 :Hamburger STR_2079 :Frytki @@ -1461,9 +1467,9 @@ STR_2086 :Kupon na {STRINGID} STR_2087 :Popcorn STR_2088 :Hot Dog STR_2089 :Ośmiorniczka -STR_2090 :“{STRINGID}” Kapelusz -STR_2091 :jabłko kandyzowane -STR_2092 :“{STRINGID}” Koszulka +STR_2090 :Kapelusz {STRINGID} +STR_2091 :Jabłko kandyzowane +STR_2092 :Koszulka {STRINGID} STR_2093 :Pączek STR_2094 :Kawa STR_2095 :Pusty kubek @@ -1651,15 +1657,15 @@ STR_2292 :{WINDOW_COLOUR_2}Odwiedzone atrakcje: STR_2293 :{BLACK} Brak STR_2294 :Zmień podstawowy styl gruntu STR_2295 :Zmień poziome krawędzie gruntu -STR_2296 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na wejście do parku -STR_2297 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} atrakcję -STR_2298 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} atrakcji -STR_2299 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} posiłek -STR_2300 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} posiłków -STR_2301 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} napój -STR_2302 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} napojów -STR_2303 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} pamiatkę -STR_2304 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} wydane na {BLACK}{COMMA16} pamiątek +STR_2296 :{BLACK}Zapłacił {CURRENCY2DP}{WINDOW_COLOUR_2} za wejście do parku +STR_2297 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} atrakcję +STR_2298 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} atrakcji +STR_2299 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} posiłek +STR_2300 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} posiłki +STR_2301 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} napój +STR_2302 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} napoje +STR_2303 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} pamiatkę +STR_2304 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} pamiątki STR_2305 :Plik z projektami tras STR_2306 :Zapisz projekt trasy STR_2307 :Wybierz projekt {STRINGID} @@ -1824,7 +1830,7 @@ STR_2482 :Zysk: {CURRENCY} na tydzień, Wartość parku: {CURRENCY} STR_2483 :{WINDOW_COLOUR_2}Tygodniowy zysk: {BLACK}+{CURRENCY2DP} STR_2484 :{WINDOW_COLOUR_2}Tygodniowy zysk: {RED}{CURRENCY2DP} STR_2487 :Pokazuj „prawdziwe” imiona gości -STR_2488 :Przełącza między pokazywaniem imion gości a numerami +STR_2488 :Przełącz między pokazywaniem imion gości a numerami STR_2489 :Skróty klawiszowe… STR_2490 :Przypisanie klawiszy STR_2491 :Zresetuj klawisze @@ -1843,7 +1849,7 @@ STR_2503 :Usuń grunt pionowy STR_2504 :Przezroczyste atrakcje STR_2505 :Przezroczysta sceneria STR_2506 :Niewidzialne sporniki -STR_2507 :Niewidzialni ludzie +STR_2507 :Niewidzialni goście STR_2508 :Znaczniki wysokości na gruncie STR_2509 :Znaczniki wysokości na torach STR_2510 :Znaczniki wysokości na dróżkach @@ -1905,9 +1911,9 @@ STR_2669 :NumLock STR_2670 :Scroll STR_2680 :Wszystkie badania zakończone STR_2684 :Przybywające duże grupy gości -STR_2685 :Parametr hałasu Simplex -STR_2686 :Najniższy: -STR_2687 :Najwyższy: +STR_2685 :Parametry szumu Simplex +STR_2686 :Min. poziom terenu: +STR_2687 :Maks. poziom terenu: STR_2688 :Bazowa częstotliwość: STR_2689 :Oktawy STR_2690 :Generator mapy @@ -1980,7 +1986,7 @@ STR_2781 :{STRINGID}: STR_2782 :SHIFT + STR_2783 :CTRL + STR_2784 :Zmień skrót klawiszowy -STR_2785 :{WINDOW_COLOUR_2}Wciśnij nowy klawisz skrótu dla:{NEWLINE}“{STRINGID}” +STR_2785 :{WINDOW_COLOUR_2}Wciśnij nowy klawisz skrótu dla:{NEWLINE}„{STRINGID}” STR_2786 :Kliknij opis skrótu, aby wybrać nowy klawisz STR_2787 :{WINDOW_COLOUR_2}Wartość parku: {BLACK}{CURRENCY} STR_2788 :{WINDOW_COLOUR_2}Gratulacje!{NEWLINE}{BLACK}Cel osiągnięty! Wartość twojej spółki wynosi {CURRENCY}! @@ -2007,12 +2013,12 @@ STR_2808 :{RED}Goście skarzą się na wandalizm w twoim parku{NEWLINE}Sprawd STR_2809 :{RED}Goście są głodni i nie mogą znaleźć miejsca gdzie mogliby kupić coś do jedzenia STR_2810 :{RED}Goście są spragnieni i nie mogą znaleźć miejsca gdzie mogliby kupić jakieś napoje STR_2811 :{RED}Goście się skarżą, że w twoim parku bardzo ciężko jest znaleźć toaletę -STR_2812 :{RED}Goście gubią się lub zatrzymują w jednym miejscu{NEWLINE}Sprawdź czy nie należy zmienić rozplanowania ścieżek, aby ludzie poruszali się po parku z większą łatwością +STR_2812 :{RED}Goście gubią się lub zatrzymują w jednym miejscu{NEWLINE}Sprawdź czy nie należy zmienić rozplanowania ścieżek, aby goście poruszali się po parku z większą łatwością STR_2813 :{RED}Opłata za wstęp do twojego parku jest zbyt wysoka!{NEWLINE}Zmniejsz ją lub podnieś wartość parku, aby przyciągnąć większą liczbę gości STR_2814 :{WINDOW_COLOUR_2}Nagroda dla najbardziej zaśmieconego parku STR_2815 :{WINDOW_COLOUR_2}Nagroda dla najczystszego parku -STR_2816 :{WINDOW_COLOUR_2}Nagroda za najlepsze kolejki górskie -STR_2817 :{WINDOW_COLOUR_2}Nagroda dla parku o najwyższej wartości +STR_2816 :{WINDOW_COLOUR_2}Nagroda dla parku z najlepszymi kolejkami górskimi +STR_2817 :{WINDOW_COLOUR_2}Nagroda dla parku o najlepszej wartości STR_2818 :{WINDOW_COLOUR_2}Nagroda dla najpiękniejszego parku STR_2819 :{WINDOW_COLOUR_2}Nagroda dla parku o najniższej wartości STR_2820 :{WINDOW_COLOUR_2}Nagroda dla najbezpieczniejszego parku @@ -2020,18 +2026,18 @@ STR_2821 :{WINDOW_COLOUR_2}Nagroda za najlepszy personel STR_2822 :{WINDOW_COLOUR_2}Nagroda za najlepsze jedzenie STR_2823 :{WINDOW_COLOUR_2}Nagroda za najgorsze jedzenie STR_2824 :{WINDOW_COLOUR_2}Nagroda za najlepsze toalety -STR_2825 :{WINDOW_COLOUR_2}Nagroda za najbardziej rozczarowującego parku +STR_2825 :{WINDOW_COLOUR_2}Nagroda za najbardziej rozczarowujący park STR_2826 :{WINDOW_COLOUR_2}Nagroda za najlepsze atrakcje wodne -STR_2827 :{WINDOW_COLOUR_2}Nagroda za najlepsze atrakcje współczesnego parku +STR_2827 :{WINDOW_COLOUR_2}Nagroda za najlepsze atrakcje własnego projektu STR_2828 :{WINDOW_COLOUR_2}Nagroda za najbardziej oszałamiającą kolorystykę atrakcji -STR_2829 :{WINDOW_COLOUR_2}Nagroda za najbardziej niezrozumiałego planu parku +STR_2829 :{WINDOW_COLOUR_2}Nagroda za najbardziej niezrozumiały plan parku STR_2830 :{WINDOW_COLOUR_2}Nagroda za najlepsze łagodne atrakcje STR_2831 :{TOPAZ}Twój park został ogłoszony najbardziej zaśmieconym parkiem w kraju! STR_2832 :{TOPAZ}Twój park został ogłoszony najczystszym parkiem w kraju! STR_2833 :{TOPAZ}Twój park dostał nagrodę za najlepsze kolejki górskie! -STR_2834 :{TOPAZ}Twój park dostał nagrodę za najwyższą wartość w kraju! +STR_2834 :{TOPAZ}Twój park dostał nagrodę za najlepszą wartość w kraju! STR_2835 :{TOPAZ}Twój park został ogłoszony najpiękniejszym parkiem w kraju! -STR_2836 :{TOPAZ}Twój park otrzymał nagrodę za najniższą wartość w kraju! +STR_2836 :{TOPAZ}Twój park otrzymał nagrodę za najgorszą wartość w kraju! STR_2837 :{TOPAZ}Twój park otrzymał nagrodę za najwyższe bezpieczeństwo w kraju! STR_2838 :{TOPAZ}Twój park otrzymał nagrodę za najlepszy personel! STR_2839 :{TOPAZ}Twój park otrzymał nagrodę za najlepsze jedzenie w kraju! @@ -2063,7 +2069,7 @@ STR_2977 :Nazwa pracownika STR_2978 :Wprowadź nazwę tego pracownika: STR_2979 :Nie można zmienić nazwy pracownika… STR_2980 :Za dużo banerów w grze -STR_2981 :{RED}Brak wejścia - - +STR_2981 :{RED}Brak wejścia STR_2982 :Tekst baneru STR_2983 :Wprowadź nową treść baneru: STR_2984 :Nie można wprowadzić nowej treści baneru… @@ -2112,7 +2118,7 @@ STR_3063 :Kanał wodny (tor zanurzony) STR_3064 :Poziom początkujący STR_3065 :Poziom zaawansowany STR_3066 :Poziom eksperta -STR_3067 :“Prawdziwe” parki +STR_3067 :„Prawdziwe” parki STR_3068 :Inne parki STR_3069 :Część górna STR_3070 :Spadek do poziomu @@ -2157,11 +2163,11 @@ STR_3121 :Nie udało się znaleźć mechanika lub wszyscy mechanicy w okolicy STR_3122 :{WINDOW_COLOUR_2}Ulubiona atrakcja: {BLACK}{COMMA32} gości STR_3123 :{WINDOW_COLOUR_2}Ulubiona atrakcja: {BLACK}{COMMA32} gości STR_3124 :Zepsute: {STRINGID} -STR_3125 :{WINDOW_COLOUR_2}Emocje: {BLACK}+{COMMA16}% -STR_3126 :{WINDOW_COLOUR_2}Intensywność: {BLACK}+{COMMA16}% -STR_3127 :{WINDOW_COLOUR_2}Tolerancja mdłości: {BLACK}+{COMMA16}% -STR_3128 :Zapisz Projekt Trasy -STR_3129 :Zapisz Projekt Trasy ze Scenerią +STR_3125 :{WINDOW_COLOUR_2}Czynnik ekscytacji: {BLACK}+{COMMA16}% +STR_3126 :{WINDOW_COLOUR_2}Czynnik intensywności: {BLACK}+{COMMA16}% +STR_3127 :{WINDOW_COLOUR_2}Czynnik mdłości: {BLACK}+{COMMA16}% +STR_3128 :Zapisz projekt trasy +STR_3129 :Zapisz projekt trasy ze scenerią STR_3130 :Zapisz STR_3131 :Anuluj STR_3132 :{BLACK}Wybierz elementy scenerii które chcesz zapisać z projektem trasy… @@ -2176,7 +2182,7 @@ STR_3140 :Wyciągarka musi znajdować się na początku trasy STR_3141 :Wielokrotne pętle nie są dostępne w parze z wyciągarką STR_3142 :{WINDOW_COLOUR_2}Pojemność: {BLACK}{STRINGID} STR_3143 :Pokaż ludzi -STR_3144 :Pokaż przejażdżki i stoiska +STR_3144 :Pokaż atrakcje i stoiska STR_3160 :Wybierz liczbę obrotów na przejażdzkę STR_3162 :Nie można zaalokować odpowiedniej ilości pamięci STR_3163 :Instalowanie nowych danych: @@ -2187,12 +2193,12 @@ STR_3170 :Brak odpowiedniej ilości pamięci na grafikę STR_3171 :Wybrano za dużo elementów danego typu STR_3172 :Następujący obiekt musi zostać wybrany najpierw: {STRING} STR_3173 :Ten obiekt jest aktualnie w użyciu -STR_3174 :Ten obiekt jest wymagany przez inny użyty +STR_3174 :Ten obiekt jest wymagany przez inny obiekt STR_3175 :Ten obiekt jest zawsze wymagany STR_3176 :Nie można wybrać tego obiektu STR_3177 :Nie można odznaczyć tego obiektu STR_3179 :Przynajmniej jedna atrakcja musi zostać wybrana -STR_3180 :Nieprawidłowy wybór obiektu +STR_3180 :Nieprawidłowy wybór obiektów STR_3181 :Wybór obiektu - {STRINGID} STR_3182 :Wejście do parku musi zostać wybrane STR_3183 :Rodzaj wody musi zostać wybrany @@ -2240,9 +2246,9 @@ STR_3225 :Włącz / Wyłącz budowę losowego klastra obiektów wokół wybra STR_3226 :Zbuduj wejście do parku STR_3227 :Za dużo wejść do parku! STR_3228 :Ustaw początkowe rozmieszczenie ludzi -STR_3229 :Hamulce tarczowe nie mogą znajdować się bezpośrednio za stacją -STR_3230 :Hamulce tarczowe nie mogą znajdować się bezpośrednio za sobą -STR_3231 :Hamulce tarczowe nie mogą znajdować się bezpośrednio za szczytem wzniesienia z wyciągarki +STR_3229 :Hamulce blokowe nie mogą znajdować się bezpośrednio za stacją +STR_3230 :Hamulce blokowe nie mogą znajdować się bezpośrednio jeden po drugim +STR_3231 :Hamulce blokowe nie mogą znajdować się bezpośrednio za szczytem wzniesienia z wyciągarki STR_3232 :Opcje - Finanse STR_3233 :Opcje - Goście STR_3234 :Opcje - Park @@ -2343,8 +2349,8 @@ STR_3331 :Ścieżka od wejścia do parku do krawędzi mapy jest albo niekompl STR_3332 :Wejście do parku jest nieprawidłowe lub nie ma ścieżki prowadzącej do krawędzi mapy STR_3333 :Eksportuj elementy dodatkowe do zapisów gier STR_3334 :Wybierz, czy chcesz zapisać wymagane wtyczki (te, które nie są dołączone do produktu głównego) w zapisanych plikach gry lub scenariuszu, co pozwoli na ich załadowanie przez kogoś, kto nie posiada dodatkowych plików -STR_3335 :Projektant Tras - Wybierz rodzaj trasy i pojazdu -STR_3336 :Menadżer Projektanta Tras - Wybierz rodzaj przejazdu +STR_3335 :Projektant tras - Wybierz rodzaj trasy i pojazdu +STR_3336 :Menadżer projektanta tras - Wybierz rodzaj przejazdu STR_3338 :{BLACK}Własny projekt STR_3339 :{BLACK}{COMMA16} projekt dostępny, możliwość stworzenia własnego STR_3340 :{BLACK}{COMMA16} projekty dostępne, możliwość stworzenia własnego @@ -2405,7 +2411,7 @@ STR_5122 :Wybierz atrakcje po typie (jak w RCT1) STR_5123 :Odnów atrakcje STR_5125 :Wszystko zniszczalne STR_5126 :Losowa muzyka tytułowa -STR_5127 :Podczas przenoszenia, zmieniaj krajobraz zamiast zmieniać wysokość +STR_5127 :Podczas przeciągania, zmieniaj krajobraz zamiast zmieniać wysokość STR_5128 :Rozmiar zaznaczenia STR_5129 :Wybierz wielkość zaznaczenia pomiędzy {COMMA16} a {COMMA16} STR_5130 :Rozmiar mapy @@ -2450,7 +2456,7 @@ STR_5182 :{INT32} STR_5183 :Wysokość bazowa STR_5184 :Wprowadź bazową wysokość pomiędzy {COMMA16} a {COMMA16} STR_5185 :Poziom wody -STR_5186 :Wprowadź poziom wody pomiędzy {COMMA16} a {COMMA16} +STR_5186 :Wprowadź poziom wody pomiędzy {COMMA16} a {COMMA16} STR_5187 :Finanse STR_5188 :Nowa kampania STR_5189 :Badania @@ -2543,9 +2549,9 @@ STR_5278 :Tryb piaskownicy STR_5279 :Tryb piaskownicy wyłączony STR_5280 :Zezwól na edycję ustawień własności ziemi z poziomu okna mapy. Normalnie ta opcja jest dostępna w edytorze scenariuszy. STR_5281 :Funkcje -STR_5282 :RCT1 Włącz/Wyłącz światła atrakcji -STR_5283 :RCT1 Włącz/Wyłącz światła parku -STR_5284 :RCT1 Wybór czcionki scenariusza +STR_5282 :Światła otwarcia/zamknięcia atrakcji z RCT1 +STR_5283 :Światła otwarcia/zamknięcia parku z RCT1 +STR_5284 :Czcionka wyboru scenariusza z RCT1 STR_5287 :Atrakcja jest zepsuta STR_5288 :Atrakcja jest zamknięta STR_5289 :Brak uszkodzeń dla tej atrakcji @@ -2565,15 +2571,15 @@ STR_5302 :Usuń pożyczkę STR_5303 :Zezwól na budowę podczas pauzy STR_5304 :Sekwencja tytułowa: STR_5305 :RollerCoaster Tycoon 1 -STR_5306 :RollerCoaster Tycoon 1 (AA) -STR_5307 :RollerCoaster Tycoon 1 (AA + LL) +STR_5306 :RollerCoaster Tycoon 1 (DA) +STR_5307 :RollerCoaster Tycoon 1 (DA + ZK) STR_5308 :RollerCoaster Tycoon 2 STR_5309 :OpenRCT2 STR_5310 :Losowy STR_5311 :Narzędzia debugowania STR_5312 :Pokaż konsolę -STR_5313 :Pokaż inspektora kafelek -STR_5314 :Inspektor kafelek +STR_5313 :Pokaż inspektor kafelków +STR_5314 :Inspektor kafelków STR_5335 :Wejście na atrakcję STR_5336 :Wyjście z atrakcji STR_5337 :Wejście do parku @@ -2598,8 +2604,8 @@ STR_5357 :{BLACK}Tolerancja mdłości: STR_5358 :{BLACK}Pęcherz: STR_5359 :Usuń gości STR_5360 :Usuwa wszystkich gości z mapy -STR_5361 :Daj wszystkim gościom: -STR_5362 :{BLACK}Ustaw preferowaną intensywność przejażdżek dla wszystkich gości na: +STR_5361 :Dodaj do ekwipunku gościa +STR_5362 :{BLACK}Preferowana intensywność atrakcji: STR_5363 :Więcej niż 1 STR_5364 :Mniej niż 15 STR_5365 :{BLACK}Szybkość personelu: @@ -2629,7 +2635,7 @@ STR_5457 :Wyłącz limity wsparcia STR_5458 :Obróć zgodnie ze wskazówką zegara STR_5459 :Obróć odwrotnie względem wskazówki zegara STR_5460 :Widok odwrotny względem wskazówki zegara -STR_5461 :Zmień parametry gości +STR_5461 :Ustaw parametry dla wszystkich gości STR_5462 :{CURRENCY} STR_5463 :Cel: Baw się dobrze! STR_5464 :Główne @@ -2642,7 +2648,7 @@ STR_5470 :Przesuń mapę w lewo STR_5471 :Przesuń mapę w dół STR_5472 :Przesuń mapę w prawo STR_5473 :Cykl dnia i nocy -STR_5474 :Wyświetlaj tekst na bannerach wielkimi literami +STR_5474 :Wyświetlaj tekst na banerach wielkimi literami STR_5475 :{COMMA16} tygodni STR_5476 :Sprzęt STR_5477 :Wyświetlanie mapy @@ -2780,12 +2786,12 @@ STR_5616 :Ostatni fragment flagi STR_5617 :Przesuń element wyżej. STR_5618 :Przesuń element niżej. STR_5619 :RollerCoaster Tycoon -STR_5620 :Added Attractions -STR_5621 :Zwariowane Krajobrazy +STR_5620 :Dodatkowe atrakcje +STR_5621 :Zwariowane krajobrazy STR_5622 :RollerCoaster Tycoon 2 STR_5623 :Zakręcone światy STR_5624 :Zakręcone czasy -STR_5625 :“Prawdziwe” parki +STR_5625 :„Prawdziwe” parki STR_5626 :Inne parki STR_5627 :Grupuj scenariusze według: STR_5628 :Gra Źródłowa @@ -2880,7 +2886,7 @@ STR_5755 :Niewłaściwa wersja gry STR_5756 :Błędne hasło STR_5757 :Serwer osiągnął maksymalną liczbę graczy STR_5758 :{OUTLINE}{GREEN}{STRING} dołączył do gry -STR_5759 :Pobieranie mapy … +STR_5759 :Pobieranie mapy… STR_5760 :Dolar hongkoński (HK$) STR_5761 :Dolar tajwański (NT$) STR_5762 :Juan chiński (CN¥) @@ -2903,7 +2909,7 @@ STR_5778 :Wybudowano: {COMMA16} lat temu STR_5779 :Przychód: {CURRENCY2DP} na godzinę STR_5780 :Koszty eksploatacji: {CURRENCY2DP} na godzinę STR_5781 :Koszty eksploatacji: nieznane -STR_5782 :Połączono. Naciśnij „{STRING}” aby pisać na chacie. +STR_5782 :Połączono. Naciśnij „{STRING}” aby pisać na czacie. STR_5783 :{WINDOW_COLOUR_2}Scenariusz zablokowany STR_5784 :{BLACK}Aby odblokować ten scenariusz ukończ poprzedni. STR_5785 :Nie można zmienić nazwy grupy… @@ -2915,15 +2921,15 @@ STR_5790 :Mieszany styl płatności RCT1{NEWLINE}(np. jednoczesna odpłatnoś STR_5791 :Ustaw niezawodność wszystkich atrakcji na 100%{NEWLINE}i zresetuj datę budowy na „w tym roku” STR_5792 :Naprawia wszystkie uszkodzone atrakcje STR_5793 :Usuwa historię katastrof,{NEWLINE}dzięki czemu goście nie będą narzekać że jest niebezpieczne -STR_5794 :Niektóre scenariusze blokują edycję{NEWLINE}istniejących juz w parku atrakcji.{NEWLINE}Ta opcja obchodzi te restrykcje +STR_5794 :Niektóre scenariusze blokują edycję{NEWLINE}istniejących już w parku atrakcji.{NEWLINE}Ta opcja obchodzi tę restrykcję STR_5795 :Goście korzystają ze wszystkich atrakcji w parku{NEWLINE}nawet jeśli ich intensywność jest ekstremalna STR_5796 :Wymusza zamknięcie/otwarcie parku -STR_5797 :Wyłącza zmienność pogody{NEWLINE}i ustawia wybrany jej rodzaj +STR_5797 :Wyłącza zmienność pogody{NEWLINE}i ustawia wybraną pogodę STR_5798 :Pozwala budować atrakcje w trakcie pauzy STR_5799 :Wyłącza awarie i katastrofy związane z uszkodzeniem hamulców STR_5800 :Zapobiega awariom atrakcji STR_5801 :Wyłącz śmiecenie -STR_5802 :Uniemożliwij śmiecenie i wymiotowanie przez gości +STR_5802 :Powstrzymuje gości od śmiecenia i wymiotowania STR_5803 :Obróć wybrany element mapy STR_5804 :Wycisz dźwięk STR_5805 :Jeśli zaznaczone, Twój serwer zostanie dodany{NEWLINE}do listy publicznych serwerów, co umożliwi{NEWLINE}wyszukanie go przez wszystkich @@ -2934,53 +2940,53 @@ STR_5809 :{WINDOW_COLOUR_2}Liczba kiosków informacyjnych i innych obiektów: STR_5810 :Wyłącz limit pojazdów STR_5811 :Jeśli zaznaczone, możesz mieć do{NEWLINE}255 wagoników na pociąg i 31{NEWLINE}pociągów na atrakcję STR_5812 :Pokaż okienko gry sieciowej -STR_5813 :“{STRING}” -STR_5814 :{WINDOW_COLOUR_1}“{STRING}” +STR_5813 :„{STRING}” +STR_5814 :{WINDOW_COLOUR_1}„{STRING}” #Wskazówki STR_5815 :Pokaż licznik FPS w grze STR_5816 :Ustawia stosunek skalowania grafiki.{NEWLINE}Przydatne szczególnie przy grze{NEWLINE}w wysokiej rozdzielczości STR_5819 :[Wymaga sterownika sprzętowego]{NEWLINE}Zatrzymaj grę jeśli nakładka Steam{NEWLINE} jest otwarta STR_5820 :Zmniejsz okienko gry w przypadku{NEWLINE}utraty ostrości w trybie pełnoekranowym -STR_5822 :Cykl dnia i nocy.{NEWLINE}Pełny cykl zajmuje miesiąc wewnątrz gry. -STR_5823 :Wyświetlaj banery z dużych liter (zaszłość RCT1) +STR_5822 :Cykl dnia i nocy.{NEWLINE}Pełny cykl trwa jeden miesiąc w grze. +STR_5823 :Wyświetlaj banery z dużych liter (zachowanie RCT1) STR_5824 :Wyłącz efekty świetlne{NEWLINE}w trakcie burz STR_5825 :Zatrzymuj kursor myszki wewnątrz okna STR_5826 :Odwróć przeciąganie prawym przyciskiem myszki -STR_5827 :Ustawia kolor interfejsu GUI +STR_5827 :Ustawia kolor interfejsu graficznego STR_5828 :Zmień użyty format jednostki użyty do czasu, prędkość itp. -STR_5829 :Zmień rodzaj użytej waluty. Jedynie w celach wizualnych, nie ma zastosowania żaden przelicznik +STR_5829 :Zmień rodzaj użytej waluty. Jedynie w celach wizualnych, nie ma wdrożonego dokładnego kursu wymiany. STR_5830 :Zmień używany język STR_5831 :Zmień użyty format{NEWLINE}wyświetlanej temperatury STR_5832 :Pokaż wysokość jako ogólną jednostkę w miejscu formatu jednostki ustawionej w zakładce „Odległość i Prędkość” STR_5833 :Zmień używany format daty STR_5834 :Wybierz urządzenie dźwiękowe dla OpenRCT2 STR_5835 :Wycisz grę przy utracie ostrości okna -STR_5836 :Wybierz muzykę do ekranu tytułowego.{NEWLINE}Wybranie motywu z RCT1 wymaga skopiowania „data/css17.dat” z katalogu gry RCT1 do „data/css50.dat” w twoim katalogu RCT2, lub ustawienia ścieżki do RCT1 w zakładce pozostałych ustawień -STR_5837 :Stwórz i zarządzaj własnymi motywami UI +STR_5836 :Wybierz muzykę do ekranu tytułowego.{NEWLINE}Wybranie motywu z RCT1 wymaga podania ścieżki do RCT1 w zakładce ustawień zaawansowanych. +STR_5837 :Stwórz i zarządzaj własnymi motywami interfejsu użytkownika STR_5838 :Pokaż osobny przycisk dla okienka Finansów w pasku narzędzi STR_5839 :Pokaż osobny przycisk dla okienka Badań i Rozwoju w pasku narzędzi STR_5840 :Pokaż osobny przycisk dla okienka kodów w pasku narzędzi STR_5841 :Pokaż osobny przycisk dla okienka komunikatów w pasku narzędzi -STR_5842 :Posortuj scenariusze w zakładkach według trudności (zaszłość RCT2) lub ich źródła (zaszłość RCT1) -STR_5843 :Włącz odblokowywanie scenariuszy (zaszłość RCT1) +STR_5842 :Posortuj scenariusze w zakładkach według trudności (zachowanie RCT2) lub ich źródła (zachowanie RCT1) +STR_5843 :Włącz odblokowywanie scenariuszy (zachowanie RCT1) STR_5844 :Pozostań podłączony do gry wieloosobowej{NEWLINE}nawet w przypadku desynchronizacji i błędów połączenia -STR_5845 :Dodaje przełącznik trybu debugowania{NEWLINE}do paska narzędzi.{NEWLINE}Włącza skrót klawiaturowy do konsoli developerskiej +STR_5845 :Dodaje przełącznik trybu debugowania{NEWLINE}do paska narzędzi.{NEWLINE}Włącza skrót klawiaturowy do konsoli deweloperskiej STR_5846 :Ustaw częstotliwość zapisu gry OpenRCT2 -STR_5847 :Wybierz sekwencje parków na ekran tytułowy.{NEWLINE}Sekwencje tytułowe z RCT1/2 wymagają zaimportowanych odpowiednich scenariuszy +STR_5847 :Wybierz sekwencję parków używaną na ekranie tytułowym.{NEWLINE}Sekwencje tytułowe z RCT1/2 wymagają zaimportowanych odpowiednich scenariuszy STR_5849 :Automatycznie rozlokuj{NEWLINE}nowo zatrudniony personel STR_5851 :Ustaw domyślną częstotliwość inspekcji{NEWLINE}na nowych atrakcjach -STR_5853 :Przełącznik włączania/wyłączania efektów dźwiękowych -STR_5854 :Przełącznik włączania/wyłączania dźwięków na atrakcjach +STR_5853 :Włącz/Wyłącz efekty dźwiękowe +STR_5854 :Włącz/Wyłącz muzykę na atrakcjach STR_5855 :Ustaw normalny pełny ekran, bezramkowy pełny ekran{NEWLINE}klub tryb okienkowy STR_5856 :Ustaw rozdzielczość ekranu w trybie pełnoekranowym STR_5857 :Ustawienia gry -STR_5858 :Użyć do wyświetlania GPU zamiast CPU. Pomoże to w poprawie kompatybilności z oprogramowaniem do przechwytywania ekranu. Jednak może wpłynąć negatywnie na wydajność. +STR_5858 :Użyj do wyświetlania GPU zamiast CPU. Pomoże to w poprawie kompatybilności z oprogramowaniem do przechwytywania ekranu, jednak może wpłynąć negatywnie na wydajność. STR_5859 :Włącz zmienną ilość klatek dla {NEWLINE}płynniejszej gry. Gdy wyłączone,{NEWLINE}gra będzie używała stałych 40 FPS. -STR_5860 :Przełącznik original/decompiled rysowania trasy +STR_5860 :Przełącz między originalnym/zdekompilowanym rysowaniem trasy STR_5861 :Błąd weryfikacji klucza STR_5862 :Blokuj nieznanych graczy. -STR_5863 :Pozwól na połączenie graczy znających klucz. +STR_5863 :Zezwól na połączenie graczy znających klucz. STR_5864 :Dostęp do serwera mają tylko gracze z białej listy. STR_5865 :Logowanie historii czatu STR_5866 :Zapisuj treść czatów do plików w katalogu domowym. @@ -2988,10 +2994,10 @@ STR_5867 :{WINDOW_COLOUR_2}Nazwa hostującego: {BLACK}{STRING} STR_5868 :{WINDOW_COLOUR_2}E-mail hostującego: {BLACK}{STRING} STR_5869 :{WINDOW_COLOUR_2}Strona hostującego: {BLACK}{STRING} STR_5870 :Pokaż informacje o serwerze -STR_5871 :Wyłącz starzenie się kwiatów +STR_5871 :Wyłącz usychanie kwiatów STR_5872 :Kwiaty się nie starzeją, nie usychają, nie trzeba ich wymieniać STR_5873 :Zezwól na wyciągarkę na wszystkich typach torów -STR_5874 :Zezwól aby przy każdym typie torów można było użyć wyciągarkę +STR_5874 :Umożliwia przekształcenie dowolnego typu toru w wyciągarkę. STR_5875 :Silnik graficzny: STR_5876 :Silnik używany do generowania grafiki. STR_5877 :Programowy @@ -3001,34 +3007,34 @@ STR_5880 :Tylko zaznaczone STR_5881 :Tylko niezaznaczone STR_5882 :Własna waluta STR_5883 :Konfiguracja własnej waluty -STR_5884 :{WINDOW_COLOUR_2}Kurs wymiany: +STR_5884 :{WINDOW_COLOUR_2}Kurs wymiany: STR_5885 :{WINDOW_COLOUR_2}w stosunku do {COMMA32} GBP (£) STR_5886 :{WINDOW_COLOUR_2}Symbol waluty: -STR_5887 :Prefix -STR_5888 :Suffix +STR_5887 :Prefiks +STR_5888 :Sufiks STR_5889 :Własny symbol waluty STR_5890 :Wprowadź własny symbol waluty STR_5891 :Domyślny STR_5892 :Idź do domyślnego katalogu STR_5893 :Kurs wymiany STR_5894 :Wprowadź kurs wymiany -STR_5895 :Zapis trasę +STR_5895 :Zapisz trasę STR_5896 :Nieudany zapis trasy! STR_5898 :{BLACK}Nie można załadować trasy, plik może być {newline}uszkodzony lub niedostępny! -STR_5899 :Przełącznik okna rysowania debugowania +STR_5899 :Włącz/Wyłącz okno debugowania rysowania STR_5900 :Użyj oryginalnego kodu rysowania STR_5901 :Wyświetlaj wysokość segmentów STR_5902 :Pokaż ścianki ograniczające STR_5903 :Pokaż okno debugowania rysowania STR_5904 :Resetuj datę -STR_5905 :Generator mapy automatycznie stworzy własny teren -STR_5906 :Powiększ pozycję kursora -STR_5907 :Jeśli włączone, powiększanie skoncentruje się wokół kursowa, w przeciwieństwie do wyśrodkowania ekranu. +STR_5905 :Narzędzie do generowania map, które automatycznie tworzy krajobraz +STR_5906 :Przybliż do pozycji kursora +STR_5907 :Jeśli włączone, przybliżanie będzie koncentrować się wokół kursora, a nie na środku ekranu. STR_5908 :Pozwól zmienić na dowolny typ pojazdu -STR_5909 :Pozwala dowolnie zmienić ty pojazdu. Może powodować wypadki. +STR_5909 :Pozwala dowolnie zmienić typ pojazdu. Może powodować wypadki. STR_5910 :Zastosuj -STR_5911 :Przezroczyste ścieżki widokowe -STR_5912 :Przełącznik ścieżek widokowych +STR_5911 :Przezroczyste ścieżki +STR_5912 :Przełącznik przezroczystych ścieżek STR_5913 :Czat STR_5914 :Nieznana atrakcja STR_5915 :Gracz @@ -3036,8 +3042,8 @@ STR_5916 :{COMMA16} gracz STR_5917 :{COMMA16} gracze STR_5918 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} STR_5919 :{COMMA16} -STR_5920 :Efekty graficzne wody -STR_5921 :Jeśli włączony, deszcz i błyski będą widoczne w trakcie gry. +STR_5920 :Efekty graficzne pogody +STR_5921 :Jeśli włączone, deszcz i błyski będą widoczne podczas burzy. STR_5922 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}Maks. {STRINGID} STR_5923 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}Maks. {COMMA16} {STRINGID} na pociąg STR_5924 :Szczegóły powierzchni @@ -3078,7 +3084,7 @@ STR_5958 :Północny-wschód STR_5959 :Południowy-wschód STR_5960 :Umiejscowienie ćwiartki: STR_5961 :Indeks wejścia: {BLACK}{COMMA16} -STR_5962 :Wykrycie kolizji: +STR_5962 :Wykrywanie kolizji: STR_5963 :Podniesione narożniki: STR_5964 :Przekątna STR_5965 :Typ wejścia: {BLACK}{STRINGID} @@ -3090,7 +3096,7 @@ STR_5970 :ID Wejścia: {BLACK}{COMMA16} STR_5971 :ID wyjścia: {BLACK}{COMMA16} STR_5972 :ID Tras: {BLACK}{COMMA16} STR_5973 :Zaczep z następnym -STR_5974 :Zmienia wysokość podstawy i prześwitu tak, aby znajdowały się one na tym samym poziomie co następny element na bieżącej platformie. Ułatwia to budowę na tej samej platformie. +STR_5974 :Zmienia wysokość podstawy i prześwitu tak, aby znajdowały się one na tym samym poziomie co następny element na bieżącym kafelku. Ułatwia to budowę na tym kafelku. STR_5975 :Nachylenie: STR_5976 :Płaszczyzna STR_5977 :Prawą stroną do góry @@ -3122,17 +3128,17 @@ STR_6002 :Lampy i atrakcje będą świeciły w nocy.{NEWLINE}Wymaga włączen STR_6003 :Widok przekroju STR_6004 :Widok przekroju STR_6005 :Włącz widok przekroju -STR_6006 :Widok przekroju na podgląd elementów znajdujących się pod innym elementem. +STR_6006 :Widok przekroju wyświetla jedynie elementy mapy na lub poniżej wysokości przycięcia (przycięcie pionowe) oraz w wybranym obszarze (przycięcie poziome). STR_6007 :Wysokość cięcia -STR_6008 :Kliknij aby przełączyć surowe<->wartości jednostek pomiarowych -STR_6009 :Wy +STR_6008 :Kliknij aby przełączyć surowe wartości<->wartości jednostek pomiarowych +STR_6009 :Wybierz wysokość cięcia STR_6010 :{COMMA2DP32}m STR_6011 :{COMMA1DP16}ft STR_6012 :{COMMA1DP16} -STR_6013 :Goście będą płacić jedynie na wstęp do parku i usługi.{NEWLINE}Atrakcje są darmowe. +STR_6013 :Goście będą płacić jedynie za wstęp do parku i usługi.{NEWLINE}Atrakcje są darmowe. STR_6014 :Goście będą płacić za bilety wstępu na atrakcje i usługi.{NEWLINE}Nie będą płacić za wstęp do parku. STR_6015 :Nachylony -STR_6016 :Edytuj kafel +STR_6016 :Edytuj kafelek STR_6017 :Proszę zwolnić STR_6018 :Konstrukcja - Obróć w lewo STR_6019 :Konstrukcja - Obróć w prawo @@ -3146,7 +3152,7 @@ STR_6026 :Konstrukcja - Poprzedni element STR_6027 :Konstrukcja - Następny element STR_6028 :Konstrukcja - Wybuduj bieżący STR_6029 :Konstrukcja - Zniszcz bieżący -STR_6030 :Przechwytywacz scenerii. Wybierz dowolny element scenerii na mapie aby wybrać taki sam dla konstrukcji. +STR_6030 :Przechwytywacz scenerii. Wybierz dowolny element scenerii na mapie aby wybrać taki sam do konstrukcji. STR_6031 :Opis serwera: STR_6032 :Wiadomość powitalna: STR_6033 :Ścieżka do katalogu RCT1: @@ -3154,16 +3160,16 @@ STR_6034 :{BLACK}{STRING} STR_6035 :Proszę wybrać katalog z RCT1 STR_6036 :Wyczyść STR_6037 :Proszę wybrać prawidłowy katalog RCT1 -STR_6038 :Jeżeli masz zainstalowane RCT1, ustaw tę opcję na ścieżkę do owej gry, aby załadować scenariusze, muzykę, etc. z pierwszej części +STR_6038 :Jeżeli masz zainstalowane RCT1, ustaw tę opcję na ścieżkę do owej gry, aby załadować scenariusze, muzykę, itp. z pierwszej części STR_6039 :Szybkie niszczenie atrakcji -STR_6040 :Edytuj Opcje Scenariusza +STR_6040 :Edytuj opcje scenariusza STR_6041 :{BLACK}Nie masz zatrudnionych mechaników! STR_6042 :Załaduj mapę wysokości STR_6043 :Wybierz mapę wysokości -STR_6044 :Gładka wysokość mapy -STR_6045 :Ostra -STR_6046 :Normalizuj mapę wysokością -STR_6047 :Gładkie warstwa +STR_6044 :Wygładź mapę wysokości +STR_6045 :Siła: +STR_6046 :Normalizuj mapę wysokości +STR_6047 :Wygładź krawędzie kafelków STR_6048 :Błąd mapy wysokościowej STR_6049 :Błąd odczytu PNG STR_6050 :Błąd odczytu bitmapy @@ -3211,7 +3217,7 @@ STR_6092 :{STRING} zmienił cenę wstępu do parku na {STRING} STR_6093 :{STRING} umieścił nową dekorację. STR_6094 :{STRING} usunął dekorację. STR_6095 :{STRING} edytował dekorację. -STR_6096 :{STRING} ustawił nazwę znaku na „{STRING”. +STR_6096 :{STRING} ustawił nazwę znaku na „{STRING}”. STR_6097 :{STRING} dodał odcinek trasy „{STRING}”. STR_6098 :{STRING} usunął odcinek trasy. STR_6099 :Połączyłeś się z serwerem. @@ -3219,17 +3225,17 @@ STR_6100 :Rozłączyłeś się z serwerem. STR_6101 :Wartość atrakcji nie spada wraz z upływem czasu. STR_6102 :Wartość atrakcji nie będzie spadała z czasem, dlatego klienci stwierdzą po pewnym czasie, że jest za droga. STR_6103 :Opcja ta nie jest dostępna w grze wieloosobowej. -STR_6105 :Hypercoaster -STR_6107 :Monster Trucks -STR_6109 :Hyper-Twister +STR_6105 :Hiperjazda +STR_6107 :Potworne pikapy +STR_6109 :Hiperzwijka STR_6111 :Klasyczna mini kolejka górska STR_6113 :Wysoka kolejka górska bez inwersji z wielkimi zjazdami, wysokimi prędkościami i wygodnymi wagonikami, które zabezpieczone są tylko pasem na biodrach STR_6115 :Zasilane wielkie auta z napędem 4x4, które są w stanie wjechać na strome zbocza STR_6116 :Szerokie wagony kolejki górskiej delikatnie ślizgają się na stalowym torze przez przeróżne inwersje -STR_6119 :Tani i łatwy do zbudowania roller coaster, jednak z limitem wysokości +STR_6119 :Tania i łatwa do zbudowania kolejka górska, jednak z limitem wysokości STR_6120 :{BABYBLUE}Nowy pojazd dostępny dla {STRINGID}:{NEWLINE}{STRINGID} STR_6121 :Rozszerz prawa do terenu aż do krawędzi mapy -STR_6122 :Nie ma dostępnych więcej roaller coaster w tym scenariuszu! +STR_6122 :W tym scenariuszu jest za mało kolejek górskich! STR_6123 :Błąd przy ładowaniu elementów parku STR_6124 :Nazwa elementu STR_6125 :Typ elementu @@ -3244,8 +3250,8 @@ STR_6133 :Dostęp do kolejek i scenerii, które nie zostały jeszcze wynalezi STR_6134 :Wyczyść scenerię STR_6135 :Klient wysłał nieprawidłowe żądanie STR_6136 :Serwer wysłał nieprawidłowe żądanie -STR_6137 :OpenRCT2, darmowy i open source klon gry Roller Coaster Tycoon 2. -STR_6138 :OpenRCT2 to wynik pracy wielu autorów, pełną listę można znaleźć w “contributors.md”. Po więcej informacji odwiedź: http://github.com/OpenRCT2/OpenRCT2 +STR_6137 :OpenRCT2, darmowe i open-source’owe odtworzenie oraz rozszerzenie gry Roller Coaster Tycoon 2. +STR_6138 :OpenRCT2 to wynik pracy wielu autorów, pełną listę można znaleźć wybierając opcję „Współautorzy”. Po więcej informacji odwiedź: http://github.com/OpenRCT2/OpenRCT2 STR_6139 :Wszystkie nazwy produktów i firm należą do ich właścicieli. Użycie ich nie oznacza powiązania z nimi ani ich poparcia. STR_6140 :Lista zmian… STR_6141 :Dolny pasek narzędziowy z RCT1 @@ -3267,11 +3273,11 @@ STR_6156 :Nazwa jest zastrzeżona STR_6157 :Konsola STR_6160 :{WINDOW_COLOUR_2}Dostępne pojazdy: {BLACK}{STRING} STR_6161 :Przełącz widok siatki -STR_6162 :Spinning Wild Mouse +STR_6162 :Wirująca szalona mysz STR_6163 :Pojazdy wyglądające jak myszki, szybko jeżdżą po ciasnych zakrętach i krótkich zjazdach, dodatkowo łagodnie się kręcą przez co dezorientują gości STR_6164 :{WHITE}❌ STR_6165 :Synchronizacja pionowa -STR_6166 :Synchronizuje każdą wyświetlaną klatkę z częstotliwością odświeżania monitora, zapobiegając rozrywaniu ekranu. +STR_6166 :Synchronizuje każdą wyświetlaną klatkę z częstotliwością odświeżania monitora, zapobiegając rozrywaniu ekranu STR_6167 :Zaawansowane STR_6168 :Sekwencja tytułowa STR_6169 :Wybór scenariusza @@ -3293,13 +3299,13 @@ STR_6199 :Ustaw datę STR_6200 :Resetuj datę STR_6201 :{MONTH} STR_6202 :Styl wirtualnego podłoża: -STR_6203 :Gdy włączone, wirtualne podłoże będzie prezentowane przy wciśniętym Ctrl lub Shift, aby łatwiej było ustawić w pionowe elementy. +STR_6203 :Gdy włączone, wirtualne podłoże będzie prezentowane przy wciśniętym Ctrl lub Shift, aby ułatwić stawianie elementów w pionie. STR_6215 :Konstrukcja STR_6216 :Operacja STR_6217 :Dostępność atrakcji / ścieżki -STR_6218 :Officjane OpenRCT2 +STR_6218 :Oficjalne OpenRCT2 STR_6219 :Podświetl problemy na ścieżkach -STR_6220 :Przłącz na dostępne +STR_6220 :Przełącz na dostępne STR_6221 :Spowoduje to ustawienie znanego wejścia lub wyjścia z przejazdu na aktualnie wybrany kafelek. Na jednej stacji można wykorzystać tylko jedno miejsce wejścia i wyjścia. STR_6222 :Nie można tutaj postawić wejścia dla gości… STR_6223 :Musi być poza granicami parku! @@ -3343,7 +3349,7 @@ STR_6263 :Włącz/wyłącz wszystkie dźwięki STR_6264 :Zawsze używaj przeglądarki systemowej STR_6265 :Po włączeniu tej opcji, przeglądarka plików Twojego systemu operacyjnego będzie używana zamiast przeglądarki OpenRCT2. STR_6266 :Otwórz folder ze spersonalizowaną zawartością -STR_6267 :Otwórz inspektor kafelek +STR_6267 :Otwórz inspektor kafelków STR_6268 :Tick do przodu STR_6269 :Nieprawidłowy indentyfikator klimatu STR_6270 :Powierzchnie otoczenia @@ -3359,7 +3365,7 @@ STR_6279 :Liczba autozapisów powinna zostać zachowana STR_6280 :Czat STR_6281 :Pokaż osobny przycisk dla czatu w pasku narzędzi STR_6282 :Czat -STR_6283 :Czat nie jest odstępny. Sprawdź połączenie z serwerem +STR_6283 :Czat nie jest dostępny. Sprawdź połączenie z serwerem STR_6293 :B STR_6294 :KiB STR_6295 :MiB @@ -3367,15 +3373,15 @@ STR_6296 :GiB STR_6297 :TiB STR_6298 :{STRING}/sek STR_6299 :Pobierz wszystkie -STR_6300 :Pobierz wszystkie braujące obiekty jeśli są dostępne online. +STR_6300 :Pobierz wszystkie brakujące obiekty jeśli są dostępne online. STR_6301 :Skopiuj nazwę wybranego obiektu do schowka. -STR_6302 :Skopiuj całą listęp brakujących obiektów do schowka. +STR_6302 :Skopiuj całą listę brakujących obiektów do schowka. STR_6303 :Pobieranie obiektu ({COMMA16} / {COMMA16}): [{STRING}] STR_6304 :Otwórz przeglądarkę scenerii STR_6305 :Wielowątkowość STR_6306 :Eksperymentalna opcja używania wielowątkowości do renderowania, może być niestabilna. STR_6307 :Paleta kolorów: {BLACK}{STRINGID} -STR_6308 :{TOPAZ}“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6308 :{TOPAZ}„{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} STR_6309 :Połącz ponownie STR_6310 :{WINDOW_COLOUR_2}Pozycja: {BLACK}{INT32} {INT32} {INT32} STR_6311 :{WINDOW_COLOUR_2}Następna: {BLACK}{INT32} {INT32} {INT32} @@ -3389,32 +3395,32 @@ STR_6318 :Desynchronizacja sieci.{NEWLINE}Plik z logami: {STRING} STR_6319 :Hamulec blokowy zamknięty STR_6320 :Niezniszczalne STR_6321 :Dodatek jest uszkodzony -STR_6322 :{WINDOW_COLOUR_2}Identyfikator sprite’a: {BLACK}{INT32} +STR_6322 :{WINDOW_COLOUR_2}Identyfikator: {BLACK}{INT32} STR_6323 :Symulowanie STR_6324 :Symuluj STR_6325 :Symuluj atrakcję STR_6326 :Nie można symulować {STRINGID}… STR_6327 :Przezroczyste tło dla ogromnych zrzutów z ekranu -STR_6328 :Ogromy zrzut z ekranu będzie miał przezroczyste tło zamiast domyślnego czarnego. +STR_6328 :Ogromny zrzut ekranu będzie miał przezroczyste tło zamiast domyślnego czarnego. STR_6329 :{STRING}{STRINGID} STR_6330 :Pobieranie [{STRING}] z {STRING} ({COMMA16} / {COMMA16}) STR_6331 :Stwórz kaczki STR_6332 :Usuń kaczki STR_6333 :Zwiększ współczynnik skali STR_6334 :Zmniejsz współczynnik skali -STR_6336 :Inspector kafelek: Skopiuj element -STR_6337 :Inspector kafelek: Wklej element -STR_6338 :Inspector kafelek: Usuń element -STR_6339 :Inspector kafelek: Przenieś element do góry -STR_6340 :Inspector kafelek: Przenieś element w dół -STR_6341 :Inspector kafelek: Zwiększ współrzędną X -STR_6342 :Inspector kafelek: Zmniejsz współrzędną X -STR_6343 :Inspector kafelek: Zwiększ współrzędną Y -STR_6344 :Inspector kafelek: Zmniejsz współrzędną Y -STR_6345 :Inspector kafelek: Zwiększ wysokość elementu -STR_6346 :Inspector kafelek: Zmniejsz wysokość elementu +STR_6336 :Inspektor kafelków: Skopiuj element +STR_6337 :Inspektor kafelków: Wklej element +STR_6338 :Inspektor kafelków: Usuń element +STR_6339 :Inspektor kafelków: Przenieś element do góry +STR_6340 :Inspektor kafelków: Przenieś element w dół +STR_6341 :Inspektor kafelków: Zwiększ współrzędną X +STR_6342 :Inspektor kafelków: Zmniejsz współrzędną X +STR_6343 :Inspektor kafelków: Zwiększ współrzędną Y +STR_6344 :Inspektor kafelków: Zmniejsz współrzędną Y +STR_6345 :Inspektor kafelków: Zwiększ wysokość elementu +STR_6346 :Inspektor kafelków: Zmniejsz wysokość elementu STR_6347 :Dodatkowe ścieżki nie mogą być na przejeździe kolejowym! -STR_6348 :Najpierw uzuń przejazd kolejowy! +STR_6348 :Najpierw usuń przejazd kolejowy! STR_6349 :Losowa sekwecja tytułów STR_6350 :Rozpraszane STR_6351 :Narzędzie rozpraszania scenerii @@ -3423,27 +3429,27 @@ STR_6353 :Niska gęstość STR_6354 :Średnia gęstość STR_6355 :Wyskoka gęstość STR_6356 :Przyzywa kaczki jeśli park zawiera wodę -STR_6357 :Usuwa wszystkie kaczki z mapu +STR_6357 :Usuwa wszystkie kaczki z mapy STR_6358 :Strona {UINT16} STR_6359 :{POP16}{POP16}Strona {UINT16} STR_6361 :Włącz efekty świetlne atrakcji (eksperymentalne) -STR_6362 :Jeśłi włączone, pojazdy będą oświetlone w nocy. +STR_6362 :Jeśli włączone, pojazdy będą oświetlone w nocy. STR_6363 :Tekst skopiowany do schowka STR_6364 :{RED}{COMMA16} osoba zmarła w wypadku na {STRINGID} STR_6365 :Ofiary atrakcji STR_6366 :Zablokowane pojazdy STR_6367 :Klatka animacji: -STR_6368 :Z powodów kompatybilności nie zaleca się uruchamiania OpenRCT2 na Wine. OpenRCT2 działa poprawnie na macOS, Linux, FreeBSD i OpenBSD. +STR_6368 :Z powodów kompatybilności nie zaleca się uruchamiania OpenRCT2 za pomocą Wine. OpenRCT2 działa poprawnie na macOS, Linux, FreeBSD i OpenBSD. STR_6369 :Zezwól na budowanie torów na dowolnych wysokościach STR_6370 :Zezwala na ustawianie fragmentów torów na dowolnych interwałach wysokościowych -STR_6371 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale brakuje pliku “csg1i.dat”. Ten plik musi zostać skopiowany z płyty Loopy Landscapes lub RCT Deluxe do folderu “Data” w RollerCoaster Tycoon 1 zainstalowanym na dysku twardym. -STR_6372 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale ta wersja jest nieodpowiednia. OpenRCT2 wymaga instalacji Loopy Landscapes lub RCT Deluxe w celku korzystania z zasobów RollerCoaster Tycoon 1. +STR_6371 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale brakuje pliku „csg1i.dat”. Ten plik musi zostać skopiowany z płyty Zwariowane krajobrazy lub RCT Deluxe do folderu „Data” w RollerCoaster Tycoon 1 zainstalowanym na dysku twardym. +STR_6372 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale ta wersja jest nieodpowiednia. OpenRCT2 wymaga instalacji Zwariowane krajobrazy lub RCT Deluxe w celku korzystania z zasobów RollerCoaster Tycoon 1. STR_6373 :Pokaż/schowaj sprawdzenia prześwitu STR_6374 :P STR_6375 :Nieznana atrakcja STR_6376 :{WINDOW_COLOUR_2}Pojazd:{NEWLINE}{BLACK}{STRINGID} dla {STRINGID} STR_6377 :{WINDOW_COLOUR_2}Typ: {BLACK}{STRINGID} dla {STRINGID} -STR_6378 :Odebrano listę obiektów: +STR_6378 :Odbieranie listy obiektów… STR_6379 :Odebrano nieprawidłowe dane STR_6380 :Dostępna aktualizacja! STR_6381 :Dołącz do Discorda OpenRCT2! @@ -3455,26 +3461,26 @@ STR_6386 :Śnieżyca STR_6387 :Nie można tutaj obniżyć elementu… STR_6388 :Nie można tutaj podwyższyć elementu… STR_6389 :Nieprawidłowy prześwit -STR_6390 :Do działania OpenRCT2 wymaga plików z orginalnego RollerCoaster Tycoon 2. Wybierz katalog gdzie został zainstalowany RollerCoaster Tycoon 2. +STR_6390 :Do działania OpenRCT2 wymaga plików z oryginalnego RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. Wybierz katalog gdzie został zainstalowany RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. STR_6391 :Wybierz katalog z RCT2 STR_6392 :Nie można znaleźć {STRING} w tej ścieżce STR_6393 :Wybór celu STR_6394 :Cel STR_6395 :Utrzymanie STR_6396 :Wyłącz oszczędzanie energii monitora -STR_6397 :Jeśli zaznaczone, wygaszacz ekranu i inne funkcje oszczędzania ekranu zostaną wyłączone gdy OpenRCT2 jest uruchomione. -STR_6398 :Plik zawiera niewspierane typy kolejek. Zaktualizuj do nowszej wersji OpenRCT2.. -STR_6399 :OpenRCT2 wmymaga do działania plików z orginalnego Roller Coaster Tycoon 2. Ustaw wartość “game_path” w config.ini na folder w którym zostało zainstalowane RollerCoaster Tycoon 2, następnie zrestartuj OpenRCT2. +STR_6397 :Jeśli zaznaczone, wygaszacz ekranu i inne funkcje oszczędzania ekranu zostaną wyłączone gdy OpenRCT2 jest uruchomione +STR_6398 :Plik zawiera niewspierane typy kolejek. Zaktualizuj do nowszej wersji OpenRCT2. +STR_6399 :OpenRCT2 wymaga do działania plików z oryginalnego RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. Ustaw wartość „game_path” w config.ini na folder w którym zostało zainstalowane RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic, następnie zrestartuj OpenRCT2. STR_6400 :Mam pobrany GOG offline installer dla RollerCoaster Tycoon 2, ale nie jest zainstalowany -STR_6401 :Mam już RollerCoaster Tycoon 2 zainstalowany +STR_6401 :Mam już zainstalowany RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic STR_6402 :Ustawienia danych OpenRCT2 STR_6403 :Wybierz co najbardziej pasuje STR_6404 :Wybierz instalator GOG RollerCoaster Tycoon 2. -STR_6405 :Wybirz instalator GOG +STR_6405 :Wybierz instalator GOG STR_6406 :Instalator GOG RollerCoaster Tycoon 2 STR_6407 :To może potrwać kilka minut. -STR_6408 :Wskaż proszę “innoextract” w celu wypakowania instalatora GOG, następnie zrestartuj OpenRCT2. -STR_6409 :Wskazany plik nie jest offlinowym intalatorem GOG dla RollerCoaster Tycoon 2. Możliwe, że pobrany został GOG Galaxy downloader, albo wskazany błędny plik. +STR_6408 :Wskaż proszę „innoextract” w celu wypakowania instalatora GOG, następnie zrestartuj OpenRCT2. +STR_6409 :Wskazany plik nie jest offlinowym intalatorem GOG dla RollerCoaster Tycoon 2. Możliwe, że pobrany został GOG Galaxy downloader, albo wskazano błędny plik. STR_6410 :Przybliż/oddal STR_6411 :Pokaż przyciski do przybliżania i oddalania w pasku narzędzi STR_6412 :NumPad Enter @@ -3506,7 +3512,7 @@ STR_6437 :Widzialny STR_6438 :{MOVE_X}{2}👁 STR_6439 :Inspector kafelek: Przełącz niewidzialność STR_6440 :Przezroczysta woda -STR_6441 :Przynajmniej jedna powierzchnia ścieżki musi zostać wybrana. +STR_6441 :Przynajmniej jedna powierzchnia chodnika musi zostać wybrana. STR_6442 :Przynajmniej jedna powierzchnia kolejki musi zostać wybrana. STR_6443 :Przynajmniej jedna balustrada musi zostać wybrana. STR_6444 :Powierzchnie ścieżek @@ -3515,13 +3521,13 @@ STR_6446 :{WINDOW_COLOUR_2}Nazwa powierzchni: {BLACK}{STRINGID} STR_6447 :{WINDOW_COLOUR_2}Nazwa balustrady: {BLACK}{STRINGID} STR_6448 :Niewspierany format obiektu STR_6449 :{WINDOW_COLOUR_2}Ścieżki dźwiękowe: -STR_6450 :{BLACK}“{STRING}” -STR_6451 :{BLACK}“{STRING}” - {STRING} +STR_6450 :{BLACK}„{STRING}” +STR_6451 :{BLACK}„{STRING}” - {STRING} STR_6452 :{WINDOW_COLOUR_2}Sprzedaje: {BLACK}{STRING} STR_6453 :Skopiuj informacje o wersji STR_6454 :Nie można zmienić nazwy baneru… STR_6455 :Nie można zmienić nazwy znaku… -STR_6456 :Ogromny zrzut z ekranu +STR_6456 :Ogromny zrzut ekranu STR_6457 :Zgłoś błąd na GitHubie STR_6458 :Śledź na ekranie głównym STR_6460 :K @@ -3552,29 +3558,225 @@ STR_6484 :Przełącznik przezroczystości roślin STR_6485 :Przełącznik przezroczystości pojazdów STR_6486 :Przełącznik przezroczystości gości STR_6487 :Przełącznik przezroczystości pracowników -STR_6488 :{RED}Goście skarżą się na dłogość kolejek w Twoim parku.{NEWLINE}Rozważ skrócenie problematycznych kolejek lub zwiększenie przepustowości przejażdżek. +STR_6488 :{RED}Goście skarżą się na długość kolejek w Twoim parku.{NEWLINE}Rozważ skrócenie problematycznych kolejek lub zwiększenie przepustowości atrakcji. STR_6489 :Błąd: Niekompatybilna wersja parku STR_6490 :Ostrzeżenie: Częściowo kompatybilna wersja parku -STR_6491 :Ten park został zapisany w późniejszej wersji OpenRCT2. Park jest v{INT32} i wymaga co najmniej v{INT32}. -STR_6492 :Ten park został zapisany w starej wersji OpenRCT2 i nie można go otworzyć za pomocą tej wersji programu OpenRCT2. Park ma jest w v{INT32}. -STR_6493 :Ten park został zapisany w późniejszej wersji OpenRCT2, niektóre dane mogą zostać utracone. Park jest w v{INT32} i wymaga co najmniej v{INT32}. +STR_6491 :Ten park został zapisany w późniejszej wersji OpenRCT2. Park jest w v{INT32} i wymaga co najmniej v{INT32}. Obecnie używasz v{INT32}. +STR_6492 :Ten park został zapisany w starej wersji OpenRCT2 i nie można go otworzyć za pomocą tej wersji programu OpenRCT2. Park jest w v{INT32}. +STR_6493 :Ten park został zapisany w późniejszej wersji OpenRCT2, niektóre dane mogą zostać utracone. Park jest w v{INT32} i wymaga co najmniej v{INT32}. Obecnie używasz v{INT32}. STR_6494 :Grupuj po typie atrakcji STR_6495 :Grupuj po typie atrakcji zamiast wyświetlić każdą osobno. STR_6496 :{WINDOW_COLOUR_2}{STRINGID} -STR_6497 :Kliknij na kafelkę, żeby zobaczyć jej elementy.{NEWLINE}Ctrl + kliknięcie na element kafelki, żeby pokazać od razu. +STR_6497 :Kliknij na kafelek, żeby zobaczyć jego elementy.{NEWLINE}Ctrl + kliknięcie na element kafelka, żeby pokazać od razu. STR_6498 :Włącz w celu zachowania kwadratowej mapy. STR_6499 :Typ pojazdu nie jest obsługiwany przez format projektu toru STR_6500 :Elementy toru nieobsługiwane przez format projektu toru STR_6501 :Losowy kolor +STR_6502 :Wprowadź wartość pomiędzy {COMMA16} a {COMMA16} +STR_6503 :Musi być wybrany przynajmniej jeden obiekt stacji +STR_6504 :Należy wybrać co najmniej jeden element powierzchni terenu +STR_6505 :Należy wybrać co najmniej jeden element krawędzi terenu STR_6506 :Duży pół korkociąg (lewy) STR_6507 :Duży pół korkociąg (prawy) STR_6508 :Średnia półpętla (lewa) STR_6509 :Średnia półpętla (prawa) STR_6510 :Beczółka Zero G (lewa) STR_6511 :Beczółka Zero G (prawa) -STR_6512 :Duża Beczółka Zero G (lewa) -STR_6513 :Duża Beczółka Zero G (prawa) -STR_6502 :Wprowadź wartość pomiędzy {COMMA16} a {COMMA16} -STR_6503 :Musi być wybrany przynajmniej jeden obiekt stacji -STR_6504 :Należy wybrać co najmniej jeden element powierzchni terenu -STR_6505 :Należy wybrać co najmniej jeden element krawędzi terenu +STR_6512 :Duża beczółka Zero G (lewa) +STR_6513 :Duża beczółka Zero G (prawa) +STR_6514 :Nieprawidłowa wysokość! +STR_6515 :{BLACK}Rollercoaster Tycoon 1 niezaładowany - zostaną użyte grafiki zapasowe. +STR_6516 :Jeden lub więcej obiektów wymaga załadowania Rollercoaster Tycoon 1, aby mogły być poprawnie wyświetlane. Zostaną użyte grafiki zapasowe. +STR_6517 :Jeden lub więcej obiektów w tym parku wymaga załadowania Rollercoaster Tycoon 1, aby mogły być poprawnie wyświetlane. Zostaną użyte grafiki zapasowe. +STR_6518 :{BLACK}Najedź na scenariusz aby wyświetlić jego opis oraz cel. Kliknij go aby rozpocząc rozgrywkę. +STR_6519 :Dodatkowe +STR_6520 :Paczki zasobów +STR_6521 :Niski priorytet +STR_6522 :Wysoki priorytet +STR_6523 :Zmniejsz priorytet wybranej paczki zasobów. +STR_6524 :Zwiększ priorytet wybranej paczki zasobów. +STR_6525 :Przeładuj wszystkie zasoby w grze z włączonymi paczkami zasobów. +STR_6526 :(podstawowa grafika, muzyka i efekty dźwiękowe) +STR_6527 :Zawody +STR_6528 :Nieprawidłowe parametry toru! +STR_6529 :Nieprawidłowy parametr schematu koloru! +STR_6530 :User Created Expansion Set +STR_6531 :Wehikuł czasu +STR_6532 :Kraina Marzeń Katy +STR_6533 :{WINDOW_COLOUR_2}Czynnik ekscytacji: {BLACK}-{COMMA16}% +STR_6534 :{WINDOW_COLOUR_2}Czynnik intensywności: {BLACK}-{COMMA16}% +STR_6535 :{WINDOW_COLOUR_2}Czynnik mdłości: {BLACK}-{COMMA16}% +STR_6536 :Ten park został zapisany w późniejszej wersji OpenRCT2. Park został zapisany w v{INT32}, a obecnie używasz v{INT32}. +STR_6537 :Zezwól na używanie zwykłych chodników jako kolejek +STR_6538 :Pokazuje zwykłe chodniki na liście kolejek do atrakcji w menu chodników. +STR_6539 :Hamulec zamknięty +STR_6540 :{WINDOW_COLOUR_2}Podziękowania dla następujących firm za zgodę na wykorzystanie ich wizerunku: +STR_6541 :{WINDOW_COLOUR_2}Rocky Mountain Construction Group, Josef Wiegand GmbH & Co. KG, Intamin Amusement Rides Int. Corp. Est. +STR_6542 :Współautorzy +STR_6543 :Współautorzy… +STR_6544 :Kwota pożyczki nie może być ujemna! +STR_6545 :Użyj obliczania odsetek z RCT1 +STR_6546 :Użyj algorytmu obliczania odsetek z RollerCoaster Tycoon 1, który stosował oprocentowanie stałe wynoszące około 1,33%. +STR_6547 :Wszystkie obiekty +STR_6548 :Pokaż balustrady na skrzyżowaniu +STR_6549 :Obiekty zapewniające kompatybilność wsteczną nie mogą być wybrane! +STR_6550 :Ten wpis jest dołączony dla zapewnienia wstecznej kompatybilności ze starymi lub uszkodzonymi obiektami. Nie może być wybrany, tylko odznaczony. +STR_6551 :Zielony wojskowy +STR_6552 :Spadziowy +STR_6553 :Jasnobrązowy +STR_6554 :Ciemnobordowy +STR_6555 :Koralowy róż +STR_6556 :Leśny zielony +STR_6557 :Żółtozielony +STR_6558 :Zielony myśliwy +STR_6559 :Seledynowy +STR_6560 :Zielony limonkowy +STR_6561 :Sepia +STR_6562 :Brzoskwiniowy +STR_6563 :Barwinkowy +STR_6564 :Zieleń chromowa +STR_6565 :Zieleń morska +STR_6566 :Fioletowy +STR_6567 :Lawendowy +STR_6568 :Pastelowy pomarańcz +STR_6569 :Głęboka woda +STR_6570 :Pastelowy róż +STR_6571 :Umbra +STR_6572 :Beżowy +STR_6573 :Niewidzialny +STR_6574 :Próżnia +STR_6575 :Zezwól na specjalne schematy kolorów +STR_6576 :Dodaje specjalne kolory do rozwijanej listy kolorów +STR_6577 :Prędkość hamowania blokowego +STR_6578 :Ustawia limit prędkości dla hamulców blokowych. W trybie sekcyjnym, sąsiednie hamulce o niższej prędkości są powiązane z hamulcem blokowym. +STR_6579 :Hamulce blokowe zostaną ustawione na domyślną prędkość po zapisaniu jako projekt trasy. +STR_6580 :Zresetuj +STR_6581 :Jesteś pewien, że chcesz zresetować wszystkie skróty klawiszowe na tej zakładce? +STR_6582 :Otwórz okno skrótów klawiszowych +STR_6583 :{WINDOW_COLOUR_2}Odwrócone wagony +STR_6584 :Wybierz, aby ustawić wagony w kierunku przeciwnym do kierunku jazdy +STR_6585 :Nie można wprowadzić zmian… +STR_6586 :OpenRCT2 +STR_6587 :Motyw tytułowy OpenRCT2 jest dziełem Allistera Brimble’a,{NEWLINE}udostępnionym na licencji Creative Commons Uznanie autorstwa Na tych samych warunkach 4.0. +STR_6588 :Dziękujemy Hermanowi Ridderingowi za umożliwienie nam nagrania 35er Voigt. +STR_6589 :Umieść przyciski okna po lewej stronie +STR_6590 :Umieść przyciski okna (np. zamknięcie okna) po lewej stronie paska tytułowego zamiast po prawej. +STR_6591 :Pracownik obecnie naprawia atrakcję i nie może zostać zwolniony. +STR_6592 :Pracownik obecnie inspektuje atrakcję i nie może zostać zwolniony. +STR_6593 :Usuń ogrodzenia parku +STR_6594 :Inspektor kafelków: Przełącz nachylenie ściany +STR_6595 :{WINDOW_COLOUR_2}Autor: {BLACK}{STRING} +STR_6596 :{WINDOW_COLOUR_2}Autorzy: {BLACK}{STRING} +STR_6597 :Nieprawidłowy parametr +STR_6598 :Wartość poza zakresem +STR_6599 :Element duch nieznaleziony +STR_6600 :Balon nieznaleziony +STR_6601 :Pracownik nieznaleziony +STR_6602 :Atrakcja nieznaleziona +STR_6603 :Wpis obiektu atrakcji nieznaleziony +STR_6604 :Gracz nieznaleziony +STR_6605 :Element wejścia nieznaleziony +STR_6606 :Element powierzchni terenu nieznaleziony +STR_6607 :Element kafelka nieznaleziony +STR_6608 :Element toru nieznaleziony +STR_6609 :Blok toru nieznaleziony +STR_6610 :Element ścieżki nieznaleziony +STR_6611 :Element ściany nieznaleziony +STR_6612 :Element banera nieznaleziony +STR_6613 :Przeładuj obiekt +STR_6614 :Nie można zmienić opłaty za wstęp do parku +STR_6615 :Tor na tym kafelku wymaga wody +STR_6616 :Działanie niedozwolone dla tego typu pracownika +STR_6617 :Nie można zamienić elementu kafelka z samym sobą +STR_6618 :Nie można ograniczyć ani zniesć ograniczeń dla obiektu… +STR_6619 :Typ obiektu nie może być ograniczony! +STR_6620 :Obiekt nieznaleziony! +STR_6621 :Ogranicz +STR_6622 :Ogranicz obiekt do edytora scenariuszy i trybu piaskownicy. +STR_6623 :Wpisz ‘help’, aby wyświetlić listę dostępnych poleceń. Wpisz ‘hide’, aby ukryć konsolę. +STR_6624 :Inspektor kafelków: Sortuj elementy +STR_6625 :Nieprawidłowy kolor +STR_6626 :Animacja odbita lustrzanie +STR_6627 :Za wysoka prędkość trasy! +STR_6628 :Można to zbudować tylko na krawędziach ścieżki! +STR_6629 :Wyśrodkuj poziomo przyciski paska narzędzi +STR_6630 :Ustawienie to wyrówna przyciski paska narzędzi poziomo na środku ekranu. Tradycyjny sposób ich wyrównania to umiejscowienie w lewym i prawym rogu. +STR_6631 :Ładowanie… +STR_6632 :Sprawdzanie plików obiektów… +STR_6633 :Sprawdzanie plików scenariuszy… +STR_6634 :Sprawdzanie plików projektów tras… +STR_6635 :Sprawdzanie paczek zasobów… +STR_6636 :Sprawdzanie sekwencji tytułowych… +STR_6637 :Ładowanie sekwencji tytułowej… +STR_6638 :Powiększony interfejs +STR_6639 :Modyfikuje interfejs, aby ułatwić obsługę dotykową +STR_6640 :Edytuj paczki zasobów… +STR_6641 :Okno ładowania/postępu +STR_6642 :{STRING} ({COMMA32} / {COMMA32}) +STR_6643 :{STRING} ({COMMA32} / {COMMA32} KiB) +STR_6644 :Ulepszenia obsługi dotykowej +STR_6645 :Powiększa niektóre elementy interfejsu, aby były łatwiejsze do kliknięcia lub dotknięcia. +STR_6646 :Autor: {STRING} +STR_6647 :Autorzy: {STRING} +STR_6648 :Ładowanie silnika wtyczek… +STR_6649 :Ładowanie scenariusza… +STR_6650 :Ładowanie zapisu gry… +STR_6651 :{STRING} ({COMMA32}%) +STR_6652 :Okno błędu +STR_6653 :Wszystkie źródła wyświetlone +STR_6654 :Wyświetlone źródła: {POP16}{UINT16} +STR_6655 :Tylko „{POP16}{STRINGID}” +STR_6656 :Usuń wszystkie ogrodzenia parku +STR_6657 :Nieposiadany teren +STR_6658 :Ustaw teren jako nieposiadany przez park i niedostępny do zakupu +STR_6659 :Goście ignorują ceny +STR_6660 :Goście będą ignorować ceny atrakcji i stoisk +STR_6661 :Losuj wszystkie +STR_6662 :Ustaw kolor losowo dla każdego wagonu lub pojazdu +STR_6663 :Kody związane z datą +STR_6664 :Pokaż kody związane z datą +STR_6665 :Kody związane z pogodą +STR_6666 :Pokaż kody związane z pogodą +STR_6667 :Fauna +STR_6668 :Kody związane z pracownikami +STR_6669 :Pokaż kody związane z pracownikami +STR_6670 :Zachowanie gości +STR_6671 :Pokazuj „prawdziwe” imiona pracowników +STR_6672 :Przełącz między pokazywaniem imion pracowników a numerami +STR_6673 :Przezroczyste +STR_6674 :{MONTH}, Rok {COMMA16} +STR_6675 :Imiona gości +STR_6676 :Co najmniej jeden obiekt z nazwami gości musi być wybrany +STR_6677 :Dodaj plaże wokół zbiorników wodnych +STR_6678 :Źródło mapy wysokości: +STR_6679 :Równina +STR_6680 :Szum Simplex +STR_6681 :Plik mapy wysokości +STR_6682 :Generator mapy - Generator +STR_6683 :Generator mapy - Teren +STR_6684 :Generator mapy - Woda +STR_6685 :Generator mapy - Lasy +STR_6686 :Stosunek drzew do powierzchni terenu: +STR_6687 :Min. wysokość drzew: +STR_6688 :Maks. wysokość drzew: +STR_6689 :{UINT16}% +STR_6690 :Min. wysokość terenu +STR_6691 :Wprowadź minimalną wysokość terenu pomiędzy {COMMA16} a {COMMA16} +STR_6692 :Maks. wysokość terenu +STR_6693 :Wprowadź maksymalną wysokość terenu pomiędzy {COMMA16} a {COMMA16} +STR_6694 :Min. wysokość drzew +STR_6695 :Wprowadź minimalną wysokość drzew pomiędzy {COMMA16} a {COMMA16} +STR_6696 :Maks. wysokość drzew +STR_6697 :Wprowadź maksymalną wysokość drzew pomiędzy {COMMA16} a {COMMA16} +STR_6698 :Stosunek drzew do powierzchni terenu +STR_6699 :Wprowadź stosunek drzew do powierzchni terenu pomiędzy {COMMA16} a {COMMA16} +STR_6700 :Bazowa częstotliwość szumu Simplex +STR_6701 :Wprowadź bazową częstotliwość pomiędzy {COMMA2DP32} a {COMMA2DP32} +STR_6702 :Oktawy szumu Simplex +STR_6703 :Wprowadź oktawy pomiędzy {COMMA16} a {COMMA16} +STR_6704 :{COMMA2DP32} +STR_6705 :Przeglądaj… +STR_6706 :{WINDOW_COLOUR_2}Bieżący plik obrazu: {BLACK}{STRING} +STR_6707 :(brak) +STR_6708 :Siła wygładzania +STR_6709 :Wprowadź siłę wygładzania pomiędzy {COMMA16} a {COMMA16} From 8b345089b56334af8d877f897ba36f7806b426e3 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 7 Nov 2024 04:02:16 +0000 Subject: [PATCH 005/139] Merge Localisation/master into OpenRCT2/develop --- data/language/gl-ES.txt | 3734 +++++++++++++++++++++++++++++++++++++++ data/language/pl-PL.txt | 126 +- data/language/pt-BR.txt | 4 +- 3 files changed, 3800 insertions(+), 64 deletions(-) create mode 100644 data/language/gl-ES.txt diff --git a/data/language/gl-ES.txt b/data/language/gl-ES.txt new file mode 100644 index 0000000000..a407b8a8dc --- /dev/null +++ b/data/language/gl-ES.txt @@ -0,0 +1,3734 @@ +# STR_XXXX part is read and XXXX becomes the string id number. STR_1672 +# Everything after the colon and before the new line will be saved as the string. +# Use # at the beginning of a line to leave a comment. +STR_0000 : +STR_0001 :{STRINGID} {COMMA16} +STR_0002 :Montaña rusa en espiral +STR_0003 :Montaña rusa de pé +STR_0004 :Montaña rusa colgante +STR_0005 :Montaña Rusa invertida +STR_0006 :Montaña Rusa Infantil +STR_0007 :Tren en miniatura +STR_0008 :Monocarril +STR_0009 :Mini montaña rusa suspendida +STR_0010 :Paseo en barco +STR_0011 :Rato de madeira tolo +STR_0012 :Carreira de cegos +STR_0013 :Atracción de coches +STR_0014 :Caída libre potenciada +STR_0015 :Bobsleigh de montaña rusa +STR_0016 :Torre de Observación +STR_0017 :Montaña rusa con rizo +STR_0018 :Barcos deslizantes +STR_0019 :Minitren Montaña Rusa +STR_0020 :Telecadeira +STR_0021 :Montaña rusa de sacarollas +STR_0022 :Labirinto +STR_0023 :Deslizamento en espiral +STR_0024 :autos de choque +STR_0025 :Rexistros de auga +STR_0026 :Río Rápido +STR_0027 :Coches de choque +STR_0028 :Barco pirata +STR_0029 :Barco basculante invertido +STR_0030 :posto de comida +STR_0031 :Posición descoñecida (1D) +STR_0032 :Posto de bebidas +STR_0033 :Posición descoñecida (1F) +STR_0034 :Tenda +STR_0035 :Carrusel +STR_0036 :Posición descoñecida (22) +STR_0037 :Quiosco de información +STR_0038 :Cuartos de baño +STR_0039 :Roda xigante +STR_0040 :Simulador de movemento +STR_0041 :Cine 3D +STR_0042 :Top Spin +STR_0043 :Aneis espaciais +STR_0044 :Montaña Rusa invertida +STR_0045 :Ascensor +STR_0046 :Montaña rusa de caída vertical +STR_0047 :ATM +STR_0048 :Torce +STR_0049 :Casa encantada +STR_0050 :Sala de primeiros auxilios +STR_0051 :Circo +STR_0052 :Tren pantasma +STR_0053 :Montaña Rusa Tornado +STR_0054 :Montaña Rusa de madeira +STR_0055 :Montaña Rusa de fricción lateral +STR_0056 :Rato salvaxe de aceiro +STR_0057 :Montaña rusa multidimensional +STR_0058 :Atracción Descoñecida (38) +STR_0059 :Montaña rusa voadora +STR_0060 :Atracción Descoñecido (3A) +STR_0061 :Danza de Virginia +STR_0062 :Latas de salpicaduras +STR_0063 :Mini helicópteros +STR_0064 :Montaña rusa fixa +STR_0065 :Monocarril suspendido +STR_0066 :Atracción Descoñecida (40) +STR_0067 :Montaña Rusa invertida +STR_0068 :Mt. Tornado medio ruso +STR_0069 :Mini Golf +STR_0070 :Montaña rusa Xiga +STR_0071 :Caída xiratoria +STR_0072 :Platillos voadores +STR_0073 :Casa inclinada +STR_0074 :Bicicletas monorraíl +STR_0075 :Montaña rusa compacta +STR_0076 :Montaña rusa de auga +STR_0077 :Montaña rusa vertical de aire +STR_0078 :Garfo invertido +STR_0079 :Alfombra máxica +STR_0080 :Viaxe submarina +STR_0081 :Balsas fluviais +STR_0082 :Atracción Descoñecida (50) +STR_0083 :Empresa +STR_0084 :Atracción Descoñecida (52) +STR_0085 :Atracción Descoñecida (53) +STR_0086 :Atracción Descoñecida (54) +STR_0087 :Atracción Descoñecida (55) +STR_0088 :Montaña rusa de impulso inverso +STR_0089 :Mini montaña rusa +STR_0090 :Trens mineiros +STR_0091 :Atracción Descoñecida (59) +STR_0092 :Montaña Rusa Lançada por MLI +STR_0093 :Montaña Rusa Híbrida +STR_0094 :Montaña rusa dun só carril +STR_0095 :Montaña Rusa Alpina +STR_0096 :Montaña rusa clásica de madeira +STR_0097 :Montaña rusa clásica de pé +STR_0512 :Unha pequena montaña rusa de aceiro cunha subida en espiral e coches con asentos en liña. +STR_0513 :Unha montaña rusa na que os pasaxeiros permanecen de pé. +STR_0514 :Os coches suspendidos baixo os carrís balanceanse lateralmente ao virar en curva. +STR_0515 :Os pilotos sentan nos asentos suspendidos baixo a pista e corren a través de bucles xigantes, xiros e grandes caídas. +STR_0516 :Unha montaña rusa máis suave para as persoas que non teñen o valor de enfrontarse ás grandes montañas rusas. +STR_0517 :Os pasaxeiros viaxan en trens pequenos por unha pequena vía. +STR_0518 :Os pasaxeiros viaxan en trens eléctricos nunha vía de monorraíl. +STR_0519 :Os pasaxeiros colócanse boca abaixo en coches especiais nesta montaña rusa. +STR_0520 :Unha plataforma de peirao onde os pasaxeiros poden conducir barcos na auga. +STR_0521 :Unha montaña rusa rápida con curvas pechadas e desniveis pronunciados. A intensidade é moi alta. +STR_0522 :pequena montaña rusa onde os pasaxeiros viaxan en coches que circulan por un monorraíl. +STR_0523 :Os pasaxeiros viaxan lentamente en vehículos autopropulsados ​​por unha vía. +STR_0524 :Un coche é lanzado sobre un pneumático ata o alto dunha torre de aceiro alta, caendo libremente. +STR_0525 :Os pasaxeiros avanzan por unha pista retorcida guiados unicamente pola curvatura e o inclinamento da pista semicircular. +STR_0526 :Os pasaxeiros viaxan nunha cabina de observación xiratoria que sube por unha torre alta. +STR_0527 :Unha montaña rusa de aceiro capaz de rizos verticais. +STR_0528 :Os pasaxeiros viaxan en lanchas pneumáticas a través de tubos semicirculares ou totalmente pechados. +STR_0529 :O tren da mina circula por unha vía de aceiro que lembra as antigas vías do tren. +STR_0530 :Os asentos colgados dun cable de aceiro viaxan continuamente dun extremo ao outro da ruta. +STR_0531 :unha montaña rusa compacta de aceiro onde os coches circulan en bucles e sacarollas. +STR_0532 :O labirinto está construído a partir de arbustos ou paredes de 6 pés de alto, e os hóspedes deambulan polo labirinto saíndo só cando atopan a saída. +STR_0533 :Edificio de madeira cunha escaleira interior e un tobogán exterior en espiral para usar con alfombras deslizantes +STR_0534 :Os visitantes corren con karts nunha rúa asfaltada. +STR_0535 :Os barcos viaxan por unha canle de auga, salpicando ata que os pasaxeiros quedan empapados. +STR_0536 :Os barcos circulares percorren unha ancha canle de auga, salpicando fervenzas e emocionantes paseos por rápidos espumosos. +STR_0537 :Os visitantes chocan uns contra outros en coches de choque. +STR_0538 :Gran barco pirata balanceado. +STR_0539 :O barco está unido a un brazo cun contrapeso no lado oposto, e balancea en xiros de ata 360º. +STR_0540 :Posto onde os visitantes compran comidas. +STR_0542 :Posto onde os visitantes compran bebidas. +STR_0544 :Posto onde os visitantes compran recordos. +STR_0545 :Carrusel tradicional con cabalos de madeira tallada. +STR_0547 :Un posto onde os visitantes poden obter mapas do parque e mercar paraugas +STR_0548 :Un edificio de aseos +STR_0549 :Roda grande xiratoria con cadeiras abertas +STR_0550 :Os pilotos ven unha película dentro da cápsula do simulador de movemento mentres está retorcida e movida por un brazo hidráulico +STR_0551 :Cine que mostra películas en 3D dentro dun edificio con forma de esfera xeodésica +STR_0552 :Os pasaxeiros viaxan nunha góndola suspendida por grandes brazos xiratorios, xirando cara a adiante e cara atrás de cabeza sobre os talóns +STR_0553 :Aneis pivotantes concéntricos que permiten aos pilotos a rotación libre en todas as direccións +STR_0554 :O coche acelera ao saír da estación mediante motores lineais indutivos, pasando a unha zona da senda vertical e caendo libremente ata regresar á estación. +STR_0555 :Os pasaxeiros soben ou baixan nun ascensor para acceder a diferentes niveis dunha torre vertical. +STR_0556 :Os coches súper anchos descenden completamente verticalmente para a experiencia de caída libre definitiva. +STR_0557 :Un caixeiro automático (máquina de efectivo) para que os visitantes o usen se quedan sen fondos +STR_0558 :Os pasaxeiros viaxan en pares de asentos que xiran ao redor dos extremos de tres longos brazos rotatorios +STR_0559 :Edificio grande tematizado que contén corredores aterradores e salas espantosas +STR_0560 :Un lugar para que os visitantes enfermos vaian para unha recuperación máis rápida +STR_0561 :Espectáculo de animais de circo dentro dunha carpa de gran tamaño +STR_0562 :Os coches autopropulsados ​​percorren unha pista de varios niveis que atravesan paisaxes espantosas e efectos especiais. +STR_0563 :Os pasaxeiros permanecen de pé en vagóns con restricións especiais, pasando por caídas e múltiples inversións. +STR_0564 :Esta montaña rusa de madeira é rápida, áspera, ruidosa e ofrece unha experiencia "descontrolada" con moitas "gotas". +STR_0565 :Unha montaña rusa de madeira con descensos e xiros suaves, onde os coches se manteñen na pista por medio de rodas laterais de fricción e gravidade. +STR_0566 :Os coches individuais xiran nun tramo estreito de vía en zigzag con curvas pronunciadas e descensos. +STR_0567 :Os pasaxeiros, sentados en cadeiras suspendidas a ambos os dous lados da vía, están colgados boca abaixo mentres sofren caídas bruscas e diversas inversións. +STR_0569 :Paseando baixo a pista cun arnés especial, os visitantes experimentan a sensación de voar mentres caen en picado polo aire. +STR_0571 :Os vagóns circulares xiran mentres viaxan pola pista de madeira en zigzag. +STR_0572 :Os barcos de gran capacidade transitan por unha canle ancha, que son impulsados ​​por unha cinta transportadora e despois caen e producen grandes salpicaduras. +STR_0573 :coches con forma de helicópteros corren por unha pista de aceiro controlada polos pedais dos pasaxeiros. +STR_0574 :os pasaxeiros son suxeitos deitados mediante arneses especiais, mentres viaxan por unha vía retorcida con inversións nas costas ou boca abaixo. +STR_0575 :Os trens monorraíl suspendidos transportan persoas polo parque. +STR_0577 :Vagóns que circulan por vías de madeira virando en tramos especiais de marcha atrás. +STR_0578 :Os coches circulan por vías formando aneis e atravesando desniveles e xiros pronunciados. +STR_0579 :Unha partida tranquila de minigolf. +STR_0580 :Unha montaña rusa xigante capaz de baixar suavemente e subir máis de 300 pés. +STR_0581 :Un anel de asentos é arrastrado ata a parte superior dunha torre mentres xira, e despois cae libremente ata deterse suavemente usando freos magnéticos. +STR_0582 :Os visitantes viaxan en vehículos aerodeslizadores que controlan libremente. +STR_0583 :Edificio que contén salas deformadas e corredores inclinados para desorientar as persoas que o percorren +STR_0584 :Bicicletas especiais que circulan nun monorraíl, impulsadas pedaleando. +STR_0585 :Os pasaxeiros sentan en parellas pasando por bucles e inversións. +STR_0586 :Os coches en forma de lancha voadora percorren a ruta da montaña rusa, con curvas pronunciadas e desniveis pronunciados, mergullandose por tramos de auga. +STR_0587 :Despois dun lanzamento emocionante, o coche percorre unha pista vertical ata que se detén e descende verticalmente polo outro lado. +STR_0588 :Coches individuais corren baixo unha pista en zigzag. +STR_0589 :Un gran coche temático de alfombra máxica que se move hacia arriba e abaixo de maneira cíclica nos extremos de 4 brazos +STR_0590 :Os pasaxeiros viaxan nun submarino mergullado que viaxa nunha ruta submarina. +STR_0591 :barcos con forma de balsa viaxan suavemente por un río. +STR_0593 :Roda xiratoria con cápsulas de pasaxeiros suspendidas, que primeiro comeza a xirar e despois é inclinada cara arriba por un brazo de apoio +STR_0598 :Os coches da montaña rusa invertida aceleran saíndo da plataforma e collendo un tramo de vía vertical, despois dan marcha atrás, pasando pola plataforma e subindo por outro tramo de vía vertical. +STR_0599 :Unha montaña rusa compacta con coches individuais e descensos e xiros suaves. +STR_0600 :Trens mineiros autopropulsados ​​percorren unha vía suave e sinuosa. +STR_0602 :Os coches son acelerados por motores lineais de indución. +STR_0603 :Unha montaña rusa de estilo de madeira con vías de aceiro, que permite caídas e inversións pronunciadas. +STR_0604 :Os pasaxeiros viaxan en ringleira por unha estreita vía de monorraíl, mentres corren a través de inversións estreitas e cambios de dirección. +STR_0605 :Os pasaxeiros baixan por unha sinuosa vía de aceiro, freando para controlar a súa velocidade. +STR_0606 :Unha montaña rusa de madeira de estilo antigo cun paseo rápido e áspero, con moitas caídas, algunhas forzas G laterais e deseñada para ofrecer unha experiencia "descontrolada". +STR_0607 :Unha montaña rusa en espiral de aceiro de estilo vintage intenso con xinetes montando de pé. +STR_0767 :Visitante {INT32} +STR_0768 :Manitas {INT32} +STR_0769 :Mecánica {INT32} +STR_0770 :Garda {INT32} +STR_0771 :Animador {INT32} +STR_0777 :Parque sen nome +STR_0778 :Sinal +STR_0779 :1 +STR_0780 :2 +STR_0781 :3 +STR_0782 :4 +STR_0783 :5 +STR_0784 :6 +STR_0785 :7 +STR_0786 :8 +STR_0787 :9 +STR_0788 :10 +STR_0789 :11 +STR_0790 :12 +STR_0791 :13 +STR_0792 :14 +STR_0793 :15 +STR_0794 :16 +STR_0795 :17 +STR_0796 :18 +STR_0797 :19 +STR_0798 :20 +STR_0799 :21 +STR_0800 :22 +STR_0801 :23 +STR_0802 :24 +STR_0803 :25 +STR_0804 :26 +STR_0805 :27 +STR_0806 :28 +STR_0807 :29 +STR_0808 :30 +STR_0809 :31 +STR_0810 :xan +STR_0811 :febr +STR_0812 :marz +STR_0813 :abr +STR_0814 :maio +STR_0815 :Xun +STR_0816 :Xul +STR_0817 :Ago +STR_0818 :set +STR_0819 :out +STR_0820 :nov +STR_0821 :Dec +STR_0822 :Non se puido acceder ao ficheiro de datos gráficos +STR_0823 :falta ou non se pode acceder ao ficheiro +STR_0824 :{BLACK}❌ +STR_0825 :Este nome xa se usa +STR_0826 :Definidos demasiados nomes +STR_0827 :Non hai cartos suficientes: é preciso {CURRENCY2DP} +STR_0828 :Pechar xanela +STR_0829 :Título da xanela - Arrastra para movela +STR_0830 :Ampliar vista +STR_0831 :Reducir a vista +STR_0832 :Xira a cámara 90° no sentido das agullas do reloxo +STR_0833 :Pausa o xogo +STR_0834 :Opcións do xogo +STR_0839 :{UINT16} × {UINT16} +STR_0840 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{UINT16} × {UINT16} +STR_0847 : Acerca de ‘OpenRCT2’ +STR_0850 :{WINDOW_COLOUR_2} © 2002 Chris Sawyer, todos os dereitos reservados +STR_0851 :{WINDOW_COLOUR_2}Deseñado e programado por Chris Sawyer +STR_0852 :{WINDOW_COLOUR_2}Gráficos de Simon Foster +STR_0853 :{WINDOW_COLOUR_2}Sons e música de Allister Brimble +STR_0854 :{WINDOW_COLOUR_2}Sons adicionais gravados por David Ellis +STR_0855 :{WINDOW_COLOUR_2}Renderizado por Jacqui Lyons en Marjacq Ltd. +STR_0856 :{WINDOW_COLOUR_2}Grazas: +STR_0857 :{WINDOW_COLOUR_2}Peter James Adcock, Joe Booth e John Wardley +STR_0865 :{STRINGID} +STR_0866 :{POP16}{STRINGID} +STR_0867 :{POP16}{POP16}{STRINGID} +STR_0868 :{POP16}{POP16}{POP16}{STRINGID} +STR_0869 :{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_0870 :{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_0871 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_0872 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_0873 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_0874 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_0875 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_0876 :{BLACK}▼ +STR_0877 :Demasiado baixo! +STR_0878 :Demasiado alto! +STR_0879 :Non se pode baixar o terreo... +STR_0880 :Non se pode elevar o terreo... +STR_0881 :Un obxecto interfire +STR_0882 :Cargar xogo +STR_0883 :Gardar partida +STR_0884 :Cargar paisaxe +STR_0885 :Gardar paisaxe +STR_0887 :Sae do editor de escenarios +STR_0888 :Saia do editor de Camiños +STR_0889 :Saír do administrador. de estradas +STR_0891 :Facer captura de pantalla +STR_0892 :Captura de pantalla gardada como "{STRINGID}" +STR_0893 :Non se puido facer a captura de pantalla! +STR_0894 :Datos de paisaxe cheos! +STR_0895 :Non podes construír unha parte enriba e outra baixo terra +STR_0896 :Construción de {POP16}{POP16}{STRINGID} +STR_0897 :Enderezo +STR_0898 :Curva á esquerda +STR_0899 :Curva á dereita +STR_0900 :Curva á esquerda (pequena) +STR_0901 :Curva á dereita (pequena) +STR_0902 :Curva á esquerda (moi pequena) +STR_0903 :Curva á dereita (moi pequena) +STR_0904 :Curva á esquerda (grande) +STR_0905 :Curva á dereita (grande) +STR_0906 :En liña recta +STR_0907 :Inclinación +STR_0908 :Rotación/Inclinamento +STR_0909 :Rotación do asento +STR_0910 :Volteo para curva á esquerda +STR_0911 :Volteo para curva á esquerda á dereita +STR_0912 :sen volteo +STR_0913 :Destaca a sección anterior +STR_0914 :Destaca a sección posterior +STR_0915 :Sección de construción +STR_0916 :Eliminar a sección resaltada +STR_0917 :Caída vertical +STR_0918 :Descenso pronunciado +STR_0919 :Costa abaixo +STR_0920 :Nivelado +STR_0921 :Costa arriba +STR_0922 :costa arriba +STR_0923 :Subida Vertical +STR_0924 :Hélice abaixo +STR_0925 :Hélice arriba +STR_0926 :Non se pode eliminar isto... +STR_0927 :Non podes construír isto aquí... +STR_0928 :Cadea de ascensor para impulsar os coches por unha pendente. +STR_0929 :curva en "S" (esquerda) +STR_0930 :curva en "S" (dereita) +STR_0931 :rizo vertical (esquerda) +STR_0932 :rizo vertical (dereita) +STR_0933 :Sube ou baixa primeiro o terreo +STR_0934 :A entrada da atracción interfire +STR_0935 :Interfire a saída da atracción +STR_0936 :A entrada do parque interfire +STR_0937 :Opcións de visualización +STR_0938 :Movementos da terra +STR_0939 :Vista subterránea +STR_0940 :Ocultar terreo base +STR_0941 :Ocultar acantilados +STR_0942 :Ver a través das atraccións +STR_0943 :Ver escenarios +STR_0944 :Gardar +STR_0945 :Non gardar +STR_0946 :Cancelar +STR_0947 :Gardar antes de cargar un novo xogo? +STR_0948 :Gardar antes de saír? +STR_0949 :Gardar antes de saír? +STR_0950 :Cargar xogo +STR_0951 :Sae do xogo +STR_0952 :Sae do xogo +STR_0953 :Cargar paisaxe +STR_0955 :Ángulo de rotación do asento nesta sección +STR_0956 :-180° +STR_0957 :-135° +STR_0958 :-90° +STR_0959 :-45° +STR_0960 :0° +STR_0961 :+45° +STR_0962 :+90° +STR_0963 :+135° +STR_0964 :+180° +STR_0965 :+225° +STR_0966 :+270° +STR_0967 :+315° +STR_0968 :+360° +STR_0969 :+405° +STR_0970 :+450° +STR_0971 :+495° +STR_0972 :Cancelar +STR_0973 :Aceptar +STR_0974 :Atraccións +STR_0975 :Tendas e postos de venda +STR_0976 :aseos e quioscos de información +STR_0977 :Nova atracción de transporte +STR_0978 :Novo paseo suave +STR_0979 :Nova montaña rusa +STR_0980 :Nova atracción intensa +STR_0981 :Nova atracción acuática +STR_0982 :Nova tenda ou posto +STR_0983 :Investigación + Desenvolvemento +STR_0984 :{WINDOW_COLOUR_2}▲{BLACK} {CURRENCY2DP} +STR_0985 :{WINDOW_COLOUR_2}▼{BLACK} {CURRENCY2DP} +STR_0986 :{BLACK}{CURRENCY2DP} +STR_0987 :Demasiadas atraccións/xogos +STR_0988 :Non se pode crear unha nova atracción +STR_0989 :{STRINGID} +STR_0990 :Construción +STR_0991 :Plataforma +STR_0992 :Demoler esta atracción por completo +STR_0993 :Demoler atracción +STR_0994 :Demoler +STR_0995 :{WINDOW_COLOUR_1}Estás seguro de demoler "{STRINGID}" por completo? +STR_0996 :Descrición xeral +STR_0997 :Ver selección +STR_0998 :Non se permiten máis estacións nesta atracción +STR_0999 :Require unha plataforma de estación +STR_1000 :A ruta non completa un circuíto +STR_1001 :ruta non apta para este tipo de tren +STR_1002 :Non se pode abrir {STRINGID}... +STR_1003 :Non se pode probar {STRINGID}... +STR_1004 :Non se pode pechar {STRINGID}... +STR_1005 :Non se pode iniciar a construción en {STRINGID}... +STR_1006 :Debe estar pechado antes +STR_1007 :Non se poden crear suficientes vehículos +STR_1008 :Abre, pecha ou proba esta atracción +STR_1009 :Abrir ou pechar todas as atraccións +STR_1010 :Abre ou pecha o parque +STR_1011 :Pechar todo +STR_1012 :Abrir todo +STR_1013 :Pechar o parque +STR_1014 :Parque aberto +STR_1015 :Non podes operar con máis dunha estación neste modo +STR_1016 :Non podes operar con menos de dúas estacións neste modo +STR_1017 :Non se pode cambiar o modo de funcionamento... +STR_1018 :Non se poden facer cambios... +STR_1019 :Non se poden facer cambios... +STR_1020 :Non se poden facer cambios... +STR_1021  :{POP16}{POP16}{POP16}{POP16}{STRINGID} +STR_1022  :{POP16}{POP16}{POP16}{COMMA16} coche por tren +STR_1023  :{POP16}{POP16}{POP16}{COMMA16} coches por tren +STR_1024  :{COMMA16} coche por tren +STR_1025  :{COMMA16} coches por tren +STR_1026 :plataforma demasiado longa! +STR_1027 :Localiza isto na Vista principal. +STR_1028 :Fóra do bordo do mapa! +STR_1029 :Non se pode construír parte dentro e fóra da auga! +STR_1030 :Só se pode construír baixo a auga! +STR_1031 :Non podes construír isto baixo a auga! +STR_1032 :Só se pode construír na auga! +STR_1033 :Só se pode construír enriba do chan! +STR_1034 :Só se pode construír no chan! +STR_1035 :As autoridades locais prohiben os edificios altos! +STR_1036 :Cargar xogo +STR_1037 :Cargar paisaxe +STR_1038 :Converte a partida gardada en escenario +STR_1039 :Instalar un novo deseño de pista +STR_1040 :Gardar partida +STR_1041 :Gardar escenario +STR_1042 :Gardar paisaxe +STR_1043 :OpenRCT2 Xogos gardados +STR_1044 :Arquivo de escenario OpenRCT2 +STR_1045 :Arquivo de paisaxe OpenRCT2 +STR_1046 :Arquivo de deseño de pistas OpenRCT2 +STR_1047 :Produciuse un erro ao gardar o xogo! +STR_1048 :Fallou o gardar o escenario! +STR_1049 :Produciuse un erro ao gardar a paisaxe! +STR_1050 :Produciuse un erro ao cargar...{NEWLINE}O ficheiro contén datos non válidos! +STR_1051 :Soportes invisibles +STR_1052 :Visitantes invisibles +STR_1053 :Atraccións no parque +STR_1054 :Nome a atracción +STR_1055 :Nome a persoa +STR_1056 :Nomear empregado +STR_1057 :Nome da atracción +STR_1058 :Introduce o nome desta atracción: +STR_1059 :Non se puido cambiar o nome da atracción... +STR_1060 :O nome da atracción non é válido +STR_1061 :Modo normal +STR_1062 :Modo de circuíto continuo +STR_1063 :Modo de inicio invertido +STR_1064 :Modo de lanzamento potenciado (estación de paso) +STR_1065 :Modo lanzadeira +STR_1066 :Modo de aluguer de barcos +STR_1067 :Lanzamento superior +STR_1068 :Modo de elevación rotativa +STR_1069 :Modo estación a estación +STR_1070 :Un paseo para a entrada +STR_1071 :traxes ilimitados por entrada +STR_1072 :Modo labirinto +STR_1073 :Modo de carreira +STR_1074 :modo coche de choque +STR_1075 :Modo de balancín +STR_1076 :Modo de posto de venda +STR_1077 :Modo de rotación +STR_1078 :Rotación cara adiante +STR_1079 :Rotación cara atrás +STR_1080 :Película: "Aviadores emocionados" +STR_1081 :Película 3D: "Colas do rato" +STR_1082 :Modo de aneis espaciais +STR_1083 :Modo principiante +STR_1084 :Lanzamento impulsado por MLI +STR_1085 :Película: "Paxeiros emocionados" +STR_1086 :Película 3D: "Storm Chasers" +STR_1087 :Película 3D: "Space Invaders" +STR_1088 :Modo intenso +STR_1089 :Modo frenético +STR_1090 :modo casa encantada +STR_1091 :Modo espectáculo de circo +STR_1092 :Lanzamento abaixo +STR_1093 :modo de casa torta +STR_1094 :Modo de caída libre +STR_1095 :Modo de circuíto continuo con seccións de bloque +STR_1096 :Lanzamento potenciado (sen estación de paso) +STR_1097 :Modo de lanzamento potenciado en seccións +STR_1098 :Movendose ao final de {POP16}{STRINGID} +STR_1099 :Esperando os pasaxeiros en {POP16}{STRINGID} +STR_1100 :Agardando para saír de {POP16}{STRINGID} +STR_1101 :Saíndo de {POP16}{STRINGID} +STR_1102 :Movéndose a {VELOCITY} +STR_1103 :Chegando a {POP16}{STRINGID} +STR_1104 :Descargando pasaxeiros en {POP16}{STRINGID} +STR_1105 :Viaxe en {VELOCITY} +STR_1106 :Choque! +STR_1107 :Accidente! +STR_1108 :Viaxe en {VELOCITY} +STR_1109 :Bandeando +STR_1110 :xirando +STR_1111 :xirando +STR_1112 :Operando +STR_1113 :Reproducindo película +STR_1114 :xirando +STR_1115 :Operando +STR_1116 :Operando +STR_1117 :Facendo un espectáculo de circo +STR_1118 :Operando +STR_1119 :Agardando polo cable de elevación +STR_1120 :Viaxe en {VELOCITY} +STR_1121 :Parando +STR_1122 :Agardando os pasaxeiros +STR_1123 :Agardando para comezar +STR_1124 :Comeza +STR_1125 :Operando +STR_1126 :Parando +STR_1127 :Descargando pasaxeiros +STR_1128 :Detido polo bloqueo de freada +STR_1129 :Todos os coches da mesma cor +STR_1130 :Diferentes cores por {STRINGID} +STR_1131 :Diferentes cores por vagón +STR_1132 :Coche {POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1133 :Coche {POP16}{COMMA16} +STR_1134  :{POP16}{POP16}{POP16}{POP16}{POP16}{STRINGID} {COMMA16} +STR_1135 :{STRINGID} {COMMA16} +STR_1136 :Seleccione a cor principal +STR_1137 :Seleccione a cor adicional 1 +STR_1138 :Seleccione a cor adicional 2 +STR_1139 :Seleccione a cor dos soportes +STR_1140 :Seleccione o esquema de cores dos carros +STR_1141 :Seleccione que vehículo/tren quere modificar +STR_1142  :{MOVE_X}{10}{STRINGID} +STR_1143 :»{MOVE_X}{10}{STRINGID} +STR_1144 :A entrada a esta atracción non se pode construír nin mover... +STR_1145 :Non podes construír/mover a saída desta atracción... +STR_1146 :Aínda non se creou unha entrada +STR_1147 :Aínda non se construíu unha saída +STR_1148 :Un cuarto de carga +STR_1149 :Media carga +STR_1150 :Carga de tres cuartos +STR_1151 :Carga completa +STR_1152 :Calquer carga +STR_1153 :marcas de altura nas atraccións +STR_1154 :marcas de altura no chan +STR_1155 :marcas de altura nos camiños +STR_1156  :{MOVE_X}{10}{STRINGID} +STR_1157 :✓{MOVE_X}{10}{STRINGID} +STR_1158 :Non se pode eliminar isto... +STR_1159 :Crea decoración, xardíns e outros accesorios +STR_1160 :Crea lagos e axusta a auga +STR_1161 :Non se pode colocar isto aquí... +STR_1162 :{OUTLINE}{TOPAZ}{STRINGID} +STR_1163 :{STRINGID}{NEWLINE}(Prema co botón dereito para modificar) +STR_1164 :{STRINGID}{NEWLINE}(Prema co botón dereito para eliminar) +STR_1165 :{STRINGID} - {STRINGID} {COMMA16} +STR_1166 :Non se pode baixar o nivel da auga... +STR_1167 :Non se pode subir o nivel da auga... +STR_1168 :Opcións +STR_1169 :(Ningún) +STR_1170 :{STRING} +STR_1171 :{RED}Pechado +STR_1172 :{YELLOW}{STRINGID} +STR_1173 :Construír rutas +STR_1174 :O sinal de sinal interfire +STR_1175 :Non se pode construír nunha ladeira +STR_1176 :Non podes construír unha ruta aquí... +STR_1177 :Non podes eliminar este camiño de aquí... +STR_1178 :Pendente do terreo inadecuada +STR_1179 :O camiño interfire +STR_1180 :Non podes construír baixo a auga! +STR_1181 :Rutas +STR_1182 :Tipo +STR_1183 :Enderezo +STR_1184 :Inclinación +STR_1185 :Enderezo +STR_1186 :Costa abaixo +STR_1187 :Nivel do chan +STR_1188 :Costa arriba +STR_1189 :Constrúe o camiño seleccionado +STR_1190 :Eliminar a sección de ruta anterior +STR_1191 :{BLACK}{STRINGID} +STR_1192 :{OUTLINE}{RED}{STRINGID} +STR_1193  :{WINDOW_COLOUR_2}{STRINGID} +STR_1194 :pechado +STR_1195 :En proba +STR_1196 :Aberto +STR_1197 :Averiado +STR_1198 :Accidente! +STR_1199 :{COMMA16} persoa na atracción +STR_1200 :{COMMA16} persoas na atracción +STR_1201 :Ningunha persoa na cola +STR_1202 :1 persoa na cola +STR_1203 :{COMMA16} persoas na cola +STR_1204  :{COMMA16} minuto na cola +STR_1205 :{COMMA16} minutos na cola +STR_1206 :{WINDOW_COLOUR_2}Agarda por: +STR_1207 :{WINDOW_COLOUR_2}Saír se chega outro tren á estación +STR_1208 :{WINDOW_COLOUR_2}Saír se chega outro barco á estación +STR_1209 :Selecciona se queres esperar a unha determinada carga de pasaxeiros antes da saída. +STR_1210 :Selecciona se queres saír se outro vehículo chega á mesma estación. +STR_1211 :{WINDOW_COLOUR_2}Tempo de espera mínimo: +STR_1212 :{WINDOW_COLOUR_2}Tempo de espera máximo: +STR_1213 :Seleccione o tempo mínimo de espera antes de saír +STR_1214 :Seleccione o tempo máximo de espera antes de saír +STR_1215 :{WINDOW_COLOUR_2}Sincronizar coas estacións adxacentes +STR_1216 :Seleccione se desexa sincronizar esta estación con outras estacións adxacentes a esta. +STR_1217  :{COMMA16} segundos +STR_1218 :{BLACK}+ +STR_1219 :{BLACK}- +STR_1220 :Só saída +STR_1221 :Non hai entrada +STR_1222 :Sen saída +STR_1223 :Atraccións de transporte +STR_1224 :Atraccións suaves +STR_1225 :Montañas rusas +STR_1226 :Atraccións intensas +STR_1227 :Atraccións acuáticas +STR_1228 :Tendas e postos de venda +STR_1229 :tren +STR_1230 :trens +STR_1231 :Tren +STR_1232 :Trens +STR_1233 :{COMMA16} tren +STR_1234  :{COMMA16} trens +STR_1235 :Tren {COMMA16} +STR_1236 :barco +STR_1237 :barcos +STR_1238 :Barco +STR_1239 :Barcos +STR_1240 :{COMMA16} bote +STR_1241 :{COMMA16} barcos +STR_1242 :Barco {COMMA16} +STR_1243 :ruta +STR_1244 :camiños +STR_1245 :Vía +STR_1246 :Pistas +STR_1247 :{COMMA16} vía +STR_1248 :{COMMA16} formas +STR_1249 :Vía {COMMA16} +STR_1250 :plataforma de acoplamento +STR_1251 :plataformas de acoplamento +STR_1252 :Plataforma de acoplamento +STR_1253 :Plataformas de atraque +STR_1254 :{COMMA16} plataforma de acoplamento +STR_1255 :{COMMA16} plataformas de acoplamento +STR_1256 :Plataforma de acoplamento {COMMA16} +STR_1257 :a estación +STR_1258 :estacións +STR_1259 :Estación +STR_1260 :Tempadas +STR_1261 :{COMMA16} estación +STR_1262  :{COMMA16} estacións +STR_1263 :Estación {COMMA16} +STR_1264 :coche +STR_1265 :coches +STR_1266 :coche +STR_1267 :Coches +STR_1268 :{COMMA16} coche +STR_1269  :{COMMA16} coches +STR_1270 :Coche {COMMA16} +STR_1271 :edificio +STR_1272 :edificios +STR_1273 :Edificio +STR_1274 :Edificios +STR_1275 :{COMMA16} edificio +STR_1276 :{COMMA16} edificios +STR_1277 :Edificio {COMMA16} +STR_1278 :estructura +STR_1279 :estruturas +STR_1280 :Estrutura +STR_1281 :Estruturas +STR_1282 :{COMMA16} estrutura +STR_1283 :{COMMA16} estruturas +STR_1284 :Estrutura {COMMA16} +STR_1285 :barco +STR_1286 :barcos +STR_1287 :Barco +STR_1288 :Barcos +STR_1289 :{COMMA16} barco +STR_1290  :{COMMA16} envíos +STR_1291 :Barco {COMMA16} +STR_1292 :cabina +STR_1293 :camarotes +STR_1294 ​​​​:Cabana +STR_1295 :Cabanas +STR_1296 :{COMMA16} cabina +STR_1297 :{COMMA16} camarotes +STR_1298 :Cabana {COMMA16} +STR_1299 :roda +STR_1300 :rodas +STR_1301 :Roda +STR_1302 :Rodas +STR_1303 :{COMMA16} roda +STR_1304 :{COMMA16} rodas +STR_1305 :Roda {COMMA16} +STR_1306 :ton +STR_1307 :tons +STR_1308 :Ton +STR_1309 :Tons +STR_1310 :{COMMA16} ton +STR_1311  :{COMMA16} tons +STR_1312 :Ton {COMMA16} +STR_1313 :xogador +STR_1314 :xogadores +STR_1315 :Xogador +STR_1316 :Xogadores +STR_1317 :{COMMA16} xogador +STR_1318  :{COMMA16} xogadores +STR_1319 :Xogador {COMMA16} +STR_1320 :curso +STR_1321 :cursos +STR_1322 :Curso +STR_1323 :Cursos +STR_1324 :{COMMA16} curso +STR_1325 :{COMMA16} cursos +STR_1326 :Curso {COMMA16} +STR_1327 : Xira os obxectos 90° +STR_1328 :Requírese un terreo plano +STR_1329 :{WINDOW_COLOUR_2}Velocidade de lanzamento: +STR_1330 :Velocidade máxima ao saír da estación +STR_1331 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{VELOCITY} +STR_1332 :{VELOCITY} +STR_1333 :{STRINGID} - {STRINGID}{POP16} +STR_1334 :{STRINGID} - {STRINGID} {COMMA16} +STR_1335 :{STRINGID} - Entrada{POP16}{POP16} +STR_1336 :{STRINGID} - Entrada da estación {POP16}{COMMA16} +STR_1337 :{STRINGID} - Saída{POP16}{POP16} +STR_1338 :{STRINGID} - Saída da estación {POP16}{COMMA16} +STR_1339 :{BLACK}Aínda non hai resultados da proba... +STR_1340 :{WINDOW_COLOUR_2}Velocidade máxima: {BLACK}{VELOCITY} +STR_1341 :{WINDOW_COLOUR_2}Tempo da viaxe: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} +STR_1342  :{DURATION} +STR_1343 :{DURATION} / +STR_1344 :{WINDOW_COLOUR_2}Lonxitude da viaxe: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} +STR_1345  :{LENGTH} +STR_1346 :{LENGTH} / +STR_1347 :{WINDOW_COLOUR_2}Velocidade media: {BLACK}{VELOCITY} +STR_1348 :{WINDOW_COLOUR_2}Aceleración máx vertical positiva: {BLACK}{COMMA2DP32}g +STR_1349 :{WINDOW_COLOUR_2}Aceleración máx vertical positiva: {OUTLINE}{RED}{COMMA2DP32}g +STR_1350 :{WINDOW_COLOUR_2}Aceleración máx vertical negativo: {NEGRO}{COMMA2DP32}g +STR_1351 :{WINDOW_COLOUR_2}Aceleración máx vertical negativa: {OUTLINE}{RED}{COMMA2DP32}g +STR_1352 :{WINDOW_COLOUR_2}Aceleración máx lado: {BLACK}{COMMA2DP32}g +STR_1353 :{WINDOW_COLOUR_2}Aceleración máx lado: {OUTLINE}{VERMELLO}{COMMA2DP32}g +STR_1354 :{WINDOW_COLOUR_2}Altura da maior caída: {BLACK}{LENGTH} +STR_1355 :{WINDOW_COLOUR_2}Caídas: {BLACK}{COMMA16} +STR_1356 :{WINDOW_COLOUR_2}Inversións: {BLACK}{COMMA16} +STR_1357 :{WINDOW_COLOUR_2}Buratos: {BLACK}{COMMA16} +STR_1358 :{WINDOW_COLOUR_2}Tempo de "voo" total: {BLACK}{COMMA2DP32}s +STR_1359 :{WINDOW_COLOUR_2}Tempo de espera: {BLACK}{COMMA16} minuto +STR_1360 :{WINDOW_COLOUR_2}Tempo de espera: {BLACK}{COMMA16} minutos +STR_1361 :Non podes cambiar a velocidade... +STR_1362 :Non podes cambiar a velocidade de lanzamento... +STR_1363 :Demasiado alto para soportes! +STR_1364 :Os soportes da sección anterior non se poden ampliar máis! +STR_1365 :xiro en liña (esquerda) +STR_1366 :xiro en liña (dereita) +STR_1367 :rizo medio pequeno +STR_1368 :Medio sacarollas (esquerda) +STR_1369 :Medio sacarollas (dereita) +STR_1370 :Barril (esquerda) +STR_1371 :Barril (dereita) +STR_1372 :Subida motorizada +STR_1373 :rizo medio grande (esquerda) +STR_1374 :rizo medio grande (dereita) +STR_1375 :Transferencia superior +STR_1376 :Baixa transferencia +STR_1377 :Rotación media alt. (dereita) +STR_1378 :Rotación media alt. (esquerda) +STR_1379 :Inversor (esquerda) +STR_1380 :Inversor (dereita) +STR_1381 :subida en curva (esquerda) +STR_1382 :subida en curva (dereita) +STR_1383 :Cuarto de bucle +STR_1384 :{YELLOW}{STRINGID} +STR_1385 :Outro tipo de seccións +STR_1386 :Sección especial... +STR_1387 :Non se pode cambiar o tipo de terreo... +STR_1388 :{OUTLINE}{GREEN}+ {CURRENCY} +STR_1389 :{OUTLINE}{RED}- {CURRENCY} +STR_1390  :{CURRENCY2DP} +STR_1391 :{RED}{CURRENCY2DP} +STR_1392 :Vista da atracción +STR_1393 :Opcións do vehículo +STR_1394 :Opcións de operación +STR_1395 :Opcións de mantemento +STR_1396 :Opcións de esquema de cores +STR_1397 :Opcións de música e sons +STR_1398 :datos de proba e medición +STR_1399 :Gráficos +STR_1400 :Entrada +STR_1401 :Saída +STR_1402 :Construír ou mover a entrada da atracción/xogo +STR_1403 :Construír ou mover a atracción/saída do xogo +STR_1404 :Xirar 90° +STR_1405 :Xirar no espello +STR_1406 :Mostrar ou ocultar a decoración (se está dispoñible) +STR_1407 :{WINDOW_COLOUR_2}Constrúe isto... +STR_1408 :{WINDOW_COLOUR_2}Prezo: {BLACK}{CURRENCY} +STR_1409 :Estación +STR_1410 :Sección vertical +STR_1411 :{STRINGID} no medio +STR_1412 :{WINDOW_COLOUR_3}Non están dispoñibles as estatísticas para este tipo de atracción +STR_1413 :{WINDOW_COLOUR_3}As estatísticas comezarán a gravarse cando {STRINGID} saia de {STRINGID} +STR_1414  :{BLACK}{DURATION} +STR_1415 :{WINDOW_COLOUR_2}Velocidade +STR_1416 :{WINDOW_COLOUR_2}Altitude +STR_1417 :{WINDOW_COLOUR_2}Forzas G Vert. +STR_1418 :{WINDOW_COLOUR_2}Forzas G lat. +STR_1419  :{BLACK}{VELOCITY} +STR_1420  :{BLACK}{LENGTH} +STR_1421 :{BLACK}{COMMA16}g +STR_1422 :Gardando datos de {POP16}{STRINGID} +STR_1423 :cola de espera +STR_1424 :Ruta +STR_1425 :Ruta +STR_1426 :liña de espera +STR_1427 :{WINDOW_COLOUR_2}Clientes: {BLACK}{COMMA32} por hora +STR_1428 :{WINDOW_COLOUR_2}Prezo de entrada: +STR_1429  :{POP16}{POP16}{POP16}{CURRENCY2DP} +STR_1430 :Gratis +STR_1431 :Camiñando +STR_1432 :enderezo {STRINGID} +STR_1433 :Agardando en {STRINGID} +STR_1434 :Afogando +STR_1435 :En {STRINGID} +STR_1436 :En {STRINGID} +STR_1437 :En {STRINGID} +STR_1438 :Sentado +STR_1439 :(seleccionar unha nova localización) +STR_1440 :Cortar a herba +STR_1441 :Camiño amplo +STR_1442 :Baleirando o lixo +STR_1443 :Regando os xardíns +STR_1444 :Mirando a {STRINGID} +STR_1445 :Vendo a construción de {STRINGID} +STR_1446 :Observando a decoración +STR_1447 :Saíndo do parque +STR_1448 :Ollando a construción da nova atracción +STR_1449 :{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) +STR_1450 :{INLINE_SPRITE}{09}{20}{00}{00}{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) +STR_1451 :{STRINGID}{NEWLINE}({STRINGID}) +STR_1452 :Nomear visitante +STR_1453 :Introduza o nome deste visitante: +STR_1454 :Non se pode cambiar o nome do visitante... +STR_1455 :Nome non válido para o visitante +STR_1456 :{WINDOW_COLOUR_2}Diñeiro gastado: {BLACK}{CURRENCY2DP} +STR_1457 :{WINDOW_COLOUR_2}Diñeiro no peto: {BLACK}{CURRENCY2DP} +STR_1458 :{WINDOW_COLOUR_2}Hora do estacionamento: {BLACK}{REALTIME} +STR_1459 :Estilo de pista +STR_1460 :pista en forma de "U". +STR_1461 :Pista en forma de "O". +STR_1462 :Demasiado inclinado para a subida +STR_1463 :Visitantes +STR_1464 :Hélice ascendente (pequena) +STR_1465 :Hélice arriba (grande) +STR_1466 :Hélice abaixo (pequena) +STR_1467 :Hélice abaixo (grande) +STR_1468 :Empleados +STR_1469 :A atracción debe comezar e rematar coas estacións. +STR_1470 :A estación non é suficientemente longa. +STR_1471 :{WINDOW_COLOUR_2}Velocidade: +STR_1472 :Velocidade desta atracción +STR_1473 :{WINDOW_COLOUR_2}Nivel de emoción: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1474 :{WINDOW_COLOUR_2}Nivel de emoción: {BLACK}Aínda non está dispoñible +STR_1475 :{WINDOW_COLOUR_2}Nivel de intensidade: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1476 :{WINDOW_COLOUR_2}Nivel de intensidade: {BLACK}Aínda non dispoñible +STR_1477 :{WINDOW_COLOUR_2}Nivel de intensidade: {OUTLINE}{RED}{COMMA2DP32} ({STRINGID}) +STR_1478 :{WINDOW_COLOUR_2}Nivel de náuseas: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1479 :{WINDOW_COLOUR_2}Nivel de náuseas: {BLACK}Aínda non está dispoñible +STR_1480 :“Non podo pagar por {STRINGID}” +STR_1481 :"Gastei todo o meu diñeiro" +STR_1482 :"Síntome mareado" +STR_1483 :"Síntome moi mareado" +STR_1484 :"Quero probar algo máis arriscado que {STRINGID}" +STR_1485 :“{STRINGID} paréceme demasiado intenso” +STR_1486 :"Aínda non rematei o meu {STRINGID}" +STR_1487 :"Só mirar a {STRINGID} dáme mareo" +STR_1488 :"Non vou pagar tanto por entrar en {STRINGID}" +STR_1489 :"Quero ir a casa" +STR_1490 :“{STRINGID} é barato” +STR_1491 :"Xa teño {STRINGID}" +STR_1492 :"Non podo pagar por {STRINGID}" +STR_1493 :"Non teño fame" +STR_1494 :"Non teño sede" +STR_1495 :"Axuda! Estou afogando!" +STR_1496 :"Estou perdido!" +STR_1497 :“{STRINGID} foi xenial” +STR_1498 :"Eu esperei para sempre en {STRINGID}" +STR_1499 :"Estou canso" +STR_1500 :"Teño fame" +STR_1501 :"Teño sede" +STR_1502 :"Teño que ir ao baño" +STR_1503 :"Non podo atopar {STRINGID}" +STR_1504 :"Non vou pagar tanto por {STRINGID}" +STR_1505 :"Non vou subir a {STRINGID} mentres chove" +STR_1506 :"As papeleiras aquí destacan pola súa ausencia" +STR_1507 :"Non podo atopar a saída" +STR_1508 :"Quero baixar de {STRINGID}" +STR_1509 :"Quero saír de {STRINGID}" +STR_1510 :"Non vou cargar {STRINGID}, non é seguro" +STR_1511 :"Este camiño é noxento" +STR_1512 :"Hai demasiada xente aquí" +STR_1513 :"O vandalismo é terrible" +STR_1514 :"A paisaxe é fermosa!" +STR_1515 :"Este parque está moi limpo e ordenado" +STR_1516 :"As fontes de salto son xeniais" +STR_1517 :"A música é agradable" +STR_1518 :"Este globo {STRINGID} é barato" +STR_1519 :"Este xoguete {STRINGID} é barato" +STR_1520 :“Este mapa de {STRINGID} é barato” +STR_1521 :"Esta foto de {STRINGID} é barata" +STR_1522 :"Este paraugas {STRINGID} é barato" +STR_1523 :"Esta bebida {STRINGID} é barata" +STR_1524 :"Esta hamburguesa {STRINGID} é barata" +STR_1525 :"Estas patacas fritas de {STRINGID} son baratas" +STR_1526 :"Este xeado de {STRINGID} é barato" +STR_1527 :"Este algodón de {STRINGID} é barato" +STR_1528 : +STR_1529 : +STR_1530 : +STR_1531 :"Esta pizza de {STRINGID} é barata" +STR_1532: +STR_1533 :"Esta palomita de {STRINGID} é barata" +STR_1534 :"Este cachorro {STRINGID} é barato" +STR_1535 :"Este tentáculo {STRINGID} é barato" +STR_1536 :"Este sombreiro {STRINGID} é barato" +STR_1537 :"Este {STRINGID} Apple é barato" +STR_1538 :"Esta camiseta de {STRINGID} é barata" +STR_1539 :"Esta rosquilla {STRINGID} é barato" +STR_1540 :"Este café de {STRINGID} é barato" +STR_1541 : +STR_1542 :"Este polo frito de {STRINGID} é barato" +STR_1543 :"Esta limoada de {STRINGID} é barata" +STR_1544 : +STR_1545 : +STR_1546 : +STR_1547 : +STR_1548 : +STR_1549 : +STR_1550 :"Uau!" +STR_1551 :"Teño a estraña sensación de que alguén me está observando" +STR_1552 :"Non vou pagar tanto polo globo {STRINGID}" +STR_1553 :"Non vou pagar tanto polo xoguete de {STRINGID}" +STR_1554 :"Non vou pagar tanto polo mapa {STRINGID}" +STR_1555 :"Non vou pagar tanto pola foto de {STRINGID}" +STR_1556 :"Non vou pagar tanto polo paraugas de {STRINGID}" +STR_1557 :"Non vou pagar tanto pola bebida de {STRINGID}" +STR_1558 :"Non vou pagar tanto pola hamburguesa de {STRINGID}" +STR_1559 :"Non vou pagar tanto por {STRINGID} patacas fritas" +STR_1560 :"Non vou pagar tanto polo xeado de {STRINGID}" +STR_1561 :"Non vou pagar tanto polo algodón {STRINGID}" +STR_1562 : +STR_1563 : +STR_1564 : +STR_1565 :"Non vou pagar tanto pola pizza de {STRINGID}" +STR_1566 : +STR_1567 :"Non vou pagar tanto polas palomitas de millo de {STRINGID}" +STR_1568 :"Non vou pagar tanto polo hot dog de {STRINGID}" +STR_1569 :"Non vou pagar tanto polo tentáculo de {STRINGID}" +STR_1570 :"Non vou pagar tanto polo sombreiro de {STRINGID}" +STR_1571 :"Non vou pagar tanto por unha mazá de caramelo de {STRINGID}" +STR_1572 :"Non vou pagar tanto pola camiseta de {STRINGID}" +STR_1573 :"Non vou pagar tanto pola rosquilla de {STRINGID}" +STR_1574 :"Non vou pagar tanto polo café de {STRINGID}" +STR_1575 : +STR_1576 :"Non vou pagar tanto polo polo frito de {STRINGID}" +STR_1577 :"Non vou pagar tanto pola limoada de {STRINGID}" +STR_1578 : +STR_1579 : +STR_1580 : +STR_1581 : +STR_1582 : +STR_1583 : +STR_1584 :"Esta foto de {STRINGID} é barata" +STR_1585 :"Esta foto de {STRINGID} é barata" +STR_1586 :"Esta foto de {STRINGID} é barata" +STR_1587 :"Esta galleta salgada {STRINGID} é barata" +STR_1588 :"Este chocolate quente de {STRINGID} é barato" +STR_1589 :"Este té {STRINGID} é barato" +STR_1590 :"Este bolo de funil de {STRINGID} é barato" +STR_1591 :"Estes lentes {STRINGID} son baratos" +STR_1592 :"Estes fideos de tenreira de {STRINGID} son baratos" +STR_1593 :"Este arroz frito de {STRINGID} é barato" +STR_1594 :"Esta sopa wonton de {STRINGID} é barata" +STR_1595 :"Esta sopa de albóndegas de {STRINGID} é barata" +STR_1596 :"Este zume {STRINGID} é barato" +STR_1597 :"Este leite de soia de {STRINGID} é barato" +STR_1598 :"Este Sujeonggwa de {STRINGID} é barato" +STR_1599 :"Este sándwich de {STRINGID} é barato" +STR_1600 :"Esta galleta de {STRINGID} é barata" +STR_1601 : +STR_1602 : +STR_1603 : +STR_1604 :"Esta salchicha asada de {STRINGID} é barata" +STR_1605 : +STR_1606 : +STR_1607 : +STR_1608 : +STR_1609 : +STR_1610 : +STR_1611 : +STR_1612 : +STR_1613 : +STR_1614 : +STR_1615 : +STR_1616 :"Non vou pagar tanto pola foto de {STRINGID}" +STR_1617 :"Non vou pagar tanto pola foto de {STRINGID}" +STR_1618 :"Non vou pagar tanto pola foto de {STRINGID}" +STR_1619 :"Non vou pagar tanto pola galleta salgada de {STRINGID}" +STR_1620 :"Non vou pagar tanto polo chocolate quente de {STRINGID}" +STR_1621 :"Non vou pagar tanto polo té de {STRINGID}" +STR_1622 :"Non vou pagar tanto polo bolo de funil de {STRINGID}" +STR_1623 :"Non vou pagar tanto polos {STRINGID} lentes" +STR_1624 :"Non vou pagar tanto polos fideos de {STRINGID}" +STR_1625 :"Non vou pagar tanto polo arroz frito de {STRINGID}" +STR_1626 :"Non vou pagar tanto pola sopa wonton de {STRINGID}" +STR_1627 :"Non vou pagar tanto pola sopa de albóndegas de {STRINGID}" +STR_1628 :"Non vou pagar tanto por zumes de froitas de {STRINGID}" +STR_1629 :"Non vou pagar tanto por {STRINGID} leite de soia" +STR_1630 :"Non vou pagar tanto polo Sujeonggwa de {STRINGID}" +STR_1631 :"Non vou pagar tanto polo bocadillo de {STRINGID}" +STR_1632 :"Non vou pagar tanto pola galleta de {STRINGID}" +STR_1633 : +STR_1634 : +STR_1635 : +STR_1636 :"Non vou pagar tanto pola salchicha asada de {STRINGID}" +STR_1637 : +STR_1638 : +STR_1639 : +STR_1640 : +STR_1641 : +STR_1642 : +STR_1643 : +STR_1644 : +STR_1645 : +STR_1646 : +STR_1647 : +STR_1648 :"Axuda! "Báixame!" +STR_1649 :"Estou sen cartos!" +STR_1650 :"Uau! Están construíndo unha nova atracción!" +STR_1653 :"...E aquí estamos en {STRINGID}!" +STR_1654 :{WINDOW_COLOUR_2}Pensamentos recentes: +STR_1655 :Constrúe unha pista a nivel do chan. +STR_1656 :Construír ponte ou túnel. +STR_1657 :{WINDOW_COLOUR_2}Atracción favorita: +STR_1658 :{WINDOW_COLOUR_2}Intensidade: {BLACK}menos que {COMMA16} +STR_1659 :{WINDOW_COLOUR_2}Intensidade: {BLACK}entre {COMMA16} e {COMMA16} +STR_1660 :{WINDOW_COLOUR_2}Intensidade: {BLACK}máis de {COMMA16} +STR_1661 :{WINDOW_COLOUR_2}Tolerancia ás náuseas: {BLACK}{STRINGID} +STR_1662 :{WINDOW_COLOUR_2}Felicidade: +STR_1663 :{WINDOW_COLOUR_2}Náuseas: +STR_1664 :{WINDOW_COLOUR_2}Potencia: +STR_1665 :{WINDOW_COLOUR_2}Fame: +STR_1666 :{WINDOW_COLOUR_2}Sede: +STR_1667 :{WINDOW_COLOUR_2}Vexiga: +STR_1668 :{WINDOW_COLOUR_2}Satisfacción {BLACK}Descoñecido +STR_1669 :{WINDOW_COLOUR_2}Satisfacción: {BLACK}{COMMA16}% +STR_1670 :{WINDOW_COLOUR_2}Clientes totais: {BLACK}{COMMA32} +STR_1671 :{WINDOW_COLOUR_2}Beneficio total: {BLACK}{CURRENCY2DP} +STR_1672 :Freos +STR_1673 :Peza para activar a rotación +STR_1674 :Velocidade do freo +STR_1675  :{POP16}{VELOCITY} +STR_1676 :Establece o límite de velocidade para os freos +STR_1677 :{WINDOW_COLOUR_2}Popularidade: {BLACK}Descoñecido +STR_1678 :{WINDOW_COLOUR_2}Popularidade: {BLACK}{COMMA16}% +STR_1679 :Hélice arriba (esquerda) +STR_1680 :Hélice arriba (dereita) +STR_1681 :Hélice abaixo (esquerda) +STR_1682 :Hélice abaixo (dereita) +STR_1683 :Tamaño base 2 × 2 +STR_1684 :Tamaño base 4×4 +STR_1685 :Tamaño base 2 × 4 +STR_1686 :Tamaño base 5 × 1 +STR_1687 :Salpicaduras de auga +STR_1688 :Tamaño base 4 × 1 +STR_1689 :Bloque de freado +STR_1690 :{WINDOW_COLOUR_2}{STRINGID}{NEWLINE}{BLACK}{STRINGID} +STR_1691 :{WINDOW_COLOUR_2} Prezo: {BLACK}{CURRENCY} +STR_1692 :{WINDOW_COLOUR_2} Prezo: {BLACK}desde {CURRENCY} +STR_1693 :Visitantes +STR_1694 :Empleados +STR_1695 :Ingresos e custos +STR_1696 :Información do cliente +STR_1697 :Non se pode poñer na cola +STR_1698 :Só se pode colocar na cola de espera +STR_1699 :Moita xente no xogo. +STR_1700 :Contratar un novo obreiro +STR_1701 :Contrata un novo mecánico +STR_1702 :Contratar un novo garda +STR_1703 :Contratar un novo animador +STR_1704 :Non podes contratar novos empregados... +STR_1705 :Empleado de bombeiros +STR_1706 :Mover esta persoa a outra posición +STR_1707 :Moitos empregados no parque. +STR_1708 :Establecer zona de patrulla para este empregado +STR_1709 :Empleado de bombeiros +STR_1710 :Si +STR_1711 :{WINDOW_COLOUR_1}Estás seguro de disparar a {STRINGID}? +STR_1712  :{INLINE_SPRITE}{247}{19}{00}{00}{WINDOW_COLOUR_2}Limpar camiños +STR_1713 :{INLINE_SPRITE}{248}{19}{00}{00}{WINDOW_COLOUR_2}Plantas de rego +STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}Lixos baleiros +STR_1715 :{INLINE_SPRITE}{250}{19}{00}{00}{WINDOW_COLOUR_2}Cortar a herba +STR_1716 :Nome do parque non válido +STR_1717 :O parque non se pode renomear... +STR_1718 :Nome do Parque +STR_1719 :Introduce o novo nome do parque: +STR_1720 :Nome do Parque +STR_1721 :Parque pechado +STR_1722 :Parque aberto +STR_1723 :Non podes abrir o parque... +STR_1724 :Non podes pechar o parque... +STR_1725 :Non podes mercar terreos... +STR_1726 :Terreo non á venda! +STR_1727 :Os dereitos de construción non están á venda! +STR_1728 :Non podes comprar aquí os dereitos de construción... +STR_1729 :O terreo non é propiedade do parque! +STR_1730 :{RED}Pechado +STR_1731 :{WHITE}{STRINGID} - - +STR_1732 :Construír +STR_1733 :Modo +STR_1734 :{WINDOW_COLOUR_2}Número de voltas: +STR_1735 :Número de voltas do circuíto +STR_1736 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1738 :Non podes cambiar o número de voltas... +STR_1739 :Carreira gañada polo visitante {INT32} +STR_1740 :Carreira gañada por {STRINGID} +STR_1741 :Aínda non se construíu! +STR_1742 :{WINDOW_COLOUR_2}Máximo de persoas na atracción: +STR_1743 :Número máximo de persoas permitidos nesta atracción ao mesmo tempo +STR_1744 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1746 :Non podes cambiar isto... +STR_1747 :{WINDOW_COLOUR_2}Límite de tempo: +STR_1748 :límite de tempo da atracción +STR_1749 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{DURATION} +STR_1751 :Non podes cambiar o límite de tempo para esta atracción... +STR_1752 :Mostrar a lista de visitantes no parque +STR_1753 :Mostrar a lista agrupada de visitantes do parque +STR_1754 :{BLACK}{COMMA32} visitantes +STR_1755 :{BLACK}{COMMA32} visitante +STR_1756 :{WINDOW_COLOUR_2}Prezo de entrada: +STR_1757 :{WINDOW_COLOUR_2}Fiabilidade: {MOVE_X}{255}{BLACK}{COMMA16}% +STR_1758 :Modo de construción +STR_1759 :Modo de movemento +STR_1760 :Modo de recheo +STR_1761 :Constrúe un labirinto nesta dirección +STR_1762 :Fervenzas +STR_1763 :Rápidos +STR_1764 :rexistro de accesos +STR_1765 :Cámara +STR_1766 :Tocadiscos inverso +STR_1767 :Túnel xiratorio +STR_1768 :Non podes cambiar o número de balanceos... +STR_1769 :{WINDOW_COLOUR_2}Número de balanceos: +STR_1770 :Número de balanceos completos +STR_1771 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1773 :Só se permite unha sección de fotos por atracción. +STR_1774 :Só un cable de elevación por atracción. +STR_1777 :Música de atracción +STR_1778 :{STRINGID} - - +STR_1779 :{INLINE_SPRITE}{254}{19}{00}{00} Traxe de panda +STR_1780 :{INLINE_SPRITE}{255}{19}{00}{00} Traxe de tigre +STR_1781 :{INLINE_SPRITE}{00}{20}{00}{00} Traxe de elefante +STR_1782 :{INLINE_SPRITE}{01}{20}{00}{00} Traxe romano +STR_1783 :{INLINE_SPRITE}{02}{20}{00}{00} Traxe de gorila +STR_1784 :{INLINE_SPRITE}{03}{20}{00}{00} Traxe de boneco de neve +STR_1785 :{INLINE_SPRITE}{04}{20}{00}{00} Traxe de cabaleiro +STR_1786 :{INLINE_SPRITE}{05}{20}{00}{00} Traxe de astronauta +STR_1787 :{INLINE_SPRITE}{06}{20}{00}{00} Traxe de bandido +STR_1788 :{INLINE_SPRITE}{07}{20}{00}{00} Traxe de shériff +STR_1789 :{INLINE_SPRITE}{08}{20}{00}{00} Traxe de pirata +STR_1790 :Seleccione a cor do uniforme para este tipo de empregados +STR_1791 :{WINDOW_COLOUR_2}Cor uniforme: +STR_1792 :enderezo {STRINGID} +STR_1793 :Indo a inspeccionar {STRINGID} +STR_1794 :Correxindo {STRINGID} +STR_1795 :Respondendo a chamada +STR_1796 :Avaría e require reparación +STR_1798 :Remuíño +STR_1799  :{POP16}{POP16}{POP16}{POP16}{POP16}{CURRENCY2DP} +STR_1800 :Parada de seguridade +STR_1801 :Retencións atascadas pechadas +STR_1802 :As retencións quedaron abertas +STR_1803 :Portas pechadas +STR_1804 :Portas abertas +STR_1805 :Avaría do vehículo +STR_1806 :Fallo do freo +STR_1807 :Fallo de control +STR_1808 :{WINDOW_COLOUR_2}Último fallo: {BLACK}{STRINGID} +STR_1809 :{WINDOW_COLOUR_2}Fallo actual: {OUTLINE}{RED}{STRINGID} +STR_1810  :{WINDOW_COLOUR_2}Leva: +STR_1811 :Non podes construír isto aquí... +STR_1812 :{BLACK}{STRINGID} +STR_1813 :Obxectos varios +STR_1814 :Accións +STR_1815 :Pensamentos +STR_1816 :Seleccione o tipo de información para mostrar na lista de visitantes +STR_1817 :({COMMA32}) +STR_1818 :{WINDOW_COLOUR_2}Todos os visitantes +STR_1819 :{WINDOW_COLOUR_2}Todos os visitantes (agrupados) +STR_1820  :{WINDOW_COLOUR_2}Visitantes {STRINGID} +STR_1821 :{WINDOW_COLOUR_2}Visitantes pensando {SMALLFONT}{STRINGID} +STR_1822 :{WINDOW_COLOUR_2}Visitantes pensando en {POP16}{STRINGID} +STR_1823 :Mostra os pensamentos dos visitantes sobre esta atracción +STR_1824 :Mostra aos visitantes desta atracción +STR_1825 :Mostra os visitantes que esperan para subir a esta atracción +STR_1826 :Estado +STR_1827 :Popularidade +STR_1828 :Satisfacción +STR_1829 :Beneficio +STR_1830 :Tamaño da cola +STR_1831 :Hora da cola +STR_1832 :Fiabilidade +STR_1833 :fallo de tempo +STR_1834 :Favorito de +STR_1835 :Popularidade: descoñecido +STR_1836 :Popularidade: {COMMA16}% +STR_1837 :Satisfacción: descoñecido +STR_1838 :Satisfacción: {COMMA16}% +STR_1839 :Fiabilidade: {COMMA16}% +STR_1840 :Fallo de tempo: {COMMA16}% +STR_1841 :Beneficio: {CURRENCY2DP} por hora +STR_1842 :Favorito de: {COMMA32} visitante +STR_1843 :Favorito de: {COMMA32} visitantes +STR_1844 :Seleccione o tipo de información para mostrar na lista +STR_1845  :{MONTHYEAR} +STR_1846  :{COMMA32} visitantes +STR_1847  :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA32} visitantes +STR_1848  :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA32} visitantes +STR_1849 :{WINDOW_COLOUR_2}Reproducir música +STR_1850 :Activa a música para esta atracción. +STR_1851 :{WINDOW_COLOUR_2}Custo operativo: {BLACK}{CURRENCY2DP} por hora +STR_1852 :{WINDOW_COLOUR_2}Custo de funcionamento: {BLACK}Descoñecido +STR_1853 :{WINDOW_COLOUR_2}Construción: {BLACK}Este ano +STR_1854 :{WINDOW_COLOUR_2}Construción: {BLACK}O ano pasado +STR_1855 :{WINDOW_COLOUR_2}Construción: {BLACK}{COMMA16} anos +STR_1856 :{WINDOW_COLOUR_2}Beneficio por artigo: {BLACK}{CURRENCY2DP} +STR_1857 :{WINDOW_COLOUR_2}Perdas por artigo: {BLACK}{CURRENCY2DP} +STR_1858 :{WINDOW_COLOUR_2}Custo: {BLACK}{CURRENCY} ao mes +STR_1859 :manitas +STR_1860 :mecánico +STR_1861 :gardas de seguridade +STR_1862 :animadores +STR_1863 :práctico +STR_1864 :mecánico +STR_1865 :garda de seguridade +STR_1866 :animador +STR_1867 :{BLACK}{COMMA32} {STRINGID} +STR_1868 :Non podes cambiar o número de voltas... +STR_1869 :{WINDOW_COLOUR_2}Número de voltas: +STR_1870 :Número de voltas completas +STR_1871 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1873 :{WINDOW_COLOUR_2}Ingresos: {BLACK}{CURRENCY2DP} por hora +STR_1874 :{WINDOW_COLOUR_2}Beneficio: {BLACK}{CURRENCY2DP} por hora +STR_1875 :{BLACK} {SPRITE}{BLACK} {STRINGID} +STR_1876 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{251}{19}{00}{00}Inspeccionar as atraccións +STR_1877 :{WINDOW_COLOUR_2}{INLINE_SPRITE}{252}{19}{00}{00}Reparar atraccións +STR_1878 :{WINDOW_COLOUR_2}Inspección: +STR_1879 :Cada 10 minutos +STR_1880 :Cada 20 minutos +STR_1881 :Cada 30 minutos +STR_1882 :Cada 45 minutos +STR_1883 :Cada hora +STR_1884 :Cada 2 horas +STR_1885 :Xamais +STR_1886 :Inspeccionando {STRINGID} +STR_1887 :{WINDOW_COLOUR_2}Tempo desde a última inspección: {BLACK}{COMMA16} minutos +STR_1888 :{WINDOW_COLOUR_2}Tempo desde a última inspección: {BLACK}máis de 4 horas +STR_1889 :{WINDOW_COLOUR_2}Tempo de espera: {MOVE_X}{255}{BLACK}{COMMA16}% +STR_1890 :Selecciona a frecuencia con que un mecánico debe inspeccionar esta atracción +STR_1891 :Aínda non hai {STRINGID} no parque! +STR_1894 :{WINDOW_COLOUR_2}{STRINGID} vendido: {BLACK}{COMMA32} +STR_1895 :Construír unha nova atracción +STR_1896 :{WINDOW_COLOUR_2}Gastos/Ingresos +STR_1897 :{WINDOW_COLOUR_2}Construción da atracción. +STR_1898 :{WINDOW_COLOUR_2}Operación de acoplamento +STR_1899 :{WINDOW_COLOUR_2}Compra de terreos +STR_1900 :{WINDOW_COLOUR_2}Decorado +STR_1901 :{WINDOW_COLOUR_2}Entradas ao parque +STR_1902 :{WINDOW_COLOUR_2}Entradas para atraccións +STR_1903 :{WINDOW_COLOUR_2}Vendas na tenda +STR_1904 :{WINDOW_COLOUR_2}Gastos de almacenamento +STR_1905 :{WINDOW_COLOUR_2}Venda de alimentos/bebidas +STR_1906 :{WINDOW_COLOUR_2}Gastos de comida/bebida +STR_1907 :{WINDOW_COLOUR_2}Salarios do persoal +STR_1908 :{WINDOW_COLOUR_2}Márketing +STR_1909 :{WINDOW_COLOUR_2}Investigación +STR_1910 :{WINDOW_COLOUR_2}Interese de crédito +STR_1911  :{BLACK} a {COMMA16} % ao ano +STR_1912  :{MES} +STR_1913  :{BLACK}+{CURRENCY2DP} +STR_1914  :{BLACK}{CURRENCY2DP} +STR_1915  :{RED}{CURRENCY2DP} +STR_1916 :{WINDOW_COLOUR_2}Préstamo: +STR_1917  :{POP16}{POP16}{POP16}{CURRENCY} +STR_1918 :Non podes pedir máis cartos! +STR_1919 :Non tes diñeiro suficiente! +STR_1920 :Non podes devolver o préstamo! +STR_1921 :Comezar un novo xogo +STR_1922 :Continuar partida gardada +STR_1924 :Sae do xogo +STR_1925 :Non podes colocar a esta persoa aquí... +STR_1927 :{YELLOW}{STRINGID} rompeuse +STR_1928 :{RED}{STRINGID} fallou! +STR_1929 :{RED}{STRINGID} non arranxado{NEWLINE}Comproba onde están os teus mecánicos e considera organizalos mellor +STR_1930 :Activar/Desactivar o seguimento deste visitante (Co seguimento activado, os movementos deste visitante aparecerán na área de mensaxes) +STR_1931  :{STRINGID} está facendo cola en {STRINGID} +STR_1932  :{STRINGID} está en {STRINGID} +STR_1933  :{STRINGID} está en {STRINGID} +STR_1934  :{STRINGID} saíu de {STRINGID} +STR_1935 :{STRINGID} saíu do parque +STR_1936  :{STRINGID} comprou {STRINGID} +STR_1937 :Mostra información sobre o asunto desta mensaxe +STR_1938 :Mostrar a vista do visitante +STR_1939 :Mostrar a vista do empregado +STR_1940 :Mostra felicidade, enerxía, fame, etc. deste visitante +STR_1941 :Mostra en que atraccións visitou este visitante +STR_1942 :Mostrar información financeira sobre este visitante +STR_1943 :Mostra os pensamentos recentes deste visitante +STR_1944 :Mostra os obxectos que leva este visitante +STR_1945 :Mostrar pedidos e opcións para este empregado +STR_1946 :Escolle un traxe para este animador +STR_1947 :Mostra as áreas patrulladas por este tipo de empregados e localiza o empregado máis próximo +STR_1948 :Contrata un novo empregado do tipo seleccionado +STR_1949 :Resumo financeiro +STR_1950 :Gráfica de Finanzas +STR_1951 :Gráfica do valor do parque +STR_1952 :Gráfica de beneficios +STR_1953 :Márketing +STR_1954 :Investimento en Innovación e Desenvolvemento +STR_1955 :{WINDOW_COLOUR_2}Número de circuítos: +STR_1956 :Número de circuítos por atracción +STR_1957  :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_1958  :{COMMA16} +STR_1959 :Non se pode cambiar o número de circuítos... +STR_1960  :{WINDOW_COLOUR_2}Prezo do globo: +STR_1961 :{WINDOW_COLOUR_2}Prezo do xoguete: +STR_1962 :{WINDOW_COLOUR_2}Prezo do mapa: +STR_1963 :{WINDOW_COLOUR_2}Prezo da foto: +STR_1964  :{WINDOW_COLOUR_2}Prezo do paraugas: +STR_1965  :{WINDOW_COLOUR_2}Prezo da bebida: +STR_1966  :{WINDOW_COLOUR_2}Prezo da hamburguesa: +STR_1967 :{WINDOW_COLOUR_2}Prezo das patacas fritas: +STR_1968 :{WINDOW_COLOUR_2}Prezo do xeado: +STR_1969 :{WINDOW_COLOUR_2}Prezo do algodón de azucre: +STR_1970 :{WINDOW_COLOUR_2} +STR_1971 :{WINDOW_COLOUR_2} +STR_1972 :{WINDOW_COLOUR_2} +STR_1973  :{WINDOW_COLOUR_2}Prezo da pizza: +STR_1974 :{WINDOW_COLOUR_2} +STR_1975  :{WINDOW_COLOUR_2}Prezo das palomitas: +STR_1976  :{WINDOW_COLOUR_2}Prezo de hot dogs: +STR_1977  :{WINDOW_COLOUR_2}Prezo de tentáculo: +STR_1978  :{WINDOW_COLOUR_2}Prezo do sombreiro: +STR_1979  :{WINDOW_COLOUR_2}Prezo de Apple: +STR_1980  :{WINDOW_COLOUR_2}Prezo da camiseta: +STR_1981  :{WINDOW_COLOUR_2}Prezo da rosquilla: +STR_1982  :{WINDOW_COLOUR_2}Prezo do café: +STR_1983 :{WINDOW_COLOUR_2} +STR_1984 :{WINDOW_COLOUR_2}Prezo do polo frito: +STR_1985 :{WINDOW_COLOUR_2}Prezo da limonada: +STR_1986 :{WINDOW_COLOUR_2} +STR_1987 :{WINDOW_COLOUR_2} +STR_1988 :Globo +STR_1989 :Xoguete +STR_1990 :Mapa do parque +STR_1991 :Foto na atracción +STR_1992 :Parasol +STR_1993 :Bebida +STR_1994 :Hamburguesa +STR_1995 :Patacas fritas +STR_1996 :Xeado +STR_1997 :Algodón de azucre +STR_1998 :Lata baleira +STR_1999 :Lixo +STR_2000 :Caixa de hamburguesas baleira +STR_2001 :Pizza +STR_2002 :Cupón +STR_2003 :Flocos de millo +STR_2004 :Hot dog +STR_2005 :Tentáculo +STR_2006 :Sombreiro +STR_2007 :Mazá de caramelo +STR_2008 :Camiseta +STR_2009 :Rosquilla +STR_2010 :Café +STR_2011 :Cunca baleira +STR_2012 :Polo Frito +STR_2013 :Limoada +STR_2014 :Caixa baleira +STR_2015 :Botella baleira +STR_2016 :Globos +STR_2017 :Peluches +STR_2018 :Mapas do parque +STR_2019 :Fotos na atracción +STR_2020 :Paraugas +STR_2021 :Bebidas +STR_2022 :Hamburguesas +STR_2023 :Patacas fritas +STR_2024 :Xeados +STR_2025 :algodón de azucre +STR_2026 :Latas baleiras +STR_2027 :Lixo +STR_2028 :Caixas baleiras +STR_2029 :Pizzas +STR_2030 :Cupóns +STR_2031 :Flocos de millo +STR_2032 :Hot dog +STR_2033 :Tentáculos +STR_2034 :Sombreiros +STR_2035 :Mazás doces +STR_2036 :Camisetas +STR_2037 :Rosquillas +STR_2038 :Café +STR_2039 :Cuncas baleiras +STR_2040 :Polos Fritidos +STR_2041 :Limoadas +STR_2042 :Caixas baleiras +STR_2043 :Botellas baleiras +STR_2044 :un globo +STR_2045 :un pequeno xoguete +STR_2046 :un mapa do parque +STR_2047 :unha Foto +STR_2048 :un Parasol +STR_2049 :unha Bebida +STR_2050 :unha hamburguesa +STR_2051 :unhas patacas fritas +STR_2052 :un xeado +STR_2053 :un algodón de azucre +STR_2054 :unha lata baleira +STR_2055 :a Lixo +STR_2056 :unha caixa baleira +STR_2057 :unha pizza +STR_2058 :un cupón +STR_2059 :unhas palomitas +STR_2060 :un hot dog +STR_2061 :un tentáculo +STR_2062 :un Sombreiro +STR_2063 :unha mazá doce +STR_2064 :unha camiseta +STR_2065 :unha rosquilla +STR_2066 :un Café +STR_2067 :unha cunca baleira +STR_2068 :unhas galiñas fritas +STR_2069 :unha limonada +STR_2070 :unha caixa baleira +STR_2071 :unha botella baleira +STR_2072 :Globo “{STRINGID}”. +STR_2073 :xoguete “{STRINGID}”. +STR_2074 :Mapa de {STRINGID} +STR_2075 :Foto na atracción de {STRINGID} +STR_2076 :Paraugas de “{STRINGID}” +STR_2077 :Bebida +STR_2078 :Hamburguesa +STR_2079 :Patacas fritas +STR_2080 :Xeado +STR_2081 :Algodón de azucre +STR_2082 :Lata baleira +STR_2083 :Lixo +STR_2084 :Caixa de hamburguesas baleira +STR_2085 :Pizza +STR_2086 :Cupón para {STRINGID} +STR_2087 :Palomitas +STR_2088 :Hot dog +STR_2089 :Tentáculo +STR_2090 :Sombreiro “{STRINGID}”. +STR_2091 :mazá de caramelo +STR_2092 :Camiseta “{STRINGID}”. +STR_2093 :Rosquilla +STR_2094 :Café +STR_2095 :Cunca baleira +STR_2096 :Polo Frito +STR_2097 :Limoada +STR_2098 :Caixa baleira +STR_2099 :Botella baleira +STR_2103 :{WINDOW_COLOUR_2}Prezo da galleta salgada: +STR_2104 :{WINDOW_COLOUR_2}Prezo do chocolate: +STR_2105 :{WINDOW_COLOUR_2}Prezo do té xeado: +STR_2106 :{WINDOW_COLOUR_2}Prezo pastel: +STR_2107 :{WINDOW_COLOUR_2}Prezo das lentes: +STR_2108 :{WINDOW_COLOUR_2}Prezo dos fideos: +STR_2109 :{WINDOW_COLOUR_2}Prezo do arroz frito: +STR_2110 :{WINDOW_COLOUR_2}Prezo da sopa wonton: +STR_2111 :{WINDOW_COLOUR_2}Prezo das albóndigas: +STR_2112 :{WINDOW_COLOUR_2}Prezo da bebida de froita: +STR_2113 :{WINDOW_COLOUR_2}Prezo do leite de soia: +STR_2114 :{WINDOW_COLOUR_2}Prezo de Sujongkwa: +STR_2115 :{WINDOW_COLOUR_2}Prezo do bocadillo: +STR_2116 :{WINDOW_COLOUR_2}Prezo da galleta: +STR_2117 :{WINDOW_COLOUR_2} +STR_2118 :{WINDOW_COLOUR_2} +STR_2119 :{WINDOW_COLOUR_2} +STR_2120 :{WINDOW_COLOUR_2}Prezo da salchicha: +STR_2121 :{WINDOW_COLOUR_2} +STR_2125 :Galleta salgada +STR_2126 :Chocolate quente +STR_2127 :Té xeado +STR_2128 :Bolo de funil +STR_2129 :Lentes de sol +STR_2130 :Fideos con carne +STR_2131 :Arroz Frito +STR_2132 :Sopa Wonton +STR_2133 :Sopa de albóndigas +STR_2134 :zume de froita +STR_2135 :Leite de soia +STR_2136 :Sujongkwa +STR_2137 :Mini-Bocadillo +STR_2138 :Galleta +STR_2139 :Cunca baleira +STR_2140 :Cartón baleiro de bebidas +STR_2141 :Cunca de zume baleira +STR_2142 :Salchicha á prancha +STR_2143 :Cunca baleira +STR_2147 :galletas salgadas +STR_2148 :Chocolates quentes +STR_2149 :Tés xeados +STR_2150 :Repostería +STR_2151 :Lentes de sol +STR_2152 :Fideos con carne +STR_2153 :arroz frito +STR_2154 :Sopas Wonton +STR_2155 :Sopas de albóndegas +STR_2156 :Bebidas de froitas +STR_2157 :Leite de soia +STR_2158 :Sujongkwa +STR_2159 :Bocadillos +STR_2160 :Galletas +STR_2161 :cuncas baleiras +STR_2162 :Cartóns de bebidas baleiros +STR_2163 :Cuncas de zume baleiras +STR_2164 :Salchichas á prancha +STR_2165 :cuncas baleiras +STR_2169 :unha galleta salgada +STR_2170 :un chocolate quente +STR_2171 :un té xeado +STR_2172 :un Bolo de funil +STR_2173 :uns lentes +STR_2174 :uns fideos de carne +STR_2175 :un arroz frito +STR_2176 :unha sopa wonton +STR_2177 :Sopa de albóndegas +STR_2178 :unha bebida de froita +STR_2179 :un leite de soia +STR_2180 :a Sujongkwa +STR_2181 :un mini bocadillo +STR_2182 :unha galleta +STR_2183 :unha cunca baleira +STR_2184 :unha caixa de bebidas baleira +STR_2185 :un vaso de bebida baleiro +STR_2186 :unha salchicha á prancha +STR_2187 :unha cunca baleira +STR_2191 :Galleta salgada +STR_2192 :Chocolate quente +STR_2193 :Té xeado +STR_2194 :Bolo de funil +STR_2195 :Lentes de sol +STR_2196 :Fideos con carne +STR_2197 :Arroz frito +STR_2198 :Sopa Wonton +STR_2199 :Sopa de albóndegas +STR_2200 :Bebida de froitas +STR_2201 :Leite de soia +STR_2202 :Sujongkwa +STR_2203 :Mini-Bocadillo +STR_2204 :Galleta +STR_2205 :Cunca baleira +STR_2206 :Caixa de bebidas baleira +STR_2207 :Vaso de bebida baleiro +STR_2208 :Salchicha á prancha +STR_2209 :Cunca baleira +STR_2210 :Mostrar a lista de manitas no parque +STR_2211 :Mostrar a lista de mecánicos no parque +STR_2212 :Mostrar a lista de gardas de seguridade no parque +STR_2213 :Mostrar a lista de animadores do parque +STR_2214 :Non é posible construír mentres o xogo está en pausa! +STR_2215 :{STRINGID}{NEWLINE}({STRINGID}) +STR_2216 :{WINDOW_COLOUR_2}{COMMA16}°C +STR_2217  :{WINDOW_COLOUR_2}{COMMA16}°F +STR_2218 :{RED}{STRINGID} en {STRINGID} non volveu a {STRINGID}!{NEWLINE}Comproba se quedou atascado ou parouse. +STR_2219 :{RED}{COMMA16} persoas morreron nun accidente en {STRINGID} +STR_2220 :{WINDOW_COLOUR_2}Valoración do parque: {BLACK}{COMMA16} +STR_2221 :Calificación do parque: {COMMA16} +STR_2222 :{BLACK}{STRINGID} +STR_2223 :{WINDOW_COLOUR_2}Visitantes do parque: {BLACK}{COMMA32} +STR_2224 :{WINDOW_COLOUR_2}Efectivo: {BLACK}{CURRENCY2DP} +STR_2225 :{WINDOW_COLOUR_2}Efectivo: {RED}{CURRENCY2DP} +STR_2226 :{WINDOW_COLOUR_2}Valor do parque: {BLACK}{CURRENCY} +STR_2227 :{WINDOW_COLOUR_2}Valor da empresa: {BLACK}{CURRENCY} +STR_2228 :{WINDOW_COLOUR_2}Beneficios do mes pasado por vendas de comida/bebidas e {NEWLINE} mercadorías: {BLACK}{CURRENCY} +STR_2229 :Costa arriba a vertical +STR_2230 :Sección Vertical +STR_2231 :Freos de caída libre +STR_2232 :Cable de elevación +STR_2233 :Información do parque +STR_2234 :Mensaxes recentes +STR_2235 :{STRINGID} {STRINGID} +STR_2236 :xaneiro +STR_2237 :febreiro +STR_2238 :marzo +STR_2239 :abril +STR_2240 :maio +STR_2241 :xuño +STR_2242 :xullo +STR_2243 :agosto +STR_2244 :setembro +STR_2245 :outubro +STR_2246 :novembro +STR_2247 :decembro +STR_2248 :Non podes eliminar a atracción/tenda +STR_2249 :{BABYBLUE}Nova atracción dispoñible:{NEWLINE}{STRINGID} +STR_2250 :{BABYBLUE}Nova decoración dispoñible:{NEWLINE}{STRINGID} +STR_2251 :Só se pode construír en camiños! +STR_2252 :Só se pode construír a través de camiños! +STR_2253 :Atraccións de transporte +STR_2254 :Paseos suaves +STR_2255 :Montañas rusas +STR_2256 :Atraccións intensas +STR_2257 :Atraccións acuáticas +STR_2258 :Tendas e postos de venda +STR_2259 :Decorado +STR_2260 :Sen investimento +STR_2261 :Investimento mínimo +STR_2262 :Investimento normal +STR_2263 :Investimento Máximo +STR_2264 :Investimento en investigación +STR_2265 :{WINDOW_COLOUR_2}Orzamento: {BLACK}{CURRENCY} ao mes +STR_2266 :Prioridades de investigación +STR_2267 :Actualmente en desenvolvemento +STR_2268 :Último desenvolvemento +STR_2269 :{WINDOW_COLOUR_2}Tipo: {BLACK}{STRINGID} +STR_2270 :{WINDOW_COLOUR_2}Progreso: {BLACK}{STRINGID} +STR_2271 :{WINDOW_COLOUR_2}Data: {BLACK}{STRINGID} +STR_2272 :{WINDOW_COLOUR_2}Atracción:{NEWLINE}{BLACK}{STRINGID} +STR_2273 :{WINDOW_COLOUR_2}Decoración:{NEWLINE}{BLACK}{STRINGID} +STR_2274 :Mostrar detalles deste desenvolvemento +STR_2275 :Opcións de investimento e estado de I+D +STR_2276 :Mostra o estado de I+D +STR_2277 :Descoñecido +STR_2278 :Atracción de transporte +STR_2279 :Atracción suave +STR_2280 :Montaña Rusa +STR_2281 :Atracción intensa +STR_2282 :Atracción acuática +STR_2283 :Tenda/Posto +STR_2284 :Escenario +STR_2285 :Desenvolvemento inicial +STR_2286 :Deseño +STR_2287 :Finalización do deseño +STR_2288 :Descoñecido +STR_2289 :{STRINGID} {STRINGID} +STR_2291 :Selecciona o escenario para un novo xogo +STR_2292 :{WINDOW_COLOUR_2}Atraccións visitadas: +STR_2293 :{BLACK} Nada +STR_2294 :Cambiar o estilo da terra +STR_2295 :Cambiar o estilo do acantilado +STR_2296 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} exp. na entrada do parque +STR_2297 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto na atracción {BLACK}{COMMA16} +STR_2298  :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto en {BLACK}{COMMA16} atraccións +STR_2299  :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto en comida {BLACK}{COMMA16} +STR_2300  :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto en {BLACK}{COMMA16} comidas +STR_2301  :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto en refresco {BLACK}{COMMA16} +STR_2302 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto en refrescos {BLACK}{COMMA16} +STR_2303  :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto en recordo {BLACK}{COMMA16} +STR_2304 :{BLACK}{CURRENCY2DP}{WINDOW_COLOUR_2} gasto en recordos {BLACK}{COMMA16} +STR_2305 :Arquivos de deseño Vía +STR_2306 :Gardar deseño a través +STR_2307 :Seleccione o deseño de {STRINGID} +STR_2308  :{STRINGID} Deseños de pistas +STR_2309 :Instalar o deseño da pista +STR_2310 :Crear un deseño personalizado +STR_2311 :{WINDOW_COLOUR_2}Nivel de emoción: {BLACK}{COMMA2DP32} (aprox.) +STR_2312 :{WINDOW_COLOUR_2}Nivel de intensidade: {BLACK}{COMMA2DP32} (aprox.) +STR_2313 :{WINDOW_COLOUR_2}Nivel de náuseas: {BLACK}{COMMA2DP32} (aprox.) +STR_2314 :{WINDOW_COLOUR_2}Lonxitude da pista: {BLACK}{STRINGID} +STR_2315 :{WINDOW_COLOUR_2}Custo: {BLACK}ao redor de {CURRENCY} +STR_2316 :{WINDOW_COLOUR_2}Espazo necesario: {BLACK}{COMMA16} × {COMMA16} bloques +STR_2321 :{WINDOW_COLOUR_2}Número de atraccións: {BLACK}{COMMA16} +STR_2322 :{WINDOW_COLOUR_2}Empleados: {BLACK}{COMMA32} +STR_2323 :{WINDOW_COLOUR_2}Extensión do parque: {BLACK}{COMMA32}m² +STR_2324 :{WINDOW_COLOUR_2}Extensión do parque: {BLACK}{COMMA32}sq.ft. +STR_2325 :Comprar terreos para ampliar o parque. +STR_2326 :Adquirir dereitos de construción para construír sobre ou debaixo de terreos fóra do parque. +STR_2327 :Opcións +STR_2328 :{WINDOW_COLOUR_2}Moeda: +STR_2329 :{WINDOW_COLOUR_2}Distancia e velocidade: +STR_2330 :{WINDOW_COLOUR_2}Temperatura: +STR_2331 :{WINDOW_COLOUR_2}Marcas de altura: +STR_2332 :Niveis relativos +STR_2333 :Efectos de son +STR_2334 :Libras (£) +STR_2335 :Dólares ($) +STR_2336 :Franco (F) +STR_2337 :Marca alemana (DM) +STR_2338 :Ien (¥) +STR_2339 :Peseta (Pts) +STR_2340 :Lira (L) +STR_2341 :Floríns (ƒ) +STR_2342 :Coroa sueca (kr) +STR_2343 :Euros (€) +STR_2344 :Imperial +STR_2345 :Métrica +STR_2347 :{RED}{STRINGID} afogouse! +STR_2348 :Mostrar estatísticas deste empregado +STR_2349 :{WINDOW_COLOUR_2}Salario: {BLACK}{CURRENCY} ao mes +STR_2350 :{WINDOW_COLOUR_2}Contratado: {BLACK}{MONTHYEAR} +STR_2351 :{WINDOW_COLOUR_2}Herba cortada: {BLACK}{COMMA32} +STR_2352 :{WINDOW_COLOUR_2}Xardíns regados: {BLACK}{COMMA32} +STR_2353 :{WINDOW_COLOUR_2}Camiños despexados: {BLACK}{COMMA32} +STR_2354 :{WINDOW_COLOUR_2}Lixos baleiros: {BLACK}{COMMA32} +STR_2355 :{WINDOW_COLOUR_2}Atraccións corrixidas: {BLACK}{COMMA32} +STR_2356 :{WINDOW_COLOUR_2}Atraer. inspeccionado: {BLACK}{COMMA32} +STR_2358 :Unidos +STR_2359 :Valores reais +STR_2360 :{WINDOW_COLOUR_2}Resolución da pantalla: +STR_2361 :Suavizado do terreo +STR_2362 :Activa ou desactiva a suavización do terreo +STR_2363 :Mostrar cuadrícula do terreo +STR_2364 :activa ou desactiva a cuadrícula do terreo +STR_2365 :O banco négase a prestarche máis cartos! +STR_2366 :Celsius (°C) +STR_2367 :Fahrenheit (°F) +STR_2368 :Ningún +STR_2369 :Baixo +STR_2370 :Medio +STR_2371 :Alto +STR_2372 :Baixo +STR_2373 :Medio +STR_2374 :Alto +STR_2375 :Moi alto +STR_2376 :extremo +STR_2377 :Ultra-Extremo +STR_2378 :Selecciona menos superficie de terreo +STR_2379 :Selecciona máis superficie terrestre +STR_2380 :Seleccione menos extensión de auga +STR_2381 :Selecciona máis extensión de auga +STR_2382 :Terra +STR_2383 :Auga +STR_2384 :{WINDOW_COLOUR_2}O teu obxectivo: +STR_2385 :{BLACK}Ningún +STR_2386 :{BLACK}Ter polo menos {COMMA32} visitantes no teu parque a finais de {MONTHYEAR}, cunha clasificación do parque de polo menos 600 +STR_2387 :{BLACK}Obtén un valor do parque {POP16}{POP16}{CURRENCY} ao final do {PUSH16}{PUSH16}{PUSH16}{PUSH16}{PUSH16}{MONTHYEAR} +STR_2388 :{BLACK}Divírtete! +STR_2389 :{BLACK}Constrúe o mellor {STRINGID} que poidas! +STR_2390 :{BLACK}Ter polo menos 10 tipos diferentes de montañas rusas operando no parque, cada unha cun valor de emoción de polo menos 6,00 +STR_2391 :{BLACK}Ten polo menos {COMMA32} visitantes no teu parque. Non deixes que a clasificación baixe de 700 en ningún momento. +STR_2392 :{BLACK}Consigue ingresos mensuais pola venda de entradas para atraccións de polo menos {POP16}{POP16}{CURRENCY} +STR_2393 :{BLACK}Ter polo menos 10 tipos diferentes de montañas rusas funcionando no parque, cada unha cunha lonxitude mínima de {LENGTH} e un valor de emoción de polo menos 7,00 +STR_2394 :{BLACK}Remata a construción da 5 das montañas rusas sen rematar deste parque, deseñandoas para que teñan un valor emocionante de polo menos {POP16}{POP16}{COMMA2DP32} cada unha. +STR_2395 :{BLACK}Devolve o crédito e obtén un valor do parque de polo menos {POP16}{POP16}{CURRENCY} +STR_2396 :{BLACK}Consigue uns ingresos mensuais con alimentos, bebidas e outros artigos de polo menos {POP16}{POP16}{CURRENCY} +STR_2397 :Ningún +STR_2398 :Número de visitantes nunha data determinada +STR_2399 :valor do parque nunha data determinada +STR_2400 :Divírtete! +STR_2401 :Constrúe a mellor atracción posible +STR_2402 :Constrúe 10 montañas rusas +STR_2403 :Número de visitantes no parque +STR_2404 :Beneficio de atracción mensual +STR_2405 :Constrúe 10 montañas rusas cunha lonxitude +STR_2406 :Rematar a construción de 5 montañas rusas +STR_2407 :Pagar o préstamo e alcanzar o valor do parque +STR_2408 :beneficio mensual de alimentos/Mercadorías +STR_2409 :{WINDOW_COLOUR_2}Campañas de mercadotecnia en curso +STR_2410 :{BLACK}Ningún +STR_2411 :{WINDOW_COLOUR_2}Campañas de mercadotecnia dispoñibles +STR_2412 :Comeza esta campaña de mercadotecnia +STR_2413  :{BLACK}({CURRENCY2DP} por semana) +STR_2414 :(Aínda non seleccionou) +STR_2415 :{WINDOW_COLOUR_2}Atracción: +STR_2416 :{WINDOW_COLOUR_2}Elemento: +STR_2417 :{WINDOW_COLOUR_2}Período de tempo: +STR_2418 :Entrada gratuíta a {STRINGID} +STR_2419 :Entrada gratuíta a {STRINGID} +STR_2420 :50 % de desconto en {STRINGID} +STR_2421 :{STRINGID} gratuíto +STR_2424 :{WINDOW_COLOUR_2}Cupóns para a entrada gratuíta ao parque +STR_2425 :{WINDOW_COLOUR_2}Cupóns para a entrada gratuíta a unha das atraccións +STR_2426 :{WINDOW_COLOUR_2}Cupóns para o 50 % de desconto na entrada ao parque +STR_2427 :{WINDOW_COLOUR_2}Cupóns para comida ou bebida gratis +STR_2428 :{WINDOW_COLOUR_2}Campaña publicitaria do parque +STR_2429 :{WINDOW_COLOUR_2}Campaña publicitaria dunha atracción +STR_2430 :{BLACK}Cupóns para a entrada gratuíta a {STRINGID} +STR_2431 :{BLACK}Cupóns para a entrada gratuíta a {STRINGID} +STR_2432 :{BLACK}Cupóns para o 50 % de desconto na entrada a {STRINGID} +STR_2433 :{BLACK}Cupóns de balde {STRINGID} +STR_2434 :{BLACK}{STRINGID} campaña publicitaria +STR_2435 :{BLACK}{STRINGID} campaña publicitaria +STR_2436 :1 semana +STR_2443 :{WINDOW_COLOUR_2}Custo por semana: {BLACK}{CURRENCY2DP} +STR_2444 :{WINDOW_COLOUR_2}Custo total: {BLACK}{CURRENCY2DP} +STR_2445 :Lanza esta campaña de mercadotecnia +STR_2446 :{YELLOW}A campaña de mercadotecnia para a entrada gratuíta ao parque rematou +STR_2447 :{YELLOW}A campaña de mercadotecnia para introducir {STRINGID} de balde rematou +STR_2448 :{YELLOW}A campaña de cupóns de desconto para entrar no parque rematou +STR_2449 :{YELLOW}A campaña de mercadotecnia gratuíta {STRINGID} rematou +STR_2450 :{YELLOW}A campaña publicitaria do parque rematou +STR_2451 :{YELLOW}{STRINGID} a campaña publicitaria rematou +STR_2452 :{WINDOW_COLOUR_2}Efectivo (restando préstamo): {BLACK}{CURRENCY2DP} +STR_2453 :{WINDOW_COLOUR_2}Efectivo (restando préstamo): {RED}{CURRENCY2DP} +STR_2457 :Mostrar as finanzas +STR_2458 :Mostra o gráfico do efectivo dispoñible (restando o préstamo) ao longo do tempo +STR_2459 :Mostrar o gráfico do valor do parque ao longo do tempo +STR_2460 :Mostrar o gráfico de beneficios ao longo do tempo +STR_2461 :Mostrar campañas de mercadotecnia +STR_2462 :Mostrar vista da entrada do parque +STR_2463 :Mostrar o gráfico de valoración do parque ao longo do tempo +STR_2464 :Mostrar gráfico do número de visitantes ao longo do tempo +STR_2465 :Mostrar información sobre o prezo e as entradas +STR_2466 :Mostrar estatísticas do parque +STR_2467 :Mostrar obxectivos deste parque +STR_2468 :Mostrar os premios gañados recentemente polo parque +STR_2469 :Seleccione o nivel de investigación e desenvolvemento +STR_2470 :Investigar novas atraccións de transporte +STR_2471 :Investigar novas atraccións suaves +STR_2472 :Busca novas montañas rusas +STR_2473 :Investigar novas atraccións intensas +STR_2474 :Investigar novas atraccións acuáticas +STR_2475 :Investigar novas tendas e postos de venda +STR_2476 :Investigar unha nova decoración +STR_2477 :Seleccione o modo de funcionamento desta atracción +STR_2478 :Mostrar a gráfica de velocidade en función do tempo +STR_2479 :Mostrar a gráfica de velocidade en función do tempo +STR_2480 :Mostra a gráfica de aceleración en función do tempo +STR_2481 :Mostrar gráfico da aceleración lateral con respecto ao tempo +STR_2482 :Beneficios: {CURRENCY} por semana. Valor do parque: {CURRENCY} +STR_2483 :{WINDOW_COLOUR_2}Beneficio semanal: {BLACK}+{CURRENCY2DP} +STR_2484 :{WINDOW_COLOUR_2}Beneficio semanal: {RED}{CURRENCY2DP} +STR_2487 :Mostrar os nomes "reais" dos visitantes +STR_2488 :Mostra os nomes "reais" dos visitantes, ou só o seu número de visitantes +STR_2489 :Atallos de teclado... +STR_2490 :Atallos de teclado +STR_2491 :Restablecer teclas +STR_2492 :Cambia todos os atallos de teclado aos valores predeterminados +STR_2493 :Pechar a xanela de arriba +STR_2494 :Pecha todas as xanelas +STR_2495 :Cancelar o modo de compilación +STR_2496 :Pausa o xogo +STR_2497 :Reducir a vista +STR_2498 :Ampliar a vista +STR_2499 :Xira a vista cara á dereita +STR_2500 :Xirar obxectos en construción +STR_2501 :Vista subterránea +STR_2502 :Terra invisible +STR_2503 :Cantís invisibles +STR_2504 :Mira a través das atraccións +STR_2505 :Mira polo escenario +STR_2506 :Alternar soportes invisibles +STR_2507 :Alterar convidados invisibles +STR_2508 :Marcas de altura no chan +STR_2509 :marcas de altura nas atraccións +STR_2510 :marcas de altura nos camiños +STR_2511 :Axustar o terreo +STR_2512 :Axustar a auga +STR_2513 :construír escenario +STR_2514 :Construír ruta +STR_2515 :Construír unha nova atracción +STR_2516 :Mostrar información. das finanzas +STR_2517 :Mostrar información. investigación +STR_2518 :Mostrar a lista de atraccións +STR_2519 :Mostrar información. do parque +STR_2520 :Mostrar a lista de visitantes +STR_2521 :Mostrar a lista de empregados +STR_2522 :Mostrar mensaxes recentes +STR_2523 ​​​​ :Amosar mapa +STR_2524 :captura de pantalla +STR_2533 :tecla RETROCESO +STR_2534 :Tab +STR_2537 :Limpar +STR_2538 :Volver +STR_2543 :Alt/Menú +STR_2544 :Pausa +STR_2545 :Caps +STR_2552 :Escape +STR_2557 :Barra de espazo +STR_2558 :Páx sub +STR_2559 :Páx Bai +STR_2560 :Fin +STR_2561 :Casa +STR_2562 :Esquerda +STR_2563 :Arriba +STR_2564 :Dereita +STR_2565 :Abaixo +STR_2566 :Seleccionar +STR_2567 :Imprimir +STR_2568 :Executar +STR_2569 :Instantánea +STR_2570 :Inserir +STR_2571 :Eliminar +STR_2572 :Axuda +STR_2618 :Menú +STR_2621 :Teclado numérico 0 +STR_2622 :Teclado numérico 1 +STR_2623 :Teclado numérico 2 +STR_2624 :Teclado numérico 3 +STR_2625 :Teclado numérico 4 +STR_2626 :Teclado numérico 5 +STR_2627 :Teclado numérico 6 +STR_2628 :Teclado numérico 7 +STR_2629 :Teclado numérico 8 +STR_2630 :Teclado numérico 9 +STR_2631 :Teclado numérico * +STR_2632 :Teclado numérico + +STR_2634 :Teclado numérico - +STR_2635 :Teclado numérico . +STR_2636 :Teclado numérico / +STR_2669 :Bloqueo num +STR_2670 :Desprácese +STR_2680 :Investigación completa +STR_2684 :Chega un gran grupo de visitantes +STR_2685 :Parámetros de ruído simples +STR_2686 :Baixa: +STR_2687 :Alto: +STR_2688 :Frecuencia base: +STR_2689 :Oitavas: +STR_2690 :Xeración de mapas +STR_2691 :Altura da base: +STR_2692 :Altura da auga: +STR_2693 :Terreo: +STR_2694 :Xerar +STR_2695 :Terreo aleatorio +STR_2696 :Colocar árbores +STR_2700 :Gardado automático: +STR_2701 :Cada minuto +STR_2702 :Cada 5 minutos +STR_2703 :Cada 15 minutos +STR_2704 :Cada 30 minutos +STR_2705 :Cada hora +STR_2706 :Xamais +STR_2707 :Utiliza o explorador de ficheiros do sistema +STR_2708 :{WINDOW_COLOUR_1}Estás certo de sobrescribir {STRINGID}? +STR_2709 :Sobrescribir +STR_2710 :Introduza o nome para este ficheiro: +STR_2718 :(arriba) +STR_2719 :(novo ficheiro) +STR_2720  :{UINT16}seg +STR_2721  :{UINT16}s +STR_2722 :{UINT16}min:{UINT16}seg +STR_2723 :{UINT16}min:{UINT16}s +STR_2724  :{UINT16}min:{UINT16}s +STR_2725  :{UINT16}mins:{UINT16}s +STR_2726  :{UINT16}min +STR_2727  :{UINT16}min +STR_2728 :{UINT16}hora:{UINT16}min +STR_2729 :{UINT16}hora:{UINT16}min +STR_2730 :{UINT16}horas:{UINT16}min +STR_2731 :{UINT16}horas:{UINT16}min +STR_2732  :{COMMA32} pés +STR_2733 :{COMMA32}m +STR_2734  :{COMMA16} mph +STR_2735 :{COMMA16} km/h +STR_2736  :{MONTH}, ano {COMMA16} +STR_2737  :{STRINGID} {MONTH}, ano {COMMA16} +STR_2738 :Menú principal de música: +STR_2739 :Ningún +STR_2740 :RollerCoaster Tycoon 1 +STR_2741 :RollerCoaster Tycoon 2 +STR_2749 :A miña nova etapa +# New strings used in the cheats window previously these were ??? +STR_2750 :Mover todo cara arriba +STR_2751 :Move todo cara abaixo +STR_2752 :Herba limpa +STR_2753 :Herba cortada +STR_2754 :Regar plantas +STR_2755 :Amañar o vandalismo +STR_2756 :Retirar lixo +STR_2763 :??? +STR_2765 :Grupo de visitantes +STR_2766 :Escenario de vitoria +STR_2767 :Desactivar cambio clima +STR_2769 :Parque aberto +STR_2770 :Pechar o parque +STR_2773 :Xanela +STR_2774 :Pantalla completa +STR_2775 :Pantalla completa (sen bordos) +STR_2776 :Lingua: +STR_2777  :{MOVE_X}{10}{STRING} +STR_2778 :»{MOVE_X}{10}{STRING} +STR_2779 :Cámara #{COMMA16} +STR_2780 :Engadir ‘cámara de vixilancia’ +# End of new strings +STR_2781 :{STRINGID}: +STR_2782 :SHIFT + +STR_2783 :CTRL + +STR_2784 :Cambiar o atallo do teclado +STR_2785 :{WINDOW_COLOUR_2}Preme a tecla nova para:{NEWLINE}“{STRINGID}” +STR_2786 :Fai clic na descrición do atallo para cambiala +STR_2787 :{WINDOW_COLOUR_2}Valor do parque: {BLACK}{CURRENCY} +STR_2788 :{WINDOW_COLOUR_2}Parabéns!{NEWLINE}{BLACK}Conseguiches o obxectivo cun valor da empresa de {CURRENCY}! +STR_2789 :{WINDOW_COLOUR_2}Non conseguiches o teu obxectivo! +STR_2790 :Introd. nome na táboa de escenarios +STR_2791 :Introduce o nome +STR_2792 :Introduza o nome na táboa de escenarios: +STR_2793 :(Completado por {STRINGID}) +STR_2794 :{WINDOW_COLOUR_2}Completado por: {BLACK}{STRINGID}{NEWLINE}{WINDOW_COLOUR_2} cun valor da empresa de: {BLACK}{CURRENCY} +STR_2795 :Ordenar +STR_2796 :Ordena a lista de atraccións segundo os criterios seleccionados +STR_2797 :Move o mapa co rato ata o bordo da pantalla +STR_2798 :Despraza a vista cando o punteiro do rato estea no bordo da xanela +STR_2799 :Ver ou cambiar os atallos de teclado asignados +STR_2800 :{WINDOW_COLOUR_2}Entradas: {BLACK}{COMMA32} +STR_2801 :{WINDOW_COLOUR_2}Ventaxes da venda de entradas: {BLACK}{CURRENCY2DP} +STR_2802 :Mapa +STR_2803 :Mostra estes visitantes marcados no mapa +STR_2804 :Mostra estes empregados marcados no mapa +STR_2805 :Mostrar mapa do parque +STR_2806 :{RED}Os visitantes quéixanse do mal estado das rutas{NEWLINE}Comproba onde están os traballadores de mantemento e organízaos mellor. +STR_2807 :{RED}Os visitantes quéixanse do lixo no parque{NEWLINE}Comproba onde están os traballadores de mantemento e organízaos mellor. +STR_2808 :{RED}Os visitantes quéixanse do vandalismo no parque{NEWLINE}Comproba onde están os teus gardas e organízaos mellor. +STR_2809 :{RED}Os visitantes teñen fame e non atopan onde mercar comida. +STR_2810 :{RED}Os visitantes teñen sede e non atopan ningún lugar onde mercar bebidas. +STR_2811 :{RED}Os visitantes quéixanse porque non atopan baños no parque. +STR_2812 :{RED}Os visitantes pérdense ou atascanse{NEWLINE}Comproba o deseño da túa ruta para axudar aos visitantes. +STR_2813 :{RED}A entrada ao parque é demasiado cara!{NEWLINE}Reduce o custo da entrada ou mellora o valor do parque. +STR_2814 :{WINDOW_COLOUR_2}Premio ao parque máis sucio do país +STR_2815 :{WINDOW_COLOUR_2}Premio ao parque máis limpo do país +STR_2816 :{WINDOW_COLOUR_2}Premio ao parque coas mellores montañas rusas +STR_2817 :{WINDOW_COLOUR_2}Premio ao parque máis valioso do país +STR_2818 :{WINDOW_COLOUR_2}Premio ao parque máis fermoso do país +STR_2819 :{WINDOW_COLOUR_2}Premio ao parque menos valioso do país +STR_2820 :{WINDOW_COLOUR_2}Premio ao parque máis seguro do país +STR_2821 :{WINDOW_COLOUR_2}Premio ao parque cos mellores empregados +STR_2822 :{WINDOW_COLOUR_2}Premio ao parque coa mellor comida do país +STR_2823 :{WINDOW_COLOUR_2}Premio ao parque coa peor comida do país +STR_2824 :{WINDOW_COLOUR_2}Premio ao parque cos mellores baños do país +STR_2825 :{WINDOW_COLOUR_2}Premio ao parque máis decepcionante do país +STR_2826 :{WINDOW_COLOUR_2}Premio ao parque coas mellores atraccións acuáticas do país +STR_2827 :{WINDOW_COLOUR_2}Premio ao parque coas mellores atraccións de pistas personalizadas do país +STR_2828 :{WINDOW_COLOUR_2}Premio ao parque cos esquemas de cores máis deslumbrantes +STR_2829 :{WINDOW_COLOUR_2}Premio ao parque co deseño máis confuso +STR_2830 :{WINDOW_COLOUR_2}Premio ao parque coas mellores atraccións suaves +STR_2831 :{TOPAZ}O teu parque recibiu o premio "O parque máis sucio do país"! +STR_2832 :{TOPAZ}O teu parque recibiu o premio "O parque máis limpo do país"! +STR_2833 :{TOPAZ}O teu parque recibiu o premio "O parque coas mellores montañas rusas"! +STR_2834 :{TOPAZ}O teu parque recibiu o premio "O parque máis valioso do país"! +STR_2835 :{TOPAZ}O teu parque recibiu o premio "O parque máis fermoso do país"! +STR_2836 :{TOPAZ}O teu parque recibiu o premio "O parque menos valioso do país"! +STR_2837 :{TOPAZ}O teu parque recibiu o premio "O parque máis seguro do país"! +STR_2838 :{TOPAZ}O teu parque recibiu o premio "O parque cos mellores empregados"! +STR_2839 :{TOPAZ}O teu parque recibiu o premio "O parque coa mellor comida do país"! +STR_2840 :{TOPAZ}O teu parque recibiu o premio "O parque coa peor comida do país"! +STR_2841 :{TOPAZ}O teu parque recibiu o premio "O parque cos mellores baños do país"! +STR_2842 :{TOPAZ}O teu parque recibiu o premio "O parque máis decepcionante do país"! +STR_2843 :{TOPAZ}O teu parque recibiu o premio "O parque coas mellores atraccións acuáticas do país"! +STR_2844 :{TOPAZ}O teu parque recibiu o premio "O parque coas mellores atraccións de pistas personalizadas do país"! +STR_2845 :{TOPAZ}O teu parque recibiu o premio "O parque cos esquemas de cores máis abraiantes"! +STR_2846 :{TOPAZ}O teu parque recibiu o premio "O parque co deseño máis confuso"! +STR_2847 :{TOPAZ}O teu parque recibiu o premio "O parque cos mellores atraccións suaves"! +STR_2848 :{WINDOW_COLOUR_2}Non hai premios recentes +STR_2849 :O novo escenario instalouse correctamente +STR_2850 :Instalouse a nova pista correctamente +STR_2851 :Escenario xa instalado +STR_2852 :Ruta xa instalada +STR_2853 :Prohibido polas autoridades locais! +STR_2854 :{RED}Os visitantes non poden atopar a entrada de {STRINGID}!{NEWLINE}Constrúe un camiño cara á entrada +STR_2855 :{RED}{STRINGID} non ten un camiño de saída!{NEWLINE}Constrúe un camiño desde a saída da atracción. +STR_2858 :Non pode iniciar unha campaña publicitaria... +STR_2861 :{WINDOW_COLOUR_2}Baixo licenza de Infogrames Interactive Inc. +STR_2971 :Esquema de cores principal +STR_2972 :Esquema de cores alternativo 1 +STR_2973 :Esquema de cores alternativo 2 +STR_2974 :esquema de cores alternativo 3 +STR_2975 :Selecciona o esquema de cores que queres cambiar ou pinta a atracción con el +STR_2976 :Pinta só unha área da atracción usando o esquema de cores seleccionado +STR_2977 :Nomear persoal +STR_2978 :Introduce un nome para este membro +STR_2979 :Non se pode nomear este membro do persoal... +STR_2980 :Demasiadas bandeiras en xogo +STR_2981 :{RED}Non pases +STR_2982 :Asinar texto +STR_2983 :Introduce texto novo para este sinal: +STR_2984 :Non se pode definir o texto para o sinal... +STR_2985 :Asinar +STR_2986 :Cambiar o texto do sinal +STR_2987 :Establece este sinal como "Non traspasar" +STR_2988 :Demoler este sinal +STR_2989 :Seleccione a cor principal +STR_2990 :Seleccione a cor do texto +STR_2991 :Letreiro +STR_2992 :Sinal de texto +STR_2993 :Escribir novo texto: +STR_2994 :Cambiar o texto do sinal +STR_2995 :Sinal de demolición +STR_2996 :{BLACK}ABC +STR_2997 :{GREY}ABC +STR_2998 :{WHITE}ABC +STR_2999 :{RED}ABC +STR_3000  :{GREEN}ABC +STR_3001 :{YELLOW}ABC +STR_3002 :{TOPAZ}ABC +STR_3003 :{CELADON}ABC +STR_3004 :{BABYBLUE}ABC +STR_3005 :{PALELAVENDER}ABC +STR_3006 :{PALEGOLD}ABC +STR_3007 :{LIGHTPINK}ABC +STR_3008 :{PEARLAQUA}ABC +STR_3009 :{PALESILVER}ABC +STR_3010 :Non se puido cargar o ficheiro... +STR_3011 :O ficheiro contén datos non válidos +STR_3045 :Selecciona o estilo de música para reproducir +STR_3047 :A autoridade local non permite que esta atracción sexa demolida nin modificada +STR_3048 :Campañas de mercadotecnia prohibidas pola autoridade local +STR_3049 :Oco de golf A +STR_3050 :Oco de golf B +STR_3051 :Oco de golf C +STR_3052 :Oco de golf D +STR_3053 :Oco de golf E +STR_3054 :Cargando... +STR_3058 :Muros de ladrillo +STR_3059 :Arbusto +STR_3060 :Bloque de xeo +STR_3061 :Valado de madeira +STR_3062 :Sección de montaña rusa estándar +STR_3063 :Canle de auga (sección mergullada) +STR_3064 :Parque. para novatos +STR_3065 :Parques desafiantes +STR_3066 :Parques expertos +STR_3067 :Parques “Reais”. +STR_3068 :Outros parques +STR_3069 :Sección superior +STR_3070 :Pendente a nivel +STR_3071 :{WINDOW_COLOUR_2}O mesmo prezo en todo o parque +STR_3072 :Seleccione se este prezo se usa en todo o parque +STR_3073 :{RED}ADVERTENCIA: a clasificación do parque caeu por debaixo de 700!{NEWLINE}Se a clasificación non aumenta en 4 semanas, o parque estará pechado. +STR_3074 :{RED}ADVERTENCIA: a valoración do parque baixou de 700!{NEWLINE}Tes 3 semanas para aumentar a valoración. +STR_3075 :{RED}ADVERTENCIA: a valoración do parque baixou de 700!{NEWLINE}Só tes 2 semanas para aumentar a valoración ou o parque pechará. +STR_3076 :{RED}AVISO FINAL: a clasificación do parque baixou por debaixo de 700!{NEWLINE}En 7 días o teu parque estará pechado a menos que subas a clasificación. +STR_3077 :{RED}PECHE: o teu parque foi pechado! +STR_3090 :Seleccione o estilo de entrada, saída e estación +STR_3091 :Non estás autorizado para eliminar esta sección! +STR_3092 :Non estás autorizado para modificar a estación desta atracción! +STR_3093 :{WINDOW_COLOUR_2}Favorito: {BLACK}{STRINGID} +STR_3094 :Ningún +STR_3095 :{WINDOW_COLOUR_2}Velocidade. cadeas de elevación: +STR_3096 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{VELOCITY} +STR_3097 :Selecciona a velocidade das cadeas de carga +STR_3099 :Selecciona a cor +STR_3100 :Seleccione a segunda cor +STR_3101 :Seleccione a terceira cor +STR_3102 :Repintar a decoración de cores no parque +STR_3103 :Non podes volver pintar isto... +STR_3104 :Lista de atraccións +STR_3105 :Lista de tendas e postos +STR_3106 :Enumerar quioscos de información e outras instalacións para visitantes +STR_3107 :Pechar +STR_3108 :Proba +STR_3109 :Aberto +STR_3110 :{WINDOW_COLOUR_2}Bloquear seccións: {BLACK}{COMMA16} +STR_3111 :Fai clic neste deseño para crealo +STR_3112 :Fai clic no deseño para renomear ou eliminar +STR_3113 :Seleccione outro deseño +STR_3114 :Volver á xanela de selección de deseño +STR_3115 :Gardar o deseño da pista +STR_3116 :Gardar o deseño da pista (non é posible ata que o paseo sexa probado e xeradas as estatísticas) +STR_3117 :{BLACK}Chamando ao mecánico... +STR_3118 :{BLACK}{STRINGID} vai cara á atracción +STR_3119 :{BLACK}{STRINGID} está arranxando a atracción +STR_3120 :Busca o mecánico gratuíto máis próximo ou o que está a arranxar a atracción +STR_3121 :Non se puido localizar un mecánico gratuíto +STR_3122 :{WINDOW_COLOUR_2}Atracción favorita de: {BLACK}{COMMA32} visitante +STR_3123 :{WINDOW_COLOUR_2}Atracción favorita de: {BLACK}{COMMA32} visitantes +STR_3124 :{STRINGID} defectuoso +STR_3125  :{WINDOW_COLOUR_2}Factor de excitación: {BLACK}+{COMMA16} % +STR_3126  :{WINDOW_COLOUR_2}Factor de intensidade: {BLACK}+{COMMA16} % +STR_3127  :{WINDOW_COLOUR_2}Factor de náuseas: {BLACK}+{COMMA16} % +STR_3128 :Gardar o deseño da pista +STR_3129 :Gardar o deseño da pista con decoración +STR_3130 :Gardar +STR_3131 :Cancelar +STR_3132 :{BLACK}Fai clic nos elementos do escenario para gardar xunto co deseño da pista... +STR_3133 :Non é posible construír isto nunha pendente +STR_3134 :{RED}(Este deseño inclúe unha decoración que non está dispoñible) +STR_3135 :{RED}(Vehículo non dispoñible; o rendemento pode verse afectado) +STR_3136 :Advertencia: este aspecto crearase cun tipo de vehículo alternativo e é posible que non funcione como se esperaba. +STR_3137 :Seleccionar. Escenario próximo +STR_3138 :Restablecer selección. +STR_3139 :O cable de elevación non pode funcionar neste modo +STR_3140 :O cable do ascensor debería comezar despois da estación +STR_3141 :Multicircuíto por atracción. non é posible cun cable de elevación +STR_3142 :{WINDOW_COLOUR_2}Capacidade: {BLACK}{STRINGID} +STR_3143 :Mostrar visitantes no mapa +STR_3144 :Mostrar atraccións e postos no mapa +STR_3160 :Selecciona o número de circuítos por traxecto. +STR_3162 :Non se pode asignar suficiente memoria +STR_3163 :Instalar novos datos: +STR_3164  :{BLACK}{COMMA16} seleccionado (máximo {COMMA16}) +STR_3167 :{WINDOW_COLOUR_2}Inclúe: {BLACK}{COMMA16} obxectos +STR_3169 :Datos para o seguinte obxecto non atopado: +STR_3170 :Non se pode asignar máis espazo para os gráficos +STR_3171 :Moitos obxectos deste tipo xa foron seleccionados +STR_3172 :O seguinte debe seleccionarse o obxecto. primeiro: {STRING} +STR_3173 :Este obxecto está a ser usado +STR_3174 :Este obxecto é requirido por outro obxecto +STR_3175 :Este obxecto é obrigatorio +STR_3176 :Non se pode seleccionar este obxecto +STR_3177 :Non se pode deseleccionar este obxecto +STR_3179 :Debe seleccionar polo menos unha atracción +STR_3180 :Seleccionar. obxecto non válido +STR_3181 :Selección de obxectos - {STRINGID} +STR_3182 :O tipo de entrada ao parque debe ser seleccionado +STR_3183 :O tipo de auga debe ser seleccionado +STR_3184 :Atraccións vehiculos/Atraccións +STR_3185 :Pequeno escenario +STR_3186 :Gran escenario +STR_3187 :Muros/Valados +STR_3188 :Sinais de camiños +STR_3189 :Rutas antigas +STR_3190 :Decoración de sendeiros +STR_3191 :Escenarios +STR_3192 :Entrada do parque +STR_3193 :Auga +STR_3195 :Lista de inventos +STR_3196 :{WINDOW_COLOUR_2}Grupo de investigación: {BLACK}{STRINGID} +STR_3197 :{WINDOW_COLOUR_2}Elementos xa dispoñibles ao comezo do xogo: +STR_3198 :{WINDOW_COLOUR_2}Elementos a investigar durante o xogo: +STR_3199 :mestura aleatoria +STR_3200 :Baralla aleatoriamente a lista de inventos ao comezo do xogo. +STR_3201 :Selección de obxectos +STR_3202 :Editor de paisaxes +STR_3203 :Lista de inventos finalizada +STR_3204 :elección de opcións +STR_3205 :Selección de destino +STR_3206 :Gardar escenario +STR_3207 :Deseñador de montaña rusa +STR_3208 :Deseñador de estradas +STR_3209 :Volver ao paso anterior: +STR_3210 :Avanza ao seguinte paso: +STR_3211 :Tamaño do mapa: +STR_3212  :{POP16}{COMMA16} +STR_3213 :Non podes diminuír máis o tamaño do mapa +STR_3214 :Non podes aumentar máis o tamaño do mapa +STR_3215 :Demasiado preto do bordo do mapa +STR_3216 :Seleccione o terreo propiedade do parque, etc. +STR_3217 :Terreo propio +STR_3218 :Dereitos de constr propios +STR_3219 :Terreo en venda +STR_3220 :Dereitos de constr en venta +STR_3221 :Establece os terreos propiedade do parque. +STR_3222 :Establece os dereitos de construción do parque. +STR_3223 :Establece o terreo que está dispoñible para a compra no parque. +STR_3224 :Establecer os dereitos de construción que están dispoñibles para a compra do parque +STR_3225 :Activa/Desactiva a colocación de grupos de obxectos arredor da posición seleccionada +STR_3226 :Construír a entrada do parque +STR_3227 :Moitas entradas para o parque! +STR_3228 :Establecer a posición inicial das persoas +STR_3229 :O bloque de freada non debe usarse despois da estación +STR_3230 :O bloque de freado non debe usarse despois do outro +STR_3231 :O bloque de freo non debe usarse despois do final da cadea de elevación. +STR_3232 :Opcións - Finanzas +STR_3233 :Opcións - Visitantes +STR_3234 :Opcións - Aparcar +STR_3235 :Opcións de financiamento +STR_3236 :Opcións de visitante +STR_3237 :Opcións de estacionamento +STR_3238 :Sen cartos +STR_3239 :Eliminar as restricións financeiras deste parque +STR_3240 :{WINDOW_COLOUR_2}Efectivo inicial: +STR_3241 :{WINDOW_COLOUR_2}Préstamo inicial: +STR_3242 :{WINDOW_COLOUR_2}Préstamo máximo: +STR_3243 :{WINDOW_COLOUR_2}Interese anual: +STR_3244 :Prohibir campañas de mercadotecnia +STR_3245 :Prohibir anuncios, promocións e outras campañas de mercadotecnia +STR_3246  :{WINDOW_COLOUR_2}{CURRENCY} +STR_3247  :{WINDOW_COLOUR_2}{COMMA16} % +STR_3248 :O diñeiro inicial xa non se pode aumentar! +STR_3249 :Non podes reducir máis o diñeiro inicial! +STR_3250 :O préstamo inicial non se pode aumentar máis! +STR_3251 :O préstamo inicial non se pode reducir máis! +STR_3252 :O préstamo máximo non se pode aumentar máis! +STR_3253 :O préstamo máximo non se pode reducir máis! +STR_3254 :O tipo de interese non se pode aumentar máis! +STR_3255 :O tipo de interese non se pode reducir máis! +STR_3256 :Os visitantes prefiren as atraccións tranquilas +STR_3257 :Os visitantes adoitan preferir atraccións de baixa intensidade +STR_3258 :Os visitantes prefiren atraccións intensas +STR_3259 :Os visitantes adoitan preferir atraccións de alta intensidade +STR_3260 :{WINDOW_COLOUR_2}Efectivo por visitante (media): +STR_3261 :{WINDOW_COLOUR_2}Felicidade inicial do visitante: +STR_3262 :{WINDOW_COLOUR_2}Fame inicial do visitante: +STR_3263 :{WINDOW_COLOUR_2}Sede inicial do visitante: +STR_3264 :Non se pode aumentar máis! +STR_3265 :Non se pode reducir máis! +STR_3266 :Selecciona como gastan os visitantes neste parque +STR_3267 :Prohibir a tala de árbores +STR_3268 :Prohibir a tala de árbores altas +STR_3269 :Prohibir os cambios de terreo +STR_3270 :Prohibe mover a terra +STR_3271 :Prohibir edificios altos +STR_3272 :Prohibe construír demasiado alto +STR_3273 :Dificulta a valoración do parque +STR_3274 :Fai que a valoración do parque medre máis lentamente +STR_3275 :Dificulta a xeración de visitantes +STR_3276 :diminúe a frecuencia coa que aparecen os visitantes +STR_3277 :{WINDOW_COLOUR_2}Custo do terreo: +STR_3278 :{WINDOW_COLOUR_2}Custo dos dereitos de construción: +STR_3279 :Entrada gratuíta / Atraccións de pago +STR_3280 :Pagar para entrar / Atraccións gratuítas +STR_3281 :{WINDOW_COLOUR_2}Prezo de entrada: +STR_3282 :Seleccione o nome do destino e do parque +STR_3283 :Selecciona as atraccións para conservar +STR_3284 :Selección de destino +STR_3285 :Atraccións preservadas +STR_3286 :Seleccione obxectivos para este escenario +STR_3287 :{WINDOW_COLOUR_2}Obxecto: +STR_3288 :Selecciona o tempo +STR_3289 :{WINDOW_COLOUR_2}O tempo: +STR_3290 :Frío e húmido +STR_3291 :Quente +STR_3292 :Quente e seco +STR_3293 :Frío +STR_3294 :Cambiar... +STR_3295 :Cambiar o nome do parque +STR_3296 :Cambiar o nome do escenario +STR_3297 :Cambiar os detalles do parque/escenario +STR_3298 :{WINDOW_COLOUR_2}Nome do parque: {BLACK}{STRINGID} +STR_3299 :{WINDOW_COLOUR_2}Detalles do parque/escenario: +STR_3300 :{WINDOW_COLOUR_2}Nome artístico: {BLACK}{STRINGID} +STR_3301 :{WINDOW_COLOUR_2}Data obxectivo: +STR_3302  :{WINDOW_COLOUR_2}{MONTHYEAR} +STR_3303 :{WINDOW_COLOUR_2}Número de visitantes: +STR_3304 :{WINDOW_COLOUR_2}Valor do parque: +STR_3305 :{WINDOW_COLOUR_2}Ingresos mensuais: +STR_3306 :{WINDOW_COLOUR_2}Beneficio mensual: +STR_3307 :{WINDOW_COLOUR_2}Lonxitude mínima: +STR_3308 :{WINDOW_COLOUR_2}Rango de satisfacción: +STR_3309  :{WINDOW_COLOUR_2}{COMMA32} +STR_3310  :{WINDOW_COLOUR_2}{LENGTH} +STR_3311  :{WINDOW_COLOUR_2}{COMMA2DP32} +STR_3312 :{WINDOW_COLOUR_2}Atraccións/Atraccións con orde de conservación: +STR_3313 :Denominación do escenario +STR_3314 :Introduza o nome do escenario: +STR_3315 :Detalles do parque/escenario +STR_3316 :Escribe a descrición deste escenario: +STR_3317 :Aínda non hai detalles +STR_3318 :Selecciona o grupo ao que pertence o teu escenario +STR_3319 :{WINDOW_COLOUR_2}Grupo de escenarios: +STR_3320 :Non se puido gardar o ficheiro de escenario... +STR_3321 :Os novos obxectos instaláronse correctamente +STR_3322 :{WINDOW_COLOUR_2}Obxectivo: {BLACK}{STRINGID} +STR_3326 :{WINDOW_COLOUR_2}(sen imaxe) +STR_3327 :A posición inicial dos visitantes non foi definida +STR_3328 :Non se pode avanzar á seguinte fase do editor... +STR_3329 :Non se construíu unha entrada ao parque +STR_3330 :O parque debe ter terreo +STR_3331 :A ruta de entrada ao parque no bordo do mapa non está completa nin é demasiado complexa. Debe ter un só carril con o menor número de cruzamentos e curvas posibles. +STR_3332 :A entrada do parque está cara atrás ou non ten un camiño que conduce ao bordo do mapa +STR_3333 :Exporta complementos ao gardar a partida +STR_3334 :Selecciona se os complementos adicionais (datos non distribuídos co xogo principal) usados ​​nun escenario deben exportarse ao gardar o xogo, permitindo que outros xogadores que non teñan eses complementos poidan abrir o xogo. +STR_3335 :Deseñador de estradas: seleccione o tipo de atracción e vehículo +STR_3336 :Xestor de deseño de estradas: escolla o tipo de atracción +STR_3338 :{BLACK}Percorrido personalizado +STR_3339 :{BLACK}{COMMA16} deseño dispoñible ou visita personalizada +STR_3340 :{BLACK}{COMMA16} deseños dispoñibles ou visita personalizada +STR_3341 :Ferramentas de xogo +STR_3342 :Editor de escenarios +STR_3343 :Converte a partida gardada en escenario +STR_3344 :Deseñador de estradas +STR_3345 :Administrador de estradas +STR_3346 :Non se pode gardar o deseño da pista... +STR_3347 :Atracción demasiado longo, contén demasiados elementos ou a paisaxe está demasiado lonxe. +STR_3348 :Renomear +STR_3349 :Eliminar +STR_3350 :Nome Deseño Vía +STR_3351 :Nome do novo deseño da pista: +STR_3352 :Non se pode cambiar o nome do deseño da pista... +STR_3353 :O nome novo contén caracteres non válidos +STR_3354 :Outro ficheiro xa ten este nome ou está protexido contra escritura +STR_3355 :O ficheiro está bloqueado ou protexido contra escritura +STR_3356 :Eliminar ficheiro +STR_3357 :{WINDOW_COLOUR_2}Estás seguro de eliminar permanentemente {STRING}? +STR_3358 :Non se pode eliminar o deseño da pista... +STR_3359 :{BLACK}Non hai deseños de pistas para esta atracción +STR_3360 :Aviso! +STR_3361 :Demasiados esquemas de pistas - Algúns non aparecerán na lista. +STR_3364 :Avanzado +STR_3365 :Permitir a selección de escenarios ademais dos grupos de escenarios. +STR_3366 :{BLACK}= Atracción +STR_3367 :{BLACK}= Posto de comida +STR_3368 :{BLACK}= Bebida +STR_3369 :{BLACK}= Posto de recordos +STR_3370 :{BLACK}= Quiosco de información +STR_3371 :{BLACK}= Primeiros auxilios +STR_3372 :{BLACK}= caixeiro automático +STR_3373 :{BLACK}= Servizos +STR_3374 :Aviso: Seleccionáronse demasiados obxectos +STR_3375 :Non se seleccionaron todos os obxectos deste grupo +STR_3376 :Instalar novo... +STR_3377 :Instalar un novo ficheiro de deseño de pista +STR_3378 :Instalar +STR_3379 :Cancelar +STR_3380 :Non se puido instalar este deseño da pista... +STR_3381 :O ficheiro non é compatible ou contén datos non válidos +STR_3382 :Fallou a copia do ficheiro +STR_3383 :Seleccionar. novo deseño da pista do nome +STR_3384 :Un deseño de pista xa ten este nome - escolle outro nome: +STR_3389 :Non é posible seleccionar o elemento de escenario adicional... +STR_3390 :Seleccionáronse demasiados elementos +STR_3437 :Demoler grandes áreas de decoración +STR_3438 :Non se pode eliminar esta decoración... +STR_3439 :Eliminar decoración +STR_3445 :Establecer área de patrulla +STR_3446 :Cancelar área de patrulla + +# New strings, cleaner +STR_5120 :Finanzas +STR_5121 :Investigación +STR_5122 :Selecciona atraccións por tipo (como en RCT1) +STR_5123 :Renovar as atraccións +STR_5125 :Todo editable +STR_5126 :Música ao chou +STR_5127 :pinta o terreo en lugar de cambiar de elevación mentres arrastras. +STR_5128 :Tamaño da selección +STR_5129 :Escribe un tamaño de selección entre {COMMA16} e {COMMA16} +STR_5130 :Tamaño do mapa +STR_5131 :Escribe un tamaño de mapa entre {COMMA16} e {COMMA16} +STR_5132 :Correxir as atraccións +STR_5133 :Establece unha área máis pequena para os dereitos de construción. +STR_5134 :Establece unha área máis grande para os dereitos de construción. +STR_5135 :Comprar terreos ou dereitos de construción +STR_5136 :Dereitos de terreo +STR_5137 :Desbloquea os límites operativos +STR_5138  :{WINDOW_COLOUR_2}{STRINGID} +STR_5139 :{WHITE}{STRINGID} +STR_5140 :Desactivar fallos de freo +STR_5141 :Desactiva todos os fallos +STR_5142 :Velocidade normal +STR_5143 :Velocidade da luz +STR_5144 :Velocidade rápida +STR_5145 :Velocidade turbo +STR_5146 :Hiper velocidade +STR_5147 :Trucos +STR_5148 :Cambiar a velocidade do xogo +STR_5149 :Opcións de trucos +STR_5150 :Activar ferramentas de depuración +STR_5151 :. +STR_5152 :, +STR_5153 :Editar temas... +STR_5154 :Renderizado de hardware +STR_5155 :Permitir probas de atraccións sen rematar +STR_5156 :Permíteche probar a maioría das atraccións que aínda non estean construídas. Non se aplica aos modos de funcionamento da sección de bloque +STR_5158 :Saír ao menú principal +STR_5159 :Saír de OpenRCT2 +STR_5160  :{POP16}{MONTH} {PUSH16}{PUSH16}{STRINGID}, ano {POP16}{COMMA16} +STR_5161 :Formato de data: +STR_5162 :Día/Mes/Ano +STR_5163 :Mes/Día/Ano +STR_5177 :Modo de visualización: +STR_5178 :Mostrar trucos de diñeiro +STR_5179 :Mostrar trucos para visitantes +STR_5180 :Mostrar trucos do parque +STR_5181 :Mostrar trucos de atraccións +STR_5182  :{INT32} +STR_5183 :Altura da base +STR_5184 :Introduce unha altura entre {COMMA16} e {COMMA16} +STR_5185 :Nivel da auga +STR_5186 :Introduza un nivel entre {COMMA16} e {COMMA16} +STR_5187 :Finanzas +STR_5188 :Nova campaña +STR_5189 :Investigación +STR_5190 :Mapa +STR_5191 :Xanela +STR_5192 :Mensaxes recentes +STR_5193 :Terreo +STR_5194 :Auga +STR_5195 :escenario claro +STR_5196 :Dereitos de construción +STR_5197 :Escenario +STR_5198 :Ruta +STR_5199 :Construción de atraccións +STR_5200 :Editor de pistas +STR_5201 :Nova atracción +STR_5202 :Selección do editor de pistas +STR_5203 :Atraccións +STR_5204 :Lista de atraccións +STR_5205 :Visitante +STR_5206 :Lista de visitantes +STR_5207 :Empregado +STR_5208 :Lista de empregados +STR_5209 :Bandeira +STR_5210 :Selección de obxectos +STR_5211 :Lista de inventos +STR_5212 :Opcións de escenario +STR_5213 :Opcións de destino +STR_5214 :Xeración de mapas +STR_5215 :Xestor de deseño de estradas +STR_5216 :Xestor de listas de deseño de estradas +STR_5217 :Trucos +STR_5218 :Temas +STR_5219 :Opcións +STR_5220 :Atallos de teclado +STR_5221 :Cambiar atallos de teclado +STR_5222 :Cargar/Gardar +STR_5223 :Gardar aviso +STR_5224 :Aviso de demolición de Atracción +STR_5225 :Aviso para despedir a un empregado +STR_5226 :Aviso de demolición da estrada +STR_5227 :Aviso de sobrescritura de gardado +STR_5228 :Interface principal +STR_5229 :Parque +STR_5230 :Ferramentas +STR_5231 :Atraccións e visitantes +STR_5232 :Editores +STR_5233 :Varios +STR_5234 :Avisos +STR_5235 :Configuración +STR_5236 :Xanela +STR_5237 :Paleta +STR_5238 :Tema actual: +STR_5239 :Duplicado +STR_5240 :Escribe o nome do tema +STR_5241 :Non podes cambiar este tema +STR_5242 :O nome do tema xa existe +STR_5243 :Texto non válido +STR_5244 :Temas +STR_5245 :Barra de ferramentas superior +STR_5246 :Barra de ferramentas inferior +STR_5247 :Editor de pistas (barra inferior) +STR_5248 :Editor de escenarios (barra inferior) +STR_5249 :Cor dos botóns do menú +STR_5250 :Cor do botón Saír +STR_5251 :Cor do botón de opción +STR_5252 :selección de escenarios de cor +STR_5253 :Información do parque +STR_5256 :Crear un novo tema para facer cambios +STR_5257 :Crear tema baseado no actual +STR_5258 :Eliminar o tema actual +STR_5259 :Renomear o tema actual +STR_5260 :Fai unha captura de pantalla do escenario completo +STR_5261 :Filtro +STR_5262 :Mundos tolos +STR_5263 :Torbellino do Tempo +STR_5264 :Personalizado +STR_5265 :Selecciona que contidos son visibles +STR_5266 :Gráficos +STR_5267 :Idioma e unidades +STR_5268 :Audio +STR_5269 :Interface e controis +STR_5270 :Outras opcións +STR_5272 :Pequena decoración +STR_5273 :Decoración grande +STR_5274 :Rutas +STR_5275 :Busca por obxectos +STR_5276 :Escribe o nome do obxecto para buscar +STR_5277 :Eliminar +STR_5278 :Modo de caixa de area +STR_5279 :Modo de caixa de area apagado +STR_5280 :Permíteche editar o terreo da propiedade e outras opcións restrinxidas ao Editor de escenarios +STR_5281 :Características +STR_5282 :luces de apertura e peche da atracción. igual a RCT1 +STR_5283 :luces abertas/pechadas de estacionamento iguais a RCT1 +STR_5284 :selección da fonte do escenario igual a RCT1 +STR_5287 :A atracción xa está rota +STR_5288 :A atracción está pechada +STR_5289 :Non hai desgloses dispoñibles para esta atracción +STR_5290 :Correxir atracción +STR_5291 :Non pode forzar unha avaría +STR_5292 :Forzar unha avaría +STR_5293 :Pechar atracción/atracción +STR_5294 :Proba a atracción/atracción +STR_5295 :Abrir atracción/atracción +STR_5296 :Pechar o parque +STR_5297 :Parque aberto +STR_5298 :{RED}{STRINGID} +STR_5299 :{LIGHTPINK}{STRINGID} +STR_5300 :Despedir aos empregados rapidamente +STR_5301 :Eliminar a débeda co banco +STR_5302 :Reiniciar o préstamo +STR_5303 :Permite a construción mentres está en pausa +STR_5304 :Seg. Menú principal: +STR_5305 :RollerCoaster Tycoon 1 +STR_5306 :RollerCoaster Tycoon 1 (AA) +STR_5307 :RollerCoaster Tycoon 1 (AA + LL) +STR_5308 :RollerCoaster Tycoon 2 +STR_5309 :OpenRCT2 +STR_5310 :Aleatorio +STR_5311 :Ferramentas de depuración +STR_5312 :Mostrar consola +STR_5313 :Mostrar inspección. Reixa +STR_5314 :Inspector de rede +STR_5335 :Entrada +STR_5336 :Saída +STR_5337 :Entrada do parque +STR_5338 :Tipo de elemento: +STR_5339 :Altura da base +STR_5340 :Altura libre +STR_5343 :Coloca os traballadores automaticamente +STR_5344 :Cambios +STR_5345 :Trucos de cartos +STR_5346 :Trucos para visitantes +STR_5347 :Trucos do parque +STR_5348 :Trucos de diversión +STR_5349 :Todas as atraccións +STR_5350 :Máx. +STR_5351 :mín. +STR_5352 :{BLACK}Felicidade: +STR_5353 :{BLACK}Enerxía: +STR_5354 :{BLACK}Fame: +STR_5355 :{BLACK}Sede: +STR_5356 :{BLACK}Náuseas: +STR_5357 :{BLACK}Tolerancia ás náuseas: +STR_5358 :{BLACK}Vexiga: +STR_5359 :Eliminar visitantes +STR_5360 :Eliminar todos os visitantes do mapa +STR_5361 :Dálle a todos os visitantes: +STR_5362 :{BLACK}Todos os visitantes prefiren intensidades: +STR_5363 :Máis de 1 +STR_5364 :Menos de 15 +STR_5365 :{BLACK}Velocidade dos empregados: +STR_5366 :Normal +STR_5367 :Rápido +STR_5368 :Restablecer accidentes +STR_5371 :Selección de obxectos +STR_5372 :Inverte a compensación do clic dereito +STR_5373 :Nome {STRINGID} +STR_5374 :Data {STRINGID} +STR_5375 :▲ +STR_5376 :▼ +STR_5404 :O nome xa existe +STR_5440 :minimiza a pantalla completa ao perder o foco +STR_5442 :Calificación da forza: +STR_5447 :Escriba {STRINGID} +STR_5448 :Atracción / vehículo {STRINGID} +STR_5449 :Reducir a velocidade da atracción +STR_5450 :Aumenta a velocidade da atracción +STR_5451 :Abrir xanela de trucos +STR_5452 :Alternar a visibilidade da ferramenta +STR_5453 :Selecciona outra atracción +STR_5454 :Eliminar límite de FPS +STR_5455 :Activar o modo caixa de area +STR_5456 :Desactivar a comprobación de autorización +STR_5457 :Desactivar os límites de altura +STR_5458 :Xira no sentido das agullas do reloxo +STR_5459 :Xira en sentido antihorario +STR_5460 :Xira a vista cara á esquerda +STR_5461 :Axustar os parámetros do visitante +STR_5462  :{CURRENCY} +STR_5463 :Obxectivo: ¡Divírtete! +STR_5464 :Xerais +STR_5465 :Clima +STR_5466 :Empregados +STR_5467 :ALT + +STR_5468 :Mensaxes recentes +STR_5469 :Mover mapa cara arriba +STR_5470 :Mover o mapa cara á esquerda. +STR_5471 :Desprazar o mapa cara abaixo +STR_5472 :Mover o mapa cara á dereita +STR_5473 :Alterna día e noite +STR_5474 :Mostrar o texto do signo en maiúscula +STR_5475  :{COMMA16} semanas +STR_5476 :Hardware +STR_5477 :Representación do mapa +STR_5478 :Controis +STR_5479 :Barra de ferramentas +STR_5480 :Mostra os seguintes botóns: +STR_5481 :Aparición +STR_5482 :{WINDOW_COLOUR_2}Tempo desde a última inspección: {BLACK}1 minuto +STR_5483 :{BLACK}(Quedan {COMMA16} semanas) +STR_5484 :{BLACK}(Queda {COMMA16} semana) +STR_5485 :{STRING} +STR_5486 :{NEGRO}{COMMA16} +STR_5487 :Mensaxes recentes +STR_5489 :Mostrar só os visitantes co seguimento activado +STR_5490 :Silenciar ao perder o foco +STR_5491 :Lista de inventos +STR_5492 :Opcións de escenario +STR_5493 :Enviar mensaxe +STR_5495 :Lista de xogadores +STR_5496 :Xogador +STR_5497 :Ping +STR_5498 :Lista de servidores +STR_5499 :Nome do xogador: +STR_5500 :Engadir servidor +STR_5501 :Iniciar servidor +STR_5502 :Multixogador +STR_5503 :Introduza o nome do anfitrión ou a IP: +STR_5504 :Mostrar o estado do multixogador +STR_5505 :Non se puido conectar co servidor. +STR_5506 :Os visitantes ignoran a intensidade da atracción. +STR_5510 :Dispositivo de son predeterminado +STR_5511 :(DESCOÑECIDO) +STR_5512 :Gardar o xogo como... +STR_5513 :partida de gardado rápido +STR_5514 :Desactivar o vandalismo +STR_5515 :Evita que os visitantes enfadados cometan actos de vandalismo +STR_5516 :Negro +STR_5517 :Gris +STR_5518 :Branco +STR_5519 :Morado oscuro +STR_5520 :Morado claro +STR_5521 :Morado brillante +STR_5522 :Azul escuro +STR_5523 :Azul claro +STR_5524 :Azul xeado +STR_5525 :Auga escura +STR_5526 :Auga limpa +STR_5527 :verde saturado +STR_5528 :Verde escuro +STR_5529 :Verde musgo +STR_5530 :Verde brillante +STR_5531 :Verde oliva +STR_5532 :Verde oliva escuro +STR_5533 :amarelo brillante +STR_5534 :amarelo +STR_5535 :Amarelo escuro +STR_5536 :Laranxa claro +STR_5537 :Laranxa escuro +STR_5538 :marrón claro +STR_5539 :Café saturado +STR_5540 :marrón escuro +STR_5541 :Rosa salmón +STR_5542 :Vermello Borgoña +STR_5543 :vermello saturado +STR_5544 :Vermello brillante +STR_5545 :Rosa escuro +STR_5546 :Rosa brillante +STR_5547 :Rosa claro +STR_5548 :Mostra os modos de funcionamento +STR_5549 :Ano/Mes/Día +STR_5550  :{POP16}{POP16}Ano {COMMA16}, {PUSH16}{PUSH16}{MONTH} {PUSH16}{PUSH16}{STRINGID} +STR_5551 :Ano/Día/Mes +STR_5552  :{POP16}{POP16}Ano {COMMA16}, {PUSH16}{PUSH16}{PUSH16}{STRINGID} {MONTH} +STR_5553 :Pausa o xogo cando se abra Steam +STR_5554 :Activar ferramenta de montaña +STR_5555 :Mostra vehículos doutro tipo de estradas +STR_5556 :Expulsar o reprodutor +STR_5557 :Mantente conectado despois da desincronización (multixogador) +STR_5558 :Esta configuración só terá efecto despois de que reinicias OpenRCT2 +STR_5559 :Inspeccións 10m +STR_5560 :Establece o tempo de inspección en "Cada 10 minutos" en todas as atraccións +STR_5561 :Non se puido cargar o idioma. +STR_5562 :ATENCIÓN! +STR_5563 :Esta configuración é inestable, toma precaucións. +STR_5566 :Contrasinal: +STR_5567 :Mostrar na lista de servidores +STR_5568 :O contrasinal é necesario +STR_5569 :Este servidor require un contrasinal +STR_5570 :Actualizar a lista +STR_5571 :Únete ao xogo +STR_5572 :Engadir a favoritos +STR_5573 :Eliminar dos favoritos +STR_5574 :Nome do servidor: +STR_5575 :Número máximo de xogadores: +STR_5576 :Porto: +STR_5577 :won surcoreano (W) +STR_5578 :Rublo ruso (₽) +STR_5579 :Factor de escala da xanela: +STR_5580 :Coroa checa (Kč) +STR_5581 :Mostrar FPS +STR_5582 :Manteña o punteiro do rato na xanela +STR_5583  :{COMMA1DP16}m/s +STR_5584 :SI +STR_5585 :Desbloquea os límites de operación da atracción, permitindo cousas como colinas de elevación a {VELOCITY} +STR_5586 :Abrir tendas e postos automaticamente +STR_5587 :As tendas e os postos abriranse automaticamente despois da construción. +STR_5588 :Xoga con outros xogadores +STR_5589 :Configuración de notificacións +STR_5590 :Premios do parque +STR_5591 :Completáronse as campañas de mercadotecnia +STR_5592 :Avisos de parque +STR_5593 :Avisos sobre a valoración do parque +STR_5594 :A atracción estropeouse +STR_5595 :A atracción foi destruída +STR_5596 :Avisos de atraccións +STR_5597 :Atracción e decoración desenvolvida +STR_5598 :Avisos de visitantes +STR_5600 :O visitante abandonou o parque +STR_5601 :O visitante fixo cola para unha atracción +STR_5602 :O visitante subiu a unha atracción +STR_5603 :O visitante saíu da atracción +STR_5604 :O visitante comprou algo +STR_5605 :O visitante utilizou unha instalación +STR_5606 :O visitante morreu +STR_5607 :Eliminar forzosamente o elemento seleccionado do mapa. +STR_5608 :BH +STR_5609 :CH +STR_5610 :Eliminar do mapa o elemento seleccionado. Isto obriga á eliminación, polo que non se devolverá o custo deste artigo. Use isto con precaución. +STR_5611 :G +STR_5612 :Bandeira pantasma +STR_5613 :B +STR_5614 :bandeira rota +STR_5615 :L +STR_5616 :Último elemento para a bandeira da casa. +STR_5617 :Mover os elementos seleccionados arriba. +STR_5618 :Mover os elementos seleccionados abaixo. +STR_5619 :RollerCoaster Tycoon +STR_5620 :Atraccións engadidas +STR_5621 :Paisaxes Loopy +STR_5622 :RollerCoaster Tycoon 2 +STR_5623 :Wacky Worlds +STR_5624 :Time Twister +STR_5625 :Parques "Reais". +STR_5626 :Outros parques +STR_5627 :Lista de escenarios de grupo: +STR_5628 :xogo orixinal +STR_5629 :Nivel de dificultade +STR_5630 :activa o desbloqueo progresivo +STR_5631 :DLC de parques orixinais +STR_5632 :Constrúe o teu propio... +STR_5633 :CMD + +STR_5634 :OPCIÓN + +STR_5635 :{WINDOW_COLOUR_2}Diñeiro gastado: {BLACK}{CURRENCY2DP} +STR_5636 :{WINDOW_COLOUR_2}Total de accións: {BLACK}{COMMA16} +STR_5637 :Non podes facelo... +STR_5638 :Permiso denegado +STR_5639 :Mostrar a lista de xogadores +STR_5640 :Xestionar grupos +STR_5641 :Grupo predeterminado: +STR_5642 :Grupo +STR_5643 :Engadir grupo +STR_5644 :Eliminar grupo +STR_5645 :Chat +STR_5646 :Axustar o terreo +STR_5647 :alternar a pausa +STR_5648 :Axustar a auga +STR_5649 :Crear atracción +STR_5650 :Demoler atracción +STR_5651 :Construír atracción +STR_5652 :Editar atracción +STR_5653 :Escenarios +STR_5654 :Rutas +STR_5655 :Xestionar convidados +STR_5656 :Xestionar empregados +STR_5657 :prop. do parque +STR_5658 :Finanzas +STR_5659 :Expulsar o reprodutor +STR_5660 :Editar grupos +STR_5661 :Cambiar grupos +STR_5662 :Ningún +STR_5663 :Paisaxe limpa +STR_5664 :Usa trucos +STR_5665 :Colocación de escenarios múltiples +STR_5666 :Iniciar sesión sen contrasinal +STR_5701 :{WINDOW_COLOUR_2}Última acción: {BLACK}{STRINGID} +STR_5702 :Vai á última acción do xogador. +STR_5703 :Non podes expulsar ao anfitrión. +STR_5704 :Última acción +STR_5705 :Non se pode cambiar a este grupo. +STR_5706 :Non se pode eliminar o grupo, hai xogadores nel. +STR_5707 :Este grupo non se pode modificar. +STR_5708 :Non se pode cambiar o grupo de anfitrión +STR_5709 :Cambiar o nome do grupo +STR_5710 :Nome do grupo +STR_5711 :Introduza o novo nome para este grupo: +STR_5712 :Non podes modificar o permiso que non tes +STR_5713 :Expulsar o reprodutor +STR_5714 :Opcións da xanela +STR_5715 :xogo novo +STR_5716 :Non se permite no modo multixogador +# For identifying client network version in server list window +STR_5717 :Versión do software: {STRING} +STR_5718 :Versión de software: {STRING} +STR_5719 :Soleado +STR_5720 :Parc. Nubrado +STR_5721 :Nubrado +STR_5722 :Choiva lixeira +STR_5723 :Choiva +STR_5724 :Tempestada +STR_5725 :{BLACK}Cambia o tempo a: +STR_5726 :Establece o tempo actual no parque +# tooltip for tab in options window +STR_5734 :Renderizado +STR_5735 :Estado da rede +STR_5736 :Xogador +STR_5737 :Pechado, {COMMA16} persoa na atracción +STR_5738 :Pechado, {COMMA16} persoas na atracción +STR_5739 :{WINDOW_COLOUR_2}Visitantes da atracción: {BLACK}{COMMA16} +STR_5740 :campañas de mercadotecnia infinitas +STR_5741 :As campañas de mercadotecnia nunca rematan. +STR_5742 :Autenticando... +STR_5743 :Conectando... +STR_5744 :Resolvendo… +STR_5745 :Dessincronización detectada +STR_5746 :Fóra de liña +STR_5747 :Fóra de liña: {STRING} +STR_5748 :Expulsado +STR_5749 :Saia do servidor! +STR_5750 :conexión pechada +STR_5751 :Sen datos +STR_5752 :{OUTLINE}{RED}{STRING} desconectouse +STR_5753 :{OUTLINE}{RED}{STRING} desconectouse ({STRING}) +STR_5754 :Nome do xogador incorrecto +STR_5755 :Versión de software incorrecta (versión do servidor {STRING}) +STR_5756 :Contrasinal incorrecto +STR_5757 :Servidor cheo +STR_5758 :{OUTLINE}{GREEN}{STRING} uniuse ao xogo +STR_5759 :Descargando mapa… +STR_5760 :Dólar de Hong Kong (HK$) +STR_5761 :Novo dólar taiwanés (NT$) +STR_5762 :Yuan chinés (CN¥) +STR_5763 :Todos os ficheiros +STR_5764 :Tipo de atracción non válido +STR_5765 :Non se pode editar unha atracción dun tipo non válido +STR_5766 :Florín húngaro (Ft) +STR_5767 :Ingresos +STR_5768 :Clientes totais +STR_5769 :Beneficio total +STR_5770 :Clientes por hora +STR_5771 :Custo de operación +STR_5772 :Idade +STR_5773 :Clientes totais: {COMMA32} +STR_5774 :Beneficio total: {CURRENCY2DP} +STR_5775 :Clientes: {COMMA32} por hora +STR_5776 :Construído: Este ano +STR_5777 :Construción: o ano pasado +STR_5778 :Construído: hai {COMMA16} anos +STR_5779 :Ingresos: {CURRENCY2DP} por hora +STR_5780 :Custo: {CURRENCY2DP} por hora +STR_5781 :Custo: descoñecido +STR_5782 :Agora estás conectado. Preme "{STRING}" para chatear. +STR_5783 :{WINDOW_COLOUR_2}Escenario bloqueado +STR_5784 :{BLACK}Completa os escenarios anteriores para desbloquear este escenario. +STR_5785 :Non podes cambiar o nome do grupo... +STR_5786 :O nome do grupo non é válido +STR_5787 :{COMMA32} xogadores en liña. +STR_5788 :Intervalo Inspección predeterminado: +STR_5789 :Desactivar o efecto de raios +STR_5790 :Cambia ao estilo de prezo como en RCT1{NEWLINE}(Con este truco pódense editar tanto o prezo da entrada ao parque como o prezo dunha atracción). +STR_5791 :Establece a fiabilidade da viaxe ao 100 % e restablece a data de construción a "este ano". +STR_5792 :Amaña todas as atracions rotas. +STR_5793 :Restablece o historial de accidentes dunha atracción, polo que os visitantes non se queixarán se non é seguro. +STR_5794 :Algúns escenarios desactivan a edición de atraccións que xa están no parque. Este truco elimina esta restrición. +STR_5795 :Os visitantes percorrerán calquera atracción independentemente de que a intensidade sexa extremadamente alta. +STR_5796 :Obriga a abrir ou pechar as entradas do parque. +STR_5797 :Desactiva o cambio de clima e mantén o clima seleccionado. +STR_5798 :Permite crear accións en modo de pausa. +STR_5799 :Desactiva as avarías e os accidentes por avaría dos freos. +STR_5800 :Evita que as atraccións se avarien. +STR_5801 :Desactivar o lixo +STR_5802 :Evita que os visitantes boten lixo ou vómitos nos camiños. +STR_5803 :Xira o elemento do mapa seleccionado. +STR_5804 :Silenciar o son +STR_5805 :Se selecciona o teu servidor engadirase á lista de servidores públicos onde calquera pode atopar o teu servidor. +STR_5806 :alternar o modo de pantalla completa +STR_5807 :{WINDOW_COLOUR_2}Número de atraccións/atraccións: {BLACK}{COMMA16} +STR_5808 :{WINDOW_COLOUR_2}Número de tendas e postos de venda: {BLACK}{COMMA16} +STR_5809 :{WINDOW_COLOUR_2}Número de quioscos e outras instalacións: {BLACK}{COMMA16} +STR_5810 :Desactivar o límite de vehículos +STR_5811 :Se está activado, podes ter ata 255 coches por tren e 31 trens por atracción. +STR_5812 :Mostrar a xanela multixogador +STR_5813 :“{STRING}” +STR_5814 :{WINDOW_COLOUR_1}“{STRING}” + +#tooltips +STR_5815 :Mostra a cantidade de FPS no xogo. +STR_5816 :Configura a escala da IU.{NEWLINE}Adoita ser útil cando se xoga en pantallas de alta resolución. +STR_5819 :[Requírese renderización de hardware]{NEWLINE}Pausa o xogo se Steam se superpón durante o xogo. +STR_5820 : Minimiza o xogo se se perde o foco no modo de pantalla completa. +STR_5822 :Activa os ciclos de día e de noite.{NEWLINE}Un ciclo completo leva un mes no xogo. +STR_5823 :Mostra o texto do signo en maiúsculas (como en RCT1) +STR_5824 :Desactiva os raios durante unha treboada. +STR_5825 :Manteña o punteiro do rato na xanela. +STR_5826 :Inverte o desprazamento dereito do rato. +STR_5827 :Establece o esquema de cores (tema) usado para a interface. +STR_5828 :Cambia o formato utilizado para medir distancias, velocidades, etc. +STR_5829 :Cambia o formato utilizado na moeda. Isto é só visual, o tipo de cambio non se calcula. +STR_5830 :Cambia o idioma do xogo. +STR_5831 :Cambia o formato mostrado para a temperatura. +STR_5832 :Mostrar marcas de altura con{NEWLINE}valores relativos{NEWLINE}(+1, +2, +3, etc.){NEWLINE}ou con valores reais{NEWLINE}(1m, 5m, 10m, etc.). +STR_5833 :Cambia o formato de data que se utilizará no xogo. +STR_5834 :Selecciona o dispositivo de son que debería usar OpenRCT2. +STR_5835 :Desactiva o xogo se a xanela perde o foco. +STR_5836 :Selecciona a música utilizada no menú principal.{NEWLINE}Para seleccionar o tema RCT1 é necesario configurar o camiño para RCT1 nas Opcións avanzadas. +STR_5837 :Crea e xestiona os teus temas de interface personalizados. +STR_5838 :Mostra un botón separado para as finanzas na barra de ferramentas superior. +STR_5839 :Mostra un botón separado para investigación e desenvolvemento na barra de ferramentas superior. +STR_5840 :Mostrar un botón separado para trampas na barra de ferramentas superior. +STR_5841 :Mostrar un botón separado para as mensaxes recentes na barra de ferramentas superior. +STR_5842 :Ordena as pestanas de escenarios pola súa dificultade (como en RCT2) ou pola súa orixe (como en RCT1) +STR_5843 :Activar o desbloqueo progresivo de escenarios (como en RCT1) +STR_5844 :Permanece conectado no servidor multixogador aínda que se produza un erro de desincronización. +STR_5845 :Engade un botón para ferramentas de depuración á barra de ferramentas superior. Isto permite que o atallo de teclado abra a consola de desenvolvemento. +STR_5846 :Establece a frecuencia coa que OpenRCT2 garda automaticamente o xogo. +STR_5847 :Selecciona a secuencia de aparcadoiro utilizada no menú principal. As secuencias RCT1/RCT2 requiren importar os escenarios para funcionar. +STR_5849 :Colocar automaticamente novos empregados contratados. +STR_5851 :Establece o tempo de inspección predeterminado para as novas atraccións. +STR_5853 :Activar/Desactivar efectos de son. +STR_5854 :Activar/Desactivar a música da atracción. +STR_5855 :Establece o modo de pantalla completa, con fiestras ou sen bordes. +STR_5856 :Establece a resolución do xogo utilizada no modo de pantalla completa. +STR_5857 :Opcións de xogo +STR_5858 :Utiliza a GPU para a visualización en lugar da CPU. Isto mellora a compatibilidade do software para a captura de capturas de pantalla. Isto pode ralentizar lixeiramente o rendemento do xogo. +STR_5859 :Permite a interpolación de {NEWLINE} FPS (fotogramas por segundo) para un xogo visualmente máis fluido. Se está desactivado, o xogo executarase a un máximo de 40 FPS. +STR_5860 :Cambio debuxado mediante orixinal/descomp. +STR_5861 :Fallou a verificación da chave. +STR_5862 :Bloquear xogadores descoñecidos. +STR_5863 :Só os xogadores con contrasinais coñecidos poden unirse. +STR_5864 :Só están permitidos os xogadores da lista branca. +STR_5865 :gravar o historial de conversas. +STR_5866 :Rexistra todo o historial de conversas nos ficheiros do teu cartafol de usuario. +STR_5867 :{WINDOW_COLOUR_2}Nome do provedor: {BLACK}{STRING} +STR_5868 :{WINDOW_COLOUR_2}Correo electrónico do provedor: {BLACK}{STRING} +STR_5869 :{WINDOW_COLOUR_2}Sitio web do provedor: {BLACK}{STRING} +STR_5870 :Mostrar información do servidor. +STR_5871 :As plantas non se murchan +STR_5872 :Evita que as plantas se marchiten se non se regan. +STR_5873 :Cadea de elevación completa +STR_5874 :Permite colocar unha cadea de elevación en calquera parte do camiño. +STR_5875 :Motor de debuxo: +STR_5876 :O software a usar para debuxar o xogo. +STR_5877 :Software +STR_5878 :Software (a través de hardware) +STR_5879 :OpenGL (experimental) +STR_5880 :Só seleccionado +STR_5881 :Só Non seleccionado +STR_5882 :Moeda personalizada +STR_5883 :Configuración de moeda personalizada +STR_5884 :{WINDOW_COLOUR_2}Taxa de cambio: +STR_5885  :{WINDOW_COLOUR_2}é equivalente a {COMMA32} libras (£) +STR_5886 :{WINDOW_COLOUR_2}Símbolo monetario: +STR_5887 :Prefixo +STR_5888 :Sufixo +STR_5889 :Símbolo de moeda personalizado +STR_5890 :Introduce o símbolo de moeda personalizado +STR_5891 :predeterminado +STR_5892 :Ir ao cartafol predeterminado. +STR_5893 :Taxa de cambio +STR_5894 :Introduza o tipo de cambio +STR_5895 :Gardar o deseño da pista +STR_5896 :Fallou o gardar o deseño da pista! +STR_5898 :{BLACK}Non se puido cargar o deseño da pista:{NEWLINE}O ficheiro parece estar corrupto, danado ou non existe. +STR_5899 :Alternar ventilación. depuración da pintura +STR_5900 :Utiliza o código de debuxo orixinal +STR_5901 :Mostrar alturas dos segmentos +STR_5902 :Mostrar caixas delimitadoras +STR_5903 :Mostrar a xanela de depuración da pintura +STR_5904 :Restablecer data +STR_5905 :Unha ferramenta de xeración de mapas que crea automaticamente unha paisaxe personalizada. +STR_5906 :Acerca a posición do cursor +STR_5907 :Cando está activado, o zoom centrarase no cursor en lugar do centro da pantalla. +STR_5908 :Permitir cambios arbitrarios do tipo de pista +STR_5909 :Permíteche cambiar libremente o tipo de pista dunha atracción. Pode provocar un accidente. +STR_5910 :Solicitar +STR_5911 :Vista a través de sendeiros +STR_5912 :Alternar a vista a través das rutas +STR_5913 :Chat +STR_5914 :Atracción descoñecida +STR_5915 :Xogador +STR_5916 :{COMMA16} xogador +STR_5917  :{COMMA16} xogadores +STR_5918 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} +STR_5919  :{COMMA16} +STR_5920 :Efectos do tempo +STR_5921 :se está activado, as cores escuras e a choiva mostraranse durante unha tormenta +STR_5922  :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}Máx. {STRINGID} +STR_5923 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}Máx. {COMMA16} {STRINGID} por tren +STR_5924 :Detalles da superficie +STR_5925 :Detalles da ruta +STR_5926 :Detalles da estrada +STR_5927 :Detalles do escenario +STR_5928 :Detalles da entrada +STR_5929 :Detalles do muro +STR_5930 :Detalles da etapa grande +STR_5931 :Detalles da bandeira +STR_5932 :Detalles do elemento corrompido +STR_5933 :Propiedades +STR_5934 :Textura do terreo: {BLACK}{STRINGID} +STR_5935 :Bordo do terreo: {BLACK}{STRINGID} +STR_5936 :Propietario do terreo: {BLACK}{STRINGID} +STR_5937 :Sen propiedade e non á venda +STR_5938 :Nivel da auga: {BLACK}{COMMA16} +STR_5939 :Eliminar valados do parque +STR_5940 :Restaurar os valados do parque +STR_5941 :Altura da base: +STR_5942 :Nome da ruta: {BLACK}{STRINGID} +STR_5943 :Adicións: {BLACK}{STRINGID} +STR_5944 :Adicións: {BLACK}Nada +STR_5945 :Bordes conectados: +STR_5946 :Tipo de atracción: {BLACK}{STRINGID} +STR_5947 :ID da atracción: {BLACK}{COMMA16} +STR_5948 :Nome da atracción: {BLACK}{STRINGID} +STR_5949 :Elevador de cadea +STR_5950 :Aplicar cambios a toda a ruta +STR_5951 :ID da peza da pista: {BLACK}{COMMA16} +STR_5952 :Número de secuencia: {BLACK}{COMMA16} +STR_5953 :Ordena os elementos do mapa na casa actual en función da súa altura base. +STR_5954 :Idade do paisaxe: {BLACK}{COMMA16} +STR_5955 :Colocación do cuadrante: {BLACK}{STRINGID} +STR_5956 :Suroeste +STR_5957 :Noroeste +STR_5958 :Noreste +STR_5959 :Sureste +STR_5960 :Colocación do cuadrante: +STR_5961 :Índice de entrada: {BLACK}{COMMA16} +STR_5962 :Detección de colisións: +STR_5963 :Esquinas elevadas: +STR_5964 :Diagonal +STR_5965 :Tipo de entrada: {BLACK}{STRINGID} +STR_5966 :Parte da entrada ao parque: {BLACK}{STRINGID} +STR_5967 :Medio +STR_5968 :á esquerda +STR_5969 :dereita +STR_5970 :Entrada de ID: {BLACK}{COMMA16} +STR_5971 :ID Saída: {BLACK}{COMMA16} +STR_5972 :ID da atracción: {BLACK}{COMMA16} +STR_5973 :Anexo ao seguinte +STR_5974 :Cambia a base e a altura libre para que sexa o mesmo que o seguinte elemento do cadrado actual. Isto fai que sexa máis fácil construír nesta cuadrícula. +STR_5975 :Pendente: +STR_5976 :Avión +STR_5977 :Lado dereito cara arriba +STR_5978 :Lado esquerdo cara arriba +STR_5979 :Tipo de parede: {BLACK}{COMMA16} +STR_5980 :Texto da marca: {BLACK}{STRINGID} +STR_5981 :Non é unha bandeira +STR_5982 :Tipo de escenario grande: {BLACK}{COMMA16} +STR_5983 :ID da peza teatral grande: {BLACK}{COMMA16} +STR_5984 :Camiños bloqueados: +STR_5985 :Cartafol novo +STR_5986 :Escribe o nome do novo cartafol +STR_5987 :Non se puido crear o cartafol +STR_5988 :Non hai máis terreos á venda. +STR_5989 :Non hai máis dereitos de construción á venda. +STR_5990 :Non hai máis terreos nin dereitos de construción á venda. +STR_5991 :Non se pode pegar o elemento... +STR_5992 :Alcanzouse o límite de elementos do mapa +STR_5993 :Copiar o elemento seleccionado +STR_5994 :Pegar o elemento copiado +STR_5995 :Acelerador +STR_5996 :Velocidade do acelerador +STR_5997 :Engadir/Establecer diñeiro +STR_5998 :Engadir diñeiro +STR_5999 :Axustar diñeiro +STR_6000 :Introduce un valor novo +STR_6001 :Efectos de iluminación (experimental) +STR_6002 :As lámpadas e as atraccións acenderanse pola noite.{NEWLINE}Require que o motor de renderizado estea configurado no modo "mediante hardware". +STR_6003 :Vista recortada +STR_6004 :Vista recortada +STR_6005 :Activar a vista recortada +STR_6006 :A vista illada só mostrará elementos iguais ou inferiores á altura do corte vertical e dentro do sector horizontal da área seleccionada +STR_6007 :Altura de corte +STR_6008 :fai clic para alternar entre o valor bruto e o valor en unidades de medida. +STR_6009 :Seleccione a altura de corte +STR_6010 :{COMMA2DP32}m +STR_6011  :{COMMA1DP16} pés +STR_6012  :{COMMA1DP16} +STR_6013 :Os visitantes só pagarán a entrada e os servizos ao parque.{NEWLINE}A entrada ás atraccións é gratuíta. +STR_6014 :Os visitantes só pagarán a entrada a atraccións e servizos.{NEWLINE}Os visitantes non pagan por entrar no parque. +STR_6015 :Inclinado +STR_6016 :Modificar casa (cuadrícula) +STR_6017 :Disminuia a velocidade +STR_6018 :Construción - Curva Esquerda +STR_6019 :Construción - Curva dereita +STR_6020 :Construción - Usar a ruta predeterminada +STR_6021 :Construción - Pendente Descendente +STR_6022 :Construción - Pendente ascendente +STR_6023 :Construción - Activar/desactivar elevador de cadea +STR_6024 :Construír - Pendente á esquerda +STR_6025 :Construción - Pendente á dereita +STR_6026 :Construción - Peza anterior +STR_6027 :Construción - Peza seguinte +STR_6028 :Construción - Construír o actual +STR_6029 :Construción - Demoler o actual +STR_6030 :Selector de escenarios. Fai clic en calquera escenario do mapa para construílo. +STR_6031 :Descrición do servidor: +STR_6032 :Msx. de acollida: +STR_6033 :RCT1 Ruta de instalación: +STR_6034  :{BLACK}{STRING} +STR_6035 :seleccione o cartafol RCT1 +STR_6036 :Eliminar +STR_6037 :Seleccione un cartafol válido cunha instalación RCT1 +STR_6038 :Se tes unha instalación RCT1, configura esta opción no cartafol de instalación para cargar os escenarios, a música, etc. +STR_6039 :Demoler a atracción rapidamente +STR_6040 :Editar opcións do escenario +STR_6041 :{BLACK}Non hai mecánicos contratados! +STR_6042 :Cargar mapa de altura +STR_6043 :Seleccionar mapa de altura +STR_6044 :Mapa de altura suave +STR_6045 :Intensidade +STR_6046 :Normalizar o mapa de altura +STR_6047 :Reixa lisa +STR_6048 :Erro no mapa de altura +STR_6049 :Produciuse un erro ao ler PNG +STR_6050 :Produciuse un erro ao ler o mapa de bits +STR_6052 :O mapa de altura é demasiado grande, recortarase. +STR_6053 :O mapa de altura non se pode normalizar. +STR_6054 :Só se admiten mapas de bits de 24 bits +STR_6055 :Mapa de altura OpenRCT2 +STR_6056 :Acalar +STR_6057 :Mostrar un botón separado para a opción "Acalar" na barra de ferramentas. +STR_6058 :Acalar +STR_6059 :» +STR_6060 :Mostrar as compras dos visitantes con animación +STR_6061 :Mostra un efecto de diñeiro animado{NEWLINE}cando os visitantes fan compras. +STR_6062 :{OUTLINE}{GREEN}+ {CURRENCY2DP} +STR_6063 :{OUTLINE}{RED}- {CURRENCY2DP} +STR_6064 :Adquirir o mapa completo +STR_6065 :Gravar as accións do usuario. +STR_6066 :Rexistra todas as accións do usuario nos ficheiros do teu directorio de usuarios. +STR_6067 :Servidor iniciado. +STR_6068 :Servidor apagado. +STR_6069 :{STRING} expulsou do servidor {STRING}. +STR_6070 :{STRING} estableceu {STRING} no grupo "{STRING}". +STR_6071 :{STRING} creou un novo grupo "{STRING}". +STR_6072 :{STRING} eliminou o grupo "{STRING}". +STR_6073 :{STRING} editou os permisos do grupo "{STRING}". +STR_6074 :{STRING} cambiou o nome do grupo de "{STRING}" a "{STRING}". +STR_6075 :{STRING} cambiou o grupo predeterminado a "{STRING}". +STR_6076  :{STRING} usou/activou o truco ‘{STRING}’. +STR_6077 :Engadir cartos +STR_6078 :{STRING} creou a atracción ‘{STRING}’. +STR_6079 :{STRING} atracción demolida ‘{STRING}’. +STR_6080 :{STRING} cambiou a aparencia da atracción ‘{STRING}’. +STR_6081 :{STRING} cambiou o estado da atracción ‘{STRING}’ a pechado. +STR_6082 :{STRING} cambiou o estado da atracción ‘{STRING}’ a aberta. +STR_6083 :{STRING} cambiou o estado da atracción ‘{STRING}’ a proba. +STR_6084 :{STRING} cambiou as configuracións dos vehículos da atracción ‘{STRING}’. +STR_6085 :{STRING} cambiou a configuración da atracción ‘{STRING}’. +STR_6086 :{STRING} cambiou o nome da atracción ‘{STRING}’ a ‘{STRING}’. +STR_6087  :{STRING} cambiou o custo da atracción ‘{STRING}’ a {STRING} +STR_6088  :{STRING} cambiou o custo secundario da atracción ‘{STRING}’ a {STRING} +STR_6089 :{STRING} cambiou o nome do parque de "{STRING}" a "{STRING}". +STR_6090 :{STRING} abriu o parque. +STR_6091 :{STRING} pechou o parque. +STR_6092 :o prezo do billete de {STRING} cambiou a {STRING} +STR_6093 :{STRING} puxo un novo escenario. +STR_6094 :{STRING} escenario eliminado. +STR_6095 :{STRING} escenario editado. +STR_6096 :{STRING} estableceu o nome do sinal en "{STRING}". +STR_6097 :{STRING} colocou unha peza da pista da atracción ‘{STRING}’. +STR_6098 :{STRING} eliminou unha parte da atracción. +STR_6099 :Conectácheste ao servidor. +STR_6100 :Desconectacheste do servidor. +STR_6101 :As atraccións non diminúen de valor. +STR_6102 :O valor dunha atracción non diminúe co paso do tempo, polo que os visitantes non pensarán que unha atracción é demasiado cara. +STR_6103 :Esta opción está desactivada durante unha partida multixogador. +STR_6105 :Hiper montaña rusa +STR_6107 :Camións Monstro +STR_6109 :Hyper-Twister +STR_6111 :Mini montaña rusa clásica +STR_6113 :Unha montaña rusa alta e non invertible con grandes caídas, coches de alta velocidade e cómodos con só unhas poucas barras para agarrarse +STR_6115 :Camións 4x4 autopropulsados ​​xigantes que poden escalar outeiros impresionantes +STR_6116 :Montaña rusa ancha sobre vías de aceiro que realiza varias inversións +STR_6119 :Unha montaña rusa barata e fácil de construír, pero cunha altura limitada. +STR_6120 :{BABYBLUE}Vehículo novo dispoñible agora para {STRINGID}:{NEWLINE}{STRINGID} +STR_6121 :Estende os dereitos de construción do parque aos bordos do mapa. +STR_6122 :Non hai suficientes montañas rusas neste escenario! +STR_6123 :Produciuse un erro ao cargar obxectos para o Parque +STR_6124 :Nome do obxecto +STR_6125 :Tipo de obxecto +STR_6126 :Tipo descoñecido +STR_6127 :Ficheiro: {STRING} +STR_6128 :Non se pode cargar o ficheiro porque faltan ou están corruptos algúns dos obxectos aos que se fai referencia. Móstrase unha lista destes obxectos: +STR_6129 :Copia +STR_6130 :Copiar todo +STR_6131 :Orixe +STR_6132 :Ignorar o estado da investigación +STR_6133 :Accede a atraccións e escenarios que aínda non foron inventados +STR_6134 :Limpar etapa +STR_6135 :O cliente enviou unha solicitude non válida +STR_6136 :O servidor enviou unha solicitude non válida +STR_6137 :OpenRCT2, xogo de código aberto que recrea e amplía Roller Coaster Tycoon 2. +STR_6138 :OpenRCT2 é obra de moitos autores, pódese atopar unha lista completa a través do botón "Colaboradores". Para obter máis información, visite: http://github.com/OpenRCT2/OpenRCT2 +STR_6139 :Todos os nomes de produtos e empresas son propiedade dos seus respectivos propietarios. O uso deles non implica ningunha afiliación nin aval por eles. +STR_6140 :Rexistro de cambios... +STR_6141 : Barra de ferramentas inferior RCT1 +STR_6142 :{WINDOW_COLOUR_2}Nome da ruta: {BLACK}{STRING} +STR_6143 :{WINDOW_COLOUR_2}Tipo de atracción: {BLACK}{STRINGID} +STR_6144 :Mostrar o redeseño +STR_6145 :Establece o límite de velocidade para os impulsores +STR_6146 :Activar todas as pezas de pista que se poden debuxar +STR_6147 :Activa todas as pezas de pista para as que o tipo de paseo é apto na xanela de construción, independentemente de que o vehículo sexa compatible. +STR_6148 :Conectándose ao servidor principal... +STR_6149 :Non se puido conectar ao servidor mestre +STR_6150 :resposta non válida do servidor mestre (sen número JSON) +STR_6151 :O servidor mestre non devolveu a Lista de servidores +STR_6152 :resposta non válida do servidor mestre (sen matriz JSON) +STR_6153 :Pago por entrada / Pago por atracción +STR_6154 :Por motivos de seguridade, non se recomenda iniciar OpenRCT2 con privilexios elevados. +STR_6155 :Nin KDialog nin Zenity están instalados. Instala un ou configura un desde a liña de comandos. +STR_6156 :O nome está reservado +STR_6157 :Consola +STR_6160 :{WINDOW_COLOUR_2}Vehículos dispoñibles: {BLACK}{STRING} +STR_6161 :Alterar liñas de grade +STR_6162 :Rato xiratorio salvaxe +STR_6163 :os coches con forma de rato realizan xiros pronunciados e descensos curtos, mentres xiran suavemente para desorientar aos pasaxeiros. +STR_6164 :{BRANCO}❌ +STR_6165 :Utiliza a sincronización vertical +STR_6166 :Sincroniza cada fotograma mostrado coa frecuencia de actualización do monitor, evitando a imaxe distorsionada. +STR_6167 :Avanzado +STR_6168 :Secuencia da pantalla de inicio +STR_6169 :Selección de escenario +STR_6170 :Configuración da interface +STR_6171 :Buscar +STR_6172 :Buscar +STR_6173 :Introduza o nome para buscar: +STR_6188 :Vómitos +STR_6189 :Pato +STR_6191 :Superficie +STR_6192 :Muro +STR_6193 :{COMMA16} convidado +STR_6194  :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA16} convidado +STR_6195  :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA16} convidado +STR_6196 :{BLACK}Ano: +STR_6197 :{BLACK}Mes: +STR_6198 :{BLACK}Día: +STR_6199 :Establecer data +STR_6200 :Restablecer data +STR_6201  :{MONTH} +STR_6202 :Estilo de piso virtual: +STR_6203 :Se está activado, renderase un piso virtual mantendo mantendo CTRL ou MAIÚS para facilitar a colocación vertical dos elementos. +STR_6215 :Construción +STR_6216 :Operación +STR_6217 :Dispoñibilidade de atraccións/pistas +STR_6218 :OpenRCT2 Oficial +STR_6219 :Destaque os problemas de busca de rutas +STR_6220 :Facer utilizable +STR_6221 :Isto establecerá a saída ou entrada coñecida da atracción na caixa seleccionada. Só se pode utilizar unha entrada e unha saída por estación. +STR_6222 :Non podes colocar aquí entrada de visitante... +STR_6223 :Debe estar fóra dos límites do parque! +STR_6224 :{STRING} colocouse un punto de entrada de visitante +STR_6225 :Non é compatible co renderizador OpenGL +STR_6226 :Activar a vitoria anticipada. +STR_6227 :fai que o escenario se remate se todos os obxectivos se cumpren antes da data que desencadea a condición de vitoria. +STR_6228 :Opcións de escenario. +STR_6229 :{WINDOW_COLOUR_2}{STRINGID}: {STRINGID} +STR_6230 :{BLACK}{STRINGID}: +STR_6231 :{WINDOW_COLOUR_2}{STRINGID}: {MOVE_X}{185}{STRINGID} +STR_6232 :Conxelado +STR_6233 :Vista illada +STR_6234 :Destaque os problemas de busca de rutas +STR_6235 :Información do servidor +STR_6236 :Xogadores +STR_6237 :Grupos +STR_6238 :Opcións multixogador +STR_6239 :Corte Vertical +STR_6240 :Corte Horizontal +STR_6241 :Seleccionar área +STR_6242 :Borrar selección +STR_6243 :Renova a atracción, {NEWLINE} déixaa como nova! +STR_6244 :Non se pode renovar +STR_6245 :a atracción non necesita renovación +STR_6246 :Renovar +STR_6247 :Renovar a atracción +STR_6248 :{WINDOW_COLOUR_1}Queres renovar {STRINGID} por {CURRENCY}? +STR_6249 :{WINDOW_COLOUR_1}Queres renovar {STRINGID}? +STR_6250 :{WINDOW_COLOUR_1}Estás seguro de que queres demoler {STRINGID} e gañar {CURRENCY}? +STR_6251 :A atracción aínda non está baleira +STR_6255 :URL non válido. +STR_6256 :Efectos ao renderizar +STR_6257 :Translúcido +STR_6258 :Transparente +STR_6259 :Desactivado +STR_6260 :Mostrar caixas bloqueadas +STR_6261 :Mostrar camiños anchos +STR_6262 :Volum principal +STR_6263 :Activa ou desactiva todos os sons +STR_6264 :Utiliza sempre o explorador de ficheiros do sistema +STR_6265 :Cando estea activado, empregarase o explorador de ficheiros do SO en lugar de OpenRCT2. +STR_6266 :Abrir cartafol de contido personalizado +STR_6267 :Inspector de rede aberta +STR_6268 :Adiantar un tick +STR_6269 :ID meteorolóxico non válido +STR_6270 :Superficies terrestres +STR_6271 :Marxes terrestres +STR_6272 :Temporadas +STR_6273 :Música +STR_6274 :Non se poden definir cores... +STR_6275 :{WINDOW_COLOUR_2}Estilo da estación: +STR_6276 :{RED}{STRINGID} ten visitantes atascados, posiblemente debido a un tipo de atracción ou modo de funcionamento non válidos. +STR_6277 :Índice da estación: {BLACK}{STRINGID} +STR_6278 :Número de gardados automáticos +STR_6279 :Número de ficheiros gardados automaticamente a manter +STR_6280 :Chat +STR_6281 :Mostrar un botón de chat separado na barra de ferramentas +STR_6282 :Chat +STR_6283 :Chat non dispoñible ¿Estás conectado a un servidor? +STR_6293 :B +STR_6294 :KiB +STR_6295 :MiB +STR_6296 :GiB +STR_6297 :TiB +STR_6298  :{STRING}/s +STR_6299 :Descargar todo +STR_6300 :Descarga todos os obxectos que faltan se está dispoñible en liña. +STR_6301 :Copia o nome do obxecto seleccionado no portapapeis. +STR_6302 :Copia toda a lista de obxectos que faltan no portapapeis. +STR_6303 :Descargando obxecto ({COMMA16} / {COMMA16}): [{STRING}] +STR_6304 :Abrir o selector de escenarios +STR_6305 :Multithreading +STR_6306 :A opción experimental para usar varios núcleos na representación pode ser inestable. +STR_6307 :Esquema de cores: {BLACK}{STRINGID} +STR_6308 :{TOPAZ}“{STRINGID}{OUTLINE}{TOPAZ}”{NEWLINE}{STRINGID} +STR_6309 :Volver conectar +STR_6310 :{WINDOW_COLOUR_2}Posición: {BLACK}{INT32} {INT32} {INT32} +STR_6311 :{WINDOW_COLOUR_2}Seguinte: {BLACK}{INT32} {INT32} {INT32} +STR_6312 :(superficie) +STR_6313 :(rexeitar {INT32}) +STR_6314 :{WINDOW_COLOUR_2}Destino: {BLACK}{INT32}, {INT32} tolerancia {INT32} +STR_6315 :{WINDOW_COLOUR_2}Destino de busca de ruta: {BLACK}{INT32}, {INT32}, {INT32} dir {INT32} +STR_6316 :{WINDOW_COLOUR_2}Historial de rutas: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} dir {INT32} +STR_6318 :Dessincronización detectada.{NEWLINE}Rexistro: {STRING} +STR_6319 :Bloque de freado pechado +STR_6320 :Indestructible +STR_6321 :o agregado está roto +STR_6322 :{WINDOW_COLOUR_2}ID da entidade: {BLACK}{INT32} +STR_6323 :Simulando +STR_6324 :Simular +STR_6325 :Simular atracción +STR_6326 :Non se pode simular {STRINGID}... +STR_6327 :Fondo transparente para capturas de pantalla xigantes +STR_6328 :Con esta opción activada, as capturas de pantalla xigantes terán un fondo transparente en lugar do fondo negro predeterminado. +STR_6329 :{STRING}{STRINGID} +STR_6330 :Descargando [{STRING}] desde {STRING} ({COMMA16} / {COMMA16}) +STR_6331 :Crear parrulos +STR_6332 :Eliminar parrulos +STR_6333 :Aumenta o factor de escala +STR_6334 :Diminuír o factor de escala +STR_6336 :Grid Inspector: Copiar elemento +STR_6337 :Grid Inspector: Pegar elemento +STR_6338 :Grid Inspector: Eliminar elemento +STR_6339 :Grid Inspector: mover elemento cara arriba +STR_6340 :Grid Inspector: Mover elemento cara abaixo +STR_6341 :Grid Inspector: Aumenta a coordenada X +STR_6342 :Grid Inspector: Diminuír a coordenada X +STR_6343 :Grid Inspector: Aumenta a coordenada Y +STR_6344 :Grid Inspector: Diminuír a coordenada Y +STR_6345 :Grid Inspector: aumenta a altura do elemento +STR_6346 :Grid Inspector: Diminuír a altura do elemento +STR_6347 :Non se poden engadir pistas nos pasos a nivel! +STR_6348 :Elimina primeiro o paso a nivel! +STR_6349 :Secuencia de pantalla de inicio aleatoria +STR_6350 :Distribuír +STR_6351 :ferramenta de deseño de escenarios +STR_6352 :Densidade +STR_6353 :Baixa densidade +STR_6354 :Densidade media +STR_6355 :Alta densidade +STR_6356 :Crear parrulos se o parque ten auga +STR_6357 :Elimina todos os parrulos do mapa +STR_6358 :Páxina {UINT16} +STR_6359  :{POP16}{POP16}Páxina {UINT16} +STR_6361 :Efectos da luz nas atraccións (experimental) +STR_6362 :Se está activado, os vehículos das atraccións da pista iluminaranse pola noite. +STR_6363 :Copiar texto no portapapeis +STR_6364 :{RED}{COMMA16} persoa morreu nun accidente a bordo de {STRINGID} +STR_6365 :Mortes na atracción +STR_6366 :Vehículos atascados ou parados +STR_6367 :Cadro de animación: +STR_6368 :Por razóns de compatibilidade, non se recomenda executar OpenRCT2 sobre Wine. OpenRCT2 ten soporte nativo para macOS, Linux, FreeBSD e OpenBSD. +STR_6369 :Permitir construír a alturas non válidas +STR_6370 :Permíteche construír carrís e pezas en calquera rango de altura +STR_6371 :A ruta especificada contén unha instalación de RCT1, pero o ficheiro ‘csg1i.dat’ non existe. Este ficheiro NECESITA copiar do CD RCT Deluxe ou Loopy Landscapes ao cartafol "Datos" da instalación de RollerCoaster Tycoon 1 no seu disco duro. +STR_6372 :A ruta especificada contén unha instalación de RCT1, pero esta versión non é correcta. OpenRCT2 REQUIRE unha versión de RCT Deluxe ou Loopy Landscapes para poder usar os recursos de Roller Coaster Tycoon 1. +STR_6373 :Activar a comprobación de autorización +STR_6374 :G +STR_6375 :Viaxe descoñecida +STR_6376 :{WINDOW_COLOUR_2}Viaxe en vehículo:{NEWLINE}{BLACK}{STRINGID} para {STRINGID} +STR_6377 :{WINDOW_COLOUR_2}Tipo: {BLACK}{STRINGID} para {STRINGID} +STR_6378 :Recepción da lista de obxectos: +STR_6379 :Recibiron datos non válidos +STR_6380 :Actualización dispoñible! +STR_6381 :Únete ao OpenRCT2 Discord! +STR_6382 :Nova versión estable de OpenRCT2 dispoñible: {STRING}! +STR_6383 :Abrir páxina de descarga +STR_6384 :Neve +STR_6385 :Nevadas fortes +STR_6386 :Tempestade de neve +STR_6387 :Non se pode descargar o elemento aquí... +STR_6388 :Non se puido cargar o elemento aquí... +STR_6389 :Autorización non válida +STR_6390 :OpenRCT2 require os ficheiros orixinais do xogo RollerCoaster Tycoon 2 para executarse. Seleccione o directorio onde ten instalado RollerCoaster Tycoon 2. +STR_6391 :Escolle o teu directorio RCT2. +STR_6392 :Non se puido atopar {STRING} neste camiño. +STR_6393 :Selección de destino. +STR_6394 :Obxectivo +STR_6395 :Mantemento +STR_6396 :Desactivar o protector do monitor e o aforro de enerxía. +STR_6397 :Se está activado, o protector de pantalla e outras funcións de aforro de enerxía desactivaranse mentres OpenRCT2 estea aberto. +STR_6398 :O ficheiro contén atraccións incompatibles. Actualiza a unha versión máis recente de OpenRCT2. +STR_6399 :OpenRCT2 require ficheiros do xogo orixinal de RollerCoaster Tycoon 2 para executarse. Establece a variable ‘game_path’ en config.ini no directorio onde instalou RollerCoaster Tycoon 2 e reinicia OpenRCT2. +STR_6400 :Descarguei o instalador sen conexión de GOG, pero non está instalado. +STR_6401 :Xa instalei RollerCoaster Tycoon 2 +STR_6402 :Configuración de datos OpenRCT2 +STR_6403 :Escolle a opción que mellor se aplique a ti. +STR_6404 :Seleccione o instalador de RollerCoaster Tycoon 2 GOG. +STR_6405 :Escolle o instalador de GOG +STR_6406 :instalador de GOG RollerCoaster Tycoon 2 +STR_6407 :Pode tardar uns minutos. +STR_6408 :Instale ‘innoextract’ para extraer o instalador de GOG e despois reinicie OpenRCT2. +STR_6409 :O ficheiro seleccionado non é o instalador fóra de liña de GOG para RollerCoaster Tycoon 2. É posible que descargueses o código de descarga de GOG Galaxy ou seleccionaches o ficheiro incorrecto. +STR_6410 :Achegar ou diminuír +STR_6411 :Mostrar os botóns de zoom na barra de ferramentas +STR_6412 :Introdución do teclado numérico +STR_6413 :Maiúsculas +STR_6414 :Cambio L +STR_6415 :Cambio R +STR_6416 :Ctrl +STR_6417 :L Ctrl +STR_6418 :R Ctrl +STR_6419 :Alt +STR_6420 :L Alt +STR_6421 :R Alt +STR_6422 :Cmd +STR_6423 :L Cmd +STR_6424 :R Cmd +STR_6425 :Alegría deixou +STR_6426 :Alegría certo +STR_6427 :Alegría +STR_6428 :Alegría +STR_6429 :Alegría {INT32} +STR_6430 :LMB +STR_6431 :RMB +STR_6432 :Rato {INT32} +STR_6433 :Eliminar +STR_6434 :Elimina todos os edificios deste atallo. +STR_6435 :{WINDOW_COLOUR_2}Vándalos arrestados: {BLACK}{COMMA32} +STR_6436 :Activar/desactivar a invisibilidade +STR_6437 :Visible +STR_6438 :{MOVE_X}{2}👁 +STR_6439 :Grid Inspector: activa/desactiva a invisibilidade +STR_6440 :Auga transparente +STR_6441 :Debe seleccionar polo menos un camiño que non sexa da cola. +STR_6442 :Debe seleccionar polo menos un camiño que sexa unha liña de espera. +STR_6443 :Debe seleccionar polo menos un camiño que teña pasamáns. +STR_6444 :Superficies de camiños. +STR_6445 :pasamáns do camiño. +STR_6446 :{WINDOW_COLOUR_2}Nome da superficie: {BLACK}{STRINGID} +STR_6447 :{WINDOW_COLOUR_2}Nome do pasamáns: {BLACK}{STRINGID} +STR_6448 :Formato de obxecto non compatible +STR_6449 :{WINDOW_COLOUR_2}Camiños: +STR_6450  :{BLACK}“{STRING}” +STR_6451  :{BLACK}“{STRING}” - {STRING} +STR_6452 :{WINDOW_COLOUR_2}Vender: {BLACK}{STRING} +STR_6453 :Copiar a información da versión +STR_6454 :Non se pode cambiar o nome do banner... +STR_6455 :Non se pode cambiar o nome do sinal... +STR_6456 :Captura de pantalla xigante +STR_6457 :Informar dun erro en GitHub +STR_6458 :siga isto na vista principal +STR_6460 :D +STR_6461 :Enderezo +STR_6462 :Emoción +STR_6463 :Emoción: {COMMA2DP32} +STR_6464 :Intensidade +STR_6465 :Forza: {COMMA2DP32} +STR_6466 :Náuseas +STR_6467 :Náuseas: {COMMA2DP32} +STR_6468 :aínda non dispoñible +STR_6469 :Establecer zona de patrulla máis pequena +STR_6470 :Establecer unha zona de patrulla máis grande +STR_6471 :Vexetación transparente +STR_6472 :Vehículos transparentes +STR_6473 :Soportes transparentes +STR_6474 :Visitantes invisibles +STR_6475 :Empleados invisibles +STR_6476 :Vexetación invisible +STR_6477 :Escenario invisible +STR_6478 :Camiños invisibles +STR_6479 :Atraccións invisibles +STR_6480 :Vehículos invisibles +STR_6481 :Opcións de transparencia +STR_6482 :Opcións de transparencia +STR_6483 :Abrir opcións de transparencia +STR_6484 :Alterar vexetación transparente +STR_6485 :Alternar vehículos transparentes +STR_6486 :Alterar visitantes invisibles +STR_6487 :Alterar empregados invisibles +STR_6488 :{RED}Os hóspedes quéixanse das longas filas no teu parque.{NEWLINE}Considera acurtar as liñas problemáticas ou aumentar o rendemento da viaxe. +STR_6489 :{RED}ERRO: Versión do parque incompatible +STR_6490 :{RED}ADVERTENCIA: a versión Park non é totalmente compatible +STR_6491 :Este parque gardouse nunha versión máis recente de OpenRCT2. Este parque gardouse en v{INT32} e require polo menos v{INT32}. Actualmente estás en v{INT32}. +STR_6492 :Este parque gardouse nunha versión antiga de OpenRCT2 e non se pode abrir con esta versión de OpenRCT2. Este parque é a versión v{INT32}. +STR_6493 :Este parque gardouse nunha versión máis recente de OpenRCT2, podendo perderse algúns datos. Este parque gardouse en v{INT32}, actualmente estás en v{INT32}. +STR_6494 :Agrupar por tipo de atracción +STR_6495 :Agrupa as atraccións por tipo en lugar de mostrar cada vehículo por separado. +STR_6496  :{WINDOW_COLOUR_2}{STRINGID} +STR_6497 :Fai clic nunha caixa para mostrar os seus elementos.{NEWLINE}Ctrl + clic nun elemento para seleccionalo directamente. +STR_6498 :Activa para manter o mapa en forma cadrada. +STR_6499 :Tipo de vehículo non compatible co formato de deseño da estrada +STR_6500 :Elementos non compatibles co formato de deseño da estrada +STR_6501 :Cor aleatoria +STR_6502 :Introduza un valor entre {COMMA16} e {COMMA16} +STR_6503 :Debe seleccionar polo menos un obxecto de estación +STR_6504 :Debe seleccionar polo menos unha superficie do terreo +STR_6505 :Debe seleccionar polo menos un bordo do terreo +STR_6506 :Sacacorchos mediano grande (esquerda) +STR_6507 :Sacacorchos grande (dereita) +STR_6508 :rizo medio medio (esquerda) +STR_6509 :rizo medio medio (dereita) +STR_6510 :Xiro de gravidade cero (esquerda) +STR_6511 :Xiro de gravidade cero (dereita) +STR_6512 :gran xiro de gravidade cero (esquerda) +STR_6513 :Gran xiro de gravidade cero (dereita) +STR_6514 :Altura non válida! +STR_6515 :{BLACK}RollerCoaster Tycoon 1 non foi ligado - utilizaranse imaxes alternativas. +STR_6516 :Un ou máis obxectos engadidos requiren ter ligado RollerCoaster Tycoon 1 para a súa visualización correcta. Utilizaranse imaxes alternativas. +STR_6517 :Un ou máis obxectos deste parque requiren ter ligado RollerCoaster Tycoon 1 para a súa visualización correcta. Utilizaranse imaxes alternativas. +STR_6518 :{BLACK}Pasa o rato sobre un escenario para ver a súa descrición e os seus obxectivos. Fai clic para comezar a xogar. +STR_6519 :Extras +STR_6520 :Paquetes de recursos +STR_6521 :Prioridade baixa +STR_6522 :Alta prioridade +STR_6523 :Diminuír a prioridade do paquete de recursos seleccionado. +STR_6524 :Aumenta a prioridade do paquete de recursos seleccionado. +STR_6525 :Volve cargar todos os recursos do xogo cos paquetes de recursos activados. +STR_6526 :(gráficos básicos, música e efectos de son) +STR_6527 :Competicións +STR_6528 :Parámetros de pista non válidos! +STR_6529 :Parámetro de esquema de cores non válido! +STR_6530 :Conxunto de expansión creado polo usuario +STR_6531 :A máquina do tempo +STR_6532 :O mundo de Katy +STR_6533 :{WINDOW_COLOUR_2}Factor de excitación: {BLACK}-{COMMA16}% +STR_6534 :{WINDOW_COLOUR_2}Factor de intensidade: {BLACK}-{COMMA16}% +STR_6535 :{WINDOW_COLOUR_2}Factor de náuseas: {BLACK}-{COMMA16}% +STR_6536 :Este parque gardouse nunha versión máis recente de OpenRCT2. Este parque gardouse en v{INT32}, actualmente estás en v{INT32}. +STR_6537 :Permitir que as rutas normais se utilicen como cola +STR_6538 :Mostra rutas normais no menú despregable da cola da xanela Rutas. +STR_6539 :freo pechado +STR_6540 :{WINDOW_COLOUR_2}Grazas especiais ás seguintes empresas por permitir o uso da súa imaxe: +STR_6541 :{WINDOW_COLOUR_2}Rocky Mountain Construction Group, Josef Wiegand GmbH & Co. KG +STR_6542 :Colaboradores +STR_6543 :Colaboradores... +STR_6544 :O préstamo non pode ser negativo! +STR_6545 :Utiliza o cálculo de intereses RCT1 +STR_6546 :Utilice o algoritmo de cálculo de intereses de RollerCoaster Tycoon 1, que utilizou unha porcentaxe fixa de aproximadamente o 1,33%. +STR_6547 :Todos os escenarios +STR_6548 :Mostrar pasamáns nas interseccións +STR_6549 :Non se poden seleccionar obxectos de compatibilidade! +STR_6550 :Inclúese esta entrada para garantir a compatibilidade con obxectos antigos ou danados. Non se pode seleccionar, só deseleccionar. + +STR_6551 :Verde exército +STR_6552 :Melón +STR_6553 :Tan +STR_6554 :granate +STR_6555 :Rosa coral +STR_6556 :Verde bosque +STR_6557 :Chartreuse Green +STR_6558 :Hunter Green +STR_6559 :Verde claro +STR_6560 :Verde lima +STR_6561 :Sepia +STR_6562 :Pexego +STR_6563 :azul lavanda +STR_6564 :Verde esmeralda +STR_6565 :Augamarina +STR_6566 :Violeta +STR_6567 :Lavanda +STR_6568 :Laranxa pastel +STR_6569 :Azul escuro +STR_6570 :Rosa pastel +STR_6571 :Café +STR_6572 :Beixe +STR_6573 :Invisible +STR_6574 :baleiro +STR_6575 :Permitir esquemas de cores especiais +STR_6576 :Engade cores especiais ao menú despregable de cores +STR_6577 :Bloqueo da velocidade do freo +STR_6578 :Establece o límite de velocidade para bloquear os freos. No modo de sección de bloque, os freos adxacentes con velocidade máis lenta están ligados ao freo de bloqueo. +STR_6579 :Os freos de bloqueo estableceranse coa velocidade predeterminada cando se garde como esquema de pista. +STR_6580 :Restablecer +STR_6581 :Estás seguro de que queres restablecer todos os atallos de teclado desta pestana? +STR_6582 :Abrir a xanela de atallos de teclado +STR_6583 :{WINDOW_COLOUR_2}Trens invertidos +STR_6584 :selecciona para que os trens viaxen en sentido inverso +STR_6585 :Non se poden facer cambios... +STR_6586 :OpenRCT2 +STR_6587 :O tema principal de OpenRTC é un traballo de Allister Brimble,{NEWLINE}con licenza CC BY-SA 4.0. +STR_6588 :Grazas a Herman Riddering por permitirnos gravar o 35er Voigt. +STR_6589 :Mostrar os botóns da xanela á esquerda +STR_6590 :Mostrar os botóns da xanela (como pechar a xanela) á esquerda da barra de título en lugar da dereita. +STR_6591 :O empregado está a reparar unha atracción e non pode ser despedido. +STR_6592 :O empregado está inspeccionando unha atracción e non pode ser despedido. +STR_6593 :Eliminar valados do parque +STR_6594 :Grid Inspector: alternar a inclinación da parede +STR_6595 :{WINDOW_COLOUR_2}Autor: {BLACK}{STRING} +STR_6596 :{WINDOW_COLOUR_2}Autores: {BLACK}{STRING} +STR_6597 :parámetro non válido +STR_6598 :Valor fóra do intervalo +STR_6599 :Non se atopou o elemento pantasma +STR_6600 :Non se atopou o globo +STR_6601 :Non se atopou o empregado +STR_6602 :Non se atopou a atracción +STR_6603 :Non se atopou a entrada do obxecto de atracción +STR_6604 :Non se atopou o reprodutor +STR_6605 :Non se atopou o elemento de entrada +STR_6606 :Non se atopou o elemento de superficie +STR_6607 :Non se atopou o elemento da caixa +STR_6608 :Non se atopou o elemento da pista +STR_6609 :Non se atopou o bloque de pistas +STR_6610 :Non se atopou o elemento da ruta +STR_6611 :Non se atopou o elemento da parede +STR_6612 :Non se atopou o elemento do banner +STR_6613 :Volver cargar o obxecto +STR_6614 :Non podes cambiar o prezo do billete do parque +STR_6615 :A estrada desta caixa necesita auga +STR_6616 :Acción non válida para ese tipo de traballador +STR_6617 :Non se pode intercambiar o elemento de slot consigo mesmo +STR_6618 :Non pode poñer nin eliminar restricións ao obxecto... +STR_6619 :Este tipo de obxecto non se pode restrinxir! +STR_6620 :Obxecto non atopado! +STR_6621 :Restrinxir +STR_6622 :Restrinxir o obxecto ao modo Editor de escenarios e Sandbox. +STR_6623 :Escriba "axuda" para ver a lista de comandos dispoñibles. Escribe "ocultar" para ocultar a consola. +STR_6624 :Grid Inspector: Ordenar elementos +STR_6625 :Cor non válida +STR_6626 :A animación está reflectida +STR_6627 :A velocidade da pista é demasiado alta! +STR_6628 :Só se pode colocar nos bordos do camiño! +STR_6629 :Aliña os botóns da barra de ferramentas centrados horizontalmente +STR_6630 :esta configuración aliñará os botóns da barra de ferramentas horizontalmente no centro da pantalla. A forma tradicional de aliñalos está na esquina esquerda e dereita. +STR_6631 :Cargando... +STR_6632 :Comprobando ficheiros de obxectos... +STR_6633 :Comprobando ficheiros de escenarios... +STR_6634 :Comprobando ficheiros de deseño de pistas... +STR_6635 :Comprobando ficheiros de recursos... +STR_6636 :Comprobando secuencias de títulos... +STR_6637 :Cargando a secuencia de títulos... +STR_6638 :Interface estendida +STR_6639 :Modifica a interface para que sexa máis doado de usar coas pantallas táctiles +STR_6640 :Editar paquetes de recursos... +STR_6641 :Xanela de carga/progreso +STR_6642 :{STRING} ({COMMA32}/{COMMA32}) +STR_6643  :{STRING} ({COMMA32}/{COMMA32} KiB) +STR_6644 :Melloras táctiles +STR_6645 :Aumenta o tamaño dalgúns elementos da interface para que sexan máis fáciles de facer clic. +STR_6646 :Autor: {STRING} +STR_6647 :Autores: {STRING} +STR_6648 :Cargando motor de complementos... +STR_6649 :Cargando escenario... +STR_6650 :Cargando partida gardada... +STR_6651  :{STRING} ({COMMA32}%) +STR_6652 :Xanela de Erro +STR_6653 :Todas as fontes mostradas +STR_6654 :Amosando {POP16}{UINT16} fontes +STR_6655 :Só ‘{POP16}{STRINGID}’ +STR_6656 :Elimina todos os valados do parque +STR_6657 :Terra Sen Propietario +STR_6658 :Establecer que a terra non sexa propiedade do parque nin estea dispoñible para a compra +STR_6659 :Os invitados ignoran os prezos +STR_6660 :Os invitados ignorarán o prezo das atraccións e dos postos + + diff --git a/data/language/pl-PL.txt b/data/language/pl-PL.txt index ba8a0f27fe..edc6a9cd0f 100644 --- a/data/language/pl-PL.txt +++ b/data/language/pl-PL.txt @@ -282,7 +282,7 @@ STR_0884 :Wczytaj krajobraz STR_0885 :Zapisz krajobraz STR_0887 :Wyjdź z edytora scenariuszy STR_0888 :Wyjdź z projektanta kolejek -STR_0889 :Wyjdź z menadżera projektów tras +STR_0889 :Wyjdź z menedżera projektów tras STR_0891 :Zrzut ekranu STR_0892 :Zrzut ekranu zapisany jako „{STRINGID}” STR_0893 :Zrzut ekranu nieudany! @@ -2020,7 +2020,7 @@ STR_2815 :{WINDOW_COLOUR_2}Nagroda dla najczystszego parku STR_2816 :{WINDOW_COLOUR_2}Nagroda dla parku z najlepszymi kolejkami górskimi STR_2817 :{WINDOW_COLOUR_2}Nagroda dla parku o najlepszej wartości STR_2818 :{WINDOW_COLOUR_2}Nagroda dla najpiękniejszego parku -STR_2819 :{WINDOW_COLOUR_2}Nagroda dla parku o najniższej wartości +STR_2819 :{WINDOW_COLOUR_2}Nagroda dla parku o najgorszej wartości STR_2820 :{WINDOW_COLOUR_2}Nagroda dla najbezpieczniejszego parku STR_2821 :{WINDOW_COLOUR_2}Nagroda za najlepszy personel STR_2822 :{WINDOW_COLOUR_2}Nagroda za najlepsze jedzenie @@ -2183,7 +2183,7 @@ STR_3141 :Wielokrotne pętle nie są dostępne w parze z wyciągarką STR_3142 :{WINDOW_COLOUR_2}Pojemność: {BLACK}{STRINGID} STR_3143 :Pokaż ludzi STR_3144 :Pokaż atrakcje i stoiska -STR_3160 :Wybierz liczbę obrotów na przejażdzkę +STR_3160 :Wybierz liczbę obrotów na przejażdżkę STR_3162 :Nie można zaalokować odpowiedniej ilości pamięci STR_3163 :Instalowanie nowych danych: STR_3164 :{BLACK}{COMMA16} wybrano (maksymalnie {COMMA16}) @@ -2217,7 +2217,7 @@ STR_3196 :{WINDOW_COLOUR_2}Grupa badawcza: {BLACK}{STRINGID} STR_3197 :{WINDOW_COLOUR_2}Rzeczy wynalezione na początku gry: STR_3198 :{WINDOW_COLOUR_2}Rzeczy do wynalezienia podczas gry: STR_3199 :Losowe sortowanie -STR_3200 :Losowe sortowanie rzeczy do wynalezenia w grze +STR_3200 :Losowe sortowanie rzeczy do wynalezienia w grze STR_3201 :Wybór obiektu STR_3202 :Edytor krajobrazu STR_3203 :Konfiguracja listy wynalazków @@ -2291,15 +2291,15 @@ STR_3270 :Zabroń jakichkolwiek zmian krajobrazu STR_3271 :Zakaz wysokich konstrukcji STR_3272 :Zabroń wysokich konstrukcji STR_3273 :Ocena parku trudna do zwiększenia i utrzymania -STR_3274 :Ocena parku staje się prawdziwym wyzwaniem -STR_3275 :Utrudniona ocena parku +STR_3274 :Zwiększenie i utrzymanie oceny parku staje się prawdziwym wyzwaniem +STR_3275 :Goście są trudniejsi do przyciągnięcia STR_3276 :Trudniej jest przyciągnąć gości do parku STR_3277 :{WINDOW_COLOUR_2}Koszt zakupu ziemi: STR_3278 :{WINDOW_COLOUR_2}Koszt zakupu planów budowy: STR_3279 :Darmowe wejście do parku / atrakcje płatne STR_3280 :Płatne wejście do parku / darmowe atrakcje STR_3281 :{WINDOW_COLOUR_2}Cena za wejście: -STR_3282 :|Wybierz cel i nazwę parku +STR_3282 :Wybierz cel i nazwę parku STR_3283 :Wybierz atrakcje, które mają zostać zachowane STR_3284 :Wybór celu STR_3285 :Zachowane atrakcje @@ -2345,12 +2345,12 @@ STR_3327 :Nieustawiona pozycja początkowa dla ludzi STR_3328 :Nie można przejść do dalszego etapu edytora… STR_3329 :Nie wybudowano jeszcze wejścia do parku STR_3330 :Park musi posiadać jakiś teren na własność -STR_3331 :Ścieżka od wejścia do parku do krawędzi mapy jest albo niekompletna, albo zbyt skomplikowana - Trasa musi być jednej szerokości z jak najmniejszą liczbą skrzyżowań i zakrętów +STR_3331 :Ścieżka od wejścia do parku do krawędzi mapy jest albo niekompletna, albo zbyt skomplikowana. Trasa musi być jednej szerokości z jak najmniejszą liczbą skrzyżowań i zakrętów. STR_3332 :Wejście do parku jest nieprawidłowe lub nie ma ścieżki prowadzącej do krawędzi mapy STR_3333 :Eksportuj elementy dodatkowe do zapisów gier STR_3334 :Wybierz, czy chcesz zapisać wymagane wtyczki (te, które nie są dołączone do produktu głównego) w zapisanych plikach gry lub scenariuszu, co pozwoli na ich załadowanie przez kogoś, kto nie posiada dodatkowych plików STR_3335 :Projektant tras - Wybierz rodzaj trasy i pojazdu -STR_3336 :Menadżer projektanta tras - Wybierz rodzaj przejazdu +STR_3336 :Menedżer projektanta tras - Wybierz rodzaj przejazdu STR_3338 :{BLACK}Własny projekt STR_3339 :{BLACK}{COMMA16} projekt dostępny, możliwość stworzenia własnego STR_3340 :{BLACK}{COMMA16} projekty dostępne, możliwość stworzenia własnego @@ -2358,7 +2358,7 @@ STR_3341 :Narzędzia STR_3342 :Edytor scenariuszy STR_3343 :Przekonwertuj zapisaną grę do scenariusza STR_3344 :Projektant kolejek -STR_3345 :Menadżer projektów tras +STR_3345 :Menedżer projektów tras STR_3346 :Nie można zapisać projektu trasy… STR_3347 :Kolejka jest za duża, zawiera za dużo elementów, lub sceneria jest za bardzo rozległa STR_3348 :Zmień nazwę @@ -2376,7 +2376,7 @@ STR_3359 :{BLACK}Brak projektów trasy tego typu STR_3360 :Ostrzeżenie! STR_3361 :Za dużo projektów tras tego typu - Część nie będzie wyświetlona. STR_3364 :Zaawansowane -STR_3365 :Zezwól na wybór indwyidualnych elementów scenerii jako dodatek do grup +STR_3365 :Zezwól na wybór indywidualnych elementów scenerii jako dodatek do grup STR_3366 :{BLACK}= Atrakcja STR_3367 :{BLACK}= Budka z jedzeniem STR_3368 :{BLACK}= Budka z napojami @@ -2440,7 +2440,7 @@ STR_5152 :, STR_5153 :Edytuj motywy… STR_5154 :Grafika sprzętowa STR_5155 :Zezwalaj na testowanie nieskończonych tras -STR_5156 :Pozwala przetestować większość typów przejażdżek, nawet jeśli tor nie jest ukończony, nie ma zastosowania do sekcji blokowych +STR_5156 :Pozwala przetestować większość typów przejażdżek, nawet jeśli tor nie jest ukończony, nie dotyczy trybów z podziałem na sekcje blokowe STR_5158 :Wyjdź do menu STR_5159 :Wyłącz OpenRCT2 STR_5160 :{POP16}{MONTH} {PUSH16}{PUSH16}{STRINGID}, Rok {POP16}{COMMA16} @@ -2465,7 +2465,7 @@ STR_5191 :Widok STR_5192 :Ostatnie wiadomości STR_5193 :Ziemia STR_5194 :Woda -STR_5195 :Wyczyść scenerie +STR_5195 :Wyczyść scenerię STR_5196 :Prawa ziemskie STR_5197 :Sceneria STR_5198 :Chodnik @@ -2611,7 +2611,7 @@ STR_5364 :Mniej niż 15 STR_5365 :{BLACK}Szybkość personelu: STR_5366 :Normalnie STR_5367 :Szybko -STR_5368 :Zresetuj status wypadku +STR_5368 :Zresetuj wypadki STR_5371 :Wybór obiektu STR_5372 :Odwrócone przesuwanie prawym przyciskiem myszy STR_5373 :Nazwa {STRINGID} @@ -2630,8 +2630,8 @@ STR_5452 :Przełącz widoczność pasków narzędzi STR_5453 :Wybierz inną atrakcję STR_5454 :Odblokuj FPS STR_5455 :Uruchom tryb piaskownicy -STR_5456 :Wyłącz kontrolę odjazdu -STR_5457 :Wyłącz limity wsparcia +STR_5456 :Wyłącz sprawdzanie kolizji +STR_5457 :Wyłącz limity wsporników STR_5458 :Obróć zgodnie ze wskazówką zegara STR_5459 :Obróć odwrotnie względem wskazówki zegara STR_5460 :Widok odwrotny względem wskazówki zegara @@ -2675,9 +2675,9 @@ STR_5499 :Nazwa gracza: STR_5500 :Dodaj serwer STR_5501 :Uruchom serwer STR_5502 :Multiplayer -STR_5503 :Wprowadź IP lub hostname: +STR_5503 :Wprowadź IP lub nazwę hosta: STR_5504 :Pokaż status gry wieloosobowej -STR_5505 :Nie można połączyć z serwerem. +STR_5505 :Nie można połączyć się z serwerem. STR_5506 :Goście ignorują intensywność STR_5510 :Domyślne urządzenie audio STR_5511 :(UNKNOWN) @@ -2724,7 +2724,7 @@ STR_5551 :rok/dzień/miesiąc STR_5552 :{POP16}{POP16}Rok {COMMA16}, {PUSH16}{PUSH16}{PUSH16}{STRINGID} {MONTH} STR_5553 :Wstrzymaj grę gdy nakładka Steam jest otwarta STR_5554 :Uruchom narzędzie tworzenia gór -STR_5555 :Pokaż pojazdy również dla innych typów atrakcji +STR_5555 :Pokaż pojazdy z innych typów torów STR_5556 :Wyrzuć gracza STR_5557 :Nie rozłączaj po desynchronizacji (tryb wieloosobowy) STR_5558 :Wymagany restart dla tej zmiany @@ -2771,12 +2771,12 @@ STR_5601 :Gość stoi w kolejce do atrakcji STR_5602 :Gość korzysta z atrakcji STR_5603 :Gość opuścił atrakcję STR_5604 :Gość kupił nowy przedmiot -STR_5605 :Gość użył udogodnienie +STR_5605 :Gość skorzystał z udogodnienia STR_5606 :Gość zmarł -STR_5607 :Wymuszono usunięcie wybranego elementu mapy. +STR_5607 :Wymuś usunięcie wybranego elementu mapy. STR_5608 :BH STR_5609 :CH -STR_5610 :Usuń aktualnie zaznaczony element. Wymusi to jego usunięcie, więc nie dostaniesz za to pieniędzy. Używaj z głową. +STR_5610 :Usuń aktualnie zaznaczony element. Wymusi to jego usunięcie, bez wydatków lub zysków gotówkowych. Używaj ostrożnie. STR_5611 :G STR_5612 :Flaga duch STR_5613 :B @@ -2786,15 +2786,15 @@ STR_5616 :Ostatni fragment flagi STR_5617 :Przesuń element wyżej. STR_5618 :Przesuń element niżej. STR_5619 :RollerCoaster Tycoon -STR_5620 :Dodatkowe atrakcje -STR_5621 :Zwariowane krajobrazy +STR_5620 :Dodatkowe Atrakcje +STR_5621 :Zwariowane Krajobrazy STR_5622 :RollerCoaster Tycoon 2 -STR_5623 :Zakręcone światy -STR_5624 :Zakręcone czasy +STR_5623 :Zakręcone Światy +STR_5624 :Zakręcone Czasy STR_5625 :„Prawdziwe” parki STR_5626 :Inne parki STR_5627 :Grupuj scenariusze według: -STR_5628 :Gra Źródłowa +STR_5628 :Gra źródłowa STR_5629 :Poziom trudności STR_5630 :Włącz odblokowywanie scenariuszy STR_5631 :Oryginalne parki z dodatku @@ -2864,8 +2864,8 @@ STR_5726 :Ustawia aktualną pogodę w parku STR_5734 :Renderowanie STR_5735 :Status sieci STR_5736 :Gracz -STR_5737 :Zamknięte, {COMMA16} człowiek nadal korzysta z przejażdżki -STR_5738 :Zamknięte, {COMMA16} ludzi nadal korzysta z przejażdżki +STR_5737 :Zamknięte, {COMMA16} gość nadal korzysta z przejażdżki +STR_5738 :Zamknięte, {COMMA16} gości nadal korzysta z przejażdżki STR_5739 :{WINDOW_COLOUR_2}Gości na atrakcji: {BLACK}{COMMA16} STR_5740 :Stałe kampanie reklamowe STR_5741 :Nigdy niekończące się kampanie reklamowe @@ -2920,7 +2920,7 @@ STR_5789 :Wyłącz efekty świetlne STR_5790 :Mieszany styl płatności RCT1{NEWLINE}(np. jednoczesna odpłatność za wejście i atrakcję) STR_5791 :Ustaw niezawodność wszystkich atrakcji na 100%{NEWLINE}i zresetuj datę budowy na „w tym roku” STR_5792 :Naprawia wszystkie uszkodzone atrakcje -STR_5793 :Usuwa historię katastrof,{NEWLINE}dzięki czemu goście nie będą narzekać że jest niebezpieczne +STR_5793 :Usuwa historię katastrof,{NEWLINE}dzięki czemu goście nie będą narzekać, że atrakcja jest niebezpieczna STR_5794 :Niektóre scenariusze blokują edycję{NEWLINE}istniejących już w parku atrakcji.{NEWLINE}Ta opcja obchodzi tę restrykcję STR_5795 :Goście korzystają ze wszystkich atrakcji w parku{NEWLINE}nawet jeśli ich intensywność jest ekstremalna STR_5796 :Wymusza zamknięcie/otwarcie parku @@ -2957,15 +2957,15 @@ STR_5827 :Ustawia kolor interfejsu graficznego STR_5828 :Zmień użyty format jednostki użyty do czasu, prędkość itp. STR_5829 :Zmień rodzaj użytej waluty. Jedynie w celach wizualnych, nie ma wdrożonego dokładnego kursu wymiany. STR_5830 :Zmień używany język -STR_5831 :Zmień użyty format{NEWLINE}wyświetlanej temperatury -STR_5832 :Pokaż wysokość jako ogólną jednostkę w miejscu formatu jednostki ustawionej w zakładce „Odległość i Prędkość” +STR_5831 :Zmień używany format{NEWLINE}wyświetlanej temperatury +STR_5832 :Pokaż wysokość jako ogólną jednostkę w miejscu formatu jednostki ustawionej w zakładce „Odległość i prędkość” STR_5833 :Zmień używany format daty STR_5834 :Wybierz urządzenie dźwiękowe dla OpenRCT2 STR_5835 :Wycisz grę przy utracie ostrości okna -STR_5836 :Wybierz muzykę do ekranu tytułowego.{NEWLINE}Wybranie motywu z RCT1 wymaga podania ścieżki do RCT1 w zakładce ustawień zaawansowanych. +STR_5836 :Wybierz muzykę ekranu tytułowego.{NEWLINE}Wybranie motywu z RCT1 wymaga podania ścieżki do RCT1 w zakładce ustawień zaawansowanych. STR_5837 :Stwórz i zarządzaj własnymi motywami interfejsu użytkownika -STR_5838 :Pokaż osobny przycisk dla okienka Finansów w pasku narzędzi -STR_5839 :Pokaż osobny przycisk dla okienka Badań i Rozwoju w pasku narzędzi +STR_5838 :Pokaż osobny przycisk dla okienka finansów w pasku narzędzi +STR_5839 :Pokaż osobny przycisk dla okienka badań i rozwoju w pasku narzędzi STR_5840 :Pokaż osobny przycisk dla okienka kodów w pasku narzędzi STR_5841 :Pokaż osobny przycisk dla okienka komunikatów w pasku narzędzi STR_5842 :Posortuj scenariusze w zakładkach według trudności (zachowanie RCT2) lub ich źródła (zachowanie RCT1) @@ -2978,12 +2978,12 @@ STR_5849 :Automatycznie rozlokuj{NEWLINE}nowo zatrudniony personel STR_5851 :Ustaw domyślną częstotliwość inspekcji{NEWLINE}na nowych atrakcjach STR_5853 :Włącz/Wyłącz efekty dźwiękowe STR_5854 :Włącz/Wyłącz muzykę na atrakcjach -STR_5855 :Ustaw normalny pełny ekran, bezramkowy pełny ekran{NEWLINE}klub tryb okienkowy +STR_5855 :Ustaw normalny pełny ekran, bezramkowy pełny ekran{NEWLINE}lub tryb okienkowy STR_5856 :Ustaw rozdzielczość ekranu w trybie pełnoekranowym STR_5857 :Ustawienia gry STR_5858 :Użyj do wyświetlania GPU zamiast CPU. Pomoże to w poprawie kompatybilności z oprogramowaniem do przechwytywania ekranu, jednak może wpłynąć negatywnie na wydajność. STR_5859 :Włącz zmienną ilość klatek dla {NEWLINE}płynniejszej gry. Gdy wyłączone,{NEWLINE}gra będzie używała stałych 40 FPS. -STR_5860 :Przełącz między originalnym/zdekompilowanym rysowaniem trasy +STR_5860 :Przełącz między oryginalnym/zdekompilowanym rysowaniem trasy STR_5861 :Błąd weryfikacji klucza STR_5862 :Blokuj nieznanych graczy. STR_5863 :Zezwól na połączenie graczy znających klucz. @@ -2996,13 +2996,13 @@ STR_5869 :{WINDOW_COLOUR_2}Strona hostującego: {BLACK}{STRING} STR_5870 :Pokaż informacje o serwerze STR_5871 :Wyłącz usychanie kwiatów STR_5872 :Kwiaty się nie starzeją, nie usychają, nie trzeba ich wymieniać -STR_5873 :Zezwól na wyciągarkę na wszystkich typach torów +STR_5873 :Wyciągarka dozwolona na dowolnym torze STR_5874 :Umożliwia przekształcenie dowolnego typu toru w wyciągarkę. STR_5875 :Silnik graficzny: STR_5876 :Silnik używany do generowania grafiki. STR_5877 :Programowy STR_5878 :Programowy (karta graficzna) -STR_5879 :OpenGL (eksperymentalnie) +STR_5879 :OpenGL (eksperymentalne) STR_5880 :Tylko zaznaczone STR_5881 :Tylko niezaznaczone STR_5882 :Własna waluta @@ -3039,7 +3039,7 @@ STR_5913 :Czat STR_5914 :Nieznana atrakcja STR_5915 :Gracz STR_5916 :{COMMA16} gracz -STR_5917 :{COMMA16} gracze +STR_5917 :{COMMA16} graczy STR_5918 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} STR_5919 :{COMMA16} STR_5920 :Efekty graficzne pogody @@ -3053,7 +3053,7 @@ STR_5927 :Szczegóły scenerii STR_5928 :Szczegóły wejścia STR_5929 :Szczegóły ściany STR_5930 :Szczegóły dużej scenerii -STR_5931 :Szczegóły banneru +STR_5931 :Szczegóły baneru STR_5932 :Szczegóły uszkodzonych elementów STR_5933 :Właściwości STR_5934 :Tekstura terenu: {BLACK}{STRINGID} @@ -3076,7 +3076,7 @@ STR_5950 :Zastosuj zmiany dla całego elementu trasy STR_5951 :ID elementu trasy: {BLACK}{COMMA16} STR_5952 :Numer sekwencji: {BLACK}{COMMA16} STR_5953 :Posortuj elementy mapy na podstawie ich wysokości. -STR_5954 :Wiek scenografii: {BLACK}{COMMA16} +STR_5954 :Wiek scenerii: {BLACK}{COMMA16} STR_5955 :Umiejscowienie ćwiartki: {BLACK}{STRINGID} STR_5956 :Południowy-zachód STR_5957 :Północny-zachód @@ -3160,7 +3160,7 @@ STR_6034 :{BLACK}{STRING} STR_6035 :Proszę wybrać katalog z RCT1 STR_6036 :Wyczyść STR_6037 :Proszę wybrać prawidłowy katalog RCT1 -STR_6038 :Jeżeli masz zainstalowane RCT1, ustaw tę opcję na ścieżkę do owej gry, aby załadować scenariusze, muzykę, itp. z pierwszej części +STR_6038 :Jeżeli masz zainstalowane RCT1, ustaw tę opcję na ścieżkę do owej gry, aby załadować scenariusze, muzykę itp. STR_6039 :Szybkie niszczenie atrakcji STR_6040 :Edytuj opcje scenariusza STR_6041 :{BLACK}Nie masz zatrudnionych mechaników! @@ -3222,8 +3222,8 @@ STR_6097 :{STRING} dodał odcinek trasy „{STRING}”. STR_6098 :{STRING} usunął odcinek trasy. STR_6099 :Połączyłeś się z serwerem. STR_6100 :Rozłączyłeś się z serwerem. -STR_6101 :Wartość atrakcji nie spada wraz z upływem czasu. -STR_6102 :Wartość atrakcji nie będzie spadała z czasem, dlatego klienci stwierdzą po pewnym czasie, że jest za droga. +STR_6101 :Wartość atrakcji nie spada +STR_6102 :Wartość atrakcji nie będzie spadała z czasem, więc goście nie będą nagle twierdzić, że atrakcja jest za droga. STR_6103 :Opcja ta nie jest dostępna w grze wieloosobowej. STR_6105 :Hiperjazda STR_6107 :Potworne pikapy @@ -3260,7 +3260,7 @@ STR_6143 :{WINDOW_COLOUR_2}Typ przejażdżki: {BLACK}{STRINGID} STR_6144 :Pokaż odrysowane kafelki STR_6145 :Ustaw limit prędkości dla generatorów prędkości STR_6146 :Włącz wszystkie dostępne części toru -STR_6147 :Włącza wszystkie części które są dostępne dla tego typu przejażdżki, oprócz tych niedostępnych dla danego pojazdu. +STR_6147 :Włącza wszystkie części, które są dostępne dla tego typu przejażdżki, oprócz tych niedostępnych dla danego pojazdu. STR_6148 :Łączenie z serwerem głównym… STR_6149 :Nieudane połączenie z serwerem głównym STR_6150 :Błędna odpowiedź z głównego serwera (brak numeru JSON) @@ -3268,7 +3268,7 @@ STR_6151 :Główny serwer nie zwrócił listy serwerów STR_6152 :Błędna odpowiedź z głównego serwera (brak tablicy JSON) STR_6153 :Opłata za wejście do parku / Opłata za atrakcje STR_6154 :Z uwagi na bezpieczeństwo, nie zaleca się uruchamiania OpenRCT2 z podwyższonymi uprawnieniami. -STR_6155 :KDialog ani Zenity nie jest zainstalowane. Zainstaluj, lub skonfiguruj z poziomu konsoli. +STR_6155 :Ani KDialog, ani Zenity nie jest zainstalowane. Zainstaluj jedno z nich, lub skonfiguruj z poziomu konsoli. STR_6156 :Nazwa jest zastrzeżona STR_6157 :Konsola STR_6160 :{WINDOW_COLOUR_2}Dostępne pojazdy: {BLACK}{STRING} @@ -3281,7 +3281,7 @@ STR_6166 :Synchronizuje każdą wyświetlaną klatkę z częstotliwością od STR_6167 :Zaawansowane STR_6168 :Sekwencja tytułowa STR_6169 :Wybór scenariusza -STR_6170 :Zmiany w interfejsie +STR_6170 :Dostosowanie interfejsu STR_6171 :Szukaj STR_6172 :Szukaj STR_6173 :Wpisz nazwę której szukasz: @@ -3336,7 +3336,7 @@ STR_6247 :Odnowienie przejażdżki/atrakcji STR_6248 :{WINDOW_COLOUR_1}Czy chcesz odnowić {STRINGID} za {CURRENCY}? STR_6249 :{WINDOW_COLOUR_1}Czy chcesz odnowić {STRINGID}? STR_6250 :{WINDOW_COLOUR_1}Czy na pewno chcesz zburzyć {STRINGID} i dostać za to {CURRENCY}? -STR_6251 :Przejażdżka nie jest pusta jeszcze +STR_6251 :Atrakcja nie jest jeszcze pusta STR_6255 :Adres URL jest nieprawidłowy STR_6256 :Efekty renderowania STR_6257 :Świecące @@ -3352,8 +3352,8 @@ STR_6266 :Otwórz folder ze spersonalizowaną zawartością STR_6267 :Otwórz inspektor kafelków STR_6268 :Tick do przodu STR_6269 :Nieprawidłowy indentyfikator klimatu -STR_6270 :Powierzchnie otoczenia -STR_6271 :Krawędzie otoczenia +STR_6270 :Powierzchnie terenu +STR_6271 :Krawędzie terenu STR_6272 :Stacje STR_6273 :Muzyka STR_6274 :Nie można ustawić schematu koloru… @@ -3400,7 +3400,7 @@ STR_6323 :Symulowanie STR_6324 :Symuluj STR_6325 :Symuluj atrakcję STR_6326 :Nie można symulować {STRINGID}… -STR_6327 :Przezroczyste tło dla ogromnych zrzutów z ekranu +STR_6327 :Przezroczyste tło dla ogromnych zrzutów ekranu STR_6328 :Ogromny zrzut ekranu będzie miał przezroczyste tło zamiast domyślnego czarnego. STR_6329 :{STRING}{STRINGID} STR_6330 :Pobieranie [{STRING}] z {STRING} ({COMMA16} / {COMMA16}) @@ -3421,13 +3421,13 @@ STR_6345 :Inspektor kafelków: Zwiększ wysokość elementu STR_6346 :Inspektor kafelków: Zmniejsz wysokość elementu STR_6347 :Dodatkowe ścieżki nie mogą być na przejeździe kolejowym! STR_6348 :Najpierw usuń przejazd kolejowy! -STR_6349 :Losowa sekwecja tytułów -STR_6350 :Rozpraszane +STR_6349 :Losowa sekwencja tytułowa +STR_6350 :Rozpraszanie STR_6351 :Narzędzie rozpraszania scenerii STR_6352 :Gęstość STR_6353 :Niska gęstość STR_6354 :Średnia gęstość -STR_6355 :Wyskoka gęstość +STR_6355 :Wysoka gęstość STR_6356 :Przyzywa kaczki jeśli park zawiera wodę STR_6357 :Usuwa wszystkie kaczki z mapy STR_6358 :Strona {UINT16} @@ -3440,10 +3440,10 @@ STR_6365 :Ofiary atrakcji STR_6366 :Zablokowane pojazdy STR_6367 :Klatka animacji: STR_6368 :Z powodów kompatybilności nie zaleca się uruchamiania OpenRCT2 za pomocą Wine. OpenRCT2 działa poprawnie na macOS, Linux, FreeBSD i OpenBSD. -STR_6369 :Zezwól na budowanie torów na dowolnych wysokościach +STR_6369 :Tory na dowolnych wysokościach STR_6370 :Zezwala na ustawianie fragmentów torów na dowolnych interwałach wysokościowych -STR_6371 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale brakuje pliku „csg1i.dat”. Ten plik musi zostać skopiowany z płyty Zwariowane krajobrazy lub RCT Deluxe do folderu „Data” w RollerCoaster Tycoon 1 zainstalowanym na dysku twardym. -STR_6372 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale ta wersja jest nieodpowiednia. OpenRCT2 wymaga instalacji Zwariowane krajobrazy lub RCT Deluxe w celku korzystania z zasobów RollerCoaster Tycoon 1. +STR_6371 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale brakuje pliku „csg1i.dat”. Ten plik musi zostać skopiowany z płyty Zwariowane Krajobrazy lub RCT Deluxe do folderu „Data” w RollerCoaster Tycoon 1 zainstalowanym na dysku twardym. +STR_6372 :Wskazana ścieżka zawiera instalację RollerCoaster Tycoon 1, ale ta wersja jest nieodpowiednia. OpenRCT2 wymaga instalacji Zwariowane Krajobrazy lub RCT Deluxe w celu korzystania z zasobów RollerCoaster Tycoon 1. STR_6373 :Pokaż/schowaj sprawdzenia prześwitu STR_6374 :P STR_6375 :Nieznana atrakcja @@ -3461,7 +3461,7 @@ STR_6386 :Śnieżyca STR_6387 :Nie można tutaj obniżyć elementu… STR_6388 :Nie można tutaj podwyższyć elementu… STR_6389 :Nieprawidłowy prześwit -STR_6390 :Do działania OpenRCT2 wymaga plików z oryginalnego RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. Wybierz katalog gdzie został zainstalowany RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. +STR_6390 :OpenRCT2 wymaga do działania plików z oryginalnego RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. Wybierz katalog gdzie został zainstalowany RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. STR_6391 :Wybierz katalog z RCT2 STR_6392 :Nie można znaleźć {STRING} w tej ścieżce STR_6393 :Wybór celu @@ -3543,7 +3543,7 @@ STR_6469 :Zmniejsz obszar patrolu STR_6470 :Zwiększ obszar patrolu STR_6471 :Przezroczysta rośliność STR_6472 :Przezroczyste pojazdy -STR_6473 :Przezroczyste podpory +STR_6473 :Przezroczyste wsporniki STR_6474 :Ukryj gości STR_6475 :Ukryj pracowników STR_6476 :Niewidzialne rośliny @@ -3607,7 +3607,7 @@ STR_6533 :{WINDOW_COLOUR_2}Czynnik ekscytacji: {BLACK}-{COMMA16}% STR_6534 :{WINDOW_COLOUR_2}Czynnik intensywności: {BLACK}-{COMMA16}% STR_6535 :{WINDOW_COLOUR_2}Czynnik mdłości: {BLACK}-{COMMA16}% STR_6536 :Ten park został zapisany w późniejszej wersji OpenRCT2. Park został zapisany w v{INT32}, a obecnie używasz v{INT32}. -STR_6537 :Zezwól na używanie zwykłych chodników jako kolejek +STR_6537 :Zezwól na zwykłe chodniki jako kolejki STR_6538 :Pokazuje zwykłe chodniki na liście kolejek do atrakcji w menu chodników. STR_6539 :Hamulec zamknięty STR_6540 :{WINDOW_COLOUR_2}Podziękowania dla następujących firm za zgodę na wykorzystanie ich wizerunku: @@ -3644,7 +3644,7 @@ STR_6570 :Pastelowy róż STR_6571 :Umbra STR_6572 :Beżowy STR_6573 :Niewidzialny -STR_6574 :Próżnia +STR_6574 :Pustka STR_6575 :Zezwól na specjalne schematy kolorów STR_6576 :Dodaje specjalne kolory do rozwijanej listy kolorów STR_6577 :Prędkość hamowania blokowego @@ -3663,7 +3663,7 @@ STR_6589 :Umieść przyciski okna po lewej stronie STR_6590 :Umieść przyciski okna (np. zamknięcie okna) po lewej stronie paska tytułowego zamiast po prawej. STR_6591 :Pracownik obecnie naprawia atrakcję i nie może zostać zwolniony. STR_6592 :Pracownik obecnie inspektuje atrakcję i nie może zostać zwolniony. -STR_6593 :Usuń ogrodzenia parku +STR_6593 :Usuń ogrodzenia STR_6594 :Inspektor kafelków: Przełącz nachylenie ściany STR_6595 :{WINDOW_COLOUR_2}Autor: {BLACK}{STRING} STR_6596 :{WINDOW_COLOUR_2}Autorzy: {BLACK}{STRING} diff --git a/data/language/pt-BR.txt b/data/language/pt-BR.txt index 7d8bfd2a87..6da43c9e85 100644 --- a/data/language/pt-BR.txt +++ b/data/language/pt-BR.txt @@ -99,6 +99,7 @@ STR_0094 :Montanha-Russa de Trilho Único STR_0095 :Montanha-Russa Alpina STR_0096 :Montanha-Russa de Madeira Clássica STR_0097 :Montanha-Russa em Pé Clássica +STR_0098 :Montanha-Russa acelerada por LSM STR_0512 :Uma montanha russa compacta com subida de elevação em espiral e quedas suaves e retorcidas STR_0513 :Uma montanha russa de looping onde passageiros andam em pé STR_0514 :Trens suspensos abaixo do trilho da montanha-russa balançam para fora nas curvas @@ -183,6 +184,7 @@ STR_0604 :Passageiros andam numa fila única em uma pista estreita de monotri STR_0605 :Passageiros descem de tobogã por um trilho de aço sinuoso, freando para controlar suas velocidades STR_0606 :Uma montanha-russa de madeira de estilo mais antigo com um trajeto rápido e duro, com muito ‘tempo no ar’, alguma força G lateral e projetada para um sentimento de ‘perda de controle’ STR_0607 :Uma montanha-russa de aço intensa e de estilo antigo onde os passageiros andam em pé +STR_0608 :Os trens da montanha-russa são acelerados por motores síncronos lineares, acelerando por curvas e giros estreitos STR_0767 :Visitante {INT32} STR_0768 :Faxineiro {INT32} STR_0769 :Mecânico {INT32} @@ -3609,7 +3611,7 @@ STR_6537 :Permitir o uso de caminhos normais como filas de espera STR_6538 :Mostra caminhos normais na lista da janela de Caminhos. STR_6539 :Freio Travado STR_6540 :{WINDOW_COLOUR_2}Agradecimento especial às seguintes empresas por permitirem semelhança com elas: -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 :Contribuidores STR_6543 :Contribuidores… STR_6544 :Empréstimo não pode ser negativo! From d76aff39de2896d0a9eb7e522b9f8b00a166b785 Mon Sep 17 00:00:00 2001 From: ZeeMaji <42477864+ZeeMaji@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:06:37 -0500 Subject: [PATCH 006/139] Improve new ride menu sorting --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/NewRide.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 95bab8f7f2..be76fc6ce6 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.4.17 (in development) ------------------------------------------------------------------------ +- Improved: [#23123] Improve sorting of roller coasters in build new ride menu. 0.4.16 (2024-11-03) ------------------------------------------------------------------------ diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index b17e59929c..2b76554c6a 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -86,26 +86,26 @@ namespace OpenRCT2::Ui::Windows RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER, RIDE_TYPE_TWISTER_ROLLER_COASTER, RIDE_TYPE_HYPER_TWISTER, + RIDE_TYPE_LSM_LAUNCHED_ROLLER_COASTER, RIDE_TYPE_GIGA_COASTER, RIDE_TYPE_SUSPENDED_SWINGING_COASTER, RIDE_TYPE_COMPACT_INVERTED_COASTER, RIDE_TYPE_INVERTED_ROLLER_COASTER, RIDE_TYPE_INVERTED_IMPULSE_COASTER, + RIDE_TYPE_LAY_DOWN_ROLLER_COASTER, + RIDE_TYPE_FLYING_ROLLER_COASTER, + RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER, RIDE_TYPE_MINI_SUSPENDED_COASTER, RIDE_TYPE_STEEPLECHASE, RIDE_TYPE_BOBSLEIGH_COASTER, RIDE_TYPE_MINE_RIDE, RIDE_TYPE_HEARTLINE_TWISTER_COASTER, - RIDE_TYPE_LAY_DOWN_ROLLER_COASTER, - RIDE_TYPE_FLYING_ROLLER_COASTER, - RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER, RIDE_TYPE_REVERSE_FREEFALL_COASTER, RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER, RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER, 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, From 155f5ae2f57b6e2bb9f85c03f336ea724a66eef7 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 8 Nov 2024 22:59:22 +0100 Subject: [PATCH 007/139] Increase cmake_minimum_required to 3.10 (#23165) --- CMakeLists.txt | 3 ++- src/openrct2-android/app/src/main/CMakeLists.txt | 2 +- src/openrct2-cli/CMakeLists.txt | 3 ++- src/openrct2-ui/CMakeLists.txt | 3 ++- src/openrct2/CMakeLists.txt | 3 ++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 23b59933ef..f28655de68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ # CMAKE project for openrct2 -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.10) + if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) message(FATAL_ERROR "Building in-source is not supported! Create a build dir and remove ${CMAKE_SOURCE_DIR}/CMakeCache.txt") endif() diff --git a/src/openrct2-android/app/src/main/CMakeLists.txt b/src/openrct2-android/app/src/main/CMakeLists.txt index 4e3dfb59db..43129b5317 100644 --- a/src/openrct2-android/app/src/main/CMakeLists.txt +++ b/src/openrct2-android/app/src/main/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.8.0) +cmake_minimum_required(VERSION 3.10) project(openrct2-android CXX) diff --git a/src/openrct2-cli/CMakeLists.txt b/src/openrct2-cli/CMakeLists.txt index 7fb991eaac..0c0d258704 100644 --- a/src/openrct2-cli/CMakeLists.txt +++ b/src/openrct2-cli/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.10) + project(openrct2-cli CXX) if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index a9b1986b16..64c2378bfb 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -1,5 +1,6 @@ # CMAKE project for openrct2-ui (UI build of OpenRCT2) -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.10) + if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) message(FATAL_ERROR "Building in-source is not supported! Create a build dir and remove ${CMAKE_SOURCE_DIR}/CMakeCache.txt") endif () diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index 27cb45aa71..6ad152ac03 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.10) + project(libopenrct2 CXX) if (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR) From 05d125efbfb1350cd0b92beee263f99ea6e110f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 18 Oct 2024 23:07:56 +0200 Subject: [PATCH 008/139] Add option to skip headers check In some configuration, such as our docker build, there's no need to perform headers check, as it is handled by a different job already. --- CMakeLists.txt | 3 ++- src/openrct2-ui/CMakeLists.txt | 2 +- src/openrct2/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f28655de68..c0dd6b38d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,9 +113,10 @@ option(DISABLE_TTF "Disable support for TTF provided by freetype2.") option(ENABLE_SCRIPTING "Enable script / plugin support." ON) option(ENABLE_ASAN "Enable the AddressSanitizer.") option(ENABLE_UBSAN "Enable the UndefinedBehaviourSanitizer.") - +option(ENABLE_HEADERS_CHECK "Check if include directives in header files are correct. Only works with clang" ON) option(DISABLE_GUI "Don't build GUI. (Headless only.)") + if (FORCE32) set(TARGET_M "-m32") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TARGET_M}") diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index 64c2378bfb..b321a5dedb 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -158,7 +158,7 @@ endif () # Only valid for Clang for now: # - GCC 8 does not support -Wno-pragma-once-outside-header # - Other compilers status unknown -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +if (ENABLE_HEADERS_CHECK AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(OPENRCT2_HEADERS_CHECK ${OPENRCT2_UI_HEADERS}) # OpenGLAPIProc.h is not meant to be included directly. list(REMOVE_ITEM OPENRCT2_HEADERS_CHECK "${CMAKE_CURRENT_LIST_DIR}/drawing/engines/opengl/OpenGLAPIProc.h") diff --git a/src/openrct2/CMakeLists.txt b/src/openrct2/CMakeLists.txt index 6ad152ac03..81afc79674 100644 --- a/src/openrct2/CMakeLists.txt +++ b/src/openrct2/CMakeLists.txt @@ -262,7 +262,7 @@ endif() # Only valid for Clang for now: # - GCC 8 does not support -Wno-pragma-once-outside-header # - Other compilers status unknown -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +if (ENABLE_HEADERS_CHECK AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") add_library(${PROJECT_NAME}-headers-check OBJECT ${OPENRCT2_CORE_HEADERS}) set_target_properties(${PROJECT_NAME}-headers-check PROPERTIES LINKER_LANGUAGE CXX) set_source_files_properties(${OPENRCT2_CORE_HEADERS} PROPERTIES LANGUAGE CXX) From 9f65e9d71baeaf14445b65a08ed89b2c29729713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 18 Oct 2024 23:39:26 +0200 Subject: [PATCH 009/139] Only run docker job from `develop` branch The dockerfile clones this repository with `develop` branch --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2eb94d889d..e2f3547500 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -418,7 +418,7 @@ jobs: linux-docker: name: Ubuntu Linux (Docker) needs: check-code-formatting - if: github.repository == 'OpenRCT2/OpenRCT2' + if: github.repository == 'OpenRCT2/OpenRCT2' && github.ref == 'refs/heads/develop' runs-on: ubuntu-latest steps: - name: Checkout image From dc052eaa030645a8afb7a13aeac6bf02f8a27f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 8 Nov 2024 23:10:58 +0100 Subject: [PATCH 010/139] Default headers check option to off, enable for CI --- .github/workflows/ci.yml | 2 +- CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e2f3547500..5daf8af0ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -471,7 +471,7 @@ jobs: - name: Install GCC problem matcher uses: ammaraskar/gcc-problem-matcher@master - name: Build OpenRCT2 - run: . scripts/setenv && build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-fprofile-instr-generate -fcoverage-mapping" -DWITH_TESTS=on + run: . scripts/setenv && build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Debug -DENABLE_HEADERS_CHECK=on -DCMAKE_CXX_FLAGS="-fprofile-instr-generate -fcoverage-mapping" -DWITH_TESTS=on - name: Run Tests run: . scripts/setenv -q && LLVM_PROFILE_FILE="openrct2-coverage-%p.profraw" run-tests - name: Test Summary diff --git a/CMakeLists.txt b/CMakeLists.txt index c0dd6b38d6..41d1396c5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ option(DISABLE_TTF "Disable support for TTF provided by freetype2.") option(ENABLE_SCRIPTING "Enable script / plugin support." ON) option(ENABLE_ASAN "Enable the AddressSanitizer.") option(ENABLE_UBSAN "Enable the UndefinedBehaviourSanitizer.") -option(ENABLE_HEADERS_CHECK "Check if include directives in header files are correct. Only works with clang" ON) +option(ENABLE_HEADERS_CHECK "Check if include directives in header files are correct. Only works with clang" OFF) option(DISABLE_GUI "Don't build GUI. (Headless only.)") From d452650aa6de2a2c5c209eca37936e58dbdbcc2d Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sat, 9 Nov 2024 04:02:12 +0000 Subject: [PATCH 011/139] Merge Localisation/master into OpenRCT2/develop --- data/language/nl-NL.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index e2b379166c..afc0c0d1a8 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -96,6 +96,7 @@ STR_0094 :Achtbaan met enkele rail STR_0095 :Rodelachtbaan STR_0096 :Klassieke houten achtbaan STR_0097 :Klassieke staande achtbaan +STR_0098 :LSM-lanceringsachtbaan STR_0512 :Een compacte achtbaan met een spiraalvormige kettingheuvel en soepele, kronkelende afdalingen. STR_0513 :Een achtbaan met loopings waar de passagiers in de karretjes staan. STR_0514 :Treinen hangen onder de baan en zwaaien naar buiten in de bochten. @@ -180,6 +181,7 @@ STR_0604 :Passagiers zitten achter elkaar op een smalle baan met één rail, STR_0605 :Passagiers rodelen over een kronkelende stalen baan, waarbij ze zelf kunnen beslissen hoe snel ze gaan. STR_0606 :Een ouder type houten achtbaan met een snelle en ruwe loop, veel airtime, enige zijwaartse G-krachten en het gevoel van controleverlies. STR_0607 :Een intens ouder type achtbaan waarin de passagiers staan. +STR_0608 :Achtbaan worden door lineaire synchroonmotoren gelanceerd en razen door een kronkelende baan die vaak over de kop gaat. STR_0767 :Bezoeker {INT32} STR_0768 :Klusjesman {INT32} STR_0769 :Monteur {INT32} @@ -3608,7 +3610,7 @@ STR_6537 :Gewone paden als wachtrij bruikbaar maken STR_6538 :Zorgt ervoor dat je wachtrijen kunt bouwen met paden die daar niet voor bedoeld zijn. STR_6539 :Rem is gesloten STR_6540 :{WINDOW_COLOUR_2}Onze dank gaat uit naar de volgende bedrijven voor hun toestemming om voertuigen op hun ontwerpen te baseren: -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 :Deelnemers STR_6543 :Deelnemers… STR_6544 :Lening kan niet negatief zijn! From c412cc29d486a9ca2ac7073d97b32d096b20b2d1 Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 23 Oct 2024 04:42:58 +0100 Subject: [PATCH 012/139] Add large corkscrews to the Twister Roller Coaster --- resources/g2/sprites.json | 240 +++++++++ .../g2/track/bm/large_corkscrew_left_1_1.png | Bin 0 -> 1274 bytes .../g2/track/bm/large_corkscrew_left_1_2.png | Bin 0 -> 1329 bytes .../g2/track/bm/large_corkscrew_left_1_3.png | Bin 0 -> 1186 bytes .../g2/track/bm/large_corkscrew_left_1_4.png | Bin 0 -> 1249 bytes .../g2/track/bm/large_corkscrew_left_1_5.png | Bin 0 -> 1123 bytes .../g2/track/bm/large_corkscrew_left_2_1.png | Bin 0 -> 5238 bytes .../g2/track/bm/large_corkscrew_left_2_2.png | Bin 0 -> 5205 bytes .../g2/track/bm/large_corkscrew_left_2_3.png | Bin 0 -> 5448 bytes .../g2/track/bm/large_corkscrew_left_2_4.png | Bin 0 -> 1375 bytes .../g2/track/bm/large_corkscrew_left_2_5.png | Bin 0 -> 1172 bytes .../g2/track/bm/large_corkscrew_left_3_1.png | Bin 0 -> 1177 bytes .../g2/track/bm/large_corkscrew_left_3_2.png | Bin 0 -> 1169 bytes .../g2/track/bm/large_corkscrew_left_3_3.png | Bin 0 -> 995 bytes .../g2/track/bm/large_corkscrew_left_3_4.png | Bin 0 -> 1058 bytes .../g2/track/bm/large_corkscrew_left_3_5.png | Bin 0 -> 5211 bytes .../g2/track/bm/large_corkscrew_left_4_1.png | Bin 0 -> 1268 bytes .../g2/track/bm/large_corkscrew_left_4_2.png | Bin 0 -> 1407 bytes .../g2/track/bm/large_corkscrew_left_4_3.png | Bin 0 -> 1249 bytes .../g2/track/bm/large_corkscrew_left_4_4.png | Bin 0 -> 5457 bytes .../g2/track/bm/large_corkscrew_left_4_5.png | Bin 0 -> 5481 bytes .../g2/track/bm/large_corkscrew_right_1_1.png | Bin 0 -> 1287 bytes .../g2/track/bm/large_corkscrew_right_1_2.png | Bin 0 -> 1334 bytes .../g2/track/bm/large_corkscrew_right_1_3.png | Bin 0 -> 1186 bytes .../g2/track/bm/large_corkscrew_right_1_4.png | Bin 0 -> 5355 bytes .../g2/track/bm/large_corkscrew_right_1_5.png | Bin 0 -> 5209 bytes .../g2/track/bm/large_corkscrew_right_2_1.png | Bin 0 -> 1141 bytes .../g2/track/bm/large_corkscrew_right_2_2.png | Bin 0 -> 1128 bytes .../g2/track/bm/large_corkscrew_right_2_3.png | Bin 0 -> 989 bytes .../g2/track/bm/large_corkscrew_right_2_4.png | Bin 0 -> 1094 bytes .../g2/track/bm/large_corkscrew_right_2_5.png | Bin 0 -> 1112 bytes .../g2/track/bm/large_corkscrew_right_3_1.png | Bin 0 -> 5283 bytes .../g2/track/bm/large_corkscrew_right_3_2.png | Bin 0 -> 5261 bytes .../g2/track/bm/large_corkscrew_right_3_3.png | Bin 0 -> 1465 bytes .../g2/track/bm/large_corkscrew_right_3_4.png | Bin 0 -> 1336 bytes .../g2/track/bm/large_corkscrew_right_3_5.png | Bin 0 -> 1129 bytes .../g2/track/bm/large_corkscrew_right_4_1.png | Bin 0 -> 1242 bytes .../g2/track/bm/large_corkscrew_right_4_2.png | Bin 0 -> 5504 bytes .../g2/track/bm/large_corkscrew_right_4_3.png | Bin 0 -> 5324 bytes .../g2/track/bm/large_corkscrew_right_4_4.png | Bin 0 -> 1298 bytes .../g2/track/bm/large_corkscrew_right_4_5.png | Bin 0 -> 1194 bytes .../track/coaster/TwisterRollerCoaster.cpp | 458 ++++++++++++++++++ .../ride/rtd/coaster/TwisterRollerCoaster.h | 2 +- src/openrct2/sprites.h | 3 +- 44 files changed, 701 insertions(+), 2 deletions(-) create mode 100644 resources/g2/track/bm/large_corkscrew_left_1_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_1_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_1_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_1_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_1_5.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_2_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_2_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_2_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_2_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_2_5.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_3_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_3_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_3_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_3_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_3_5.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_4_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_4_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_4_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_4_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_left_4_5.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_1_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_1_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_1_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_1_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_1_5.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_2_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_2_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_2_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_2_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_2_5.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_3_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_3_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_3_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_3_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_3_5.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_4_1.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_4_2.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_4_3.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_4_4.png create mode 100644 resources/g2/track/bm/large_corkscrew_right_4_5.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 7105f9b22a..6fa94c7119 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -6535,6 +6535,246 @@ "x": -25, "y": -5 }, + { + "path": "track/bm/large_corkscrew_left_1_1.png", + "x": -24, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_1_2.png", + "x": -24, + "y": -72, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_1_3.png", + "x": -28, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_1_4.png", + "x": -24, + "y": -50, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_1_5.png", + "x": -24, + "y": -37, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_2_1.png", + "x": -24, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_2_2.png", + "x": -32, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_2_3.png", + "x": -25, + "y": -52, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_2_4.png", + "x": -22, + "y": -58, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_2_5.png", + "x": -17, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_3_1.png", + "x": -16, + "y": -5, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_3_2.png", + "x": -18, + "y": -21, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_3_3.png", + "x": 10, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_3_4.png", + "x": -8, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_3_5.png", + "x": -16, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_4_1.png", + "x": -26, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_4_2.png", + "x": -26, + "y": -28, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_4_3.png", + "x": -16, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_4_4.png", + "x": -45, + "y": -39, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_left_4_5.png", + "x": -25, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_1_1.png", + "x": -24, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_1_2.png", + "x": -26, + "y": -28, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_1_3.png", + "x": -23, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_1_4.png", + "x": -31, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_1_5.png", + "x": -32, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_2_1.png", + "x": -24, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_2_2.png", + "x": -16, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_2_3.png", + "x": -24, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_2_4.png", + "x": -16, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_2_5.png", + "x": -26, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_3_1.png", + "x": -42, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_3_2.png", + "x": -16, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_3_3.png", + "x": -28, + "y": -51, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_3_4.png", + "x": -31, + "y": -57, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_3_5.png", + "x": -25, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_4_1.png", + "x": -26, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_4_2.png", + "x": -11, + "y": -73, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_4_3.png", + "x": 9, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_4_4.png", + "x": -18, + "y": -51, + "palette": "keep" + }, + { + "path": "track/bm/large_corkscrew_right_4_5.png", + "x": -25, + "y": -37, + "palette": "keep" + }, { "path": "track/railway/quarter_turn_3_tiles_sw_se_part_3.png", "x": -8, diff --git a/resources/g2/track/bm/large_corkscrew_left_1_1.png b/resources/g2/track/bm/large_corkscrew_left_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b937ad056dfe5323bd149c0db71cee650ceb1716 GIT binary patch literal 1274 zcmX9-acmQH6#i}N){Zf6OK}C8*+GF5PON&6qE&9}hGm@W2Di{)l~XR*K!pQuP+672 z3Rb94q{AXL6fIeSlT|ZD#X_2_juI*~W=M$_QbK|LF{F@c>R9Aw3CZ`~_ufD6`{VoG z?v8e2?S$th003&+7Pl@h@vEgm6&0o4{b*DKpaOKf-MOf=mX(#2mzP&mRLEqq%F4>B zsw%l$u23kdtE*L7tro|1BuOv~#c^gq;GIsV&ld=XBk}l%B;^YQTn7jPps5v@P z0UH54j6B54V{RlJQWlbGnA5=m3&%YW#%;3u6T<&84IBpZ<|8ogR))EXF!;`C;o0G zB;|-p-c&A>DaH^2C>fx#0F51>9=SfCGKNuejNnrycSZ>2J#jcdV@gi1wiz+E$q?em zsKBJ0T-qmOMQ1+dE2c!4jU!4uikWb|g&=JV_63L8=z!X&qzkW{5!zVw`wY;4H&3CVVSelQwwJz+O zzxUuDZQnbaCW4N<<1{<(g9p?1Y~QeL=-8=A>sK^>T077(QzJ@y@?g zUBk+I<117ZLzDac)HCjrGn#MC@A|xdaLa<7k7jrGuDiWr&V{X3XRtsx;+B!ep`0P!0+pY() zm||UT-!FS9c4pb?J-3#Rxp&+?KV#tVH^`b<&F$VFs%N(_!N)`XtEQ@kHbp}~L|U+2 zTi55_`10lE#$N}Qb{qJX=a1eQ8Xi2`b!_*e)A_N&fn&W7UwfwWor#XVL*Mp<>XSdu zRc%rbjhDab=@v()C0Z^>@3t14ul{H>mCR^Bej#_r|%-O+LhBx1`bUdDd(Yn6l zFW#>g-@J6Kw|wRGubU41rZ~NGXnf0!9k(|&RoAV(_Sv*6_SOd5tO=VI4F7dGvS0S+ t8q-C5e{ESYN$%^r{~t{+dJEBPfXkK+b_b6n&Xo)VZHwAl`&-`c`5y=cEIa@J literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_1_2.png b/resources/g2/track/bm/large_corkscrew_left_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e0841d5a8ab568b51cda477b3e87a7042a87c9 GIT binary patch literal 1329 zcmX9-acmQH6#i}9=tf~3%+QSnySB*9oLbmH8dmU_x7n4B-Lk{gP@rfD9V>FmF$-4G zXon4!a6pk}6s)9R)ozwJ;lzrSG+3b15(X4jrC}8+f!Rp26=eFegyehgd+(q3{qenT zS9_a!`qbG|0RYoAElnK-mKADE8L!auV@-bmzys~AE1L^zQBhHGaWRj_D=8@{EiIig zWeT6qFDol6FE1C#<#G&D5Cl$9TBA|VFtpunce}m8AQy=YCzIJ+4pRVJ1xT$xudgzj zB^Il~;Z(Ujq(5i~g_&5~nM(Tzl&@0>XsyVmldwj_%V2|cBJ9@1f^;(K$RvIFY(y;v z1{7Fuz*2la%?~?;34c{CCWaXW%o*Tg7Q%=e01^NLpHB;gHnEsR5T8mlNRm;LDPgnS z^Lk-8EXJzjxJW@tR0c#%qdFUAWL1oZum`lR5ao**xTHy<6f4wn6@_YzN3>CK<6K*CQuxG>Wd^`Zt5n+`QL3NnYgcBBuavF^uizVoEhP~c6$EAjcv)L>J zVj3WBKIRt^Au$z0O)0{W*84J+P?jCe1v8Hmc_=`ILZwKgmdGhoVN|IYE$J{6j#-0F zSJWR&M&h{?4h&j8LkVpL32R0@Ry^RKLLO5zU`vEOnM5R)y9aRqbO0~_umA)Ahysx2 z16Tk_Kq~_SKA2392%s_G!U3lSNfJN`Kw1Qy81#{lGsBnzCVk+E@k*d2fR5ywjUt-` zb+Kx{&ln2Xs;j0xw zJuWd*nAN0ZZDya#77DoHkw7LHfw`1YtA!kZNdRHN3r9ijDa3ZGC!JP$+)u&8VuW5# znaxJ4mBtiyrNWJ40Rjta6~iQ&(aE7f0&NKNV35OMTw8d4<%@#9pJZTbM;ir}-MPM@ zFsC$4jVoJr{r;Nf-DC5ojsMGDTX$jSm#%HHa_2;Cov5*M)|tCq=d6=?`RySi^vx*knk~J97{{cXOAUxjk%PY0F?Di{4nZR~xp$~jklzG-ixtgE5> zgj!a!dftuu=j--O*68~dbk2(N`*SBYOX*9F8NJ=iOD8t7BhQ#`|GBob zGt<1k`n+cJ^&_s{t9^#Khbw+;sXoG-+cP$>3Hffaa`Bwc#(G!7Gi??9k!?G#2F&6s zT;-0E3F$-Y9Q&n;uDT6l@1aC$>$S7d;lEVKaLd8W+B?fHum4T+O;*z1I@ER$Ek9iU zsq}(i&#eQepF2D91Jd`(gC1#P!|I;JCtblMOUu`njknF!ez0kceBc`Iz|bnq%c{VJ zvlGWpx6k7`H4Qa`FZ}a~GS+{pw!<|3PHp$>`KR{3KT*b;BRe$n;fl|Dk4Bem{3>x> z+Hp*9Zc*R3jCZo$A{$+CXiN3wgG*`}>$jZ#X!O)uyOvw~&C*Bh3C;5z0~4X41-E`F zW0JQ=h4Q=49$oGj*q43v`|UUNJG|W0D~|+AdbZEd-|s4<002#MThrICto!hPeGN+z literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_1_3.png b/resources/g2/track/bm/large_corkscrew_left_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e47904d100e89cf673ae490eeb5a1dec52ea1f2d GIT binary patch literal 1186 zcmX9-Z)_8F7=Fk8T*sUR8?11eLrQYWMQS{tn2Vfno85M7H+l;d8d8!Y6exIxqE$<{ zKtqbDaG8ZP(3px9tDacQKJ-I1oit|7MvIQo!G$$aMg!;?ZLlBa{8>Wsy#KzuPx3tP z`~Kj7y>sERg#ggm+tcM})F&Fj8=4!rZ_OUhU_Y%C^CwLFe0R#bDNITfLt1wa6BW0-6-Dmbo^WP)Kv1YykMDJshScpPQ3 zIBl}9W~)FjZqhDOPKB0K#uwv)8Xw7siM%_ldk7nDwObgG;w76)=H!qNio4@!IbBe4 zdZbWEmg-p}3nmfF9v}ihs+cWqwx>u}mX!<6aLJdbsyQ?wP$tQS`|VWN$s{E%;}Z)( zsTlQ@wO}`r^JQIu0+M3sj3sTRAsJMM;(;WXfvDbghiyR62tg-A>?i>3#7u4v1Cfm6>23G z+&tzJjf$I4y;Ll~Y9TQb^NeXqF&nECbG6!i!~!@0d;ltd1~3Lt#sD=Sa46tIS_0`s zfdrX`2n%UD=mH=SkZeX_8YKjj_M&_U=?QpfybX8`oC4;R%!;3isP<$+%4C9tf>x;% zP=gEi03GOHRkM&F+-XwQ8MW%tYW_?;nx9LTP_asyz(!zptI@?0UXc!XcvbNxB1%S! z6mnWc&!Jk$#`7o*NC$)(UW6KSkAMdQv2xiKi#~!cpXXdI(d(500hzW2ZPqADYaE^B ztrG%Oaaxd@KnjUsG)l9mz&DQH_Cm*B4}aj0V?cyg?@aA(^n<-!8;91PJbrcC!QAr4 z+IHSV`}?=Gkb8fg-F*G&UB9mTb_SpS@Dkm&oNQvI$+6M7rdKA&zv;cdj12A@ zuhhmT3$Zt}m%+3KgO&ft^O-OD}Oe|T?l_})|xGjM`g zYQ~;PEq`N3bIgVutLI12nw8bA=!xL16^yIZv37iMU;U`I%5?cKF*W=8y5II=gIm8j zdS)eVc%b~)-hch=7w1NMj|_KD_w}zJ79MzacI}(vldt@F@!#ov4SZQ+Jm(gofVkfv&GN?L78B#;FRd literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_1_4.png b/resources/g2/track/bm/large_corkscrew_left_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f4dfc39086cf91d4e15b387486d39d4b9ccef789 GIT binary patch literal 1249 zcmXAoZ)_8F7{`BQY_~C?F@;oUv_Og7IG4kmq_AeW*<IxCb}34sGDT$W}uv5^y|7Cn=WHBfLbnzhjZgZwNZ`9A;NJl_|e z=h?ft+rDtYvIPKug+!Gfr%A8sggKRNfzgFv#=4>YAt%b-DsjwjI&w=2Nhte%e={8C=*Yr zX{C}U0P8>mTI*wtq8p8Pi9~=-MO>MLFDFNexpbv64G93800;nx03-m&08l^xtcoI` zSAdBaRCAOW@Hhw&K(Ygs0+0rf*TWzVV-%F!FdKks3_J#J0S*#4Da6g`eI7I<+T$@U zmGUb}qF7X5)yv=lxVMoI^;FErN@iZQiX|pd@uX(M**Pf>b0xD5Sd54r(=vq7P2*md zL-e_0AzvyHQqqZ{nue9U#o>SwfGU8n$|6v;dm@A18z~elk?<1<*(}L0wA;;jy*!Tj zEm)Yq6C^G>un7t+I!%x@LZ2B%a3~Q_aa51r($YBd_y>0Obkm^y_Ko+dz1X$k<=)P{ z2L_oVdzL>{`zQRPw|#u5i66!_>^gGKz|Of>nZ&7h`#a@*ifqgTAirx&kMFK*ZOU&78EJ2kz4Dqo$w zd}Hr=z+Kw*#_jHf;Zo4jicHH@(rEQvv zm3L^G-~H&r$-XaUE-v$RTKk!i!FeXWpK`u1(y$p+%S{O zU1{91n#nm+$RN0|=0lvv8n(_IENEnrl@Z5*Wu$UK(CFgULFh8YgPQh$1h`K~+^^u~;gV$>+^dY00)5%_ivwh6aIm1cR<{ z7>`8#@dTYp3%R^hD5_;EQLSZJ0t?U%g?DQKT$gFIV!~O;xte7Us{2t>LhCw0B`<&gAYqu|bZQ=t?(=17dO;8tL!pYMtz>y zS5j)th&76-HOoM?lG8=`hyY227&an`30Y1@BKbt3n8{eCSzTIcG#Usz3iwhOnRBuQ zk60!`RW@D=X6uncLtkp<>+6*@5CBjCbN~Zj5uk*%iSD z3JFODOb%=TkO)X|qXdbv0y4v>97lE*o*GX9&q6@J!m?Y75J{cOW#vL4W?4qPZlM;J zCj?~F!RT%wi%X_Yv1z>#G@6mZTB^KmR#Bzla{+~8oZlH_@UTcmL%gnqvq`OBB(0KB zw@av5rFb5hfNVghC`i*W$Wjx--ilgMO{#kY>1ddac+^anne7#CsqkLCAT{id*??p@jnA4?+cq=JbCShi_uS?YdbPD7eDdtt$k%%SBLLx9e(xv z8&gO7{`qj1bR6%w{Sk5hyI&u@eB<}Uqc`?-?p>Lmd?j#xoFpD8{~l=!4eUN(oqaO? z@rfTFvjZLJorBB%ksYhw%#4MOy}xnGz)<4m<_YKDdj`zY>Yg`PDrOz)tG$$Wk zNE+3i19Q@>b8vdolb=EduWxJEFTXij;Cg#kyOq>m%Z{nnDwoUW?w`MQbzAtsl{*T3eCX%ddK*2v!}|+6dF(WI e9Y6EmUB_tVIf#SRX literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_2_1.png b/resources/g2/track/bm/large_corkscrew_left_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..46c8168400849b9f6edd9128aafb4276d61c18cb GIT binary patch literal 5238 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_2_2.png b/resources/g2/track/bm/large_corkscrew_left_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..267bd68fb9a73cff1f81f25c7b574b0658c0d59a GIT binary patch literal 5205 zcmeHLe{d6Z7XS7aDJ@K}MXLs;Aw>fh)7@m#CQaG~NJ|?-o6__s(80LbY}44Ln`YA{ z(DNcxree?tJuF(ZVsxq(rQTJEHXa3fnuCtUvjaurQO=%L;iPmjPyxBUZ_)x~bmoSc z^FK2C>-+t__j&Jq-h1EK&5nxllKCn3rvL!vt4oV2;T?tN;^YK)4WG~41aC*TRIRsH z;tsCWM%9`dNUnXemE@96b1eYQFD(@-(~hFaA4XETpL<90KuB$QX_8f_FMZ?wX49YJ zp8sOOch0XUdz1B^-QaUjXTgi9AJ21o$@!n>?SJwG;lD;-F8?fj$+ivo7bn^K0f>9j ztWs5|RjTXJz!>&DzN?^gaK)mJ^fkrH?`9=DElYf}yk+g$VC6@=^~)^V*DYR?eQn!= z^VLtgy=OLBFA#q^d*_VZo%vfj5}`=FdoY|JVZ^zIm&kO{&_z%J$P4*M&e$ADZ+1gWC-&rrZ|S&bWfWioVA1Xz<`a^5fz| zhxeSkRLwd3761E-2k$A2zvAEOK6miJiMUS1;mCCmAhnBPEeHDKs z$L~K`Sf2UByyo|Qm#}D2{8;hvN2Z((%0w|Qn=ei!a6Ptvvo9Shf>qaIhSjycY>k|t zEZMk`GLYF$ixrj~0QpL%6({ORJJ&#(%#8)SiNFAlYc>|}s&mTFGOLQLGna0$k-9DA zRm7HhBG1TE7N+Do)!FS<+Y5L+xX!)qpT$~Mb_2eVo?!vH1VT2D z7AQ(XtD;*>mZ-}rZfHa)FqtjZm=+}a7D>Cg_9j`k_!eD>g)`d`sD1WX$;Cp$X8P~3l7t1 zw%{fbu{N4w3sJ)5D=X9mJaIO9bEcvJx7R`i*aPN9BjuoPE>)Q=q|S~<`4maTc~TK% zBx+uqmv>WW9ciOsEk;pAXf`$-Pc$)d7!ITsk5(!Kh-tuRvT1rWJ!~+?nu*JewS^ofrbD3d7Sb5=6Jkv-5p{T@iG=&dOu=5CH~&I0 z-C#uazj zOsbaOD(|Qxqj`Xo2}P)I7G*qSCRil8V_c6mANd&{`7wc6TMX2jo`YK#+zF8zTj2~} z(M{)9{LSRySF`}3?-;o)e(%tAhpyXV;I@SCRM#E4Zi|82624Pi|2Mi)ZhlOWjqnY~ z0Y8dbiAhOGbLPxpu~^B;$#dt<&B)5i!Z1Xo zQtEUXf~cWss;#Z9v$MOm*FQKo91c%JA{YXc3ZT`b*3_ie*JnCfk#@JDvrF64s}Bs& zLm~I*m{%oWRVz{{O@^yF(?jsPX{@hJHPBf-)Juhf?c-tZ)Wl#32j~UBp#&ZstA}C@ zxY;8;>5(B0GmbD3J#*E=FoRhDXaUf(SQMM>;&42CzE`2>(`thz(}>G;uDhEV7~o*( zS;`DVo2k(AODI9L3nM%Vx=YpO({u!M-XXm|Y|4~!kdiEgPM{&AHI#~K*S2@-yZw|u z1mFj2mOTTE<_`47D?1 zFNh{y3N$KEt!32{87_yQ!&B1ZB?5uAP{=nv9%7&^jtO9`sY*|V)|;vK^Qo}HGg0G< zI093hLs$Ky%*X^k9Y`}-B?!AlnOU#HT1^^{tKQq;3ivuggTC?bAQKstYBY==Fk!$j zFcOCcSC_9;3~xx=hR&OF<}~xz=i6D@-P`YahsZcv zv24@VZSu%9(KE$Q9r)bv*1IC_Bat`wXD@wxc}IVG$JF`1NSClP(-x0ceCiv+M0Bv} znT0*TAADh0`s|6iiIKUc&O%`aNAT<={i;WwTKegeISBvth28H*e*Dh#=DV#Q ztoU~F*udL+jx%8V(7otx^W2W^;EqEJ_a>s>nC4$SVmlK!pxN3N7IKg7nK*g=i0k>C z>3=?@_LX{Rs3$bq`Jyy(EHN4NbKT>_#g literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_2_3.png b/resources/g2/track/bm/large_corkscrew_left_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..62b43ff0945306bba7fa0c9334b6344ad3b52665 GIT binary patch literal 5448 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_2_4.png b/resources/g2/track/bm/large_corkscrew_left_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..462697c3468d4cb4e67b265ff2b8076038a3a42b GIT binary patch literal 1375 zcmXAoe{2$W7{T->FT5_8ni6pY7`x=Rh#TPjLGMH-@O04&mYhG z>}*)3FC8;}3;>|CesSIM+^o)(wn&ug8>7!edqiZ0IQlkNOO;FrDaer4zxC46m01 zlN#7D;GvKZjYQp&cu1O!$zfUpvnDv|fsj`MKmuSw5LzN}%HK|>NeBBx?%OA>dbjKQ=$lJWFq!|BoZ2rN-cBwCqFuTWBIjajF&5v0qMJLU+x zy*;6Df)}z$444SSMoF9|g~zJ)J22KoMf{c?))|lb({VnVeFQN83;@^w@BqL9&;vjU z0Wb%NLx&BrL70e>DnO&aivdm#5+r~WfV2#{Q5Ym4XN55rOa#GeaY+Vr#0wxMp&=Fv*`p6vq>#MKn}nJfH3EUD<}5`IpgrBQd+<74YpVeHySCc z)$DN4sD{yMd>G2&Xq3?Ok?OQT2~7&qJZ~dGjB6w zt*=|KV)4!+w^!~xJh4oC?>xM@YUQmqZ>68OJZWO-hxP3<=01OW*supHo;u(0e6UM# zS1dhvVP<1dXRl6qWBTJeI)1a{`h|uc1EG=!Cx+f1Kf4$I!@bA9Ni#MgxA?pDcSZXz z_3x|YPq&2^9epr&)gyo2i=QqH-0Ge3Vohgg!|mX=TlPJUY#SXIVI|a?AT9-Q(xZvuC8Xn_+MHIn{M=M*x$CT zAK5ZP#$?~^`2=m<+P}TypsG=lJ>wpl``@+Rt9MF&73|cGJra@c^s`-0MO@j*1C{*o zL)T%$w3d3|gU_A+i2uIS(fk`RE?vC-#Gl6!P2FvCG|k6q-s3W?iRq~L{<{ zZEsz>Tl$h_i1Q1-x_NbgdU>yUvRXVa{hf3AuIB91Ks)z?#Cv#2QOj_R<>bz;rfI5I zt+Cc~nnj_RE3R!;9=h5+3EkW4)pbsJ*vNHMC~6mm{Nt>lRGd(c8o* zDlY!q+*sGRdzXFNk;>0jFRlJdTpnD~vfAK|C+E9XS7hZ({;rR>(h6)V-oW1H`?oHw zpZsKKd*R2-sNsrfpsReSnR=_eys>>_Rd3mt@{9kjt2oMrs%m4K23HpOx~@EZwRCUs o%j$1nRqL?pNzHadbJm%MjecS4?w|L2?n^-Z!ew=xwQIKj51%+~UjP6A literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_2_5.png b/resources/g2/track/bm/large_corkscrew_left_2_5.png new file mode 100644 index 0000000000000000000000000000000000000000..8722af6b72279d3929435a40e5621e64e2df0bc1 GIT binary patch literal 1172 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_3_3.png b/resources/g2/track/bm/large_corkscrew_left_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..b04b68d9d04643ca274f3e6a04776ed1213ca90f GIT binary patch literal 995 zcmX9-Z;0D;7=G_hFTI^-#o}^UFk=NH3nNOvfKj66j^2@ZIWLn;3Pvty)qV&py2=WM zT^Uu2WTTwns8TQ=DnwTCK4h$n;PTqelQ>er0)aJ)RH7bv!v0_cMPlTmhJZwNs~;VmdJ~F*!LoH8nLoJ)KA- zW@ctE3`-`Hv$L~!Hk)M_S`c_y7Bwwz7<#2rvF&EN?FGSp6phAXh6bJkNu0~))5RiD zD$~^(XE&r)TkZHpH>~vsjzD1wH>ZoZsSuV%HVtN{BKWq_ZR^o)br?AZqac?7m4Xrv zmW;J@%&(<-t@OB?K|>miRdi?}6l4J;02RaZRLaa`ERu9MZby=K3x%F(-f1?G?`N2F zmd9y{;8ZfFQ;NxG7H2esiYwMTveQ+)s6en8I+x{SO4QiAF6dRM+EkmK?uBL$)x%+{ zf8eKhNXvj1fG7iLVQdr6waL8C>!DKX8_viI(2hiKvm~W3Y=IX_vRu=&Myb@U)%<2N^t}H5{%ABpkkNs(F{YIgIvKf375YMT zkavcq&dAyyw}*$l12jjaQY?<=h^$P}8pj!;R8`|;<#w&U+iFKaIPUYHikKm%OqH;T zRHMwhRk_nB?7C*pZw!0Eczg%(01AKsU;(%Qy8r_WPz*^xWdpemih2?WIsQNzs=Rkw02N9%MdVdxHrA&Rv!1z^f^yoE~+ zp?ahqan>mBj!T^byL;&MQEx=1fhDjUoyzk>QD({o(K3rp-R!vaFmQ)afX01R6p;rg z0)*l$sM|sKFqQ zN1+%WKYMcS&wD@c?)s_>&;NSs&6r$XS$yI2!qzJ{Uw-)Fv1DTHFaN5opPXFz;nbIx z_LNrl^P6z%v0vu5ws)RB`}0F@B;Nk`(+@WnzIbA9T$ vuyl0W=QfuAJ-Rjhs&-y2zO;GmHTC*;k6-%a`zODR&B4mj>f)6bU*G&6RUWJ& literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_3_4.png b/resources/g2/track/bm/large_corkscrew_left_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..96e2458635c6203731b513b0e8e89f22229a519f GIT binary patch literal 1058 zcmX9-acCQL6n;(GUc0Qu8ESM9P8aN{hX%RAAt#>gwTtznS9XQqf}DC_+#;NMlOWj) znqk~hI9+s+Wf0*g5pEi!!*iT)vZK~6vQzp;g!?0#!DcWax_}wh@iSxaz4!S3c^@C& zdnc9_;}g5~?gD^`h3DoD4CZ}B{jL*_fJ8!u z1x>_i3T79B&046}h@egk^(3^TA>>2>1ON%clwdFyiD(3&Gt8PGY@|}nT<&_ciflVV zg`#XYCg6-j#1%4;qhyUyD_q{-OO~iNB-2abbR-s!G9t;#bW-7zf>5YRRZ}tDoa2?; zPOa6qgDiwZ2&Vwg0-<4aH5{)KNt;#NM6spnUClvj0vVF&NG47e6HHC!ELC*#ahZXrL8I0hJA~ zT3FC=$s`ny(Yi^am$CZg#*W!S%`OoF8pqU;Kk~^trw-k9{K4J(vq+!t9p0W= z{n9!0Xpy{mYhU-X*)zWBnK}9AiTn3iopaPbr=Q<^ro>E72mXBJUUzEQKXD;&*mvyg zoHq6A$IF}Cg_G+K-RPdU@x|p!cOTp93p~Ak@^$&hySvZ-@Wi*@`5t)ng!Sf=f4!fa z+%vo9!=o$nZvbv=FC6;nD)!^#RXbYxX4H4(^zkK(yx2+2uO8f-`RKp>_q=y`d7?RT zCHB+GAM%SAAIpBe{^^so(dw*S=1@AKckbkkp3Syd+gefZ$O8!XH( L&V4=m@(2F|odU=p literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_3_5.png b/resources/g2/track/bm/large_corkscrew_left_3_5.png new file mode 100644 index 0000000000000000000000000000000000000000..1a81938aa22f2b0dab419fe5ff68c827a60ce786 GIT binary patch literal 5211 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_4_2.png b/resources/g2/track/bm/large_corkscrew_left_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..bd44b2b32f162461ddcccbf8315548fcd54a726d GIT binary patch literal 1407 zcmXAoe^AnQ7{@>U>g$h;CS6oqF~<4w^SW$DuCi5(*`_`;nQQF3e%ADnAbltt5=eg&f=l#d~^)wX~ z3KHYz#RC8m^Ye0w!}H^Cp|Mfn9<-7h0Ehxb1tq!RH6kJ+GBPqMDk?fUIwmG&+O%m1 zg2cwg#>K_am`o;$a`=3VAcRt>SgBNKwOW(O;&3=Uolc~AP}1ZaqB658#Uym!vF_{ByiFIp@#_o4uAwf6cmbvPB*YvRvzypj`zuAevM|# zVu5Zq9i=ic8V6_aBrJh~Ez+P;15at@Ywbd#i?DhnPEy9;(m4Vqk6;U>T(N?$(BV3Z z#Nt#qeHssG^aX6g<8BHDs05(N07DH}283&&2^=i38&mj1`eCItXz;+3IGZZv(p3Vs zUc|FW`7R~l(@Om&<%nGybeqO~b~xgpP`NC&2<6H!zKS69QmI*`a_IGLi^b=34i63n zgFy)B3cxZUsExvR(FreGHq6(Jh^+yYD`*%DIRcaZahSlSP`EUjfWai#94U{d6yiEb z_?X(EH}=^aq{kN;#(+eKC<%&2!Z66$W;JHl5iYZ=&#v*i%>lnB6dHpV03raC02lzU z1JDP+2m)YOI3KE&&~AmKA7=pt3XB+V3IK@%NC2pyK|KnsICRRPR|iQecoRGq2>C#S zBXTKCqhcEk0-IIpa%p`&dm!M0VK2H2py~w7K*OyJiIb%ud4{0a9#Xl+P2Nf8F!Tpm zRKR5*0uDutG2{fQmI)0Sxz(s~*^NGrJwSS3XqYP$LMMPEfH0heE^PN!bgkMvGQu^R z-b(59^2K68E|;p+3Y4Sea!eR%=c8^RXAoxxL`*1QKn)9;QRu{=PZ)-uyEx&=n;)nt zE+jzqgBw)2gvUpGg;cg_IqA!YZr(X_PWq!t(9&-@~}@o*^_>$3Gwz*PWN2M`pF*3Fnc=HlwQBKQ{*%&u z&o=7^+8;N)*4@j#P?2#tKcQFE==-! zcWeK;bTf5cmEloa+mEfRq#Z*S%dSjj4Qabp|Ijt@NiR2jEYOnuew=RF;il%AQw{O0 zJ^kqQZ=2T-T~=IO8n{!sy+?jxdFtLRmAhum?eAJbL~f{R*z_m9>(dkIvp3$Au5hkC zu=b)Vr@e7e&CFDK^>|wYLwqyE*uFJyyt86vchNG!e)?CkQzyTc-SVO-A?11NXkqHc z@Ro4M;G-B%s;H(&o6^^GzIwW}GOJ`ucTV-Wf`Q+!s*KT>aw~ jm1@t5+c{lR>PZ-b`S4$CEBAMVDFXSqg*n|T%69$_VHbW> literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_4_3.png b/resources/g2/track/bm/large_corkscrew_left_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..6dbd2985915c1f6f0b0e05be0f45359654898a66 GIT binary patch literal 1249 zcmXAoZ)_8F7{?#>?=}iFvy&1FmRQ392Xy3ur)kWM-L?WHJ=`HRc5=YMYSzesHz`7qm8N11k?knRC6H%%dBi@#Y!3}SqYmq*cVNh=4T1X_xbnc`M&r( z&+%<`>%#fZ%?E&mn>Tg!)+%0$)y?&_j1@230jP&`4M4R5{FvJCLMNUl45>5P|C-uWz}i` zo&XOGGKa-QEFIM5;<`%4fJ$am;nAFokZJ;80eB1(wOXISAmez%10GZ z$@znl(Nvk6pGwK@tX93>UT-y;IKnJgERu~4@U>;$WH2-yPv+HZ zr9cC3!z51YW7(4+_fsFwNi@628&qIV{Ydj{TQvPf< zQ7UCo&CB2d(yO6mJsUIf3NGd?a@m=vcv97HW=<)fTp8B^WyGvzt&=voInwL0$v$^1 zjI7 zKTi&om$!lZhOc>N!rt-uY@6$Y`fH{rzH(v@KeF*c=c-1!XU%A^+PCtV;hl?y!!3Vq z8|zqbt)pYZ^q~f+WwyQF`uzIA*1?hYADkT;>^e89`GLLDT@p@*Uo))V^6tXj6YKhK z#zt=Ze&$N$l=|SC4Z%lW|I;>lTphEo{%iQ|yOmM;5<5 zNxe6)XYWx-XVM&7acIqf0b%b^<A*DvngOv*(i!r|;D`!RBsz*ZIy} GL;nL_Fdw7< literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_4_4.png b/resources/g2/track/bm/large_corkscrew_left_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..9500e7fa175d50e745ede7d71260e5bdf56143d9 GIT binary patch literal 5457 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 D7hfV( literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_left_4_5.png b/resources/g2/track/bm/large_corkscrew_left_4_5.png new file mode 100644 index 0000000000000000000000000000000000000000..b53d083246723540c671b7f2cd4b345af4c76006 GIT binary patch literal 5481 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_1_1.png b/resources/g2/track/bm/large_corkscrew_right_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..30971a185b93404a7c7f82b143d9b4209b305868 GIT binary patch literal 1287 zcmX9-e{2(F82+|(>&C0ZF&!S*#0sZ5u!ar` z)TP5ZZcw1cnlxHnV;a_x0bM9kW0A!*a=;)Ro}plkHLFsvnKO*|Swix>zw##U^T+eN z2Rl0qbLT9Y0|1z7e6ej~v92x#T3J@id+z7L0F;5w_Dvg#V@XL#X=!O$S(!{GD=#mv zsHl+3<&~9{RaI3gjYfmxT9PCfhGJPW&vP!9%jXM3BGE)*LXz@@0^*{rnL z)OLr~?a}-EbSPqp#rdS@NoRs2CO7G;IZEX;sRb4d@c4*}jQdQ<2q%rXvr=#-pD-Z6 zf&n`L1V$d>!2)Lm2oo9rXaFp7Ij2xK5kx@Ipk6;h(_>a^%IVAn z0x%v&aHWP&X=%0If*Lr?B(InarDx&_0w@`vvI4aOpn_Z%P#GeqIZkk*$&==Tc_9HuXiUlK5W4~MnDil* zjPZ=) zC&xnyGKMfo%$g?M8FMgekL87lLL@tznt|1rLZMTs3~CL7X<5CVr)amOc+3&;c*jB! zDIpfp1h7zYo>4e0YQcv29Yom8#QfH=urn3+XH$tnAqNQnOaSlz2mlmqFa|(I4qy>9 z2^~BP2ceXrQNZEAOMs{WNHl;9fSd|?a2TXv)CQAoCMU=%kmU8H*i#O3g3GCIHS5%^@1G@BWljdeIU zT177{Pq43gC}HF#j}`TBo- zvf1}5O5SXaM_wn&lv{gD$1V$(-S6IcJUw4=xxLBqkEXGAVM}#e@8Q44PHIlQ^4+V{ zovOZ%#k;k&d+WP%m)456SFC@ByfysXZrNnbuJQAB+X>@GFJCy(&^5hc`)c-?FIumf zyFOe_&@U{T*FJvpL3{5ck2Gz0qKO<`KpA9RU-u6_UVgv9*Z4!OuX|_9+ro~zH-c9e zT{`t=zk6QeH`nSWSFImj(u_RY+IrhKK=k~yrvH|6NBeti=MiL6cd|x#Wa_?4Q{VH{ zxr;YDDyDKHy=Uvo#Fg{*G;H5x+&X-5-NkJ4XRh$d(b46L@67+NWqh!C4YMWJbZE5c zFPTBwf8+4Z9&+i%PDy!ve__bDVkuVJ2$fgJ`r`vibaQ{-HvN;8O(k^=wSBEVbV*0e zC!_bUZR7X$x%DNAF9$9?wyf(2&vun`O`YrbwER}fwSyP7FRt1rJzce6=gm3SzncE_ z$3yw=&kj{BJYz2|pO@|4dS?2>VCnMd%}n*TvuSPb2ScA9m|V5As3tIO=x7^i?LP27 DwKXp5 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_1_2.png b/resources/g2/track/bm/large_corkscrew_right_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..040838d28f83bcc00e7514071c0025b030b39fe3 GIT binary patch literal 1334 zcmXAoe{2(F7{}jHMmGx7c*epicB2Ugt6JO*ZpkqYxXrSZ?Ql2fTp?vSXbD9xSh0gT zD-e9X8O-0mal=Voiptqk#$qPHCiOWe#jefvH1ZOGv)YuYaEJAD`#x zSks`IIlW{$0AOa_s+z`pt;`2jB*^Eik8cG)0M@K-s?CoD1qD;4Oc4kKQ>RWXEG(Qh zZJJOhEGjB0E-seH<#G&DQWVKBYL?ZSOq|VTbGyC4U?>_*@O(Cx!<2v|0Ie2jwTRIu zGh38)2jTY6{-7=#F~#DJRN6-=gc?G`sU=p8%*mo&6ELZ8&njSJ3l2+@u z*9#*NDTc^NiISEPI#k6eG**mt5+)C23#eUT#uw9tc!La=DphiVQK(s5%Tb)2wtIEn z5EqJDqr5Ag@uwytViF(>kQji>0#K(A_exYjR2w0=xWWWj$td(BX)9z41^el}Kc>SqP*Y zK;1&jFQ&p$CZ;f?D0^D#%b3GiXCfEOOeQCwNFf&E5{XJCXB0}7AWUl7uFEg81Rbs+ ze~^#Hb14$&)It*@w(4X~qrzh$19m3tF$@K)$%rSDjOKFVkOV*jfC&I60097o07we~ z%!{U=#RLOB$R}wOa2RlrAfy634Il#`CxH$O`e+z3!k8WMKJXYk4%8IT&_W|Cv6>Yw zr^@eR!(m%I9>`?kFz+Qb0L&sHof6t7(}hruC!ASrAZHFwxMP!{6ijAO1mH5EN-5To zG9!ao3~Hy<=yO@a0arX4$na5^OW|rY3<1ak2=grLdAlc)+AN-Q8uz%L$P|lFS}kKV zvK9-6DQ&pYO=1BGi>Q?eT9MJnp-u*^DD+@3M8dc_fBg81qI-{j;H}061}q=FrqB1k z*VU|OTGjE5RfP8S?bFZU1K-%a>1XNA?~NKb7083GeIqJW!u&u3id9*Ux>g zt@FZtt`ofc?P9@sVTpVm@)PoG#z^>j_| zU3sbL=&vsgo-Zj(&puvq^+dC1;|!$n)zW391#DGs?z>qZ*V7)6d;Y==6?3~EUhdLR z59`WoZQJ%Q8A_hxe!J1N!%@BXi!r2e*@lZnXI^j+m3!ai7u_T`*u)19JJ8)0>j+(vsk)EvH@}Tvm28mqvA9!}~ z&_t`abSQGSqPyH*e{y)T&r)&s=+U-a3mSLAi+3(Go3|}k+CIA$L6F=vyBY^wOL{rnkkmA<+1&+w5M1IG^i`_F^& zcHL{l;d?b&avX!;p^?)<<#&cy86aXO|AOjPf{KI-ZADuW`6PR z`n###wpq9DUpvKEVNApwC^1pxV8Gp07+q#~kZ$IC15Xr*_b+rvOr&ey<^FNgr BROJ8w literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_1_3.png b/resources/g2/track/bm/large_corkscrew_right_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e9b08ec72d2de50da8ea673d249c88e063321d GIT binary patch literal 1186 zcmX9-Z)_8F82;@~cVpdBT@9D*qSaKnup3l3^n`+^+_20u+~9CEl0;g8e#43C^p@e;y@n;Fi^ZxttKFRaE z@4lf8zOIhm4gf&c;QE10jfyv7aeGT6zaRb~3_uGQdSUar#@N)<)ZE1Zi(?U$9^S>UO(H(!($`&$FT!kYyCq7MTC z0m3v;cqA(!g@mJ=b=FH5ta)Hvfb$B3MK=H(00M$Y4o4Kj6dYH*-U*JI3I@y3=#5MU z777^YbknGZb9n{aClUTADJot$&BQb|ndjA#pqoJ#g?W5#FHf){6_6My&c!oAMwfIW zS~QbJEnAr@IB4MH0U89Z2*4GD%Amd+9w^X~;ZIa#)l!OZf+L(Fg@t`Y!tc$BOkU=V zm{?B9RV`)}Qgem|t3`*C!U;b~1!*SC^9fN*hr_uV-2)bjq^ngbow^6PRAK@FJ`@ro5sCD~C{KzeHHIv( zo*9m)`Q1=(!6**XB-CkWu#MxVme_CJ{ehjEHt^t?KQF)1=!XUep56S^{{5E%-LZ!| zZ9{hoC;QHg+q%buuD!moZPUJ~>pg=@5A>2tFE2v(T)6|r$DTZkcizW*7yR@PInZx? zR_Z+T)^B8}d0%?%_ODO$^mk%d@!XDoo;&_a|Hbzn|8l%X{k`|r&Am&0vR_%8Dl9*M zzP{??`Q4*q)2DtOKJ-a&Nodc3$>KP@hJE?)x09~fm*jUQZXKK5w))5;KYp?NQQP8$ zlRMk?ANvS##T*YUCMj}F{||6*6$BNy?J-H*MvYIOY* zvv%@`{i{<={Q2{{{@xhZnOCo^xZeJJj#ftw=k{&&T^bsVT|3%wVb3YrbN+;I$I7qB wy;dXt+A`bnuK%0US@qc4=KK|O``I(M-&p;}nS(1&H-rX*>oyFGuif^+|5}*>i2wiq literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_1_4.png b/resources/g2/track/bm/large_corkscrew_right_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..1c1589c5b88418dc3d9d6588992edd3435dc48e7 GIT binary patch literal 5355 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_1_5.png b/resources/g2/track/bm/large_corkscrew_right_1_5.png new file mode 100644 index 0000000000000000000000000000000000000000..b3041ef5d7a60db81a123579ecaa251448e286a3 GIT binary patch literal 5209 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 o`!{{JbjhASI2FEfNm^|Hpa{{R30 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_2_3.png b/resources/g2/track/bm/large_corkscrew_right_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..5f95313384b67b0e8666e6624ba6539b23fbcfe6 GIT binary patch literal 989 zcmX9-Z)oFm7=E{I%l!vqY-C%GWh~PQL81gLSTI7AD*X_> zDn+6MDbn+b6bxsDz!jMixPAy4jvZDF$8Z%Q^h4!xcwmtT0|)!raqztF%k$-ZK0MF! z@$Qbeym(;|0G78l*Z0ovWS*GMO!gTz{WU-acCYMjOz70q)b#XpCX<<&nVFrPotvA( zFl>H)eqmuDUnmq9h86@~Q6ybgP1C5=YRzW5+x5fnD2~Tz%Fw`bAWKWCnk$!yN|mnL zT(c#2x>_$V`;k2yxdMe1xg|r&TSdar$+pQH)P$f}?01d$u%5*3$v6~o&?uGdmk1W8#R8{LlFq7zVASP$TWkAJPkyjfB&6CJO zqcEFeNvg=OC0?i~immIdN~LStLAxFK{_yB%JRT#!4IrBs)5!`wT;GZc^!u zoujmyoDNRV5|z!e`MgLJ6pGe4&XnZ3HhEU<+Kt0bHx8q8$b%+frjoTZ!YNa&D(}^m zUaNHIS%aXJ48k;hfOvo+fC=CLcmRh0BMi_4vVf{4@>~=TWD*Pp8a((S#4;cSkda3= zgIpQ;Wz?^u*oAZBS&#%M%2-*?TNSF|h#gn&^=eV%B}s%PT6hVV>JsndWtY%=(ug@{ zta@pschc;i`a?7rlR01sOr*0aPm~p=T9O>A>^7{P*N8$di9?hQSxG`ZpcoLEcu}9o zJp^8>wnihi)qDuE-xpL>DVOzX)nMovOE-DO6PQ4vk7Oz-7LZ0Di$pC3`8MYk literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_2_4.png b/resources/g2/track/bm/large_corkscrew_right_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..6a129836433560fe3b3b095f59b254e8e0991195 GIT binary patch literal 1094 zcmX9-e`p(Z6o37B{b7j`T-L?*lqgZp63glCkNe}C*Ba|duk1E6h+T?@W*YRsTS>Rf zW!*8-5%93t$Yx++-ZVmHgR6Sj2!TacXoS-h8`(|c4DO~CQb}2-MZcyDKJPs~|GW=; zKJT3z8};^d?dSr4o{{H=b~onsM&TVTjlOj8-?sr;VC=;`!wuTh)YRPE+|tt0+S=OI z*4EzMj$v3wM@MI8r^DrPk)(%Z8A0Gg(J#xAqA1B^I+xRn#bwj1)$61O7#eu4+wZrB zLU=ghiN)z;iqGT%`GQY__P=sk+@7P0#cEVlY^aMpx5m zR46z}yNhvnc$^Nny%OPzlA=n>DOSmHiM*hd0=gN*DW}Klq6LBzDZj)@F+P?Kq;*L* zqD3=dSeeR3!N!1H07nq;2)I>@N;|wcx4*zhhA&=`wVGN)^E_b}DQDPA#C>!|Wb?9M zC}KG&SF=j3klZk`s9LnyDL3IGsUX9K1tBhqsc<+Kj~CKuL)RI?%RBuKT^LfQEvX*6_ zhL$r3WTcx>9lVAIbhl*EYR#Xmhw~fB(xzTP<(k_L6pnd4Ha~-h1Tqrj)M!XcMDy8% zQOsIq5!EXc#~~e%2?#Z^h&ANy!l^`3)hd-r-i2H$v3|c03W<@3M0ym;lVr#&OBOiK zGEZ1O7Yg7g>P9IN=?pTs#_>}F-G6QUz`@<40z7l`$JZKUePn3Yo=4xCyc)WsJlWAU zal7#OKL?InywLT~KC6HB@Zz4AZlmwI3NnOd@a^+S$2cIEoeJLL_3)1i6e^0vO4ht7TU`UB@aInXrt z#O0@^t_)Vc`|bChl9 z?|Wu)g74|x*9`zYqpu84HS5#O==_eSR;+<}Z6lBJ$a7sjsBz?)8k~6fT z88d3>%67rVf?WcKABYgRbc{(l_^iuYU=_m?t*EKGUPQ|xX_py1$dgfzJ1uj0RWibI zIj&YS;d&vyZDdfjXtOge(nB+TmJ3Q!RF)ILU^W^pB$GxiS6N@L*Xsyy1zd5APTROV zE|o}sg^N_Zsah~!*Vh}_+D>^JSxK9XaX5IwDUp=ycB_II@imu)veDRTI%^hM9L@ps~N3aNYu*3Mq>-H03HApKnKVGtO8UqKuw4o3aKcQLS|WX zfkH!!g&Ys22uK2?I8c;EDG}uYs1!kF3ho=vfWU!A!~(KI3z9LNPp9O3K5Q77TFpRB zF5C}v$ja&tF-7=tF2!`~b#JB-%x}j_JGlxf*IjmC2#lv}UX}<*bjUC0S|AnE@|l=X z%+$;xYE&3OKsi7rAk_3C(xiI;JRC|?t4t#P0BWhkdA(8~AcsNSY!yz<7fJqi zZ@$&{_tFo)=Kp!&+zIx!^~2KH)tQxNc6ZQV>fz-dgeaAx#w;RarN+%8;(2IKStl|8S15uoCz;ZCw}YjoZ??Q{&o43dE)Aq z)zJ38o7HOv-kYba)0ZMEC;joq@B{n%)C?66@j;P) zb?gv+`is}6dPl$QyHI`hp+}z@KeqpgeLMFS-#0$H?0BU3{gvyB>+JN|cb9frHjfSx Tzi+7nO?hB+WMX(}Xy)|)^-SRr literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_3_1.png b/resources/g2/track/bm/large_corkscrew_right_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c1b7b42f8b18c1a098b64cd4aa3c41b992c9bf0a GIT binary patch literal 5283 zcmeHLeNa5Az~Hqm7CV zYHYJEcIXsW)~2(xX5Ea#)@)68v5hTN#!a_YX*b=)T~umqH&SY8{pj19fQqx7*>Pt3 zpPBpe-aYr6-?`^^&bgD9oz+!kGt(bU2LQ~hC@-mj_vP?nq@}=bD&x%y@D|=sTkohr zoy=xCVX`#gOvn0WoQbzuOaQe0%~~Cu8Rn(kFzQ*=~h<%&(6qSdIbKckMN*6y&PuV4%_GVSfs#X0p@3ZP3w{BlOZ)N_?t&3(> z?DF`|J>7f-JN)IjfBnwi=4Yn8uvw~*Er^Ld=6i$c|BWrB}YGgW%O$Pd%f>OZpyChedh$|F3-V_qO*xv zk*25RBby9cUS6>M`+cqN{U+lDLdCtd=urQWzZWJYM~=OG z_PaX9vCr9;t{!=0Y4Ww;7SH7)i(*Ngien#j^M`DFUsd} zOIs~10@l)WW})3^lGl{1n1q0{B36UL(JV(0r_-756y_6lGs2h2WC%}y2n1ZH!6nz* z9B3=oM&`vKCNN5H60=*H9TvjIjANn(Vx6Oi#e(b1Tl=#%S61GJw~>=9Kt7OGv>D;& z^AM{QnQB2gN?Rbvh~2htUT1Gggk!`Iya~5L zRT6sT-{rEbqO$t7MVtb&#oC;(f@I&N>9CmYkagGI;wy=8rfvk9-^RU5`&R4;WvEqI zDK8ug67l$4)F?!`e5uLA!wseazCbhuLSwhU zszjTn?kWytgiul$pDz(g1zZzmFmgpaqk)SWq(ZJyfTOYk)PNiDf&`QildmA`Rurbw zVnxk3(rhy)7UG1|?NJCf=q)M0`Kum>zQBjF_PEY(`9xYmKj`Q%FkG6`QS zm5QZefs{AlDuK8fx0A3IpL6pcpe~STt1IGg)$a087vY%F>Xa$i2N5Hg$aczM+~%^kinx1o`lHl zqi~Y1_@VPNekSwqGkSo~_nq7mzxV07PuD#$a8JtjtLr{p_r$85hO08CnVLFl|+S=MWJG%pcU^sj_8jX#O2@#-F0F63Br^{+=%yqhuc8{X7OVbn3 zhx*8Yh-YZnr{d7-6d8m%+g+FI#n|1Xu(wUs*I73ZAfo;4BT?UYEL_F_dJb?ZfmciK zA?SUc%)y?lu>l4(f>2|6>bjSr!g&B_0MOIvL}sR&!SJ%#K82!JqvW+}sH=qwj&AAc=QkJLCa@3eaN2rK)O?$V# zJ4gg0?r^jtGSV|N-j}HaSz3^72DvW4_R=NY*<}H?u1`rs>O4cFFXjzXy&6syCSf?s zIG#F152gx{+DIEV*hvoi+hTp4;}JhK9L~&=usL-?iCL*~YPB8=>vB2+9#3C)cO)1b zI(<48i&20<0Cp!`*psOWF|-35^N^~2SmzsYhGO2+V}X(DgX2^NCo@x$on4ljr{y4+ zLP4rE?Rp623V1sDdjipLWNb(Y^lCb(&2;N?y^WkMm(t&^4Rx9O{qDiOu93m;*w|%C z2|yhHBmiCj`~dU=FiZy&92ynnA}PO*iVkYnfDnQXB?y**s0L74KoQxLM@acJRIrg6 zXs4n+5Kp`Ws8yg&LvO^g-A+!2x2(s9g+gtSh<{`xLP1{)GZ4Bml-_KOFIOLA6H$dX zrt^C0?SxWyRJ^P_Ww7H9<5on{RC|Oo39k{Uflwlil#V%s&wuli`m#k9DI`Z2gT0IPwZ2F)?K_oG`!=~OsQY_ z{rZnnzpux~h?BGmb58Ds9jpHIk1qG3ZT~!Z!8vQEr2OLUi{2kc7mxB&WA;P%=ilg3 zUOYT!8SPX+SNL_97+4Vewq`rhG@6t%?}d%O`0{YZR@&RPORGw+ZCE?*d1w9%<|>yw zwPR*M0ZsG93+vmfcaYY>@T1nkZ4W#%`-e1C{N4w$^We9~+x4$+Y>^(KjBVwMxt?p6 zXa4fXjUUTAwPzlvmoGhXbO3DXzC3TM%RN_dz_-=4?Y!g5LEZlIR8m9W)!ykZJ{jj8 ORFqbg{C@fKTmJ)Ha=^O) literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_3_2.png b/resources/g2/track/bm/large_corkscrew_right_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..9c70daf17d1361ff97695e9a75636bd713f96864 GIT binary patch literal 5261 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_3_3.png b/resources/g2/track/bm/large_corkscrew_right_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..31440f8c9606136c67c27fde34974f128fb24df3 GIT binary patch literal 1465 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_4_1.png b/resources/g2/track/bm/large_corkscrew_right_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..23cbf7e7c217f78fb45c8a791982061bd9f9f2fd GIT binary patch literal 1242 zcmX9-Z)_8F82)t|+{OxJ)=;HL!457^w7O%S>D)nXv0)Xf zt5~48lT|F*kb+HCq=bIp&q1mwNex|6<mWPXhoYr4nWYBmro1z16CA zICM^z(d#1uK{^t%#S?s5^5ybj%79pidd{qITXX`8hIs6>he`x2=@=)cyahR2E+$P{ zU^4(G2?Pd-a7e5WxEd78clkFF_>B0%2Aw`_J(XB zkrO3%Qua%QNUoevkwDD=jUDJ*02L5Cq%p-%Yl7q?i!aBAi$W5frVVNq*E&rGpM{99 zRGeod51S3}`KYIu2$ZEL%qLZ995q-l+)h$XhVij%(CLi%e2Gv<62)95Q!ExC&~g9` zAXr32#kEY@V9!zByfs{K#*0Fx6e~<-%dp;{QsEknNvCHFMwTFWGwroij=5q!e<~7_ zlTs;10-G7(8I{|n6C8%1i;Q}ic+j4Ty0eL3A)73f#vuuS1ppoZ0f0&jQUK%;04ty= z=;C2C4CO410uBRy5{M=s(*QC6avJEvV3>xY1E#%D4ueO=mYnf&AU!GOV77>=0j@(#MwOM+IT*}k zHw$h@*zb-<{ZcYokdv^K!_8(W0w@CrD_(dja*v_)xPtjS9t=DNpH5R&E8}pmE*FOx zJ-9JIVo?f9n2j0QP_XEsO$Xg53}R3up=7RvAAhd?{-Yo0U)RZi*0HPGD)Zis_Lbc) ze|+f5hI5{IO3+nKoH^Ha=k*Vj4@*z95B>20^AiGBQFC}??Yic<7t4xg|HT^Xz(8ZS ze`(|OMYA?Pcwu+v0gP?@arx2X7XvGf_E9^z^-B-kGTr*R_|gP>vSny%ZOfkW1;yKK z%)LL~U-8*-W=`L(!>=v)O4F|%*mvUK*)s#1pS-)EWkP@K#w(egFUQXN6j!zChqs4L zeX;1;%&y4l#S<&P*~lrks+Km*mlf*SI-Mt|7eNB3<%GG~iF zaHwruy!mTCv+TRb7IN99d6U`On=WVmX&n3%UYo7i_h9jz6AaaV&^~mwK{Qv*} literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_4_2.png b/resources/g2/track/bm/large_corkscrew_right_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..571036237a70f54b8cb3e68f3699bb00af239690 GIT binary patch literal 5504 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_4_3.png b/resources/g2/track/bm/large_corkscrew_right_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..6e283d52607988618daa7264d9891f9a5e310f6c GIT binary patch literal 5324 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 Hv2n-$`5#V5 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_corkscrew_right_4_5.png b/resources/g2/track/bm/large_corkscrew_right_4_5.png new file mode 100644 index 0000000000000000000000000000000000000000..886e59b61639eaddac6c55e621f7ff2d806eb005 GIT binary patch literal 1194 zcmX9-e~i;)82-3%*Mr@;z>paROxYjHSxpTk>0u#73RY5}K)DQDbYgQGFlO|1adA(j7$7q`3c~%etvMeczqG_pYHfI=R%W5>6I0h&ZaI8HLaE3yj za0H9RNiE4`vcY^oE}8LaEls0{pR`M?E9&>Cf-fcGqY7Qn{H3g96=QWP-D((&8w61h zrhv*L83`%G9hHo;S#rZV2Ae@Ru0m*d0pI`#B8cR0MBQ%H=S!31D905=u@a5mNu^++ z;KrR^%7t+rGU#I@)E~tKm6VgTqO*xSpDqP+mgphe7~>^*log18L`yL)mI|hFQqGJT zR>G`js;z>90!|*dMBs@4pNbGE7nAh`3Y28}<5fA`Pz^ZBp-zEthZ!{PCo=+_mw8hW zDwWe$a&CuZ zcu~Ks-JX*@QU2^A_vF^5V;@0de2XvzTkzB3{#!d@8Jhll-i@Kw>Cp@^mOutu?@`-r zKOTSgynbfZ^~Tm=^zemOUz5j<9o+o* Date: Wed, 23 Oct 2024 06:59:28 +0100 Subject: [PATCH 013/139] Add medium half loops to the Twister and Vertical Drop Roller Coaster --- resources/g2/sprites.json | 264 +++++++++++ .../g2/track/bm/medium_half_loop_left_1_1.png | Bin 0 -> 5401 bytes .../g2/track/bm/medium_half_loop_left_1_2.png | Bin 0 -> 5453 bytes .../g2/track/bm/medium_half_loop_left_1_3.png | Bin 0 -> 5552 bytes .../g2/track/bm/medium_half_loop_left_1_4.png | Bin 0 -> 5503 bytes .../g2/track/bm/medium_half_loop_left_1_5.png | Bin 0 -> 5270 bytes .../g2/track/bm/medium_half_loop_left_2_1.png | Bin 0 -> 5185 bytes .../g2/track/bm/medium_half_loop_left_2_2.png | Bin 0 -> 5103 bytes .../track/bm/medium_half_loop_left_2_2_2.png | Bin 0 -> 5451 bytes .../g2/track/bm/medium_half_loop_left_2_3.png | Bin 0 -> 5518 bytes .../g2/track/bm/medium_half_loop_left_2_4.png | Bin 0 -> 1519 bytes .../g2/track/bm/medium_half_loop_left_2_5.png | Bin 0 -> 1118 bytes .../g2/track/bm/medium_half_loop_left_3_1.png | Bin 0 -> 5209 bytes .../g2/track/bm/medium_half_loop_left_3_2.png | Bin 0 -> 5051 bytes .../track/bm/medium_half_loop_left_3_2_2.png | Bin 0 -> 5119 bytes .../g2/track/bm/medium_half_loop_left_3_3.png | Bin 0 -> 1471 bytes .../g2/track/bm/medium_half_loop_left_3_4.png | Bin 0 -> 5567 bytes .../g2/track/bm/medium_half_loop_left_3_5.png | Bin 0 -> 5246 bytes .../g2/track/bm/medium_half_loop_left_4_1.png | Bin 0 -> 1267 bytes .../g2/track/bm/medium_half_loop_left_4_2.png | Bin 0 -> 1375 bytes .../g2/track/bm/medium_half_loop_left_4_3.png | Bin 0 -> 1497 bytes .../g2/track/bm/medium_half_loop_left_4_4.png | Bin 0 -> 1671 bytes .../g2/track/bm/medium_half_loop_left_4_5.png | Bin 0 -> 1097 bytes .../track/bm/medium_half_loop_right_1_1.png | Bin 0 -> 1259 bytes .../track/bm/medium_half_loop_right_1_2.png | Bin 0 -> 1277 bytes .../track/bm/medium_half_loop_right_1_3.png | Bin 0 -> 1353 bytes .../track/bm/medium_half_loop_right_1_4.png | Bin 0 -> 1517 bytes .../track/bm/medium_half_loop_right_1_5.png | Bin 0 -> 5240 bytes .../track/bm/medium_half_loop_right_2_1.png | Bin 0 -> 5178 bytes .../track/bm/medium_half_loop_right_2_2.png | Bin 0 -> 5052 bytes .../track/bm/medium_half_loop_right_2_2_2.png | Bin 0 -> 5108 bytes .../track/bm/medium_half_loop_right_2_3.png | Bin 0 -> 1351 bytes .../track/bm/medium_half_loop_right_2_4.png | Bin 0 -> 1437 bytes .../track/bm/medium_half_loop_right_2_5.png | Bin 0 -> 1094 bytes .../track/bm/medium_half_loop_right_3_1.png | Bin 0 -> 5255 bytes .../track/bm/medium_half_loop_right_3_2.png | Bin 0 -> 5131 bytes .../track/bm/medium_half_loop_right_3_2_2.png | Bin 0 -> 5488 bytes .../track/bm/medium_half_loop_right_3_3.png | Bin 0 -> 5621 bytes .../track/bm/medium_half_loop_right_3_4.png | Bin 0 -> 5656 bytes .../track/bm/medium_half_loop_right_3_5.png | Bin 0 -> 5269 bytes .../track/bm/medium_half_loop_right_4_1.png | Bin 0 -> 5431 bytes .../track/bm/medium_half_loop_right_4_2.png | Bin 0 -> 5533 bytes .../track/bm/medium_half_loop_right_4_3.png | Bin 0 -> 5782 bytes .../track/bm/medium_half_loop_right_4_4.png | Bin 0 -> 1467 bytes .../track/bm/medium_half_loop_right_4_5.png | Bin 0 -> 5226 bytes .../track/coaster/TwisterRollerCoaster.cpp | 426 ++++++++++++++++++ .../ride/rtd/coaster/TwisterRollerCoaster.h | 2 +- .../ride/rtd/coaster/VerticalDropCoaster.h | 2 +- src/openrct2/sprites.h | 3 +- 49 files changed, 694 insertions(+), 3 deletions(-) create mode 100644 resources/g2/track/bm/medium_half_loop_left_1_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_1_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_1_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_1_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_1_5.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_2_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_2_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_2_2_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_2_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_2_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_2_5.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_3_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_3_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_3_2_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_3_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_3_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_3_5.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_4_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_4_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_4_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_4_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_left_4_5.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_1_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_1_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_1_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_1_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_1_5.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_2_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_2_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_2_2_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_2_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_2_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_2_5.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_3_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_3_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_3_2_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_3_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_3_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_3_5.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_4_1.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_4_2.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_4_3.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_4_4.png create mode 100644 resources/g2/track/bm/medium_half_loop_right_4_5.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 6fa94c7119..d00ce327e2 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -6775,6 +6775,270 @@ "y": -37, "palette": "keep" }, + { + "path": "track/bm/medium_half_loop_left_1_1.png", + "x": -26, + "y": -34, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_1_2.png", + "x": -33, + "y": -55, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_1_3.png", + "x": -32, + "y": -95, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_1_4.png", + "x": -44, + "y": -123, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_1_5.png", + "x": -26, + "y": -35, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_2_1.png", + "x": -27, + "y": -10, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_2_2.png", + "x": -16, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_2_3.png", + "x": -16, + "y": -85, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_2_4.png", + "x": -33, + "y": -148, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_2_5.png", + "x": -25, + "y": -45, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_3_1.png", + "x": -29, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_3_2.png", + "x": 0, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_3_3.png", + "x": -6, + "y": -69, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_3_4.png", + "x": -32, + "y": -154, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_3_5.png", + "x": -19, + "y": -45, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_4_1.png", + "x": -24, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_4_2.png", + "x": -26, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_4_3.png", + "x": -32, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_4_4.png", + "x": -12, + "y": -126, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_4_5.png", + "x": -27, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_1_1.png", + "x": -27, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_1_2.png", + "x": -22, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_1_3.png", + "x": -21, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_1_4.png", + "x": -46, + "y": -125, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_1_5.png", + "x": -27, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_2_1.png", + "x": -27, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_2_2.png", + "x": -32, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_2_3.png", + "x": -32, + "y": -62, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_2_4.png", + "x": -27, + "y": -153, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_2_5.png", + "x": -24, + "y": -45, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_3_1.png", + "x": -32, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_3_2.png", + "x": -32, + "y": -35, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_3_3.png", + "x": -32, + "y": -85, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_3_4.png", + "x": -13, + "y": -149, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_3_5.png", + "x": -14, + "y": -45, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_4_1.png", + "x": -23, + "y": -33, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_4_2.png", + "x": -17, + "y": -52, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_4_3.png", + "x": -5, + "y": -102, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_4_4.png", + "x": -32, + "y": -125, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_4_5.png", + "x": -32, + "y": -35, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_2_2_2.png", + "x": -16, + "y": -38, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_left_3_2_2.png", + "x": 0, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_2_2_2.png", + "x": -32, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/medium_half_loop_right_3_2_2.png", + "x": -32, + "y": -35, + "palette": "keep" + }, { "path": "track/railway/quarter_turn_3_tiles_sw_se_part_3.png", "x": -8, diff --git a/resources/g2/track/bm/medium_half_loop_left_1_1.png b/resources/g2/track/bm/medium_half_loop_left_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2f3759ab876bab6e2aac99208d5df6d9eff708f2 GIT binary patch literal 5401 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_1_2.png b/resources/g2/track/bm/medium_half_loop_left_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..b230401b3e9baaeba2bc18fd87a6a238286d8fb1 GIT binary patch literal 5453 zcmeHLeNaQEOYtjPahh7RwBk07*kT(MRywBIDq7lN*VVT-0TpLEv*XP6KQs5` zy?gIDzjMy-oO35HFBRlxPa{7@h9GEKZcauaxbwjEWK0zJe!Ok@B5*rWT~ur%P z1=ktMF`BK)jM1=4gARf!zcUu3&+Mkf93I)SBt7EMZRleuebirm&wSiiehB{XQ%TFT zlcj#rSqYbKe&V&o!PTp=V{12WdPyRR{%h*e4JE!48$GdW5-)S~%x?#%BOON$?_P09 zJKs(@xT2t<=6Bv_ioK%C=UzVja!lLwbK9#=wHJQn`{=+&%PwxrUsU#!TwU&P>>Zx2 zapxR)Ge-wquHU$p(ztce>tAE1*PhsE(#8JnZHu}Vy+E`|vAsESDg;GrGRR~FxiZ)!?gK z`5M}JdGJEJr_Mu**-$G=5hWeUd5MsdS(;SQ)t)YgtIJ+{au@gOpSDEq*3JH)a`}mi zE01kcP2z5f*u-7HQz~{+;A?Z#qt~wg%KmKMVgD`hzg|E5CDfWT2Rnq!z^D67PfLQ& zUzpC!C0`d`-|NHT*j`d$Q!L2nR~8uB-ehd zIQ65EwSLkscoe1In0G#kZLj?&<5~Xv?4SD{Ax|E>)%ZygY3ljNjf=hBZhs}Z6=Z!ns}T7c~PBy9%WJ+kieEwmF3XQCrO{Vwi((syDH3j?XVJV^$Qt_!)B zn~_Ej*_UW>)S#7w9}!fHE{3^67Ehx|W(oLw5lbXO7qfU;5vt(}VLp$?n*fz-vf2<6 ziiMy6INJblV7^8pfCVs%k0B^akSqWY8X?9)Frffo2{l@+W&(u5VgOZ%luz_31f>N~ zS^+HPYDGGhn5WaS1gIEhA)@4DmXT>>BAc# z!X@bixoLDhn|p7ipd7L3fCA_NgGr0qt@pNy3`R_8LqdG=gnY4(%N2{nVgXl}EVw7M z60=xAErw8eTsABU?}QQ~0pS2@kx-=qfbcqqMk2Fdhz++C;dpr(J>(QEqXh( zu^}0V4FjNDzCgm`O89UQPblGwB?2*%%ad>?$m3druIhhDhuVjhI+pYtgB94X3NMZI zloESxY&JG6H-wvsMhmxv1VP6_up$+hHtZ+B8rwqGASOKq&X4hey|ZrkgJR&qsDO|0 zg)A-?6@p@bxh#-05lg6ng~DW1oSZB|??<=dI-4D_VCj0mBj5@YXqYS7!tqok-7jxn zgN5<{C}Z)stO=CSIpe`{LMO(ZXj3`=#YbvbV8Rgt^v2e}(FIOI&fTMMoUhQK^Cy1B z^YABH0MHMOJP^MR>3T@l12OPG!VjzKAzcr|zyk?CtginXUF3T&QdLCFb9&RKni(mNlAQJ8P)FK)H_p}TNG^_>MozP*Y6w{ za?6+`RZ1)_r_`vZE|k$~h4AAT<-ROCgt%)P|FM&ba=z z_>tZOBFG^|)Wl5}L3AfVkOG3#BoZDMSCf$7Vldn(Df<+P9=*Q5rsl`iR>J2?fa4RT z6pn(LqGn{{OjQkxx>BqyvO15vsY~hZReJ+^sxX0*otUCz%28nnF2m~;^{whwFYfi% zbO)OJ!M1@>Uz`+*S3(p$M0G$67fIMk$?jm3_@uaBOq3*bNA%m%cg?g#Xu2ecvw8d`ka5{aht$wd}ps#Ou zc$k0^aEQ@Ng4^O`T?xuwrhY(HKUCrl+Pj8beIp&goBg9iEHf@nNTFm?6O~L3nv!Cb zE9%t%%+cX&>S^l;bo)mJq>x%pvMS?h)Kpg)v&A9x)GNDM^gW)MeqT$lzk6ilM?wlg zDhRSdkPCu55Yz)fLnMd*Lm?v^R>I>Z0{sdGgu_si6!K<60R==TAp)lmPMB~j2yYqD zTTcYsP$=<2NG^j^3Q`$Lsj)MgT-j}Iw5zMm@Am|QegfD^&_l2zR_dZC+*Gxffd^7t z!zG>(d)H`l?@jLj(LcGCxByFI}`H!(6Gl*vq{@Q{fH1g~WsA2Nl959(;&RGS>ij5Cl z5zyQ3%mRxfTW($^=?5}p`dnUAl5-o-3Fc;`7v=Q4+x+Y|duTCBTZohSjCA9Iq|1T# zrTa$qY_?Q=b@0=_7~hug6yFt}W-jd-^pr;IDn$-dxmV!i{Z(~)4?$V|M`kz9>|8UW zNfMh?aMl*{q?jr9lteVNCe6%Y(r4{xY0dE%`XXZ-fYItl`DWN4%J zDP}|cnFAZIoV;{{n_<|oE%$mwLDqV8!&ZfhdDFc**ynih=~-FtRP2vo%sX*4`$lGQ z=iVN4M`oq(3*qz)RqT&foUGWaA&qROHi}+xzS(m8N%Grmdpj?(=IOGQAK2TrX>h)D zn^Sdo{g!Bz@YEIE$wT>=bT~cmLHh^MFLoZksz0yZ@%{eMX98)R1)j>8EtTXIee54p ziRTwCxp`Z;qjP`9?yM)SBwZr0vpfHiKDfVr!@R2znV%mwNUty7weCjg`j}&mQ~$OU lL_TwCr?ZrKJMnhJ-x|xlJg3oL162U!X69#nxNP+c{{hFH5f}gf literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_1_3.png b/resources/g2/track/bm/medium_half_loop_left_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9065c70cb83ef546983c4c900d19baa0bb51b8d2 GIT binary patch literal 5552 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_1_4.png b/resources/g2/track/bm/medium_half_loop_left_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f502821ecf6dcc5fe5515aa41ca9a663bffe1cb6 GIT binary patch literal 5503 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_1_5.png b/resources/g2/track/bm/medium_half_loop_left_1_5.png new file mode 100644 index 0000000000000000000000000000000000000000..f242002ca60eecb0c77abf973ee5ae4a82d7e002 GIT binary patch literal 5270 zcmeHLeN+=y7Ju>;1Qiu6R&ZNwNRUyv_i)PQ_M42RI7LK`QONk~I7kckAPHeInI zg*LUcWed2p8!c68X=PnbH+7>%m$kHpE-LM&UE1Pqv{qTmZn4F6_9Y}d;Uf+y$6vNxe?L`}Hg{Ylg zVI}m&a-444R)N#;YNH;2>c5x^O6GX!v&MZXRT1AU-!M&D^)QiQ9cP>eFT*6gJi$PEkK8d9P8j?pL!f4z+DKp17iGlf3?$Z((RNb{Q3l zf?S2-b~G@CwjFzAIo{PvPHWT$3Rlc|U_s@d3if^bCGG2thc-sU9yr{8sP@bOP5=I7 zxs{a*N@M3dz4Ec8rEOccRxFG-5jWRBV`e3!TzBNYk=01+{dcu}q;hP|+?Ge*Y>{zS zpI@20Z%@PfHxDhU&YG);UVVK3sr9ngHhpxGeCi8t@1T3R@4HoFflI|PkAy$PsBFBv zJL`ir8E)g{wy}Ee+bdH}1y03BJ^td2y;qL(5pBvju^Iew-N5K6RQuk!)7FIUBX7+2 z&COo$sOza^fg>lkHFR%2-2J`mhge0V`C;$Y7FW)enYsJvYu7DZScERi>s}K){@~qU?N*8jhD_@UV_|hHY@tuu*18}jwFB8m56`H z!;3ffYD{5d`+lKh^Tp^zpGKv=BW?MBR(cJ1RlnEeyl}B2WkJL7@dtOPf3fI;$ekt& zadk)ADzNFBCx3_%i6Z`}eEHb5>(~Bp?XS0F1J_1qZ#-;$-*H;1g;iH&gw?e%f4u}F z%&Dl3(Bi4p<_cJL0A$FkD^SdY+vr-{V6?~>BW@3aZq&&b#cBDR{0aqLX3W`c#nsz4 z6k*#`K&sIS zgqzAi%w}Y|1!>Ewf*_L%`bi722sSBFh?B%tD~4xP;TBu+bO;?bWnZz?S{@2Vhaq@5 zZicEP^vb=hF+s*V=+Jp>U=z1e#Cb-lcsz_K-5v z%FmZ%64=(@@^Uj}jG%vsj=+pMN$63)(du>SD9YApxk9!eO_#>ja?(X?oSUZCa??3l zj+j3UD%V2VPz#0!p&)pw5#sPg7>aV!xNKCX)v^T~zKAX2aJ6hPF2d7A9HCw)5KMzm zS>N(eml53PR~1l#t62q>068Y`p-7tI_KOY%wMlvH59y=p{W36?1hVC>zh`64qi6mCH%xi$dnX#7JN`kXkfYsSqF}htWtBRvfhv)*^x^ zmob76^q}R`bUth-9cn`}Q5z0HIXr=c%aQQ-MI4cY1E0Ap4p+jNrcdaM`fdM9JJ>$- zjESV@7)j`VTSzp~Q);|&Vl*)o6Ce(%$DpRRji;GUH4SJ!>I?umhWQodhZ|2Mi~ z?z~Ll7Wfay4qugWj(+(y0O6oueNh&C-I_6DMp#%_czAe3L_}m{WK>iXjYf-(j-EMl zWu>S}I)=tPadHr^1_=g`R0Eh!ny@_~yNg-kkrTe+h9S~5;`CD8 zDpouuOtfdS8j7VIn8Hn}eYMzNGdbK@JK|{`^L0|g-ne)nlU2+Y8srMQTHSzQt#*4? zLxZQi-PhAIG%zqSGD3kw0x+9t{Ej$H(A=P!!BX9dtKwB-Yln4i5`knY1F3rTxEI;(q&S$8&?3jp-lnXj5bcS^{TI)^RNJcV;hHCHC;gZ`8SDsSz9Jed6r?jY6XB;5CdfvU}eXWxsxCu(^00 zdB}V8)yFN0rnx(lW@9lXZ$V(E-&Sh0q<$Fl(EOLUgZc9+8?Os)mDYbVuMBH6E8jl4 zj&-K$L+A6urY+uS!?c(6DBM3N`mLciiV_qgGen>XUaE_A3juNtq-y%8BW|F`;oF{GoA PO^}3<`uPi#T>F}<&HC};Z$F5B|6W2xC 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 WX)ZsyYCen-6cwz>Kd@q5<9`5fLZQF_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_2_2.png b/resources/g2/track/bm/medium_half_loop_left_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..bcd075348c2092a12c466cbdb6f41c9ca9a14c9a GIT binary patch literal 5103 zcmeHLe{@sz75~-(DXq}XszoYGmV!}2`jWh)Y0`#R(wc@)QkzPZZpN3Fmo&7=OY>5a zQf832l`Tprg_UE`$_ZLrHae*qC2Ej}okj`B&WctkvuIH^3)EwoMc=+jN-1Zav%@*_ zKXP8)kNds%bMO7!d%q_yzpGxYnwPmS696zzU0GfOuYCAjmXQw6xBfNu0K6RDQ2U^> z26M6O4$@?4B3RB=JHaB{783yOkFC{Zw;bkYygr`Uv+Xa7m&Dc9r!O#;>l^khY%w25 z`@=^$4W3U(XS4nG?FSmHFW==ASw7(%6CKMws-C}m)3#+jU%fq;b8@BIweHCu`k&Fy z8Tsn=o!JHR0cjEK$taHzp&K93pEc1Wg ziM;a0pHG%Na;l@_iL^!Ohx|DQv);Mc9Uwk+jBZ|NdS#oZO;)D;#mcWQ3)J+kMe+t#-5U;8HO zDbZqH;nvNKZ@uL|@<*?)fB*dbn^~9AKKtkCy=U1=en9SdY0HJvuQJEJmVbRJZAJg# z+I~*vzO^4z9>EPop{3tF{Eva0%?qN>zP(D`@$mbHS~h+fjShx0;ts{c=-Il9ccquI zn|FM9-;-{ydwu`&)G5yV7q{=t>B-eDbe4Ul+8>)AX)gSD+4=Xkb*MkcZQpXlkQe*a z`zwFDvQ&BJn%XBX{^n27%u(Lab?u$HrF;*M88l>M+Sch}_NH;x}atU7e4$lmhV z&vrZRJ%9W8KIt1TPc(lAjQfJ0=bt{Ev+M4fZx6=8lLy--Csu_c%+N*0;o-{}Pr$BQ zZ-L$QVAU!aPFf2wBWWNC-BvqnI{-=*ZaaoI5>A$ZFk5VL_EAZewl>))nOn|I;>zHCLX5CkNfl?Koc&-` zHA_i42$rZ&RLJL5xGn32?B$uPQistbt0}*43IaaK*$qyoU4|eom#ff)7LpD#B9Ka@ z2w#W@g*>RiqgriF%+0e=1qp~0Mma&@4vXDsA#JP#CT1X8oN_iBuCuPhXSG*VO~c!$ zDHb3fh#RvbfQEng(Y#L{9OY7mHcB2%%5CzTQ?&rl>0 zizWPGi2$}og7p-X+D17s8%`vkprp_Oaf^5_9AwjsTtXeH+3k&&ICDl!s(*zCR3|MSN(nVces%mmy& zrW*E&-11}1Ai_kr7&Y-wp@h#9;e?2X;ZiZrfC@2#2^V9<;#4zCqf?~G>B1aDnHlm3 zxq=Ov0ZUHsml>jqud#lUqb-{`IzbX^w%*QI=;yZ&!< zWnO)mB5d#%kPE&lz3^{YD*)-BdR1)&eBDY*OS|c&o6^(MXU&>5d-m)(bLKD@jEszo zxpU{{6%-VpD56vV1e`7g+MBHm=j&oz^RTjgq&_g}3Xl0ujQ5RB4o=Wn-0W;g zUY?3spyMKVNeQLVw(B8STc59Upto-*8Xq540KJAm>9Rd~roWNf-KGe(>%!gUfuLtF z(mgsD9UnhOD*&hifC9h|KoEcd07e*qhKE*3w^4L3Ko1RSIevmcpN> z4KVc~4mnifAFB_JyTTJ)vB}UdJvhe61rjDhg=E(&n2kEL&8+cz8Uvl4aIiBT4UP^) z>G5HSMni`HJp^bP)}kG{OC9;%w(gM;Nq1N3pkgs)eZ8)+5pQcFQN$}jx)f+oiAFTY z2`zWDu7K7vX%C0)M(L1(j%#4^OL$oq5;NeeS*-*2esL21w*}G+8dW*iGJ8=ae3)ym zdOdd2SD7T@m|{moqT-E6eL teA}giuQ4yLd2c}8-(?zZ{?fLKIp>K@0!?_wYcM9Du2@~Zf5ju4{{w=lek}k1 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_2_2_2.png b/resources/g2/track/bm/medium_half_loop_left_2_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..d2f4d5e75c0ef910e182bed5b545e0bb340eac8a GIT binary patch literal 5451 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_2_5.png b/resources/g2/track/bm/medium_half_loop_left_2_5.png new file mode 100644 index 0000000000000000000000000000000000000000..9856862ded91cb0fc2cedb526b6bb36695b6e4b7 GIT binary patch literal 1118 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_3_2.png b/resources/g2/track/bm/medium_half_loop_left_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..e0e7dc4cbd6eaaff841456c64125bbdecd0a7f93 GIT binary patch literal 5051 zcmeHLe{@p!75^qt!9-ut=teh-iChIMrd3zroF02XTNYu3X%2VTpV1@QZW+G7jh?a%Fv z8@=l>AII$>ZH^X#MUqk$-g`O{9hN?!hAeK)Nu6j-X{Uku0m!I-b}^`oLQ zpLQ2K>FRsJy7n)u4bQyJf91|ydlz%XCmw9veitKkaa$0WGnT3m`dm0-7HnR?tbeuD z_PF$-^5W^kPWOAfJ2usB=uUL=?t77Qv25(y!IV6-<&L()ThEKBSGmUviy zz5U&h-yAl+^zhWikN*bK4!T zwl?bTQ{tqv0<)49qN2^|hD8TJmAcK1;mw4XV+Yc<~ zF(MWVpoDuAt>DAaC;r3i<8B~EaWzCHJ1zbIoJGiy7l_&@GfeG z1;_`|hPe?@g%EK%k=YuQw{|-OnQ`cAHK<0|qR4uJBDZ;PqINss@|Mkpu;SPC-P=4Z zxp1sFLbMQ0C`v)AqMJLJPMI{nKjLN5>thn-C z(&NNnIvq~TP9ScVJ!d0JxbmI`Z8cY1A-u8D(1LkwPyzOU!(}CX)Qzo1hm$aRu`Hh= znOFgB$|@x?p+c;f4m^jrf$&hU7PF`#VFfDBsb>?TgyBGHv23M6fZRHaMyc@-n3wc4 zl4MIYHw(eZYF^*g!-leAUaSW55)f11%3foRtbACds=`DOK=CTv; z{Fo`&YwM1$DF&-mYO#rhLP4d15D6rNln`KYi(DWT2~i<|DZ~;Cy&0V%ZC)SdA?~q5 z9wAq-KyzGiR?eiV{APLIRwA1RNSQz+6wIQGi_8RzWKWE1(N-b<#Ya_6VAc@>^`_V0 z(FIRJZi(O9bls-wmKeAt;oH@9o32}8;Fg4MSJ(fI zuEHBHQ-llt0`kFErE&X)T>un-hWi?8;pT~Sk0Npo|l&yRHV zs6u^){sD6=PK_jbQWFskpJ7rJkvdj~sWgc5!W4QUpoxb}BLie|xGSBEOl5}Z*ucyO zJ~ap$8T}+9-cvl*Uotturqc*LX{Ij+X?my(00RJK27@dv?qIWnJYGblI$5&uHwy@jjn#prvFb|8 zjC=%FsVJSH%M8K%13kUN{R7FN#AHeh%sK{TEbcIu2AlbPes#3V80)hSM?1#ied)2G z$;k_}8UPaj6aYa0q5up7Fu?#c90m>Tr|4*ePL3IPfJ8yB8VuHfqyf-IK$9%G2c;th zda#)u>7tVnkWIV{=rq7&U^L^b4j;caSl1uHW3fOY5lyEPG_=LG1Jqxn4zdi9Qu82> zOsayJrs$+EHWeDVJeZ=#GQ1KXD`nIn#ZBtcW+Upi>w+E4k=~A2v^OynO(%!w$&^f| zqXz+<1T+nE(FM&-4|c%cH!&gW3r!DdWJJ@{WNdE6{eBWf0x~3|Mxz=uu0uu*{Iscz zHkZ;JJh~612i0^!2a8`OD7u*K0q^>CMzH4myYQbakY~}=)quTozf%t<^WF8EAX!Bv z*((n`dEidC$na|QwTw>+SxZY6-F>Poi?Bgkb5G;S#K&*^aS0GH3)Wmh7M(Wk)3==K zd~}QFRh4BiH+A~ySDvju#65Cw#mb9I_6&S^^kv3#uYLdBeJ3BSDOav2TvqAtTl3oL ol0a&7{OBduJ6C?$ac1t@U&`3~|JC~hv;efV>uQdz{qe5<0FT^TV*mgE literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_3_2_2.png b/resources/g2/track/bm/medium_half_loop_left_3_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..1a8bbf2a65806a9997133ce3c0e387feab76a02e GIT binary patch literal 5119 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_3_4.png b/resources/g2/track/bm/medium_half_loop_left_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..2180a7dd8c7a4beef43fbf35ac312b52555b99a7 GIT binary patch literal 5567 zcmeHLeN+=y7Jqyh1u;EEjfyR4P-BhBB$>dF0F9VnU?T<$iW+SkCPT;q8At*_X~mja z?9v4kDpgc0L9orKtjZP@x2dv<9@-*`#!3}iRQzmIR_&JJ>;zEpY|q)_IototnXmWW zy}x_!@80{)Og>Cppa}Gz;tv1_jE|Eqr0x>xOdjn+U9VJi@~K

2&%81ddtccXCx zz1eGxU0Mzs=(%Mq=%E<|7o}iu5n_#7rV$TUS>_H58n>tgqeNC*abIr?KJPs~|GW>p z&*#mIjs*JFZ(0ukeZx=h+-J`%c5Uu%xBEjQg${sr7~Q>pmrdK++SaXG*WTXV(b3V_ z+1b_Ag<)8CcXv-ukIUonkfe`cXr5<9F(k{9s;au4&gJr@(z0bWTP@NDv>!OOHxzP4 zBJOC+7f<;06qm^fg`!+B6Sca*5LnRPE3qym=+;DUS|%4&rlz^h?Y+7-xoLq%FLgNd4KG_?|1LT3Q;>O6 z6|1^j&#KL$zG`Msz2tCGULr_RVVa5Zd_ojc(P%D_D5le9K3`j2ZZ?|;a0$FRMrIsL z0p}}3xW>fmA)^s3G_~bcuCZ2KMZJW>LAhK3w}&TuqTesGTwJi1#d3*cIg_(WW~)Yn zz+y7*Pz1LYAyP3q8|MqDa5<|~i>XGn)M~9D8XyQD184wQfHFWG17w3^P)tTy16fth z3la%Q8u9_KI6yog$%PUmGB}ivph_HB2HY{80+xXwhebq}5+#yaAY+Jyf@+%CM#Dt5 z79IvN)=O(H&TtEPuVnePW+>Z=7FPAjTE2#=O|KIuHx}?YLbN-=ld&+XDG?*76tYRP zlx7F2#8^xseJbVCX)?=@Mb@{> z5sjb+32vl#QHn%)8kwveerjv)-*RmpBs4K`mr-7GG<`M(Q~T$ z(e{@%+DH1~(|2Bd`?D6l_i*8xLx(3HduHhD)P+~@=`Jnz+QrWg8W+v`$E~+c9vpKn z?E2%%m;Zf#Wbi`YA;vLre%r~z7XH)4;_R_!&rUQyn0o%w<)QB;`p5rzle@(%EWK~! z=C8Y%`2#OZZ~pqZq45*n_TRVX#-2-0vNO{&+phimJNDJ79UpI1=k0U=4DTA*d2VQI F@_*E%-qZj9 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_3_1.png b/resources/g2/track/bm/medium_half_loop_right_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..49c7fc9b072da37dd301ee42512b1e143d9389c8 GIT binary patch literal 5255 zcmeHLeN+=y7JrBu1QjZ+Xk(i+lt#rcNhS~yJ|Yb?V89@uVx=`sCX<)~nV1O#r4>us z;%=<*tHqXfSvOkT(n=LQvCXkjQ%iTTX4S29%~q(`#;#qXVoO`Bvo8S^&-R=>p0oYW zocVh1-TS-u{_ef+Waf9J3l&phAB+V6OereNFN1d}JZHv4!)wJepEbeT;nn3!tYw&u zZMKklV>Q9Ht}+vBqTZ+np#DrvY2{QOd-AYCM|_q$B$#@3Zgu^f2SV&gQPED~ubJv&7wts?N%4ua95< z-m3jiH(mR~CmGDgUhmZ8ZGEdiu_!cCH}hlBfPX%v|@^Qqj&gO_swhje>YZhCn|QN1o3~5u4kE$$7`qr9{Y zO;v{vJCD9&cXaKZy1R+}W7N6t`gdI5q})K}>|1xG{{Sm=Dd*DJsK>jGly`AscP;&_ z@F=d$aL@gD*;m~OO*4Fd{J1!0)3RfSYM=Yk=j-*v_${)b;Dw5-k40y5R&M?FiC60F z^>tluQ)jtT_iWyg(3Yrr(3*EnvAbugcV*g{d6$oE+*I^gV)MGA+N7RmjxBh3LAHF> z;__FnzVxmyHpn~v?9St7hR!3C&+mU#)N91D+`R>;0N z$J+Btk>xMv=h`>nQBUsLSS|aJb^X%mdBrM8(F-&FHmrS$HL#XUT9H2Q;_w%HmvYw* z%{*{YdgIx|ZNrZqJaOWP;?SWC^U5zzoX_dEFlMYdnIhktf|P781!w&iS}pT0PruwL zIk}THi)%?qu@on3 z(l8yVCDQ6^%&_VJ$d=WcF}#YfvbBW4Xv*P)JYEjlsLSD0q?hnZ%yMFdv2eA8P_JHC zj<2r5B|45QH#WOo3IS>eE5@#`sWws4`W#LKR|=oQ(+Gzh5wTX~aF&#mvgM?OV2jd3 zX?$Kmy|GTn$&F=aTXcG9S^g8F5O9>kSz)!Br3hlP+0txi8fh^g0*OR|@P&v_$b%9* zYL&@~)$>eLau{L+BcGsfi_vT~k|uT-6VsBl)*KE8uCs6YS7R|utqSfisVFKby`>SRz+kK~N3cSu@|`rBmP;ahkm63$php!zM`JEU*M9ubC8 zB_+~)60Z%rSCpT_3EP+INZhECMjkT=ex_KL!RHC}>3p6@gk|tDGei=eL?RO5LLsUZ zVAvR_A`@lBOgIsSg5YUJh{MmsGQ{aZlt&08={ymN3wT&2pU)$-nHfS+MutEu#>YUY zEJj$BSoK)1!caO0rN<-?2+!b2FkHeDWx|Vuuh;T22{coW3i!C5AR1oQsli}6 zjWw8oK+GmXWFbtrG_SNMha*hm-<~P0#;kg%0DHh_(vddm_ENdAhEQ9vFrNakP$Cux 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_3_2_2.png b/resources/g2/track/bm/medium_half_loop_right_3_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..565747b91bedc167890d202848c420167df3f103 GIT binary patch literal 5488 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 E0%&Ugod5s; literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_3_3.png b/resources/g2/track/bm/medium_half_loop_right_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..3c6b2a778c1a7af8b9765e593955aaec30a15a24 GIT binary patch literal 5621 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 K4`(m_`+orH&}}UM literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_3_4.png b/resources/g2/track/bm/medium_half_loop_right_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..71dd87e1ed8ec53858c5b108e9fe0990e7e9c130 GIT binary patch literal 5656 zcmeHLeNy=O9@_VLV#Jr%A$7*=?I~}KE)LtBv3cHK1VisPA3oZvzLfF)yfvRjc;dzfKl%3O zpU-_F+iH8^X;<3Jp!3w=@|dHHg8Ar$mUiZD-RYgxRpKDLytv@iGmhyf06|*}GFeWx zOm;sQGK4+r-;!jtr^cOA7s@}#i+geYft~*;E(m#g&5O%k+_a_p<)W`Y`=J{u>fU*< zB`N%PC`CHU70LPPjJPFy(`CxmQ?|MTweQ?%J9v@tC)>b=v#nz-Rg}txWrt=Ua^ox5}whweLWR=eO?~9ZJsZ=_6tP%{z4cxm#0j z4IetZ=C91iQzz#~H%2RmEDNq?9+yY9t>N?yUwa>sH0)zWMn`P9{9O>EPPGWs6F7B^u`Z@6Jg} z##KMOeSTR`e8-eOrPwQ{47m@p9nkK*d@HSabqF9|N) zhpsC|MOudRrSOzWF$qwLSrB?Gpv0dTF&Pd?E#j|K5+I;KMkAJ)FvNnJ@^HLF z!tgsq_iH{_R*(&)MJz}fV!=pIE?*$#aY-igxQSvI7V||cE>FyzB#&ziy0!n8w7-4m zDHBQ0GMGvGYXeggJ*C3dOpGRmC5AvV(dmJ<5F_YB2xg=L(+2z`u_l(#BBV@@k^9HJ zg1tX)_!q?>5@`{gmd9tq35bp@5Re(vpjs|ln*i%zt%$D?=_Y7>fNsWh7As=H7U)SH zNv_BO4RA%De=k+fKkALO2=nKGq>RnuvL{i-fbIng`FD)_(WXHEi;t9mz@#mP)SH+i zw=QxggdS{#_xK`x{dfNE<>B9Hf=+*8E!2DP*Bj6DN}-jgF`|>LPJBRPMu1jP{P8( zrcIj`6CWQB!;nlSRjK4CT4*-oHk+-!zOkvv-QM2g_4-CfVF*Z*fl?k(SQuSgOtV%& zHMPn04N7N|y0y*h>8$M^aL8Dc{NxB+9#fr9v!l#LGknS>Ypc)qG~wQknnAB)%-5b7 z3)C!Nl>)np;>0O!wbWi`^r$D67=(yXH8E}{i1v5@lmMtH6r4(}j*Yc5nU3V-Q%Yrr zUf)|?eY3HVXlsjwqvNG9kdl_HW@h57{Aw7rCz~5&HkZ7vRps!g-CjLS7z<^_C#zU; zR9J}1@ET=Jqq@*>~&i=7BsuV=4K#U&HssPhY5jMtTHZcp^q&*i$o3E{YtkXpdv{R#nOjbTD)JtVnm8up+ z8?4r*+S<0p#!k1pzo*CN^AR8x2h4g3?4-(CV^toOzF$@|Q0N%6w)*TnqfLY3y<i0GI)=1KL(7f$0I8&R23JaRaH0)*@RHN z6n4qrHaXOzWDVxW6KWb!%_JIN!Yw5_-*%4$ffFMim5*0}O+a>b9EfA!UXQqLz zp>wjx!8Bu50ZCRwwEqkOyZ6i{Cn=U}MLK0DJSKGBoaH{^833l7$WB|3x4ix9_Y`j* zrAKZ4i0E3E7qYi*r1QqS{hGxBE&G+TtNvkmb!pwMU3p&aH|q@B_xiCF zw~x_Ae_>sjRkveK5ig^zeCys|_AK`38TtNmztV=SbB6m4n7aCW;=3)*?bjMY7S%t$ zVb({TD`ot+B`#~wpU=Mf_bVp-JKb@dz2A99x;e1XXS+j(y7pf2{?gDi=a=TPxF}QP%980( zxv#%;OL2Qkvq#b={Kpo-&FeiUnlAj|LwogyKIF8@Hn(uzX9bQOw~tMKf8B=uH_n@H z+!)c%m^tHZ=W%_`dF*4>f^pRziap~U_D#< z1?Y1|&5P>GxVf>K>OPhr{wMR9)T+W!$`^@?XeV2i&*;1H=l)H1^1okoE#zX^@aZ$y zP57AR;t%ZcuxYf5+lLRw%rtvG+5Kx!k>hp6$#KxoGn2QUD&KV2dlJqrFSxq>c|~~S z#jkz{spz~=x_bSA6_xs*wm++z-Rs==!m||{cPykoGXw>P?o4$)UlDsDtfKcFAYFE~ z)l&J^l4)^-?vsVPW)977K7n^-pFVK$H73D2w(4NPz*wz-`_Gf>7ap4PM&kY}`xYht zQL(HoE6$LzLyPS1POU%pIe+f$nXEnbyqtzNzKObUqr*Y@; z&)FII9g+<7=eN8|tdh$c=WdGGw`^O-(D1g7 z_U1qRyxPl*&qfYjeKT)QYVphqMa|E3y_rFE|0cz+eH^~+%i$YjJ%jA@C27YOuHN)N DmYIo7 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_3_5.png b/resources/g2/track/bm/medium_half_loop_right_3_5.png new file mode 100644 index 0000000000000000000000000000000000000000..f130b6a5bb8ab5f1129fd50811f28423e9af64fc GIT binary patch literal 5269 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 QSZ*NAT9o-##!IjK2TMH-NB{r; literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_4_2.png b/resources/g2/track/bm/medium_half_loop_right_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..7e824fab687d0caa0f9e3d610d91b83ebd9022fc GIT binary patch literal 5533 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_4_3.png b/resources/g2/track/bm/medium_half_loop_right_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..feea7cff214b0066e1d39934c1b07ff4a95c689d GIT binary patch literal 5782 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_4_5.png b/resources/g2/track/bm/medium_half_loop_right_4_5.png new file mode 100644 index 0000000000000000000000000000000000000000..012cfc0e848f6359722c195a7d43c40ee1ec8837 GIT binary patch literal 5226 zcmeHLe^3)w9)J9hAgHm2iap8^!?o0gut_$sBoLzw7%*ZuLX8%CaoKEQ3}It75Cm;( z@kE=Rv85bWz~OAPv?AqN#!{QwRHM=kJ>wnqXqzgXVoR+psb!|rvF+YVK*hPv+&FXn z&&+Oi_r1^e^L^jX_xpX5&7RUV%DD-@O#lGQEiNi3gV$VmE{czV-!J^!yBS_i)|aod zm*EbM)kYaiRV2s0)k<>6I+Fo_x{ocT74!U@IoAVAYh%CLv1{~POR@LFUSI6LUasof zIXg$RKvghlk?`cJ@R6k zOt}1fX8Qi!u46wQUR+l=UlG6jor9-V%bs8V{z-b<1^>XX_rbt-%O=OZ)FwO-vyHpu z>C3wc-&&FHHC^tQ+~Yrzx%AZ7sie5a_Wkh8mDdKT4%NKGe6&hGG;s>AeD#CVw&cFo z4*VuCU%B8B&$cCFubtfL>U*@O?|a#`M8z!2{r;LZPtnHN#RoYLuS{K7jxSl&z4EC& z;%^3IKc?@M7iK-bVWGg5`M0=*&yKQ~#*qtcr!OzXmM&n`>#D93bK<{_?%8E=rUh%S z#C|J}(LOq$Ge^^%2QlfRm*N+H7?<@*UfWx&4dcMCep6qx_fpr=1+I6l-@9G&yTxzK zdeU4?eY3q|8Cd_-=4)}exv^(d&mAAXI{xZ zoF&c@@C)lqwIc4a1Wvw9Z;+N1temERPcrT%yWJ{95QoE&8t5!6`&qS z9d1R0SpvjjL1tRe_QG07GQFT*w4lpjlOkm#P1V>4vapt{wx`de&=WW9tu?l)NH}@| zA*)CWgwoKf@HUsq;*!#v7GVjDCW|#<1;xG%X*U^eiFMoB!ZVR@W-bJp-{idweIxb= z7@|r_qy-dF6JB0%fs7mWFV$0oNiU7u8YGpZB!?jRVzCJ0i*vHG`4SWp^U)lMP?9ak zHRR~Y8C1p9v>mS|$S@To&oV(Ci9jsEB{<5j6o?7FSd^Q~$1zgC7wJ)B5fhXiK!51yq45Q)(N?$rie{=wULDT z$8^Eo7&rYwF$gh(Fb78s{7MoP^2K@)%Etu)2|pWyITRX%gc#4cot>r(b_Z@FR~Vs= zP%BuV5v@26PN!<=?Rdu~GMon}8D9vC?3QF)WI9+Rykp#mHXr#fJ@O-f8Cwjrn;L^# z7u*Svn_JeYFD^kBd>GU`$ASlYZqN|o%?rn!lXP8#iNRQOu8gS}L6plK}VnGE@rDL}^q z4mogZSX~s$=VA|cB~1*bFk=Wap<}MQ8OEOufEoZDi$$^7&Xg2)MusOZuTQNWFdB!Q z&MTdrjL(;XCZ)@h5p`OgE<;K2v`&<8=h5wo#%@)!SK}Gf^#_e?V~>JK>m!REkN*T|%gEeA;&kZc5L4IsnK!a9?cy%`lgITg^lMrcpS?PvPb zyd(lkaVU8%ZC)3l@Y0$+B5l_m2z>g+d_)q);HEm4$Y(72XuhAkR3WXd12Xj5)j^_s~S|*!AH_CXvTxW68$r^fH%>!M%L4ROkL=JQ+7Oi1Bb!l!huf0Lu-K6oh8wa|b!@l;h zVgJO$6-Ew#762LmHvruL3;;070t`IV3Z{W(x;;#ASe*eV6g100zY+x1fYAVkN@iRr z<54sHW@fO733@;{@fc7kfL6^i6Uj~oui35a@(^BcV<6ByHWpx@uM{Id8xrO2WVI(v z*PlTJ^W33|?g@u?vUTu!{|GZ2%18oO8cT_=E97Zr4ccH-xt(TDv(ww%9PoFK1^vv# z2&Pgo{eTGqhJm?gg6^h{l*Wek(NV0ub?Tr82Ne|+8nc;bXrNG}5kp$#Xtx6OsgNNx zZ%muc=+YQx2Gfo*{c5w6u)B zxRJPU|M729w7yqY)gyh5?ztzFt25tpUp;b2?kf6yX#Zm5A1#Z^q)9!s+s1dWemu6Q zzh~hPc29Bc2O*7LhGj0=bI*?Qw>SQ?VOK}l+QUK9(d|z~?fdD8*0YV9_ofEgE5G_f ze_d*Oi2do6C2O93;o3{=r&b-0E=l^UdbL+)DyZtRjz^VNoyyOMOV_S3e|qC;{U4X8UcayK4d#V!FYIHq)$ literal 0 HcmV?d00001 diff --git a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp index 424a3d0fe5..21ca359236 100644 --- a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp @@ -15029,6 +15029,422 @@ static void TwisterRCTrackRightLargeCorkscrewDown( session, ride, 5 - trackSequence, (direction - 1) & 3, height, trackElement, supportType); } +static void TwisterRCTrackLeftMediumHalfLoopUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 5)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 10)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 15)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); + + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 1)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 6)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 40)), + { 0, 0, height }, { { 0, 31, height }, { 0, 32, 64 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 11)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 41)), + { 0, 0, height }, { { 0, 32, height }, { 32, 0, 64 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 16)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::topCorner), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 2)), + { 0, 0, height }, { { 0, 0, height + 2 }, { 32, 32, 0 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopLeftSide, 14, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 7)), + { 0, 0, height }, { { 29, 0, height }, { 1, 32, 96 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopRightSide, 16, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 12)), + { 0, 0, height }, { { 31, 0, height }, { 1, 32, 96 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomRightSide, 18, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 17)), + { 0, 0, height }, { { 0, 0, height }, { 32, 32, 0 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomLeftSide, 14, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::centre, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 144); + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 3), + { 0, 0, height }, { { 2, 0, height }, { 1, 32, 160 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 8), + { 0, 0, height }, { { 0, 0, height + 140 }, { 32, 32, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 13), + { 0, 0, height }, { { 29, 0, height }, { 1, 32, 160 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 18), + { 0, 0, height }, { { 0, 0, height }, { 1, 32, 160 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::bottomRightSide, PaintSegment::centre, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 144); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 4)), + { 0, 0, height }, { { 0, 2, height + 48 }, { 32, 32, 1 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 9)), + { 0, 0, height }, { { 0, 2, height + 48 }, { 32, 32, 1 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 14)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 19)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + break; + } + + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomCorner, PaintSegment::bottomRightSide, PaintSegment::rightCorner), + direction), + 0xFFFF, 0); + + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height + 16, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + } +} + +static void TwisterRCTrackRightMediumHalfLoopUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 20)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 25)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 30)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 35)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); + + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 21)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 26)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 42)), + { 0, 0, height }, { { 0, 32, height }, { 32, 0, 64 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 31)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 43)), + { 0, 0, height }, { { 0, 31, height }, { 0, 32, 64 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 36)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topRightSide, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomCorner, PaintSegment::bottomRightSide, PaintSegment::rightCorner), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 22)), + { 0, 0, height }, { { 0, 0, height }, { 32, 32, 0 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomRightSide, 14, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 27)), + { 0, 0, height }, { { 30, 16, height }, { 0, 32, 96 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomLeftSide, 18, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 32)), + { 0, 0, height }, { { 29, 0, height }, { 0, 32, 96 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopLeftSide, 16, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 37)), + { 0, 0, height }, { { 0, 0, height + 2 }, { 32, 32, 0 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopRightSide, 14, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::bottomRightSide, PaintSegment::centre, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 144); + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 23), + { 0, 0, height }, { { 0, 0, height }, { 1, 32, 160 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 28), + { 0, 0, height }, { { 29, 16, height }, { 0, 16, 160 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 33), + { 0, 0, height }, { { 0, 0, height + 140 }, { 32, 32, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 38), + { 0, 0, height }, { { 2, 0, height }, { 1, 32, 160 } }); + break; + } + + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 144); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 24)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 29)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 34)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 39)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + break; + } + + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::topCorner), + direction), + 0xFFFF, 0); + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height + 16, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + } +} + +static void TwisterRCTrackLeftMediumHalfLoopDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackRightMediumHalfLoopUp(session, ride, 4 - trackSequence, direction, height, trackElement, supportType); +} + +static void TwisterRCTrackRightMediumHalfLoopDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackLeftMediumHalfLoopUp(session, ride, 4 - trackSequence, direction, height, trackElement, supportType); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trackType) { switch (trackType) @@ -15426,6 +15842,16 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trac case TrackElemType::RightLargeCorkscrewDown: return TwisterRCTrackRightLargeCorkscrewDown; + // Medium half loops + case TrackElemType::LeftMediumHalfLoopUp: + return TwisterRCTrackLeftMediumHalfLoopUp; + case TrackElemType::RightMediumHalfLoopUp: + return TwisterRCTrackRightMediumHalfLoopUp; + case TrackElemType::LeftMediumHalfLoopDown: + return TwisterRCTrackLeftMediumHalfLoopDown; + case TrackElemType::RightMediumHalfLoopDown: + return TwisterRCTrackRightMediumHalfLoopDown; + default: return nullptr; } diff --git a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h index 81a60da118..444e95d258 100644 --- a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor TwisterRollerCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Tubes, - .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::corkscrewLarge}, + .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::corkscrewLarge, TrackGroup::halfLoopMedium}, .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop}, }), .InvertedTrackPaintFunctions = {}, diff --git a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h index 1ece6430ff..10759179c9 100644 --- a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h +++ b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor VerticalDropCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Boxed, - .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes}, + .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::halfLoopMedium}, .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist}, }), .InvertedTrackPaintFunctions = {}, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 35129f442c..c01bc94fd8 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1287,7 +1287,8 @@ enum : ImageIndex SPR_G2_BM_BOOSTER_NE_SW = SPR_G2_BM_DIAG_BRAKES + 6, SPR_G2_BM_BOOSTER_NW_SE, SPR_G2_BM_TRACK_LARGE_CORKSCREW, - SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_LARGE_CORKSCREW + 40, + SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP = SPR_G2_BM_TRACK_LARGE_CORKSCREW + 40, + SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 44, SPR_G2_MINIATURE_RAILWAY_BEGIN = SPR_G2_BM_RC_END, SPR_G2_MINIATURE_RAILWAY_QUARTER_TURN_3_TILES_SW_SE_PART_3 = SPR_G2_MINIATURE_RAILWAY_BEGIN, From 95bc00d7f937f4809f66e6011e65750773b670ea Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 24 Oct 2024 02:20:56 +0100 Subject: [PATCH 014/139] Add large sloped turns to Twister, Hyper Twister and Vertical Drop RC --- resources/g2/sprites.json | 384 ++++++++++ .../large_turn_left_to_diag_gentle_up_1_1.png | Bin 0 -> 1284 bytes .../large_turn_left_to_diag_gentle_up_1_2.png | Bin 0 -> 1227 bytes .../large_turn_left_to_diag_gentle_up_1_3.png | Bin 0 -> 1016 bytes .../large_turn_left_to_diag_gentle_up_1_4.png | Bin 0 -> 1182 bytes .../large_turn_left_to_diag_gentle_up_2_1.png | Bin 0 -> 5181 bytes .../large_turn_left_to_diag_gentle_up_2_2.png | Bin 0 -> 5137 bytes .../large_turn_left_to_diag_gentle_up_2_3.png | Bin 0 -> 1016 bytes .../large_turn_left_to_diag_gentle_up_2_4.png | Bin 0 -> 1069 bytes .../large_turn_left_to_diag_gentle_up_3_1.png | Bin 0 -> 1024 bytes .../large_turn_left_to_diag_gentle_up_3_2.png | Bin 0 -> 997 bytes .../large_turn_left_to_diag_gentle_up_3_3.png | Bin 0 -> 5108 bytes .../large_turn_left_to_diag_gentle_up_3_4.png | Bin 0 -> 1017 bytes .../large_turn_left_to_diag_gentle_up_4_1.png | Bin 0 -> 1288 bytes .../large_turn_left_to_diag_gentle_up_4_2.png | Bin 0 -> 1220 bytes .../large_turn_left_to_diag_gentle_up_4_3.png | Bin 0 -> 974 bytes .../large_turn_left_to_diag_gentle_up_4_4.png | Bin 0 -> 1128 bytes ..._turn_left_to_orthogonal_gentle_up_1_1.png | Bin 0 -> 1108 bytes ..._turn_left_to_orthogonal_gentle_up_1_2.png | Bin 0 -> 860 bytes ..._turn_left_to_orthogonal_gentle_up_1_3.png | Bin 0 -> 1181 bytes ..._turn_left_to_orthogonal_gentle_up_1_4.png | Bin 0 -> 1300 bytes ..._turn_left_to_orthogonal_gentle_up_2_1.png | Bin 0 -> 891 bytes ..._turn_left_to_orthogonal_gentle_up_2_2.png | Bin 0 -> 860 bytes ..._turn_left_to_orthogonal_gentle_up_2_3.png | Bin 0 -> 992 bytes ..._turn_left_to_orthogonal_gentle_up_2_4.png | Bin 0 -> 1112 bytes ..._turn_left_to_orthogonal_gentle_up_3_1.png | Bin 0 -> 1147 bytes ..._turn_left_to_orthogonal_gentle_up_3_2.png | Bin 0 -> 860 bytes ..._turn_left_to_orthogonal_gentle_up_3_3.png | Bin 0 -> 1197 bytes ..._turn_left_to_orthogonal_gentle_up_3_4.png | Bin 0 -> 1198 bytes ..._turn_left_to_orthogonal_gentle_up_4_1.png | Bin 0 -> 1088 bytes ..._turn_left_to_orthogonal_gentle_up_4_2.png | Bin 0 -> 860 bytes ..._turn_left_to_orthogonal_gentle_up_4_3.png | Bin 0 -> 1310 bytes ..._turn_left_to_orthogonal_gentle_up_4_4.png | Bin 0 -> 1367 bytes ...large_turn_right_to_diag_gentle_up_1_1.png | Bin 0 -> 1298 bytes ...large_turn_right_to_diag_gentle_up_1_2.png | Bin 0 -> 1171 bytes ...large_turn_right_to_diag_gentle_up_1_3.png | Bin 0 -> 960 bytes ...large_turn_right_to_diag_gentle_up_1_4.png | Bin 0 -> 1100 bytes ...large_turn_right_to_diag_gentle_up_2_1.png | Bin 0 -> 990 bytes ...large_turn_right_to_diag_gentle_up_2_2.png | Bin 0 -> 980 bytes ...large_turn_right_to_diag_gentle_up_2_3.png | Bin 0 -> 5086 bytes ...large_turn_right_to_diag_gentle_up_2_4.png | Bin 0 -> 1006 bytes ...large_turn_right_to_diag_gentle_up_3_1.png | Bin 0 -> 5225 bytes ...large_turn_right_to_diag_gentle_up_3_2.png | Bin 0 -> 5183 bytes ...large_turn_right_to_diag_gentle_up_3_3.png | Bin 0 -> 1059 bytes ...large_turn_right_to_diag_gentle_up_3_4.png | Bin 0 -> 1138 bytes ...large_turn_right_to_diag_gentle_up_4_1.png | Bin 0 -> 1267 bytes ...large_turn_right_to_diag_gentle_up_4_2.png | Bin 0 -> 1268 bytes ...large_turn_right_to_diag_gentle_up_4_3.png | Bin 0 -> 1014 bytes ...large_turn_right_to_diag_gentle_up_4_4.png | Bin 0 -> 1170 bytes ...turn_right_to_orthogonal_gentle_up_1_1.png | Bin 0 -> 1059 bytes ...turn_right_to_orthogonal_gentle_up_1_2.png | Bin 0 -> 860 bytes ...turn_right_to_orthogonal_gentle_up_1_3.png | Bin 0 -> 1122 bytes ...turn_right_to_orthogonal_gentle_up_1_4.png | Bin 0 -> 1141 bytes ...turn_right_to_orthogonal_gentle_up_2_1.png | Bin 0 -> 891 bytes ...turn_right_to_orthogonal_gentle_up_2_2.png | Bin 0 -> 860 bytes ...turn_right_to_orthogonal_gentle_up_2_3.png | Bin 0 -> 1032 bytes ...turn_right_to_orthogonal_gentle_up_2_4.png | Bin 0 -> 1112 bytes ...turn_right_to_orthogonal_gentle_up_3_1.png | Bin 0 -> 1147 bytes ...turn_right_to_orthogonal_gentle_up_3_2.png | Bin 0 -> 860 bytes ...turn_right_to_orthogonal_gentle_up_3_3.png | Bin 0 -> 1236 bytes ...turn_right_to_orthogonal_gentle_up_3_4.png | Bin 0 -> 1302 bytes ...turn_right_to_orthogonal_gentle_up_4_1.png | Bin 0 -> 1088 bytes ...turn_right_to_orthogonal_gentle_up_4_2.png | Bin 0 -> 860 bytes ...turn_right_to_orthogonal_gentle_up_4_3.png | Bin 0 -> 1307 bytes ...turn_right_to_orthogonal_gentle_up_4_4.png | Bin 0 -> 1378 bytes .../track/coaster/TwisterRollerCoaster.cpp | 710 ++++++++++++++++++ src/openrct2/ride/rtd/coaster/HyperTwister.h | 2 +- .../ride/rtd/coaster/TwisterRollerCoaster.h | 2 +- .../ride/rtd/coaster/VerticalDropCoaster.h | 2 +- src/openrct2/sprites.h | 3 +- 70 files changed, 1099 insertions(+), 4 deletions(-) create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_4.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_4.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index d00ce327e2..561997ab11 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -6535,6 +6535,390 @@ "x": -25, "y": -5 }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_1_1.png", + "x": -26, + "y": -22, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_1_2.png", + "x": -32, + "y": -24, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_1_3.png", + "x": 8, + "y": 8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_1_4.png", + "x": -18, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_2_1.png", + "x": -27, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_2_2.png", + "x": -16, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_2_3.png", + "x": -24, + "y": 12, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_2_4.png", + "x": -32, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_3_1.png", + "x": -6, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_3_2.png", + "x": 6, + "y": -5, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_3_3.png", + "x": -32, + "y": -2, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_3_4.png", + "x": -12, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_4_1.png", + "x": -27, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_4_2.png", + "x": -27, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_4_3.png", + "x": 0, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_diag_gentle_up_4_4.png", + "x": 0, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_1_1.png", + "x": -26, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_1_2.png", + "x": -19, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_1_3.png", + "x": -13, + "y": -18, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_1_4.png", + "x": -32, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_2_1.png", + "x": -27, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_2_2.png", + "x": -34, + "y": -5, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_2_3.png", + "x": -2, + "y": -2, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_2_4.png", + "x": -14, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_3_1.png", + "x": -16, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_3_2.png", + "x": -8, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_3_3.png", + "x": 0, + "y": 13, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_3_4.png", + "x": 0, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_4_1.png", + "x": -17, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_4_2.png", + "x": -8, + "y": -24, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_4_3.png", + "x": -32, + "y": 8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_diag_gentle_up_4_4.png", + "x": -13, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_1_1.png", + "x": 0, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_1_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_1_3.png", + "x": -32, + "y": -18, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_1_4.png", + "x": -32, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_2_1.png", + "x": -12, + "y": 7, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_2_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_2_3.png", + "x": -10, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_2_4.png", + "x": -19, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_3_1.png", + "x": -32, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_3_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_3_3.png", + "x": -19, + "y": -3, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_3_4.png", + "x": -24, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_4_1.png", + "x": -14, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_4_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_4_3.png", + "x": -25, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_to_orthogonal_gentle_up_4_4.png", + "x": -24, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_1_1.png", + "x": 0, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_1_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_1_3.png", + "x": -32, + "y": -3, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_1_4.png", + "x": -32, + "y": -5, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_2_1.png", + "x": 5, + "y": 7, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_2_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_2_3.png", + "x": -16, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_2_4.png", + "x": -24, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_3_1.png", + "x": -32, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_3_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_3_3.png", + "x": -13, + "y": -18, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_3_4.png", + "x": -24, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_4_1.png", + "x": -13, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_4_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_4_3.png", + "x": -11, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_to_orthogonal_gentle_up_4_4.png", + "x": -28, + "y": -20, + "palette": "keep" + }, { "path": "track/bm/large_corkscrew_left_1_1.png", "x": -24, diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_1.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..bea103aeee6a0eb5799bcccb93d54ee092ccab9e GIT binary patch literal 1284 zcmXAoeQXnT7{`Bm?OuQa70amDk#6Z&g+gxeLMoo4C1sRwV>hfxB~?ynW`$F3(zp&T zdV^-vb zx|=teXICt$007KxT4!p>*ZO>{C@ae6=H`Wm0Vo2^8(P=q$AW@_!otF$qN3vB;*ye* z($Z3yOjcG_R$gAN)MzvaqBj~bg0PUJjixDStZI(b25DrFHOBqcWRwy|JQ*>RlM-eX zuQ?j^Mo(e0nNfpfKVb%_3I0zFO0B`{8G8rY8Gb$CQ)rJg)K^z}(I8qGr zAQ*)4xC&8dFr^+>8|+#$rL!^!$rMB&u?mbzZ9> zOd4Y}A+Ti1Pmf1fDelh+5jdWZD^RV@il7e6=pqO&Nd{c5sMi}01_ho^kB&-`1c8bI zTE7el%Z)J=k<>ZTM$fn{lySu*ZZsRs%%pO#QYV+AN~Kw?A#{4uV4y9y$DUv2j(U9~ z;i#ApvS|$1Ei#&rGj=uS)CJsF#6!daj*$qHiU%^OL^k^XVgOhHpaI|jhyXAGz_<*+ zyl^9Q(=ZZ(VhYy+3IRS0@Ma+501^OFO6Wyk2#35ACOuFLfv4b6U@-zKE_0Gf#-;Od z=5UCN#aKazWHJKGd#M}%aaUrT5)Y~Eyp|FToMek+U9p@$Im4%6O42F-s+O7cavP?0 z5{TPj;TUJg$HXE&ArZ-l37Acz77OG76aj>J7M{G_GpSg2V0;`6_@9YRCXF^5;dGL2 zH-+d~RPV=-h!Kff^rN^gW7R;r8ZufKKp>An!ID3IbXn!p(;sMW*+_ub?%vp*?+2Pp zjjijtdk)(M*y_2aTku-{rW5_9+fV*1?K)PtVEDU<>zCWnM8mD)cm4_9J^1#nZJ~(` zci!Lh>VduAPOx?JcD?wXP_uZa(E6l-nmqmYxnJ}_=SRNgr3Li^ z9<*v`-xqs7+dX-HUd6pmYwcKg!;wpC>23A={;rPR`0lwl|l ze01qDajk0g1yujStlD3f)L36`=v_Q@^UA`O?~k;vo^SK-6?bcV}60`H;_j9O=DZFjTCs9hFafB@9_6k~6BC&mDRvC$%*e z7^Lz&nsfDiA9v)|pYPfdSUKOkR2o_Ld3Y5pc*C^6qqU`dZXP9QTD#HIzvit^{s;cI BK^*`9 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_2.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..bc65d9bd7b93c1a5ac5e22c47734f419def8f8fb GIT binary patch literal 1227 zcmXAoeQXnT7{`Bmz3z>=l~_ZCGghhbAY~q*n8O@;n`Io?4Q|qff(0(DV$n04Sg^VS znpkH;PA#FsDm8XevXfO9cnKvmSYSef2Q;pli)*mBN+48HV@WXlEFt+mZ~r{sKR(Yh z+}CSwYo5~#0BGx3(Y2;p=T~EquCAI_Zo4-JfI85(s=vEB*3{J0*4Eb5)z#P6H#9Uf zHZ~#%qSNV`nwpGevl+*&6h*Qu&2dga;QfAoI2=tRlyo|)X{B-*w*ry?4Bg^%8ay7< z>$3)eL^#646Ru=R$f&`5Ax2?{gJ|Jtqv${-&Jq>y2|twzJ2DAgn+z1SSf!MXa}xDbTb>qV1EvRGmSF~KmCZg)-;Z$+ap zl``Q5GikIkDB-f$dCVc=oJ0r_$}iKQBpb`P6wQs=Ojf&@U@@ArIeCf?FoCEms_=>` zrnQh-jOQyUJqZjfFuDQi0~QIfMUD1^#hD^`)e+1Kv67UA6AWhHY$mTA3p$86MewfP>}tlRJfwbu#napY!=Lc+uS7OW!WIdMZDfbFqn!)RYl2Xv!zlA0uv7`VFZus zsicX`VD3B>C^%z9Z?Yt1%ZcLsTm`mZdcDnPw4-JgvvLF>&`iKpUFJ&!LzD4@mR8Go z61ZqYVD+L4l{{F)N6G;<8F5d_VlEXa=F;WzEl2|306+jh0zd{}5`Y2%U{wqSeFBtY zP|GnEz~dl90>utA20#`--Ux#@j4@F0z)S#YG4K$)4bT*DFo=gUie4-v+2b)Tne?lw zTr8@v>Sb~R+}A=%Mka>36br8rQpqWoy~#>Ab6?5BT*+bpHWaa2^-dD?u(;1nOQI(h z5|eUBP0K|s4a<2OO+y7h4M13B5vbZdlF9Fj6biOT_>qK6hH^StkB9U5c--o@S;HhQ zQ+SHDW*MyLFhds#MGK7JP$8j8SC8Meu;uQ{5n|eclC6=+`n|+(fvIK z(oeN^?SS%&OGd6gGkC(buu)(0;O)0BHZJ<-y(7il%0U0M_HAzfaB=ecEjp}m`9v1(AKvm+WpI4& zsoJT}w$JJuxKuME{C#=-$ocx6&mNxlQfy?r<6hr&y>aOG%|lNge`4dNkLT*fJ`hJ2 z^md;)GTc1qy)jD+Uhev7Xm&52G0Cujvp9#N8g!yJh=73($`*C(s!c6 z{AKdf&of)sMb3Rv8g4#y@Ui01;o0Xd#cS5D8tK^kpgG&Vc3Inh+yAJ!u=UQ^yoF<1 z@H>m!?tJ~`TQ~eGMi+OMmARuo4^1`ThmE(txzhUYsrB;?tzLKV?ze*>_fF_?nhAQk s6va+1NN?*uE#4I6sk29s=*&$Nz1q2K{)foUDiP4r-P<+(%ErC_1I*AHqW}N^ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_3.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9e33894d4d557dc5ee7a85d92e23f59ca139986c GIT binary patch literal 1016 zcmX9-QHa}g82|2icj?_RtJgt?RU=f$Lm0V{hrmUMXYS~ZjLWf1Dn!jNV@3Orhj{j( zJ2F?XXoV=9RMv;e0u~I~V<&`BAwni)*M~5QR0*T7qESv)M%6=4`I|BLec#9L<@^2M z_kHhgZDx-xJh=b>$2Lx{osH&+s2-2UqR##!wg6(Vb>`f9M5m^vrl+T4vDnPa%=_P^@iALD;-zw`PJdb;z=yWE^0!`$l<0+GmPaMj?eJ3OX_o@-hG-fP!IKB4MP{CP7#%yC;g>e12dU2hApO-87xd za4AZ}S%t`IWX_;flhqr1*%oRY$?7RikjI%cmCdjcDX5IB@mfW!G?k{KIlkcqH9u?( z58VU@NeNPUz)L`w7}HE;+l1_LnxCrm$27 zcI$_}jYeJ~$q;0YX7U_gl%%SvHj2e|wdyvTzT*u0{qcB=AguvW$LLmq@1&(3nIH0% zk!*#<&e-fv+TqdQ5G|641d~c-@r*=LD$DAESW%*7rFON}ZM6f>pA0!r1WcC_hJu>~ zvQgsfiqvW3yS6cK8{xp4Ob!qSkOR;GOaL383oya}MG$#Z(vfYUU?38p(NN>S$wD9k zk^pHbRHcz6BBy|Q6%<(TFn9(89&#d9P*X;cteM%CrFJ@H-?ziiN0C-K4|HjfGgG34 zD-NLrtT~qLNwITS?;SZqG#C>}U~nu;C1egSNOUPLm`1^>86CUkdv+LjXfk930XcvI zKq$(h63IP6x?F0EMogpr2zsx_%d%7`sHKudQ)Py#bF|IVu0ZugGR$R=f+K@K4H`Kd z@`dR5nUjkT9{#{vXE!By;pZPNM&$F2wbgScK6zuUGg^Vg5AeY*Ai>=%E&hu40QudQ5q^UK7qm!B!@+_<^C7Jq)~ z_q!LiFU;TT6Cb^^Exxw7^4$mbZ~yf2+AEcn?Pb}wz2A~wtFK;~GMvBeuG|QJj2y$p M`sUhKFP^{hKgf)=Bme*a literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_4.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..a77bddedef39de7a2ab169a3394815ae4fda095f GIT binary patch literal 1182 zcmX9-Z)_8F7=HJU+t{!l8q(+iH?5;AMK5rKgEVmBZ7a*o9q!N?FXS*MR#Na159y$R z8Y(H!;03BSQlLTu{cw&(7gM!rqm?w!nNu5AwaMzzguWWHOb_7D}aBy-tz9IDqFmMbYf> z5MCb{3^^iEK9Q8t88vT&%9S{4$6St1g|qlwgeKc!Dm5NpGZ9xlsg!cTYAHTn%Q|t8 z?BHcU6R?DWWkRN6!d%bes7j)`gcdY}vQ_{dK*BJ^Wb)&N6F znG8;ut&D}_35R5JDt4Ejk~N1KWdk}FP7Cq8lq$Ii8Yi7rhhXPqT2xpi$OmImETyCj zf3_4hs)_P^#>9YG0E-(4AJ{aEj#->Zo0wq~!xbv4@tT%JT^<;ISIFCB*CKGM3I0>s@CuN62<@lh~SmsNH!ns7Ulr`#Q z1|$ws1(RPQG><*%WAvbqj=FQYznF~H=YKL1s9KbWQ*Tx4{OduTu!G0hM`xh z25NBOZlHXfjAr5Egp{%=C5KiM^}07bAIUGI%BWbgnSmxSCutHH!Xr>VH>deM@vuLw zhmEXWEoD)?OmiGc0V)AP4KIQXx(C1mzG$UFMg33l)8BTt z&mlhg_(1%?wPPo)y|m@(n(^nv{G*pYZ#y$^X~X)8>#yalug&lW|0BP=eY|(_O=+FA zN!B(7(Xy$Y-V5d(Cx88WYCyc$d*$q^f0yn(IyDwJRy<_sn;6?PG&j8+w)O~*-+&`4 zx7`f9`?c-J!CQ+*zS!^n=dI_L&g^X6fAE)c53kctESg{kqiu&ZUWO5|dxe t(Nm{;@tyO-UCbMBxbnx6(DdFJV&99_C$EkXg@(v5*gxEN<>{SA{s#sl3B~{b literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_1.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..68f84e87876a5ff8fb989cdc79a25c4956bd5326 GIT binary patch literal 5181 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 PAkeB;mmFHT;fenOFWZv@ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ea21ab3fc48c50bf513086d59c8072a8e866be2b GIT binary patch literal 5137 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_1.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b46205e74eab1f3b08438d8e723492afcb5a08a0 GIT binary patch literal 1024 zcmX9-QD_@=82{R|y>?v}CDR)_XNEy<<8XO6#v%7`U9Tn9lV06bg5=?f2c9m-AtwZh za@eqi8SpI8#hF5e$H>Fs;;48^#8i*AV9>+$A!CPRG-w_s91^7uE&Y3A@cX`x-^=&= z!SDO7E-s{|j+{IK08{fX&Rz`X>9Atsk+5&Qgf;;pu=w)QTu6t8hK7fSBaz6+$jIpE z=-Aj8hGFC5;}a7Tcp{OY=_Jo{k|ZcfM%T4Mp-`#R8V$#FcYHq>4Co|qEQrEnCKJnM zGcBNs-)Wu&EGEeeQPgpQv}Eq z({$`ttbaE32+tSc_2-Uso|*xnQ3vFmo9a6D==NOE>batA#y3IlxFJ+-_#|qpmZvF z&n^V5%ARMVo*RuZB$cKamE&`gR8o{`F4riPTD6+zINhC{AP5i;8jux?u1EPMA+;&B z%NKhYtDkEI=FXte-|y_9Nh%s;a6A=HNK{f`SzQo|a=0wtD3!PC4d3+!T@GXc)1{~( z$IUEN&2x59YF5>4+vv2a{f;{rJU|>k8bAjy0c?P6fF1@Ygvg`3j%*A09gzf$hB60E z3Vace1W3bCiAI))oGfY=k#E7n;298jNQ+oj!HpbMHdA#=X*LUyS z;-VFo9a8gIGsxJ3Tyw9|-gmmF6Ob`r;#evf&2aIoMCVn(G_qFNXxe4Zwfnw{23LseU?vP_y0>BZwWei@(m8dDzI-TLXmQJ0D{3g7={LFK~_1hay&AdJL-?@X8d`*0Bb$aBxmCDTdbGrwBzO{V#RqDgT bfA=C!yn-KWT)KNDbPn@#3$wRomRJ4<)Udh^ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_2.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..015b44d34a2090ff4ddb7c2d59cb44a18231ca59 GIT binary patch literal 997 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_4.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef94b94514b4f5ccffebe9883f8d05734a258e3 GIT binary patch literal 1017 zcmX9-e~8<36n}TUUhc=X3Y|n&rLv0Ai(WXQ2F)MQ@adw4$L1FBSx&Q2XQM~g$xUpS#W64P7ge|uNi~SdymgQ@AHAr zd+!`tPVSu9GXnrSm!4Z(3Fe-l?w$$-UHx{~!vG;TbnwXjfR2rgjgOCqLZOL?iEubP zIXQ`8*wob2^z<~INF->Q;(1Pz1Vu?}np!9nDwSHJVY_a}_lKhqO##P(D9onQ(QG!J z%TvV?Td9imhTL?twpZ%)O`gP3?5rx_dMa)xL`|dD3%pZFwHvD6Dh_;ebLb{xAd`^e zz>u)IiaDi7w;mm}V`xC3k&Lzsgxmyx2q0sa8j0w!m_ZOG%dU%JE0gK!`psGmIZlj@ zCODiDI% z-rIB{97H9+GZ4=MVPH%RPd13O!>L}X)YHtN;i7esj4Dhlmn2Imwyy9^P4Ws#x1#l} z!qBN~dKT)tktjouDVoV}d`^-|ic-zx8l{p`t9iEF>vV?0A%d6+LTaT0G7@2MJQ+_&B&D#dCWu8jSe9>;%B_0CcfC=M16jZ{DWc19 zBTH8EoK=*X)lAFMyH0h`bw{I{hyzFgXaEL)1<(TMV}JsPJj!dxGLhdE2~cS$b6_XI z7Xe9tR2-FPWQxenqIMDaCfp950fC2a5{SdxmQxp-Eh^BKX=vu0UuT4m3*2EL0%Jw_0a z4af(Cf-H)G+#SRU`D(w&*Q-CVu(_9iMw0|G2aL z$LYQAvd0hpcjd~(A2#OEdhz`BRXee8*m>i-^BeA(wR+~B-4DLCaNx1%3y;6_$g^L5 zzVXfONdL*RN8daVer@J5WS>7tKb86ZuDSVpFFX*w&->_!f4(?yZQ--p@7vdaT2zqaG=_iz2V?^M)y@zQE*{;TVpbN2MVAHEts_nxqJ^6R}HTwOVK1N-q> WckP1sIg)h&8XzihSltVTUW-x4t69BbaE!g=%9&5yh)W} z4lGh;qZiX+XR4G?q1NJxSy+jcRZ?LKl^ofW4v$b`7n-q|W)^JXke?+a-{cSr)Byk*+Bdd#mg|~wG|4K<`6hqy696i~*3H{Z<*}loV&1%Ym6erMRaMp1 z)ipIW2!hCDvfA2OrADJcQ9X`h6h$zMmE%~K%jNe6W3hNDH7-eoViDB?%m_%L-fC6Y z?P`Zp@Aeq|0Wut;6G<*Dda}6?u0t%wdX`Y~7PY`=gB&{O!jpbWI>t&P?z|K#6;fsu zpmo530f9ooERyudGhszBt%7+yEYfgJfH0*2fCPX>5LPbdRVqQN4H=DtBspTUWq5u% z7=+2B3RP$@rJht9X|0*nS$LEYj9dVBMG0?$3Z?0|WK$bddb7qz=?KPPWpUO`x`T8u z&c;PPC3(esI9p1}F`%G;(gxH{pcN29P-%{7tx1d(EuJhFDhMe!Na_@fLFF*(JQib^ z!4n)Mx|ocg%SBySIYOrCrgQ7eP6L2_U9#1kD6yx#i_;{gEfI!6p ztsgGCpX%;Oyi z$E1{4%wm8h5RQ`bv|6z10!}RIrV;_$NR-bc1NlsNOr)z3cpf!@vz3aq;~v8UV*wYRR{ zzOnCw&pPCKO=kKU-ZgXk z2xHUlv_;m!TW@UI;u(_$+9F3537Q9DUB=S1Z2OI2aQfECre$3di$|MUsxB2iZtm)y z@kN5`DgBARKl}36RrkYlr>^g8RL`zkv1#J;WXsVG)2R3LPX}l2RG)pM1Xj(e_%z@4eS7e9Vx=a}) z(fP}|(Z1TXnads5q{i-Jy*=C94@;L<^i&-;A(xnJWU6iX{N^vTUk#rBXCQxQ|E~Sl zcli3PyO$nc-t*J8vGiEPclYGr%Y9?dk2dYucV*w|A+2ZO@5O_+he8ea8uMGed1P6+ zwdbXptFHf~*1F~^JMR3;`${e7%fM$Kl&dn C2SmpJ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_2.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..9d1de1a741409c5c74e7aec57cb7fc76489dc1c8 GIT binary patch literal 1220 zcmXAoZ)_8F7{`BGyIs37yQG9BE1`sD9C$zt2Nu1=>$uGW4|ik-6zGdXYN)fwDTUQo z&B3ZETJg*(UbK-C4sEou%WO;av&Bq6+{P03JaEt5tM3BotK$Vv=P`!C*xcZ>7_) zP;lTj7io91PJ%~i0rQD?KqA5^DwbuEc}^+wsvdND9B$f0a2ONt_ytOcv+*>aRs~fP zi+WP4XR31rD+z2Ium^!N3Q!60r0sML^%qD%^ChZbr6CpJB#YSs9!G@65i( ziv=ojxR#AI3i6zmg|(v9=0PzZ?g^4qgyRx{Kq?Z+B@%^nT2s~P^mL=qfWRRDR7UWO zmC8G~G8U{-@tR+$NAeA6x|yrrt;|6SX0>|kcG~IUFn53;!VDYdTg#%kM6#60=|!zs zB>~SMVa_V@PAP3`Fu>% zvh}(KTV9SJz@rvYva^blS5ZMHq=rA+jO6F!@?EtGD-F~JJWhmmTm7Un#Np8(BZ(m; zDdw|Dt(dLrMcAx*7zU~U>HxwPi+IcKp&YSjs#f!)s_cV*ueJ;p5p@_m14pkCrOzZePD=oJl{J??XAr5$FF7Ije`!^2sZ&`Qr*j8pi zZ1KG7_vy*O`O?W#>mPsCw0-J}^C#c9WNsFHpI&+`OP3#Er|#`KJrXahwf@Z_S5_Xl z^5!eOy1A#gE3?hA=psG%Z?FB&j8atIA_k8*7meqJ=JtF)@7Q|>o9GF-RQY;Id6qRj z_cJkZ{`m5bms-3xX7!t2Egcm7`21@(%tybyKgwT$=;F|toP5k+&Qd1W1czGIo0>$#BY!Onx{Tn)ji+1@9@gsx3B-_=7o{P zJHI(=e2PfTd>BF!W#hy$;9GF@PI$%X{bxQfUhUu7E^o74SbI3Px^Jv!)Hvcb{j{3v z>+jBw%j4eJWyZZTzo;8N>Dl}0=nrSx=~JVjCk`B1buE5S+Ejk2k0}k0k^RCu`-5k8 zzaH0QY+>$r?`&r0BgTpAfBpCTj@gM$_r;IA^{#zWYx@mP+8#UCae8>*yLs?$RbQ6khO zVwJk|kVAKkY{ja9Es|x5j+#TkfH@SbYz}kiLJmC?w!**$?cf~7$}FV)*;g9701L47_Re~`&dtru&(AL`EG#ZAE-fuB zFE3*lmdRvRR#pndVv%8JLEsfd(zLQ+==FNtaXP)8ABKlBg;DKbWjlBOuon$ zXqn(tQq-xE#b`EXw1v7Swfc%XRQW}fV45TQxJP(IpFoE)EpabVu$EJrt%t#nPg_7 zL>`)ixjai!C5El=f~hD?O>3KGuh|Sboyhmchlfd$Ai#AX9gOMbgg&kesmfSrOv>)m z>?ii&tT#O!ouDk0%dv%mNE8){);P|P&G=h}lS&xFrsmbM;SKi}K?#C`3%{KMnwho9Zi zU!Q;J^X(sZoiA@*eD_y%^_zdb`0L4kk3V|xH}QvSw{Pud2z2x^dhbE;Rdam0YQ|S@ zXKwuY(_6=Pci&lE-Fvck{r3yq<9}aZzFL3(kNe->%-*~IOJb1U?sM7eHgT7>cP?Jo R{yNnG8|#~E`&Vy#`adzNp)mje literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_4.png b/resources/g2/track/bm/large_turn_left_to_diag_gentle_up_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..e305c400f237f96a86a9d649461c96816c02fcad GIT binary patch literal 1128 zcmX9-Z;aD)7=G^`z2lAyS#X3!228A%s{2rrLZ<0KkIYLi*Yk=rGNfn&iMOG|dyBq*kj65|w(XQ*;v9Y(So%>!Qt^jnw_~?%9?XjbyqqDQKtE;QKySt~S zXW6o47>4!s_V)Gl`GUb9Nro7P=6P0~%Dm&atri&qIt(1!AB}qB z@jxOON@v2kJXb7J!%8Z=m(gm?#%BHPW zoUGj}))y@g4PG96F$g39*D$K!iM`B;^x{QYK>+3btw1=jUD5Mc|hK&tYWI!<7Ae zm59}ubR()a6J=MMZw3d^O%_OfItlbtJ;oQmD5(;%{# z!h2LPpv8%Nk~Y$OIUk!d)S8uV)+(*m0-^x~00lq;FaYKN8W^B9I0hvZWa!ALaX82% zWN9!X;BbI=K(Y^INThSfjH7BAIXc`mo&uHufy3gGPfZY6EmG8_ayez&Mzd+7HkUsJ zWU`;ue4HK-OKUb*z@Q99`E!M^vdyXZbsMJyYj2}(Z3#f?&t<> zHa7j)=%uYsPb?VA?;IV(51(Ckdg=W`4_w}B9{6?Y^xrGaXRqH7)^7R7`(oVH&OP&^ zcHgWz{MyI(g~IH7ko<*L>U5;^g!D_YM7b_@cKt+cPk<;gGiO$nKAi m;jcd?4sG(j^3LGbH?iBvpLhRJn;dP+1tZ(XhR<)?d*pu^SL~Gl literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_1.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..9b8975170904721c510ea6bf2f27dba14e012105 GIT binary patch literal 1108 zcmX9-eP|nX7=HVaUO!gzN2Z}hNHO3kw-U#Rw{ebZcP(kTtyg-JFmEH`LF0&W!c8LN zj|0Pu61I~?2y0|=hurNI&b6z#<*CafzkSj^Hk`332vRzHJY<<%)Lq3QQ z5NALWu!4+L((Zb})2{hYD~Q?=w5=gz1^{?~2!_dSx9an0IIh$53eQ)g(YmUx=kusi z@sXYY;|=nDI)aB}BCL{ggcpw}WLJL;!=!BBt}2u`9znUzy~Dj&(0*!pK%Q-B5H#Gtml9cqGaf4-x4wU69zaB3MbO zo>iJg(y3%OEdw=8w}--sFiAxjHZBNhNy^3J#dNxo&s(KZV{OfG90WcY@GM3a+-%t= z)QD(6uI?EEpbf#J;+NRZRFc9G| zMR2PTzZN5M3C2hXTvm@ zKqiJ5&CBclNC}s1T609B9WQTYYulv;syny`C_feox<$qx6UaoA)6|%rQOicgGL4pP zqIQGgI8*{;1411yQXRUd@Ff$uW|PWgpF*kCSWy&WF)5Ld$zYNSW*O38$qE--9Ja)9|J#ure6j!fKjta1x9_KO3kyrlPxtqI_ulv;qWALZTkGH7KYQxRN3X9w)?3qu zJ{3>(i-tP2YuPk4`c>$fbF1&D+e1_b5@e}9v#n>$f(73#J zevm)=+s?pq*E4t4@xbj{FMZ&;_TL7(k-z8KLzW*bo)O2+{TduT;54t&_wRP3ftjh< K$)){ofBZji^XKva literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_2.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_3.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..c97b87dc12b6aeec3986cd6269771d9aaddc6417 GIT binary patch literal 1181 zcmX9-Z;aD)82;Vg-k309A9ise&7b;3T(xL`E{8X0oIniOvw6VEtEfd$8<(IHb7!s#?4ITX#$5t8Tq_vL+(=Xu|E zHV*~n&be<60ATLm`u;7gx~vtC^mMfHfo+>70O$alH*Othjcsjh?d|Oy9UYyWon2jB z-QC>?g7ozCI2;a-&*viuKf};G&x&G5mZf++o=#`;d81e?+jgVbB>aG;0LMB*A$KH# zMq~a&l1gW|TwX8>a>+_oYZ`+iLCPty9wmsXB9@hj@i8j-1&5{?^{je#(+bV=b9{?Nx0)j{`m*VxR7^YFwILA$e!xcrjk zl9p?FyirKcS~{#1U2YP?g9I6-nJCXEMKKeN=99@nHftG1wOnpA8W4CTfTa;4=VDAR zU&6yxCQ%D%^{ClU%gucKc4ZbiahHqqcmk-8$NeHj$t;%;TFYYjWNIpxw~JP@N&|sK zWZtC+s2agDFd6yhThF&2{uf1LEEX+md+0_!hx zcs=NY0tyujW(a7|&|+K1PcC!*b>|0O+cLz1)z>bMw0d^1f6dmF`}U`vJ`i7g&%iXi zxbDpPFBUJ!Zt6WXy!YbhrE=^O(zSeK6?GO$-;ISvNPz5_|J14ZeU+>I& z{jV(Rof&!Jg_9EqG5Wn96>kPV{$}- zY-iZSN{Nq_+R-iNMA2^pp0{Y-R=vm>LjrcuLnQ;&bc~lLy^0(z6;fs$ zU{T;Cfyf{c9!dJt*@&i?)dOh?f|!CAX;j1EI;R=+S&0Zo zB?LzDaM^&6k9rEpKuLE6@~l z2{0Ola+Wp%9s_<7#LYma0b~H=wa|ybFb(4lnD#*^ za8rQ9q7;_2m@+h~SPhWXL$?tIF&HPIWOU+?Kyv#ERV z_b=oNv#qN3B23=tYDy$udH8r=>zUp7?V0la{X6YfYWrHZoE*C;kcokbr%fpZ`bG}_ z#co@*XxWj!8&96dOF?y;e_$)#+&@!u=-LMhj~soc-SKjI;wu?FTZfgJ?dwjTncC<3 zgANw29Xn_uuAe@#=AZkgj-6iBO*PCKX6oMlewTN=(Cq)kQ~sgpY{QuYsjJojcDQzU z^^QCBUBoW$NT2pw)fA`OHn9HFt8I--INiXqjhBbt=u`H6w*1Ex6N{%*o}m{<7mk!m z=a)`*x<6UcVD2;Q;a4u`8UOgaasK=CTEp~jO_vtbiW=cUKR#Ujrm}fOaM2#en5%Wi zj54(Fc<;lZ_NAHsZuQT5`ciSa|C%Xe%d~Y}7CJ{8h|#-cL;1j?RS)j^x<~r6s##>3 zt}AcmZcg{B!!3>PeuFyiyf*%*W9Ri-!J%+hdg{tz?YhT*4o)xk9O}Nmcgykdv8Kxt z=WejOw;M*z-;FYiKe literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_1.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..8847bad5eb422634e61bf5438ddd3bdd57a4101d GIT binary patch literal 891 zcmX9-F^HsQ6n?w2yUyNlSPVfD145>dAi;oz0SlA3hgl5kavqt0g#jT`OyPkCQwT9c z!X#K&Od(;4DJ-TCVzGq*3keoeOkrS(2}qb61Celr921y?J^15s@V)o(74Ln;_uh}U zH}b;=?>qp2hu5E7J#HCm>!RCf`$xY$y8`II?dMM(wesZTYbUtC;Z z7}o7}FE1~N!C=5~tR#t=rkJK~+m`2fVYo<=v?w-J)f^5S3!(t3($n?+cuY+kcIpe^ zTwNwcmfP#n-|Zub!G=Q5QV4fQ1tz_)xjRqF!{Iuys@1fvqGMCYBp3`#LC4k~LMQ3uBR5Y3UZ#tgM&2V~&f^*MJxS z@|6KEMv4U@IFs7 zLyjMb(nQmI)0|HxiSOr&MVY3%&8BG@1f&IYh;d6?%1CX^jCRs=uSfMHYl6)osqeQ( z)MId*CkUAuXbfu#f~}}iqh01C{%o~Os-isXL@*T0)^OLLf-y69#CWP@^U*4HxB0x@ z7Kg(NBmxWpY=8hD23P^?F+eR;2{|^3BUEiw8Y~WGBBU}@Dj*GzMIfI;k&4nWT2E0G z!Rz38P$U?t*w`f82{Q}iWn^ZVSC(;Im#Fn3N5DBfF(A~4GE&;AgrL#m!z4R~>-%(v zwhi3}p2B1n*F|cqan48y+;KE>vv^h(aa|SYu;Ud4rGP3xsLf*9+PwkkIrIIVpNDT? zuh){UYvZx$I2OlxJR6E!EOEKQZd9fo4v;}1mqv3Ar6MYo_W1b^dM{u9z_Z6U8hrfM z?_am#{p+hwo^*dQe|h@+w9|#Z6XV-|{_7Fny!!X$_s`$G{qq(6!`YX=zWw1PDDS=X V#VGmXz8!+=M>khLfBMyT{{ylacv%1d literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_3.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..631774c76f04005f9058c225543beca900f25f0b GIT binary patch literal 992 zcmX9-L5SmI6n-5j1+yF?y-pf}mCUkCYZhn3~l}arvEG#ZA zE-fu#7`D8;yt1;A%jfe9Lkj{g%c8253`4J0tIcM++x5b*AIFpFl%av=KoZlXQdZN5 zib>b%T(c#0x{4ndy{JAMIRb?hxwJ0ktRi8nWZPhlszT5#_PTm}TpP#E$s{b`piofZ z!IrU(js^A1pp%{Ua5SdTR6#Qvp)e010Vo)zXEGL!+a&35+>s<5m&*godeCm8Ai$Yy zp3l(|!6{@xr-~M%+MLl6s;=1ZWv8cjahYIox{&8&N>tgBF6cF>)>hh{?nPD@H==Q8 zcoJlI$jXo_17QMbV{AKD=#r&?*P~*6XgCu)L`M>pRav}Jpz1}gqYAzuM^$yuG)8W9 z5;RXD7mdP9mL;ho!kt#F$P-@Nv0Em4`xY zRC2}@e`5Ei-SKR2g3?qb!{%}YA}>?4%5jD$)s$qJ*{wH@JKZ>prb8YS5i{hBr4Y78 zwM^cv$$qPR>{^4MH6Dc1=>xhKvBXpHD^_*hF$15s_$2$$Q_R(lxX2)V9Ydc=Ol+v zJW`K2ds1?z75}8!n|VVtn2=du39LY8N<5*-j9C_KOLH2Q?>3^)9mgS>4p~t|9-tTy zO0uXWa*u#l&DLndwwjM%^m;<6Bx{;#nmR*QS-QzHuD}E$-Iu6wF^?1iStM#P$m3BY zCdbb{oBr$J54^L#E5p|P-`+~d$2;3ETzUGFcYhMs!Y7v(_x=sOd2Va4|Ivl?xtG*m z*!}Jk|G|xo`*#k>I|m=$Jbc^yl-L}mJ~+7jr}5(^@tAwle`dZg|HJENSKGZ){B-U5 z(rb4${PMl8Zhc-mU8CN-_4S2~!^eM?XYbFpDjVn4FI_`g>ip&3$#1{kdo`ua%<1Ol kQ&(T<_O18q;`4L={CfWGcYj}NCeC2z;_mjBFTQc`KlYQSwEzGB literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_4.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..21f43870f3f9b046a9f33f3dd683a83ac0586719 GIT binary patch literal 1112 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_3.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..df532007af50a19c39f0e31fc82ddef1e54fc50e GIT binary patch literal 1197 zcmX9-e{2(F82+{~uA{I@YAkxlO^T^_fsP!@%^b-&52#yVx9o;hFL>xh8m)T9BNk|4 z6KX88!Xce$q)3H}G~pbT5LQDqbzICeRSq3c@QjT#+x;;}#cCQE$!7`4^ZxqheUj&S z-_fB#-;za-ECK*5>3??PaI+H4SYc~x=83IW{{o;53~d?N)Erw{T3TCM+uGU|ELhOq z-o9|*LIgoOyMkdb2m|`kW%1P!_+%nZhP4}Td zz(JS>3WsDRq?mA&v(9=6g_alA1vsxjsJj7R0T2*GayX(Ws(3sqMV)2YsbH`ijm~8< zuvkP1r<-4I2+FhnY@%Y zqPm$htZb!GbkM-b0ap-U5#Uh}GUM{)JbaOsj6k9yt2IT3XIb1Sl4#h6CjwMfWC}88 z#Kdw+u4=JbG1V|MSk)a)(t`&GGDtIFj!TGQIvma=62(l$$mc85)3sU+0#pK?6hdSj zOabLec(B66tGsH33pHiBp0no54QR(54$|fFVQvohiWDXL*|^YL7Re=&Q`wxU8}$ke z1V18kj;MesAv_(SwK!Ku2dA`XxtO-fdc8geX#fHM$N(q+XaGzBP(=W2f@NSthMEe^ zGV1{n0g^Px`+&&;$N?z1V1j@u3-cjZibGQc_lzfjp8)|D35l*~7*8s`tSS}?F~iU- z%YaQTGzf@@omO0|iV1m-WKv3v*XrRyBUPHuS75p3aRL%Ud|n4nVFxuKMbgzOnNHn@Tq-d<&xJx_Bq9;s80k&XgvJm> zzjvC&t$-T}7>s&gnt*v48vf?-lWXj^@BP58;Xw{OJ$r3uv*-Ia_Kox&_~dZkL$R*K z?GdP+d$Mcy;Ul&mPV@tQeB#I##-9%Q_mRfe+gDged+w}!ZSUL%FLw?1WRFkGjqMy> zxh-<=d<9$baj&s_&*Qg8cPiuT)%{wvtaYc`t!3hNMAZVM^`6o-~BlMz`o~t zjDL4^53ai^920K+_v%+OSzJ1HXHkpe)7GuFo7eZB{5jOS^DTSJ3nR(ksNF_2mOkO! z&pnJi&)xX4@0!@{`zB70nP+BJ5C?_#kKWkRAyC_AJJ1vR_s(`M8;z}*^j*5UW0kUj z-Zb+Oz2%~Q&g$6QyGr}*`~J=AOIOx*Uzi;2eD{p&y=C2}Zu8h=Q*+S2X>jA|XLjuS EA2YWL4gdfE literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_4.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..605a875b31a2c4bbbe42812a9e5eedd045d791c4 GIT binary patch literal 1198 zcmX9-e{2(F82(^CuA|Hb8Yxh;gN~i#U`M=!15P~P2HiN^;cl^xqDMHfV*fakLkiaH zfTE2QbA%d8tk{@y6mmcjrbQZZlFOK(LW46FZDJ!O7M-Dzs*6tiEFpQ`U;n&M@;vYR z&Zb^Z>$JJk006B$-Cce4y1X89EDiO{pLomwpaE>!*uSnmPMI=g>eQ(X4GoQrjZIBW z&CSgSf>nVfbjCEtip6TJM&N*^0LNN=K6@bG z3Wo4Vl!_;~R9eUyaxNb&l{E%Kyp&a99g5ebifB?M&W9Nz?#-p8;%KB&)F!H?#|Z=s z1Zkl1NJ>JCsI8E)*K$r+!C_5+lPZL!8vqUf0YN02O>sI^6xAr|Jjadt{RKrCPbQ&Z zI0?I(cHo?g5>StXc@;ubDLKJ}bvBmewVaSC`dy?G_qZt@V@1*@F;aw!B!y%~%H$QZ z7|T~ur3u4E13M2Ke&7lLR7J?7!;?mR1}){i(UPoHRTG})FuO=PgB~pErBWi3mHB*F zEX3uq9Gn3o{^G!x|cs3<0a!E`igB$N3}rZhHItyUp$N&t-`M9Riw zoqP`SmzYS|r&WU4sybFnS0)P+(2Ch?q{HEHxp@p1DN1I!h)`b^N=IX(sdUlI*Ge=H zSVZP+ir`WMSRzF05k8ynkLpUnNK^`Dtu_v60K5Rm0H^@y0E_}qMgXjXV_-;zx(15{ z4h0ecVl>EjK#>EG2T*drC;>GNW&$u5fkh2GFrEY~1H2p(5FJVoi>aQJCT6qYd|t0q z^03b3^aCPfrBw%~xr7WV6)Cmq(`&)(L_9Z{DZxS&wFA;VU97>eSWFr0$axTaCe0(4vhC&j7he z^aGdRjsBNDoowIGw$v6odtqy4Y}KEQ$-nh&YYVTN$M0f2_qSdfxbn*B+wE8A7e48K zduZug^N#lFN8jJNw6A;a<+s{8W)1XMZk!#d^)#<9EyVZE_~vAFa$o1s#qS+oHu!k3 zeYGXR-e&3P~7fn`{hDz!=;P&XR<_f!Lic8%Ogva6&F7oUfVq9(Sz$(+&DV# zZs%Zd$GN8#ywQ=`G1zf$<)I_nx=ZGGa`?OF`ZxCNINgeCD`)?J{zJBXd_8owZTRZ+yf3wdHx1QSh>;8G07L7>rhsb?fn#Nm(KU1#$ zWm)**FT~LR*nH-{(9^pgiC5P3E$Y~Vv_9Xpd*(L6_2n~-!kQE9H+Ox$z2o1(6L*@v zK2!O36 Mb-i6@)^6SZKOJ=n(f|Me literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_1.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..28e1ccce5dbebe00d05f254a34505e7849c67967 GIT binary patch literal 1088 zcmX9-e`p(Z6o37->kns~K_WX#CK+Dk7!eM8ow2=c*O`S|ds}Z3Fv3kv&1Ne1$F+tv z;K9-@8-d+slnkN^a?CIf7Nv!BM0U7X3I@Gu(FpfP)C?o5G}Q>97WOq`@Okg?`R9H3 z@Okgj@hSiA{=NMGusd*cV!A!|w(IHMu6AF4eXs@41;>w_Jkq8e9UYyWon2jB-QC?i zJw3a2?ZPmux3{;iug~T2cqq!tvWy^bk`z)DIUbLv)7gB!P%5q4cB9#(yukQ?=LSL{ zXC&f|#=ME7FP-6Yd9i3JWh+^&=`4u_eFHM*QiE!DNR8i2&V!;l(Y254g_ym%Z=#b3H2|ke(vjw?e zsU0rPqfGZ5{7!VppXI=h05i%Ls3MQ+H-q1>DktdxJjYs`tGU&@mY*7)c zxKv3iH6z|I(=E$DwUWb06J(I0!wef0grp>8qS1UZX=bxlp-^34Z!{VRa2bd+M&%rA z5f{p2xXLDKA-x_gHnjC-zP?jwp#jq2pj|G%+ar)($>&ozJ|VW3#q!D2YA$b=tY(z~ zk;4?hp^9!TLS|x&kr0ZR@T#F!%uKyfYBo0z0}upI05kvtU=^T-0cwM1QA|OGj_e9g zfJ{M(fr1}w9*_V?cA+GNbRHEVsGLBy4iAH;fny=aV-d-vM#+@s&*@UJ7`H5=Ubj$N z3l9So8(=gSue-$pA=^H!5i*+5Vk=$VDO6FVK{$bSV}7qA#JD2@6$^8k8qrf~(MVY( zqi&Z_vr2OuDgd$pp>`IDw%jA&@mQu-qciD8P|9UC6cQp4DHf9{Z=Cj~8OmTOlk=|g zWIgCXq8q6M%224lAd71sKYd`}?}tAyJ3S@9_#eN#-6orXi9;ucuFm}sxqN=#V?Doa zs%P}zc$iok|Jtn#y)-WpS0~1Lm##SQJ#W1_IePe;o6B3tfNS{O*ES9Xwmw?H&#v8R zOmZg7ss!k{wK2U{>a^th4*KkT>70Dtp7`% z`*`xdt%;k?+jG=?k9p;(;h_h@SG_Ohj?L;r+dp5v@ZN{U;Ms%ES1$Z{LJ6({F1H}f;wUAKl8QghOsXWPypaAa!Y*5Om<{s()L+U@`V literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_2.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_3.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..7f38c16dd91df733e6c84736de4befd161f79d6a GIT binary patch literal 1310 zcmX9-e{2(F82(1LUB@=M*+7+|opf-60%be2ghCEHSlLQ?V>i-3V`?};HC2yTL&a`Z zs9Lcj2R2(F4eO-FGS1k@k5#F1CRIA=$N_V7Sg>kgC0STwIxSGbX9>yk{`%*A^5l8n zgB=E4?dTirs(WRhB~ z3cEw?_Go>6G88sPd0Rs8q%%Q6g&4Kfj9%t6Dp(o~*swD$g7+B{VI~!KXH&sKE~b+M zvkKU8z*0zvL3ocO8ItA`a+p=aycrf*2xBD;BmiavVI&f#T+X6sP^&#dl5vYA>2yv7 z0+8qBm{f_&)TBadMsPVbFU!Gt-IvM4liwN9y}RC-!tVhF}fx&!7w zgoy~wSjsD8L+Ju9!GV+lG7C^R0LmhofJ_%gO+3yBMo-!n%&{?ehEz#ujohwNd5qc+ zO+;;!;G&a0TZVJxcwa%_U?wJ!YEYFC(^zoAPEj73_S@}YkB1Kggh(VkHkQlfAdoWv z^&wbDLPX_MLS;!4?u;pzwMTR8SU#LBCJV4yC6Q=kGMz$6snoPqYtxf%b7`3)?D57! z;Z#h>r*UA`BQ{FnG%HxE%J0BAHx>0;;+!+d`?JYdK0gI<0E__G0AK;&0Eh#SK>#d) zB%s3vxgbm>Nfa;`@Zun%11S_yBU4p=6vjQw}$t?hLRO76S3@XeKlu2pXoQccZqXl207)irq4wV9p0@0}@CR|~q zFo#9YI;}ykGs<~|7?(}OU_PzU>tO`I6o9bgg}X%e6mpltpUG(azNfGy5`@V_S*^6g z!C-2aM(x8fj=*@mdW=+MjY?=%Kqm_Q7>wXh(3g&1v%LDBCqM9Rr-1_NCnt87`q8$H z8@g5>>gj6h53a1a^H|5#(Syv++Ihd7;E{%juCooRuNJ+xYY1~9W-qkx=X1|rT6@{N zzpJTcT7I|+>F#xkhE{(3sB*ACxlcCR_9;Sl%0`BJ(m`=w=5}(9a(d|HBeQ1)`X5|x z4lgvl{W<^Po|(BLD;oIw?7&q)U-7$PF!08OvVFW^?q*fpFYgKU-ywA)jWvy@u1^%& z&TVU1KeW(bH{N^H+5Ohgvii=u+rp`Fs`c8bPkP2)zrSwhO9Sr8o5!ewt!vwbiCwiV zM{f*2v-R?~sBQeh?qWsH@%b%F|GPK(a9sCM?V8CK(TD3!j5m+``KqDCj>2b^ni|rXADt2Zb0vd1Sc1>4%5Uj<+1%-aC|OZvBh9+i_)d zlsLDeo(SDy2V~{7U$*rQG(TPyS@XR_G0h!t9x4`o+B?&+?aKK=-xkB^*1D1Y_Qie6 z_Pm+fzGnC7qrZyTyOaKg#xC#0cj7nEYv|b=-_&@VYM;XYP7k(;tM@NDy=uZq1?~FzqubcY$vxWng ZptQHxdP`&tl}rY0n+zMjdF8bO{{uv*OC10J literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_4.png b/resources/g2/track/bm/large_turn_left_to_orthogonal_gentle_up_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..bc1351b1682cc682486cf9ad5c9fbf0c708148df GIT binary patch literal 1367 zcmXAoaZD3;6vux;p#|)!cG%2H8rNYNRcdx~M^g3F0}HEigu`|5bS2(G(FzwGcShr5AGA-I=Ea386jmhV|m-o;6{_%a^ z_UbAHH+Nnx0DxOrQC5?lNV-r?X1ag-eD7NTWP<9owdLt`#*7&m85xX3dD9iW zD!H4+{W>yiq9b-)++#`x?2};+j0bsqR3cR&s0PFJBx#{(hhFcsSOQLG*yoFlj3kpu z2!srf*x87ihx>(ONUDk9<~Zd_=>19SNXna-j!eQlDUXK=1PYOul*(wiT&E<=>hv*# z*J2xVd!xZ{Duw~IlC2|oMzzSQl{yTV$4vSinn8~-5^y9U!BlD-VgRTB&;eitzyrV_ z0C6^eX$Tw|bkO61(Fh>{3<7Kz@F_r)0FVTb5kLz9T?F)LVaN=lF7VoT6ew|^BG_75 zVAM-(R)yO|`~9YH*po=@#~k$_S*LP!%TF;t77Q34$Z^kFcpe4U8Jc`sgPV0%p!306M( ztsa1ktje-gwH57Shn1bCB{R!*Ls#Kf*!(OpRgZKwuIlWbJ+$M(iPO7Ie&Sh7-w#dI z{k(YEcx>H@x#R!MYMx(ytgYm6HRniaRZ;z-lG3c^l6@}02NyKG<@@jD)n4u@D;qs} zCri#Myj(MzuHQSC`|=mGaepyhpuJPzV-=jtuYYV5xAF)j?@+X6B}sFf0^iJb@x$;!10Iqzh*pn)VS>^pTip7-8S<$Yjd)7teSgsXa#5A zjZ4cH^tRSr&pZ51M(&)atz9`kl;676^GA1`Kj-EZ&$Hb{hJ6zor~JqM++Quc{ocdc zXNF#Ct8C(9Et*_2_SdTo9mSIG4wdzpFyOm2Xp}X#RQcrGAoNHR&)qbn}_ra2m zsYUl^N?MvXZhBtbd1&F7zqjhXXnV`~Ph0x?-kPeoxWd9M?d#_D4eeQ0IJ#)!?DeV6 zo&8@Fl%B4gC9*V`mNzyC`ZhGvnP(_(-@8}O-Z(S5#HpIYzuvO*>6Qm;I2-@|=0WaH zTZ31>B!AS-`@Hf)_h?&VM`6#?rq70LuMQlQFT2hCms@mjV1Np2IX`i?ZDGw&fmggT zwvBmv&rr`D_tIjOtKwp)_{H6#<{E}W3dSeC9^>4cx9Pla!P*|q`^(tZnmQU1r%p9> nH5_c1V%p{&NOG#iWS9|Tw^8wd+8s;N-vKJitIE!;uG{-RdX!yF literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_1.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..88a64053fe334b017262f0bdda4bf4f2f8834fc9 GIT binary patch literal 1298 zcmXAoeQXkU7{`D1?b@PciYc|IxDiJksb_O8q`S@2ULEaVJ=1gIisrP}mKjnn@l05X z4kuGoVyL1;N0d37XqaW0FQ{xmq_IZYVM;eP&y6N*L#-VewluNXe#4l2pSORW?;oG% zIk>J(GpDk)5&$r#wWYbeP*)bBzPz}Qf3jXX1VAxZr(3_aFwUAatEi}`xVX5aq@=X8 zw5+TQL6GwD@`{QIsY0Q^Fq9+-n%1(cf#*4!&E|G{gTYWNmK20sK98Y*zyYNd84MDW zNp7~Fb_eeEQ2rnjj_~n>Bc1V)DnyTqIIYyGmpfUdm&Y#I$cS4X4|2k=JuCR8b1{t! zFe+dsfRjf291?MeQ+`Q4E`wPV<{3ESgfON6fC7L)5Kb(%%4ANZ(ud=hC~DYfOj)gy zUN4M9WSB%jNKs0TGfEAo(pxdsiSr)P7SOuFv@gzt1fyInLp2JVR%uzafg?FPW%n}P z5En{VV}dJ@^{1yJVgg8LATi|Zax#R6oHLmZW@l2<;Le;OkT-{?-SL@F8m4ke2~f)s4JtMe zaubbNj9RDF-*WKOF=4N5$?WETA!Yht`+pUm#aH$2ZN6LG@!-2Ni%;sx2D;B}X#D3x+Oz)g za>cRsnW^5(5B_Qhk9VxfHC!8woV}PD8(mRXe;WyYJ^jgh9S4pOJAbqKH*}Q@)x3&E zXL9qezrI*hlKXYp;WzG3boGy>WP&avN-rbs|ne&Uf20v{&zF&81 zd3dUBcJ#`Q#g)Fp0|$og^$tI*EqZODv%OO-d^s_`t9o0%(7N&a-ftFdUK_q$)Y-@1 z@2@z2ru$CO(Sc5McUQEBog2M6_0_5ID;GCzQQW?{1J5@9vAUz@+tRC5D@%6ut;08` zs-JId#C7{dxcf5Ni`FJ}%^zg^I-OSNg<`H9PTC}qLY>{{J?bEgs z(Pc|}dUx&%&MrMObTi7FFk$lvuJ#oe~ik&)5ShCR1*OWrI~VwWd&do8*~ z(Gy`I-yv<9S9?;tA+lzoLEH2L*3!6V#f|&>yPx&coa@_EMO)m_N_qrMela$2LhwB= PfCa5<+nNWPw(R{MGypxl literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_2.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..39fe5903a6c5954ac438a00e0dbcf8eb54707fa8 GIT binary patch literal 1171 zcmX9-e{2(F82*+_4;%@mb5k1^MPkKZwH_WtbcK1e|>CdXlQI~Y-(z1Zf`Cc`lE~Ll8JkQyj;LA}`C5s;Y@ZDw{R(`6=73)@lR}C?8;%4xV?0 zLTFgQqcLA1$!4-b&XfyQtW-|Z7!vSxNQ^5IKsC{ul8I53HWPtDRn*>in7s^kTN90 zisbFMRmqfQO$P;>9B>5zssOKskSUix>*Y;KvI4P^oUUqlILcy9k#vXsSS;Ynh;&Zo zELAKfIY&f5wGft6C_T#MlEHC3QZ$p5V!l?p4JiNu0LTDn0O$aW15ic)tb?VYB11h5 z?IP<15&_~AF#Nz~0ptLbTrft!Gz*OoEJUH52KS980YifTi-bg1B#gy1elHf>YbBClpaGx_Agp^4tQwv4<0_W;k4Q_ zzyBJ%{PO<6#AA!!JKweP@lWud(aA5$H^xprb>!5OCk`}R%DeAu|4Uzc=eSyWWZxg# zI~TpK-2Uz1t6iVAe|~9O|M1bH)}qt*R-=t8ZoJuf;KRTB=I{CbiOIdogT>RYF725d z^32G)2fG#J%&*ZV`*33Vry=v=>JUG7V%L9#WN%~OdbDTp$%C$C(at|#d#khgn8!N0 z>%u0_*6)5lIdp+nCjNQG-@R~p+0d=&mdSB!$Gxjpu{U-|)buy+zjE#ROSgu1y4DUD z>fPYX-texrE$6zYj|Gf{mzQ0By=tQ?X{L_eWFO&^bI%IMZ`3IMTZN-I4P* jk+TzynF&@qHG%f^Fk3b)C?BsY3)b|n>l=A~@Pq#WWAFyV literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_3.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f63dda7ac444b625aa0fe20b1b6c4fc535e47323 GIT binary patch literal 960 zcmXAoL5SmY6vp37XC|GkJ3$I|HHRz~3`@{38zEv?qGpCVL?-KIpfXh=#x+R693u1( zA+QyS28`0x9*PtRSTSJ15u@}Fmw-J)h*FjcIh5V5_ArMc6^hK^Z-#~My~n$}-{E`T zN7oN47cV?<0RS!@yu5egd}ehipUe7V&$QkF$iekjj`p*4ZEbCReLa`UZES38Zftw@X zS`Odo%Kd>l49z%krZZ2Zu_|9Mq>^1FU5)CQ>`7A$JJon#q@&h6^;V0hLV!v`LjYI7 z`UVy{_@rN4#sr!(XsMzz7on&OAOolvX5hF@5H3Y|Jbxm~BVC`^_Gzz&!jNE#Wue5# zB(G8xgRa`F=JIA&Z2D4rsCcm&q&mqFOr^{#w4`x0Lo`})tEct?BS`EhZ71{obQR(P z6cs4xKw3b#7}qOR22?E+jHK#JO>f~w=tQQA8b>rLv{U8#nm9C-q^V6h=FD#{!pC~l$DgLC6KkVL4;SY0dG4Z7`C`kpo%Hj~7k&l8lf2pw3fAh;#jBh`R1Qr=zE z{AFXf>cnTk6ipUX5jYa7FnCQM>k4b>l55w!wmtOQN#xJd2rZ|aB%uIM3J7Ihv@+a7 z5lyQ*n{nOFLz!_b)@n+`+s-w6wIgwzjpk*=)A< z_V$jB4h+LOJ3G6&x||-5hah}3O>rE<^C3|b5{X16lPeUoQfbjN>x~BC1IiC9(-R6g zqEUA&?n|cpnJk+xgp0aZHd57^LgQG_-y<+iDd?7YZ%!m86SSTQmJ5P8o3u=2tzHVa zAdEwd0-3||0;Z?zmAs=-b|K4$8ey~{BUJJLumE8U6YO@$<&wQ##qXbF+1W^>B1tQ` z9MW|c;qXvSAM5sqy#WCaN(3+a#VnmrnRJm;%3;lnxJj2U;PG=f!;>L_7Lsf-7tU#d zW=JJ7ZCLs0nr^4S!GSXZ?l^d5jLbO$1#d{F1S6QLib`EBp-C2Z@T4miz*9kgo~Mf< zXC(MaMy#ocx}I4xR8%Y39i$fz5@dv;V;q;_`D`p!NTu{#&d{{#;$ppCN8l2`o56^@ zoi4h#G9IbY$y!LUV#T_=*eF;Vl{M6Z+wG*&8E|_z+{gR|_;pSn~>|U#^GLMy$A&DQ{?1RH=I%K)SJj&mN-OQI3d57+H!cX{o5D zjgo4aCDf>r41+X4CLq+zBH6UN4_6|dt<}hE=03!7nGS`xXq1n~1;UpgeHn^SX+mdw zi!5#hJt*u(k{4wOq*2IVn&l^V_N?Cffp><7IM~0u^jcHg9UM4t?Aej`KW17>+d2on zLJOl$EVKXG? zU7z;6+5aD$8d2uXzxUSHU3v3-5#j(^UNto(TP8m%uqQu*WGmRombcJ)!~6Q?fy zQ@OC^o7D$xsXvz<<|e+lJ+?(}*S4a~f6IUEdj9xB19R5h#INnM>$Q`wCU-VF0x)=J LXkh%{%jf?GgOB70 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_1.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..f02de850ae08bdd688bd639246cee95572c56913 GIT binary patch literal 990 zcmX9-QHa}g82|2icj>LnGOJ`*FiM38LBbX#4-qq$+u{+u+%AV1M9d^$hkeK(N`)ek z71zxUqt+2v!9HYAN0@y$MjnDz2<{#_h;ojqK?;^xWDi9uE9{WJ8H3;Vef(a&-w%G@ zcWHA&Jb2)#0|0Pv{k65NbUvHbB7Ro;^JZ^lUZ6?T3%jW zSy{m_ESt@)uCC&xQi)+`LEsfdG7QbK%zC}#q89DzN-#;X0qFuB;I@)iAB&UsPf<_ zSl7h*&HS)im<@_(LZg|E_8o+x5`YY#W0;xG+r^?ok{-wH$ntKvJhbh5oet{vi%g-! z2ORZ4x26~W`3ARX!B~GCvgVjvIY{-p{-U-YgwxgsKPr9Rd zKhHx!0lW-E4M+!LJGj^*wLWjgYI9_HQzt?@GF33xVpXJ?D%UlH&{E>MF?6l5U!V5f zdF-QclrOL(r7~=p7pjWVG>mq&+G{rZolYDCqrJW9bcP_kE*H!p-mWk8ijLSw9X zlWI71_GZ1w{&0?RR6ft*xJZ-~iZ(dTlH`V-F01vLt=(=fiQ?Ia2VKG}C2#A5Q=!^5 z-ft*jyS(e$!+v`*jApZYhzC#sEC2_<2iOG|V}Me~0;*Za_fRsFNiZ2`@eqiR$bb|; zCXSj6@?;cL(4c`54;}{3f+T<{V-*9pt5nMoyPgq-^*Ht?lNhC1#WFCp9Pi+=N9X}* zCY&?X{8=@eyMz5;goabH04#xtbYA0$io(>&l4DoAmL2-7IPxb+gk~dFl28CB0ff>l z8mZhP6zjG2c+9rlN3aG1LDQ5<#i-RxhOV=;%QL>f^d)*vrY33$=>)P#)Mik?qgYCh zpM4?s&%+;he``a5V}JenZb~k%uf4kc{1;a~KlNDjO!nA!=+5@p>XlU@iQ)S7A8-8D zJoFs>>9rR#A79-3DGri=H^>VhrT)f#KlWrm$ZL>zIGdb zDQn)ptiMU!`TLK-?|0AKc;%<>!;jtx{&SBksSgfQ*{4qtS1+79|MG47?vugE!}rmx i53bHnzLz=r*#itecXaEBdSN~F1?wj^*1kP{=KTL+&7~~> literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..7f22eda49ce425da72a4cfc9151163146f6e32ac GIT binary patch literal 980 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 C60FJq literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_1.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2b4d62009c01a11ab905c6b53c69e0caaec64c10 GIT binary patch literal 5225 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 H-?aTdLYJlZ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_2.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..dff7f5ef7c333dd3dfbe95720b1ad338a2191bbd GIT binary patch literal 5183 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 Mzc_b!_T@AG1I_Hvp#T5? literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_4.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..7b5392091a501e85f867368f309bec5c06e4bd03 GIT binary patch literal 1138 zcmX9-eT>s|7=F30-f>=rjJUucJDf*Jnsb3ds;OFz9`26n6|cxR8!Sl^mbkoBN&lESL)9ZTFq2b{@NR*0^ZVqPDiS_V)IUj*iaG z&aSR548yv+yL)$I9-;{`5N5^`0^u);pd8wmPof#76HR9Gd!C$du3Pz+P6 zSSi!a*XPSF2HXO8!r+Smu47cz6D;ClnNiG8vaaSFy@Jm2gj=S((IAlw(RrCIse&1o zYiYGnh&$!y`Mq%3Em(PA=L&Sp)+sL#$ij)TCf0G`Ikyo)V) zg(?xQvx$b7v!f+PpKTWHh1xvoC0s7b;|cow0uhjDTIKkJ)LIrRCR5Y-qE#`Qbp|93 zQw5hM`Sb{pi7|zQP|Ad-3tFw5v1^rPa}F^8ApjLX2Pgnc12ix|E$}Rgsi=@cR*lC& zAtA+p5d@0|Bmh!8C`qCmkBkVaCXkhbJH}JMu@K_1i0sj#L`o0lb8@K^H_d`=o2bR* z4FehLWpodp^GOD-ShVhlg=VxgpRO(#byRb3H&8w-7;uS@*>fqy9;kTmT5GoO!_X=YLyj5Arg^eF@+4osX&?`3oKdY0<%0} zhx|zLAq__v5*Z9Kxz_PhgS|KI{J@LjV*+ft_S2qL-#jrZU4+GptU zGegfFAKoCy#la>WsK%(d(1jUy)xpZ+{>bH)0$ ziL0lRaQ`1WZF=UdH+~%)_~r(4bh7)v_%Yo5@6e36^2)^NCFIc);$Q}{;renj(`2}QS!~DgLNR!9DUL~aAp6Iz7g!Jfr$%yV?PW& zIypR$xw?Jze-B(EUby$e@2~GLe!F;m^K<;Ue4jD5vI4A literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_1.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d87c823475a62b767204f55a413c316a2b82094b GIT binary patch literal 1267 zcmXAoZ)g*D7{`D8=cUFjNNgjGl8xxjd9HDuF2l@S?Nwrp^wiVE8RY5?8zs!cT`_~m zZd)Ab7TXh|jWcSfw;AMYV<|P8!JRWNI=Euy3X6J-$f8Dx7$vak3jP)mzR$lm&-caW zdA{4y?QELcIu`)Y)U~m5TeU8)Mw_m#n)e?K2msW9Et|J*sE#!?HMO<1b#-<1_4N%6 z4RhwqK@dcz(=|3WnygkUj@w9*plKJ&dU&1-27}RPJef>oGSiw?u2gUvARK^l={+8! z&u8%mY@x6t8lw_PCav&lHk>a=B!;*hdd_7M+!m2V<2*hdB$cRJO>){~sHjOZ<&4t| z7!3FcAks*JLzJ)~moQdTGc4L*g@Lmogc&OU6aWl@a0Y{5Hj5}KIUM5@HR<){1fdj< zLq##;Mk`^mQ5FY-IyuZO;H>E2V`NZvMbfmSGAYe#v72p9tAoZ|tlh(rT!;$AnRtpz zWrd6u$rcm&8O1;VBMnSmUg3G$Yd0r}u88}X1M%HfjJF&3akzmO* zPiKQ{F3K0=U|EUIWMx>$7>srlbK`a|LHcPr%(5}RKN$`y@pv|s%1=+1%Vh}696+N8 zo-mMUGp%CYJQ*r@q@q7v7N;x8;%sgP>M?`CZZbJ7RvNRh4hQd|LQHj8AQ_HKCX!kv zTgelEaUncy5EzT-!(stK4$%F6bS=7 zlqIO;C=_rwh!7y<1R4b(4IpQNVH`>nO!=T1f|>+gfwuz}3EULoV@-k|i-^vI#HQ21 zY*sE7v#{!A_5wVhCqxq^S(p^cX%4aMkt_c6OjMms%HW1)&ThMNc z61Ys_ipw@lVMVtUG8QPHFowev0kf{^@!Q|kKYR59ecQTe(Ei|7Z?zxp>RiA5gMoqL zp25tU^ETXuf8MFD_0$|~B3QEj&V|ZTYH8n*w&Iod9>C}E$aG_g?bC}}&6h*>)Q^-y zV=tenr}a-xT|0drZ8=xcjjZ|o=E7wSkCt~thUfkAw0+m^OKWu#(#8`f@1^r-%jNdP zBdc^>H~RFlcD?gL`{~4~hSK5o&QAwdCJru}Kg0~JI{!Zt(6tuiAfXZ0$fZi+30&#`=$s|NQHs`P+Ig zT`Nr;c$(?h`&mctSn0U1OOzKJZb>~MzgTdwE!aHN&#l<`)(^pT`#b)f@Wc+i*q>+} z{A=pB*h-T#jT<`@u*3oh6a|l)veEAt^3Y5+^(NG zx0zk+Te!kBwYNt&JL=v^=tpNat&&&Vxc>O!N&aOm)4IfFP|oBJssCN=8GU~C%#IKD zpt}mqt;EhN-P$ME#54cnQ>)(|X#ww4LNDG}(+EEQem>XrvUlFSX3Z}{nk|2kxB6CNT8rf zXcVSWdO~X?btc+iVKEzzJA4EuT7-zzAE!b|M#`|V>N1%1CY#a1;1p+e@>V`T2cm3L z=4Hi~Rzpf5mMf=F5@;Eqa{+@FU?O6U>TC(jnId_`5zGlvQB1>O8rO1Wy~ltK+85)EZH%mkn+fv4cjfU*Jyjkr0T&x40VTTJ4T zNx!1R3k3yMy!0+Wcr~P`qa_0?W4vk+i_Un-lPrfbkL4W97BMX_8xWfbb&>`*LwH@3 z=yOXUUosw2((!_thNYaDqM!_*3Lvbo2vqEzN$>YY@_BP4{7gb7V|6+ix0~~NdBWs3 zo5Ca!w-PDJG(qD9hY_*{=)+)yfHDacs&f41X3c}AKd_~{lL4)Ff9YvYFW(TCt*6&K{$6h*gYTjgj`QX~R@l=!d z;=nIQ4ZoY;HysW=JkQMhTZ{HIo#|TB@u#}*t@n1{Jg{*G^H1Qp&W;ZIhB@-ht|E?;?5n!RazU+$}AYN>I>C(BztF5J)$ExYsK9_*)ZyLfr@_N$|- z*9AMr<{qCraJFSokyAq%JJoiL*kbXgqu+d2YjbHurmThU@51OA( cp0M9WmR+UL@wT0ZE9ii|y|eAq>J2;p2a_f*NB{r; literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_3.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..b93d19129277a7f80b2641239ebcfdf6f4a55b4f GIT binary patch literal 1014 zcmX9-Ux?du9RJ?Gp^ogxxH9t) zw}Qnh8llVzMf(u3asfLyN05kl$goO0Jdq)NvsOsx{}9uEB3WAOQYzkFW4pNG%q z^X|#@?BT`bMF2Rw_Wa7m+)6>&4Gc&WZvvYHE zhYlUWFl>H)eqmuDmC0lnh86@~mPJ*~>$+Ahm+SRryX^)+FN(%-%+SDdAc={5K3Oah zC4;V1xq3rtwH43TyJ2-Ov;_*waS2UKnK{Bz$)?WimIc3_>$bJ1QyE3}-Z;pnL7||; zgC%1v4fCsbzm<%;X*8lyte|}hp&$bw0Vo)z;kcPjTO?_7+^!^b3WdID-flLL@28n$ zhELHF!6{@`qjDyrTAbbx%8pp`WV@@lQGsC7bT-4ul&G?KP0%V*rKvPs%?-^Us)eK0 zV9&>SNXn2Z0AT=WVQe#%ZIgMQ*TP(Npxa|BK)Vu^RM~VXOI34ROBFm_4$Er4t`D8^ z*st$}4jKk{k|n7e!xng=q6~Zb~ z4TE(S=pAYdR{pUozW;n6RmUs7$d=3Daj@j zm((K88t0w37GQ5av7u$$RtsNK`xI% zaT0#^SmN)44xHaum*JUPH{O_#PuEtSJ+*ZC^$*0mgClpX=*WKJyf|DAFjXs^3LFWhWPKXZ-2XVWw7TGOoZGUfAPks5-+N^MqPCVYbcJ=Fr z=l=QR26pA_FRN1@KDb@qIr~WQMf~!yZ$5e}*I7=!^RJgN9TTp;`TNpQiajVWtgWuE Kd~y8DrT+o!FtnQh literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_4.png b/resources/g2/track/bm/large_turn_right_to_diag_gentle_up_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f10f781762fb502ab55b2aa480ad5e5840814fc4 GIT binary patch literal 1170 zcmX9-eT>s|7=Gb^9-KIIni5CYg$V_V46LL;jYSF$s9ZUU3^QbgqD2=|xn5jgLJh+V z9nu^#PFT1l4wy1GIv@wb+Rve8&Eoh=uvMui1G zkExqbnFz6&h?q~v#f(-m617sH(YT9P055box-ZiR=9_VIBv(PDI$;OeiFw>MAL|T=R7mD^Es%<7`Ap0z zWNPICYE)>RM>#-cK&a(Kq(%1#j&LYZt{X=JWceZ~L zLY~B|RgCiW%=I|-pK^5mjf$!|6ktZIk{zw|mR)8?PLk zW}H45ZOr|7YxmZZyRRKEKRbPY&DuL#hWn|Di?;VQXOtd$_siTI@3Fz}f5KnClw7{x z&_;RAt$CAH4d)%Qd~4p}7Z2t?P%jgmN478IYztnM<=*~hdx}#FlMe+iU(H5)Hvh5n zw{z3?e9`sB%A|su*NzXTb{|xm`*vKId_?bE gd3fItvyDL4X3R2w>G^nPOITR3tZV6aOWxY`KhSXq(f|Me literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_1.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..ec3c4c09d43b317aa1211b9c28c96514b46f26f1 GIT binary patch literal 1059 zcmX9-e`p(Z6n{;BT+^&X$uwZlR5N$dV+1_(#Ot`Vmm0g9z0&Ip80030M#<#HPKX-x zU>O|UP0pH0l(=RPM&^zgp}PAcl%Ns%NB+3gDyiNivOuF&h$BeEs$Vk(pZ6Z0f8K`= zpZAs*=A+|d4~zl8_}sIR#r~Y=*Mp;j{r=C9)h_`CVd2=)Y@ZGc47gmb!NI|yp`qd7 z;gOLM48ul8N8N6>KNJd)WSC_cLEt1Qt|)RQlgZ@@<+4?)Z8=V-+a<%m(7}+Ulr`YS%q5%*I zNHJgtSV_jJy0=mCb?X7t4x_G!_6&q-Apjmg#4y?GRRaM7$BQ(*#`7DAL_<|~3k6iI z21s9s@rU^!E#gs`h^eGx&`O@om|V6Z6zihpB!W~R91YO|!AVqHW@U}n3Sz;MEnBTQ zS-V|o_Nrb6d;<6r5KIGZU{t{$E#vVjBik{(sT4a#4XyEnPoe^;D51yblEhXN!OlpH zoYFEgoocRUo2XUu`Y4=;kyL_VQ-YvNQa+U`>w2|Nuq~^(wbki#5Cmkva~N6jvXy{P zClXCoYsHK0RHb8Vb<6F&Mh|%iub1-sqrs3sge96*I9?O`%hF{%yHP4THM`qnK;$q* z@Ty|aND}!pV`@SrpV%26yZ+r6mTrWcq}RT)fAC6qNSo#sbp;1Y`1OH*9s(n zOnVr^&liKDh06|YbmC?=Rq5sGdsY)QI=Bz0AQlaK<4iCqkm&?xsL5hht(aN6X11Lg z>NY8kLlz(h5b9^4_2up&kV)rTEh?Y83#DFX<8dLGl+tOL3}>itjv-B!ta9Nko@mEH zNDLwsM|l!i46?cY@l%I9x9|MG8;kP-9NF1^rB62JBGXHct-SL={Qk_uzQ`K7eBX4> z_3*#H4_(m4&ohT_((dbz{#rEH`bozRGGBWez*~hJKf(2{g>a^?D#fOf~ z{B$+>!{Nkpr+O!@?R;{@Gj-Gb$HdV;KR@tW;<9+JDqqvy)ATPUA9?NMrz=nWyyzcV zdTZNstsXsos=Iw!d*=4H<@M#4FRgy;>_*OQAGmmHa%$|a`4{|*i~04;tp5I+o9n~p z|8r>f`pFynmsd9re)o|cIR4e8t?H{UK5=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_3.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..10f53e8bcaa2dee6471846ca816d77ab6c5fbaaa GIT binary patch literal 1122 zcmX9-e{2(V6o319gE_0INrfX+Ql*KPd6IKE!hxqAv%oQq?B*(|dM0ORuzy^}87nE~ zqLox>@RUkw?6Ag*R=sEwM<}L)y40|lDrd4tNiNuhW)`!B4l8V=%GVN-&wHQu{&}B2 zKJWA1-aWp))oWJ+K;Om&x;iyKUhJ>0rLPZaN03czQ;&5mEArMZP#=|}$?q@PGmsdqA zDwmUL)r{5)$z{t#)uO{mdkH^92U#vGig8&^g~Qo+ypT>?xm;y-wqCCzz!mT&F)HKW z^0-(cf)y@S4H&g>zOK(UvbAP;8TAql2kmnC+#Zo2Wrk6CAttqsMY8e4bS7&Ttwx0f ziN{pYp-FB%M5H3D858rV;Iyfg3#nSU*k~*u7Qhdn0_XrHz%)P=1Jr`Rp@@o11KDN4 z3kn4Z7IHqY1wbMo#f9P&G6a+hp;8Rl2HY{82A%`IfQ4k27A6w9FJs90eAKecTFpW& zEj$QRq?grQg5j2OUd3kgdcbUi^UKLnGgm?7y4MM`8}pHl0P7BkR3ymjTF6Lfc{5=Z z&6-_AjS9{4CkA8D}>BFAKUo5Trc3>^T1wx09&F#XSS2qkU{WiYO z_-OPSU0!_u>c^vd-4!|VG0II{BU z_2&=1d%1#-{G1-U_QaJl4+euTXcrHkII!i=!pU3ZBX7-|d2>F~`I7(2J2x&3w-vr- z?#*m|{p_LU+5fg)m@0Qs>jpM)#SI(B)=#>B$dX;xTz?PEk3BZ|<&VuReM1+V;RjY` zhQ7bGGO*1YnQLtQ?5m^g+s-YV>fERP{?}4-lzQc-ho74YOp=d|?{8+f>c6vVstM|X iFSzT2Pv*b4-S*@o{pa}|;a2njb`I{@{@pV#zx_W@XZ4H# literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_4.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..714e1c7cf653b5d312a259951edc0be09ac94941 GIT binary patch literal 1141 zcmX9-e{2(V6n|U0-F~o?(3lQt>|%wI97`h?J(g2%^EL|{a%8tqwS?O|v6x0ra+njF z*gmYBEt`i&n{}WWy&aZjRvtd}0DuK{Y#SSCjx8-Mt*xyVi^XcSwzajj zx3^;$*3r??+1crEyWIrgWf+?0Sy2qgvJ{O*lgV^0rx%M$rde+^2rtkSaBO!VU=M{{ zO4u8VQ^^#U$qD&_Tr%R7s>a}$pX!!aN5t<^MNe8L=Auj?=`ZCZb0JnUwdH!z=L7)< zg$9+!G7?sZ+sYYxqvS+2FKP(rmWoi(4Zr~i7$(_l5vNo2cr=QdvaT92|P)R$k>>? zlP}@H3KOdaw3?Eyt4obs?N)gib>lW0>2Ua5ZXWlF6eY7EkmR>>Sy2lQr3-ftx0ooPfiExlrBOxsj$!8Nr zFs8JzV7U_UYK&a_OtVwql&S*GQt&*waUC5;p6A193kQfe2gf~ihlQfZKhyv?f z;_#Z^jRY5pcu>jPu#MvWVYq?H6R}Fn| z|JdzsmG5WBOB=2p-TBa8)yezLJo8@kpY^{?jQ5K7rn@%3iTx2{XMJCz3yVy-Cq3g=KR^G+ynoO-RQr*b57rXqPOtPuU!)-+GkoPKc2Gg{;a>> z`qss-&wsM2ckA`>`H96N=A%r@y7bJGr~iEIr+~KWv8n#&j&lQJKmP8v9^1BWU;U%Q z4=#;;vGJ9a)2DmB8~U`dcXIv_X5+Qs`pd$~%eLv4j;R+;q}DXGgDoT5hi4xjKlDGO CL-o%9 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_1.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..7ef7c850d2182d5e49c9f7647111bcd781c0ff2a GIT binary patch literal 891 zcmX9-F^HsQ6n?w2yUyNlSPY2}3lFA{Ai;oz2Nq`I9%eDD$9XV?g$F{Wn1BHfrmzrB z$Pg?nrjRg%30Mq4h{YBbLM$wXFoj2^n1IC;6C&XX2?n;<;*ZC{_uj`>y!RE~dp|tC zl^;L)pT2#44bX$&luXlEKc7A?-adClR zSij%Dyu2hvqY=lkk|b)HVw$>bTb}2I;VMbeqS#ec)3zK7q5!Hg(DmVTO3fU0?hD~k zT_;AC+uPDV93zRr#=^i-2zN{cCcUz`J5S2P@iwul&AhIn`=*ddFc_GL5NO!i!g3$q zuZQiHL^X?A13d%?6(ax@z`!sI$6b;PXgU&vJ5}9GCVSU?w_2e*C%NHBBv_Ra3|h9B zvCEl(U@s*vRu-8SZH=^=P&~=XBSB*nlh-ZDnyd4bu}ZD9bco`v*H}f&$&C%+Tb?naucOVQos8t(Bg+5A9>@HFb%GaaLzys2sNUNl(s4%X!N+9W%uFsAw8gd zLl1$cFqy@5k(z3pGf@I}8ZF!`UX(>#R|RShyrQ5KPz4BeSBCIyD`~;#iMoLy?OmE?3x{%GBc#GAQKIXvv{eM5WRlKmXa_-}gW8`o*mVU;O>& zH=X$O=KAVo|3~u`ys>K*elLxy|LWxM+fOID7kZ QHv~7&Zm)m+^3|LF0j^wkcmMzZ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_3.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..07cffe6c1654e1c2348da6c8032a3546db39479a GIT binary patch literal 1032 zcmX9-e~8<36n}TUyWEeRg;njbqCKvEWFwqGf&}Rx+vP?*qL*ViRqP*w>7~=e@`0pZDRz z=e=`ltBKj^1JeL7yYkZVaep50>&eN0-@p3&)<*yVSbKT>m`_JWMn*?R1A)NU*x2~^ z_{78nhGCPFlT%Yu;aDt2Q6$SUg1|{qN>Su|K3^(TYBj6TXuEEIFrY|a;=pq=sZ=PF ziDq+TL5r8le6=RlZKdUC-JZb`STa5%b73_Z)g`>5P&;|nE+tzv*=-g)*BJI2i3o@U zWEs!}tSV!+7VK0*gH{B2BpQflPe-T`1KXnB=2z5l_fOQl%t4u9Vrl$rbB@(Go2;9i<~=A{G}2PNGvXD;M}eMXXq|<){s} z=y=uc&<-*X5+Iz0Xbx~4qbuP=4NuvO>?F0WV)XR}+Tn?iL`Sj-LQBT05?faUCogqM zO3%#q?b6UOQLhmU(KwN$=rqG-1woUfayDDjG`mu9EUVjY_xpVW5gG6jMpc7sJtDM- zbeApkQihkU_x1Lm=IwQcXod&|>2Np^jR^!P#p4Rc7es$quBH{6)tcLI23-b34pW4n zDn|7TQO+@DL8zD0O;hdIWv|m14DKQZAPJxV=l~`_6QG9y^1-txry$cnZimM~rl81x zl>nCqBmk1bNTZO!BP)Yi1>_p=D0mt;7Lq)ck-}=0DC&u-A=T@7$1y$6LB3Wb4ODK1 z(ZjqE6)jwL<9a`34zl%OskLWyQKyfGfR17bGMHkb8G*{BIbF>dMYV1gordYT4K(P| z9EU7GE+FJ*QSjv+Ba+XRdp){bdJLu2VpAz0laX>cnIiKvSz;)YrEHFD^Msd-Au)o{Ie+fo`FB4(`|#>7zgFkJ`+IKATKg#w*u1)V==$~jbHu*C9!!2Q()8Bf z{^rM}!^Fw$g|}YYI`}$&=g7vPuYcB-_HO@ndpGfk$6WdN#%wCHxNz#Zn0M>jGsE*& z?!VeCp1Pr(zIWzy@x|)3E$lz-V(;Sc_mkyk&ThW){JqvYZzglkF4T{rFWV2q!#Dpt i@x+!*VmB)n?gutjUYM@_uz1aP04v8s|7=G`A>v0DTnKEU>5vD1jl4%-g!u}}QgF$Mpa6QxDV(O*nFw0p&!Rbv? zWZ*a&ZO9U*Oc+TcBQ&^6F0jasG-k?arq}458A%hCIOCH0$bu6mobl%f$@6~w^FGP* zyzltl!O-fy^?d-ade82Gp>`$Ov9`CXo$vl#Ndt7j-j|1Ww#SZ+j?T``uCA``?(P*U zR`m4rU>Mfh+q-h*N{`>~C&>WA&^*sdQdm*sL?V$+XY=_&sWj_2jb@V!038I5?GK0D z(WoyL4Y7iV$o8{wpOhf41o#3ewp>Cf=`$5tU^vE7%MH5^RhFYtUE@lQ3`oM zBp^nE&SNqz9D@lQ7v-kvGa>!HM`NZy@9k@&qeUVVRMWTrw+W3v$6$ zOHRtJ=c+BsMT46MPXv5%z;%qudO~?TY|*kUXjR2%=p{7C5pId{#zKT91alHoRCqff zRnkh$Of;-?%QjK1j%WImI&Dw=Rb#}JVXdv*)fTuAs=VFRp zzDz`_OtKa>>ak)&pKa#r%as=DCtNPd;|clvJQ0wBL51a#VtZLUucfAQd8cGIt2Br# zrtmIR^yyI|6Q|82U(7_NO|@cW>XlNnxqxT@0YCxJ0Zf2tfEos<4UR!^1(^nNDjW_n z2`L&1A#gZAJRsSFG!hvcDnwB^i5vqS7*7GqfWTo<$)m=Ilpe|%Qn8q@ZL?mtQJc#f z0W#iC>mJVVi3MDCf_futHe+WpXG5`4fOSe1kZJW~$Z4-wN^nASLiPW*voeffJBPXtnjcpp8U^d9@w*UaNw(#UO)an38(4{ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_1.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..1bc591d792b3af8187a3527ccc85ebf9fd57abbd GIT binary patch literal 1147 zcmX9-e`phT6n|~nUTdeB#F4QGSB>tFn+x+~H_hu*wZGJXyB2Ta*I}OXnex#Whn|4;P_-6#OnCeBQ5r-UmLP z_dXjM zU0q!mhIMy$_w@9*yn*hD6?`>NajL0UDnNb z*-D#@d~MEfGT;)y9R@rGgo@EQH&-Nr1|yq+R87%rwT#9E(k0QJC`YCO{=CGN6wypb z)r?XvBy1xyXBJSs>~zrt8KCGe!$w6hB}v(6w3td6xtyu%wW%rFwh?$_ATk)0cd{jq zSRunTHdzm9jcCbMr<%pae02`>l1?Y>c5}E_Bz=Cf_=KdUfx^CqMAvjzJMN&P?xZ^{ck_Z`%3Vsl(~u=}-Ee8MuvZ zUUnSg_ifs8Me0yetW4P=4BPU-vIyw2@;EHed zbKQ$q55H+#Jbd>K?0a;gZ{!R<@c7>B;+1#$`>30KF{`VKNm+&{X*=X)Lq(o^U5E`Z!J0h zcmZv{p}Txj#OSf@3{Qa;j=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_3.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..26a4d0ee42a67c01bc89b46a561d698c61702a42 GIT binary patch literal 1236 zcmXAoeQXnT7{`BmVYe5sn35Ddph7iAxNHZx>4`@?=55w-Y`5&tMjCVAB^1)c3m#BR z3761dB?V5bQn0}i3+o?^HafBziZs&T3d$BC%8|oy!#r!>rXv0x&e-xemA6 z>h;=vej*s6BT+t)5;IvPuZK$IIEy1Lx`lPSWF>D18g?p%BN&wJXkT}(`L?z z0ucv325173kdbW2QcPHDc@$O%SQFu_24T(t01tqOAhN}xqNs*pahe|G`Eie@sH*p3 zF__Jwq}9RL2;NSMm{Z1GDk*8S5@iEPE}RkKc`=a5k9khUR66KazImicNVk|AE zbv0*%^-7{NowYE)Dgc`Y*!=+05GrPKrZ9Jwk#$$7q{K}v2S<6_Dp9DKT+4#6!Ok=V^Yo(T`~$38MAl%+$+o|Dzz7dGCxzw^wE$v009EFPZNaggx0CrXO~X9lXrwdzaF zYo`}Ejn2D0yD`&OeVVC0`ePSg#V=t?E>BI}?wLD!??!j^r`d&j?OVK_^l|KimDqkU zc7Cf#(_fuiKb3j3ps>Lmy}B8Fb-!ix`dz=iI8vD8uZ-P3`u0@t@Ug3&qtA;EzuVgN z{fE(811s{y9m}tr`1$0!uM|7;)kBNf?O*&k^6eUZ*SYNj4`SCRCQhC1HZO)wTuxln znF~kujHSAwDqgBO=#k3KYne@r-@zZ?IvX^N@kEt8UfNfd0P0-mhQVwC{h6^eI#T literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_4.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..0f83e8e6197c09b77d86bc071a262b6e65a2d87d GIT binary patch literal 1302 zcmX9-acmQH6#i}9){QY6HcXL{G_0@=PAGVW1FPKFb#$e&+jfL16;3^*gEB7JX)0Fe zw30FkUPfn%DbPqK1sZAMa1B%}v4aIWcDe-$IYtR{YXqTz4knrSvxMY(?|bi`_xLl8Jc85zdRajetn^m_f_a3mfd7R5|9i)sL_1*EamY_70c zl{UM^<<@$AWH3xeV_ZUTr$z$=A~k7CS)<%xQu2)2&!Ig|BIY$E!mQZuN{fNXOkA%3 zGy-fm;3;X4mB!q%WUwNeP{6bXW@$LZLl{>9KmtHZrL0WmP$+n{I-u3|kYvBbl5{xk z`TZ~!Q=kIQ}9ZXHeWH_jxfZPIJj2bI?lOiumk!$VEkcmi~|<8S|x+@oe@U!~rnnG5`P%KnQ?-07j(% z=0FnA&cRRsib+xpSQL105YYpX1dsxdl|wfQ10;-CVZsH)0C;XZ28;wSky0xoci0dQ zuMY;8Xw)ePp>$e+IW2_+p!QOnmy-b{9Z|EQmd}_&SzC0{o0y8EU^1hw0GLv$*T~Gc z(n_Iri;;I&10F{-1ok6lOHS2!JAhFz1CUC-(vhr`8T^K~~*lE=STKhZP0 zamU*7Pc9brNlI$&;v++o^~c(yy8W-sIsWqq9%#K`s2Z#6l6@9GS3dv8f5_WaJD$+t zrn#+Eb%&lUJoI;LQvms}?LqCucK_;aXOFzRF;7^$O)Nj;eW3g9^$maA#SdPZI*@<# z{DlKOclO+RuXgL1&d|~}epXhe9b34wrE6|=@Qw3D+`A92w|rHNbv#o4v_n7g`1h7x znzC)KIWe}lsdXlHiavAmrFZJrp0Z^>l@Hur7t$>|dGF3&i>DLwe;ez4{L8-l-8ZVg z{`Sb5>N2Lf?n1cRL>=!q)@smj{cVnCi%xg>iZ~t_TQd|rykKnQ?dG%m@&%I<8JVGI W`qkB&hPLO-1%|o?-Rau*zx*FJ9!OpQ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_1.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..6d3511c987d09d2fb5b623e3ad642727346cc083 GIT binary patch literal 1088 zcmX9-e`p(Z6o2WjOIybkqed1>ra{wsn^!pH!2EIBE;TJTd+V+v!Z}m8X@pP?Jh#ZQ zd9oF0f@}>j(gBnVs?P>&>mby5HX4>$PXcy8!*LchACfkJ@auzP`Tx{{Df1fx*GS zp`jrR!|ZnZ@bIwH%W8Kz6bXzEcy3e_9g&DT z8Y2@)Upm9*3!!33shY_~GshBG&^Ib`PBrM(ByU!s*5hm`9jq2)tCDD0xo*20a6yQG zCT+pbZ_eji=lM!FTvyd=*(@rR zT$IDZI7!~^3wZ-F5mYHj^C=lNu5+oPkgJ9aE9|CSWWeJS2u`9!nUxcKA{)vYvSF%a zD`mFwjcy5Nz#)J$4DJ|sHH^+W0|l>GVq`OzY$&<5Rz~YQ;gD!oG(aSSzP!X16~T;4 z^|aE|Me^ElBr6*V3o~IgMko- zDFUvB+**Xl#27sx6f@z9uGUMLR=wQmTtf^%5I_OY0Ca!~KobMh1J9zEg7h4+>bw_Z z3Q`Oh0kC*L0wCFmk`&7E$cUh70$Dk@9Xt&j3qc->NKQ3Mq_jXjCl!lv)6`on6ZN!Q zVW488jOOHX?vUY?EuYpF^-i?dO;iL)_9^7 z^q`O%sa}+!kij66>m5J6WAw)DA9#7+oB%t2|LKJu`E%C4YhmKlp;O}8>)Y<~$B?Kj z+dsM6PPUpuW0ln#hiwlZd-VAqfqdz&4~I{%@87fdU>K$^KG5#Y-}Il9&YyklkTQ97 zNcrK9?FWnlwj&C+_*meJvGrdL!@)CW`ra*C8z23%?Ui#QudW>2!>)h*wnSZ6TKf4y z@a#nT%F~@)zwUnLgNJl=`P-f2S66K3X1u){&sq-ivH>dg@Su3=sHa*sGxC2o!%oBUTh`lNcVI<~Rn s^X(>ng0(;Qx3FKmgdMjQ^8dk+@85W0?U_qgdd^{Xdd`1w_u}#Y0dD8m?EnA( literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_2.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_3.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..901c87e437ce708ff800fc7608fdc3687ab1be1a GIT binary patch literal 1307 zcmX9-e{2(F82;E;Z(|#k6fDwhg%v1Lv5|`@#o!i`l{N0CFysN~Qi6fL2F zItwf2Cf(?;NJ%=VSf$PZCp1|@>NaM9V;NY;Ar*@|b%X}1S0Jc-F|;C8s!p+Q9;P&a;O&QF+dngEf$&G zu5>uH9xvt(5aFmb7H5*YH=POL8pMp1(nh($WAa+Xba%g<4 zAsnJ&F*nagM3IMiE`<%C&Qd)qCqhaqr=|sr%~~QkM{L5MoaE9ll~v1tPKg+_Qj1<` zCsC)($hzzypDPye@rj5iBw#MBGa4ZWpa3Aud*R8`J%hsS3}iC8fd3hoWD>VnNV}bK zI%!nv)@l8EG=igXqjr?gh-MYEDxpga11RM5kT>R!U$?CE$7{4`z# zuWYAQuL^Y!F5w=?+FK?2nW|Y+XEy%j&YkVwvX~mmlz{%wrnWUZcQx(p89r3oqis)J z2$vkX+C8wR*BeQi`e5E54KM;`RzpnDsZo{dRopE_2tZ%O>l2aPqhS?A}TSiL`W<-f!B!C;lP zS^}yU&0!+c8e|btJ@sAs@t?hPL)-A*Rbu7NZ)P&hg98;`x1*mFdjcz+3-9g-e7y4B z(m`JA^N3BgC0%ctxFhVvI3#0V?p-#}+*AIjxpM4Qhqq#6={vP8YHQ8p{pKfUNUpg4Min`; ze@jPvwy*C*2Xm;~wBTXt$zt)shxc9>J^KCdgBvHF-&}K+`t39pWr|vqb(7qWul~Nl z@p#v{?y={buiO~Fc}aHk!0?r+Z`<9Xb@OGUt6mzr~Wp7tLWY72tFWqK0eKZ_@ YH$F8~F;aOw?=WbnH`Secee=Qp0saO`Hvj+t literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_4.png b/resources/g2/track/bm/large_turn_right_to_orthogonal_gentle_up_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..5301553d21d76be437f5aadde0cae7e7a892b1fc GIT binary patch literal 1378 zcmXAoe{hm@9LK-=`E25jDJ3cQ zhC8Ns!%4~ti%wivTrEXoN=D~QN@jSX_o#HCa^B{V;)T0q-|)P9eLkQ2{PTJL@qT~0 zR;`qmOqf0a08rA{P^ZjJG+T>{^0HlXdLaWq9$3}XT%TQYa&mHWbMx}@^7Hcx3JMAf z3lRh^2F6IgZ0u&X?WEepxC`zr@(`K{T;c)qU{!l2&FsXDJ6$4BPa0N@P=IC^M zgHdd;N*zwz<0At>eK=x`C)_d-qLQ*`1=pnF+bE$+j}Dk+L5C{rqnRN~l5uBJAvq6_ zB4EIPjX*p!611{o9!@&UgGn(=lW^PyVMqV~4giTDG@EVW@oYk&TPhvE@ga>SW-^Vq zTre2qp&S9m72|vC)g&EZ_|mKM$Bs=0#414*Axpnld(`bJpwTRQ~>A!umRu&U(g290{?bwehG3jvJ+I|lr6z~BH90McA&MWGvqejN;3AmawljF$j~45)BKM{!LC zk=-WuxT!$E9Eo_7$q3A9@iYK6vM?JLck@ZVkY=Q|l-ip%1Tv2BxIYeKDIo_)_=sH0 zR%3h}ff_Xmn@Q)kn*v^YB;-vpA()O!6bk4EkO2^8y|85Ep2IU6or#3R>3EJl9G0oo zgic2pjWjAYOT-Qg^~%toLL9|KNtFPSd}tCvCkp)-j3~0jCeD(wHDOVC;>AmY6 z0OXc7*3~vQblp1C*z?uGiS;A@$w%fi;(hrw7dN$4eg5N;Img$WT2%TmzvtY!5|Z>k zJVQR>uDgkqb&TN$RZXSBk7LJ)m&kSN+WR<>?VU9VHnUfZCYyvwYeJL9&b>BjFncRtRH{VAF| zd-2rqjoM3Fe;KTD7DURd?{|*neevYzrHW-weep@k8`_zbtG{op-qUmcr&$Cvs-_(` zUE54Q*lHvNrIopll>hARo39+g_uhSX-&1>Kc`w~Co0>nRwsu=($9}mSj3*~;y71TC zz0-bfKK$ZfQ}5aPOXfA&&v$IUL$#Fz_?NFT7hHn3TAjabY3*(}(T#mXe$9+d?>N6u z5?nuwzWv$lrpXzsrKU)5syKy~=!=0mdd zhKBy8;Z3iocc*IxT(>G(K5>5+9A00vr@u;jr20tjMElm!+~E!Ru5Hoov~52se9}GI z?piY?aCzRAYHuf=xmT5P_vDu$R|9KW2Pdsve3Y*#ekZ3Pxq}H#uTT0v?Rcs8ht1Gwj)Y9VWwhFD1>ifHv|H7Gji1y`;Qy09poLKkam6^v5 v_b0W>4{}z(vK3vAn|`2Ywe8&JBt!8*meStRUfY}v3TUifS@-R-wY&ZYiKkx% literal 0 HcmV?d00001 diff --git a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp index 21ca359236..88d7763af2 100644 --- a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp @@ -14582,6 +14582,698 @@ static void TwisterRCTrackFlyerHalfLoopUp( } } +static void TwisterRCTrackLeftEighthToDiagUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 4)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 8)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 12)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 1)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 5)), + { 0, 0, height }, { { 0, 0, height }, { 34, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 9)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 13)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide, PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 2)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 6)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 10)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 14)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 3)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 2, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 7)), + { 0, 0, height }, { { 0, 16, height }, { 16, 18, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 3, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 11)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 2, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 15)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 1, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackRightEighthToDiagUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 16)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 20)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 24)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 28)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 17)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 21)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 25)), + { 0, 0, height }, { { 0, 0, height }, { 34, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 29)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 18)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 22)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 26)), + { 0, 0, height }, { { 4, 4, height }, { 28, 28, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 30)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 19)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 1, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 23)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 2, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 27)), + { 0, 0, height }, { { 0, 16, height }, { 16, 18, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 3, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 31)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 2, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackLeftEighthToOrthogonalUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 32)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 5, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 36)), + { 0, 0, height }, { { 16, 16, height }, { 16, 18, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 5, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 40)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 3, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 44)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 33)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 37)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 41)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 45)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 34)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 38)), + { 0, 0, height }, { { 0, 0, height }, { 34, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 42)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 46)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide, PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 35)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 39)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 43)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 10 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 47)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); + + if (direction == 1 || direction == 2) + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::SlopeEnd); + } + + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackRightEighthToOrthogonalUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 48)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 3, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 52)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 5, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 56)), + { 0, 0, height }, { { 16, 0, height }, { 16, 18, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 5, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 60)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 49)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 53)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 57)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 61)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 50)), + { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 54)), + { 0, 0, height }, { { 0, 0, height }, { 16, 32, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 58)), + { 0, 0, height }, { { 0, 0, height }, { 16, 32, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 62)), + { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 51)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 10 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 55)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 59)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 63)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + break; + } + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); + if (direction == 0 || direction == 1) + { + PaintUtilPushTunnelRotated(session, direction + 1, height + 8, kTunnelGroup, TunnelSubType::SlopeEnd); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomRightSide), direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackLeftEighthToDiagDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + uint8_t map[5] = { 4, 3, 1, 2, 0 }; + trackSequence = map[trackSequence]; + TwisterRCTrackRightEighthToOrthogonalUp25( + session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackRightEighthToDiagDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + uint8_t map[5] = { 4, 3, 1, 2, 0 }; + trackSequence = map[trackSequence]; + TwisterRCTrackLeftEighthToOrthogonalUp25( + session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackLeftEighthToOrthogonalDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + TwisterRCTrackRightEighthToDiagUp25(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackRightEighthToOrthogonalDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + TwisterRCTrackLeftEighthToDiagUp25(session, ride, trackSequence, (direction + 3) & 3, height, trackElement, supportType); +} + static void TwisterRCTrackLeftLargeCorkscrewUp( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -15832,6 +16524,24 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trac case TrackElemType::FlyerHalfLoopUninvertedUp: return TwisterRCTrackFlyerHalfLoopUp; + // Large curved slopes + case TrackElemType::LeftEighthToDiagUp25: + return TwisterRCTrackLeftEighthToDiagUp25; + case TrackElemType::RightEighthToDiagUp25: + return TwisterRCTrackRightEighthToDiagUp25; + case TrackElemType::LeftEighthToDiagDown25: + return TwisterRCTrackLeftEighthToDiagDown25; + case TrackElemType::RightEighthToDiagDown25: + return TwisterRCTrackRightEighthToDiagDown25; + case TrackElemType::LeftEighthToOrthogonalUp25: + return TwisterRCTrackLeftEighthToOrthogonalUp25; + case TrackElemType::RightEighthToOrthogonalUp25: + return TwisterRCTrackRightEighthToOrthogonalUp25; + case TrackElemType::LeftEighthToOrthogonalDown25: + return TwisterRCTrackLeftEighthToOrthogonalDown25; + case TrackElemType::RightEighthToOrthogonalDown25: + return TwisterRCTrackRightEighthToOrthogonalDown25; + // Large corkscrews case TrackElemType::LeftLargeCorkscrewUp: return TwisterRCTrackLeftLargeCorkscrewUp; diff --git a/src/openrct2/ride/rtd/coaster/HyperTwister.h b/src/openrct2/ride/rtd/coaster/HyperTwister.h index f1d950cdfc..7a34b8c36b 100644 --- a/src/openrct2/ride/rtd/coaster/HyperTwister.h +++ b/src/openrct2/ride/rtd/coaster/HyperTwister.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor HyperTwisterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Tubes, - .enabledTrackGroups = { TrackGroup::flat, 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::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::slopeVertical, TrackGroup::curveVertical, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes}, + .enabledTrackGroups = { TrackGroup::flat, 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::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::slopeVertical, TrackGroup::curveVertical, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge}, .extraTrackGroups = { TrackGroup::liftHillSteep, TrackGroup::brakeForDrop, TrackGroup::booster, TrackGroup::poweredLift }, }), .InvertedTrackPaintFunctions = {}, diff --git a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h index 444e95d258..3bf805ad27 100644 --- a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor TwisterRollerCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Tubes, - .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::corkscrewLarge, TrackGroup::halfLoopMedium}, + .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::corkscrewLarge, TrackGroup::halfLoopMedium}, .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop}, }), .InvertedTrackPaintFunctions = {}, diff --git a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h index 10759179c9..5880b6e87d 100644 --- a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h +++ b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor VerticalDropCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Boxed, - .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::halfLoopMedium}, + .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::halfLoopMedium}, .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist}, }), .InvertedTrackPaintFunctions = {}, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index c01bc94fd8..bf3d1810ff 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1286,7 +1286,8 @@ enum : ImageIndex SPR_G2_BM_DIAG_BRAKES = SPR_G2_BM_RC_BEGIN, SPR_G2_BM_BOOSTER_NE_SW = SPR_G2_BM_DIAG_BRAKES + 6, SPR_G2_BM_BOOSTER_NW_SE, - SPR_G2_BM_TRACK_LARGE_CORKSCREW, + SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE, + SPR_G2_BM_TRACK_LARGE_CORKSCREW = SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 64, SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP = SPR_G2_BM_TRACK_LARGE_CORKSCREW + 40, SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 44, From 16d5fd74a2f4269e3281533ba51aecdf1beadc16 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 24 Oct 2024 03:52:34 +0100 Subject: [PATCH 015/139] Add large bank slope turns to Twister, Hyper Twister and Vertical RC --- resources/g2/sprites.json | 768 ++++++ .../flat_to_gentle_up_left_bank_diag_1_1.png | Bin 0 -> 1003 bytes .../flat_to_gentle_up_left_bank_diag_1_2.png | Bin 0 -> 1091 bytes .../bm/flat_to_gentle_up_left_bank_diag_2.png | Bin 0 -> 1153 bytes .../bm/flat_to_gentle_up_left_bank_diag_3.png | Bin 0 -> 1302 bytes .../bm/flat_to_gentle_up_left_bank_diag_4.png | Bin 0 -> 1273 bytes .../flat_to_gentle_up_right_bank_diag_1.png | Bin 0 -> 1241 bytes .../flat_to_gentle_up_right_bank_diag_2.png | Bin 0 -> 1137 bytes .../flat_to_gentle_up_right_bank_diag_3_1.png | Bin 0 -> 1003 bytes .../flat_to_gentle_up_right_bank_diag_3_2.png | Bin 0 -> 1127 bytes .../flat_to_gentle_up_right_bank_diag_4.png | Bin 0 -> 1292 bytes .../track/bm/gentle_up_left_bank_diag_1.png | Bin 0 -> 1103 bytes .../track/bm/gentle_up_left_bank_diag_2.png | Bin 0 -> 1045 bytes .../track/bm/gentle_up_left_bank_diag_3.png | Bin 0 -> 1320 bytes .../track/bm/gentle_up_left_bank_diag_4.png | Bin 0 -> 1098 bytes .../gentle_up_left_bank_to_flat_diag_1_1.png | Bin 0 -> 1003 bytes .../gentle_up_left_bank_to_flat_diag_1_2.png | Bin 0 -> 1075 bytes .../bm/gentle_up_left_bank_to_flat_diag_2.png | Bin 0 -> 1166 bytes .../bm/gentle_up_left_bank_to_flat_diag_3.png | Bin 0 -> 1280 bytes .../bm/gentle_up_left_bank_to_flat_diag_4.png | Bin 0 -> 1247 bytes ...tle_up_left_bank_to_gentle_up_diag_1_1.png | Bin 0 -> 1021 bytes ...tle_up_left_bank_to_gentle_up_diag_1_2.png | Bin 0 -> 1064 bytes ...entle_up_left_bank_to_gentle_up_diag_2.png | Bin 0 -> 1085 bytes ...entle_up_left_bank_to_gentle_up_diag_3.png | Bin 0 -> 1384 bytes ...entle_up_left_bank_to_gentle_up_diag_4.png | Bin 0 -> 1292 bytes ...entle_up_left_bank_to_left_bank_diag_1.png | Bin 0 -> 1122 bytes ...entle_up_left_bank_to_left_bank_diag_2.png | Bin 0 -> 1108 bytes ...entle_up_left_bank_to_left_bank_diag_3.png | Bin 0 -> 1332 bytes ...entle_up_left_bank_to_left_bank_diag_4.png | Bin 0 -> 1097 bytes .../track/bm/gentle_up_right_bank_diag_1.png | Bin 0 -> 1219 bytes .../track/bm/gentle_up_right_bank_diag_2.png | Bin 0 -> 1035 bytes .../track/bm/gentle_up_right_bank_diag_3.png | Bin 0 -> 1113 bytes .../track/bm/gentle_up_right_bank_diag_4.png | Bin 0 -> 1181 bytes .../gentle_up_right_bank_to_flat_diag_1.png | Bin 0 -> 1193 bytes .../gentle_up_right_bank_to_flat_diag_2.png | Bin 0 -> 1147 bytes .../gentle_up_right_bank_to_flat_diag_3_1.png | Bin 0 -> 1012 bytes .../gentle_up_right_bank_to_flat_diag_3_2.png | Bin 0 -> 1108 bytes .../gentle_up_right_bank_to_flat_diag_4.png | Bin 0 -> 1287 bytes ...ntle_up_right_bank_to_gentle_up_diag_1.png | Bin 0 -> 1236 bytes ...ntle_up_right_bank_to_gentle_up_diag_2.png | Bin 0 -> 1073 bytes ...le_up_right_bank_to_gentle_up_diag_3_1.png | Bin 0 -> 1041 bytes ...le_up_right_bank_to_gentle_up_diag_3_2.png | Bin 0 -> 1137 bytes ...ntle_up_right_bank_to_gentle_up_diag_4.png | Bin 0 -> 1340 bytes ...tle_up_right_bank_to_right_bank_diag_1.png | Bin 0 -> 1233 bytes ...tle_up_right_bank_to_right_bank_diag_2.png | Bin 0 -> 1065 bytes ...tle_up_right_bank_to_right_bank_diag_3.png | Bin 0 -> 1172 bytes ...tle_up_right_bank_to_right_bank_diag_4.png | Bin 0 -> 1177 bytes ...tle_up_to_gentle_up_left_bank_diag_1_1.png | Bin 0 -> 1016 bytes ...tle_up_to_gentle_up_left_bank_diag_1_2.png | Bin 0 -> 1109 bytes ...entle_up_to_gentle_up_left_bank_diag_2.png | Bin 0 -> 1074 bytes ...entle_up_to_gentle_up_left_bank_diag_3.png | Bin 0 -> 1390 bytes ...entle_up_to_gentle_up_left_bank_diag_4.png | Bin 0 -> 1288 bytes ...ntle_up_to_gentle_up_right_bank_diag_1.png | Bin 0 -> 1265 bytes ...ntle_up_to_gentle_up_right_bank_diag_2.png | Bin 0 -> 1070 bytes ...le_up_to_gentle_up_right_bank_diag_3_1.png | Bin 0 -> 1040 bytes ...le_up_to_gentle_up_right_bank_diag_3_2.png | Bin 0 -> 1174 bytes ...ntle_up_to_gentle_up_right_bank_diag_4.png | Bin 0 -> 1332 bytes ...e_turn_left_bank_to_diag_gentle_up_1_1.png | Bin 0 -> 1167 bytes ...e_turn_left_bank_to_diag_gentle_up_1_2.png | Bin 0 -> 1171 bytes ...e_turn_left_bank_to_diag_gentle_up_1_3.png | Bin 0 -> 983 bytes ...e_turn_left_bank_to_diag_gentle_up_1_4.png | Bin 0 -> 1110 bytes ...e_turn_left_bank_to_diag_gentle_up_2_1.png | Bin 0 -> 1006 bytes ...e_turn_left_bank_to_diag_gentle_up_2_2.png | Bin 0 -> 1051 bytes ...e_turn_left_bank_to_diag_gentle_up_2_3.png | Bin 0 -> 1001 bytes ...e_turn_left_bank_to_diag_gentle_up_2_4.png | Bin 0 -> 1026 bytes ...e_turn_left_bank_to_diag_gentle_up_3_1.png | Bin 0 -> 1046 bytes ...e_turn_left_bank_to_diag_gentle_up_3_2.png | Bin 0 -> 1060 bytes ...e_turn_left_bank_to_diag_gentle_up_3_3.png | Bin 0 -> 981 bytes ...e_turn_left_bank_to_diag_gentle_up_3_4.png | Bin 0 -> 1050 bytes ...e_turn_left_bank_to_diag_gentle_up_4_1.png | Bin 0 -> 1289 bytes ...e_turn_left_bank_to_diag_gentle_up_4_2.png | Bin 0 -> 1278 bytes ...e_turn_left_bank_to_diag_gentle_up_4_3.png | Bin 0 -> 1000 bytes ...e_turn_left_bank_to_diag_gentle_up_4_4.png | Bin 0 -> 1209 bytes ..._left_bank_to_orthogonal_gentle_up_1_1.png | Bin 0 -> 1062 bytes ..._left_bank_to_orthogonal_gentle_up_1_2.png | Bin 0 -> 860 bytes ..._left_bank_to_orthogonal_gentle_up_1_3.png | Bin 0 -> 5410 bytes ..._left_bank_to_orthogonal_gentle_up_1_4.png | Bin 0 -> 5182 bytes ..._left_bank_to_orthogonal_gentle_up_2_1.png | Bin 0 -> 919 bytes ..._left_bank_to_orthogonal_gentle_up_2_2.png | Bin 0 -> 860 bytes ..._left_bank_to_orthogonal_gentle_up_2_3.png | Bin 0 -> 1026 bytes ..._left_bank_to_orthogonal_gentle_up_2_4.png | Bin 0 -> 1050 bytes ..._left_bank_to_orthogonal_gentle_up_3_1.png | Bin 0 -> 1226 bytes ..._left_bank_to_orthogonal_gentle_up_3_2.png | Bin 0 -> 860 bytes ..._left_bank_to_orthogonal_gentle_up_3_3.png | Bin 0 -> 5443 bytes ..._left_bank_to_orthogonal_gentle_up_3_4.png | Bin 0 -> 5378 bytes ..._left_bank_to_orthogonal_gentle_up_4_1.png | Bin 0 -> 1055 bytes ..._left_bank_to_orthogonal_gentle_up_4_2.png | Bin 0 -> 860 bytes ..._left_bank_to_orthogonal_gentle_up_4_3.png | Bin 0 -> 1238 bytes ..._left_bank_to_orthogonal_gentle_up_4_4.png | Bin 0 -> 1390 bytes ..._turn_right_bank_to_diag_gentle_up_1_1.png | Bin 0 -> 1400 bytes ..._turn_right_bank_to_diag_gentle_up_1_2.png | Bin 0 -> 1274 bytes ..._turn_right_bank_to_diag_gentle_up_1_3.png | Bin 0 -> 973 bytes ..._turn_right_bank_to_diag_gentle_up_1_4.png | Bin 0 -> 1121 bytes ..._turn_right_bank_to_diag_gentle_up_2_1.png | Bin 0 -> 1011 bytes ..._turn_right_bank_to_diag_gentle_up_2_2.png | Bin 0 -> 1031 bytes ..._turn_right_bank_to_diag_gentle_up_2_3.png | Bin 0 -> 980 bytes ..._turn_right_bank_to_diag_gentle_up_2_4.png | Bin 0 -> 1010 bytes ..._turn_right_bank_to_diag_gentle_up_3_1.png | Bin 0 -> 1020 bytes ..._turn_right_bank_to_diag_gentle_up_3_2.png | Bin 0 -> 1073 bytes ..._turn_right_bank_to_diag_gentle_up_3_3.png | Bin 0 -> 1013 bytes ..._turn_right_bank_to_diag_gentle_up_3_4.png | Bin 0 -> 1090 bytes ..._turn_right_bank_to_diag_gentle_up_4_1.png | Bin 0 -> 1137 bytes ..._turn_right_bank_to_diag_gentle_up_4_2.png | Bin 0 -> 1159 bytes ..._turn_right_bank_to_diag_gentle_up_4_3.png | Bin 0 -> 988 bytes ..._turn_right_bank_to_diag_gentle_up_4_4.png | Bin 0 -> 1138 bytes ...right_bank_to_orthogonal_gentle_up_1_1.png | Bin 0 -> 1100 bytes ...right_bank_to_orthogonal_gentle_up_1_2.png | Bin 0 -> 860 bytes ...right_bank_to_orthogonal_gentle_up_1_3.png | Bin 0 -> 5326 bytes ...right_bank_to_orthogonal_gentle_up_1_4.png | Bin 0 -> 5247 bytes ...right_bank_to_orthogonal_gentle_up_2_1.png | Bin 0 -> 919 bytes ...right_bank_to_orthogonal_gentle_up_2_2.png | Bin 0 -> 860 bytes ...right_bank_to_orthogonal_gentle_up_2_3.png | Bin 0 -> 1035 bytes ...right_bank_to_orthogonal_gentle_up_2_4.png | Bin 0 -> 1082 bytes ...right_bank_to_orthogonal_gentle_up_3_1.png | Bin 0 -> 1110 bytes ...right_bank_to_orthogonal_gentle_up_3_2.png | Bin 0 -> 860 bytes ...right_bank_to_orthogonal_gentle_up_3_3.png | Bin 0 -> 5442 bytes ...right_bank_to_orthogonal_gentle_up_3_4.png | Bin 0 -> 5165 bytes ...right_bank_to_orthogonal_gentle_up_4_1.png | Bin 0 -> 1089 bytes ...right_bank_to_orthogonal_gentle_up_4_2.png | Bin 0 -> 860 bytes ...right_bank_to_orthogonal_gentle_up_4_3.png | Bin 0 -> 1346 bytes ...right_bank_to_orthogonal_gentle_up_4_4.png | Bin 0 -> 1528 bytes ...eft_bank_to_gentle_up_left_bank_diag_1.png | Bin 0 -> 1134 bytes ...eft_bank_to_gentle_up_left_bank_diag_2.png | Bin 0 -> 1113 bytes ...eft_bank_to_gentle_up_left_bank_diag_3.png | Bin 0 -> 1293 bytes ...eft_bank_to_gentle_up_left_bank_diag_4.png | Bin 0 -> 1104 bytes ...ht_bank_to_gentle_up_right_bank_diag_1.png | Bin 0 -> 1240 bytes ...ht_bank_to_gentle_up_right_bank_diag_2.png | Bin 0 -> 1054 bytes ...ht_bank_to_gentle_up_right_bank_diag_3.png | Bin 0 -> 1185 bytes ...ht_bank_to_gentle_up_right_bank_diag_4.png | Bin 0 -> 1192 bytes .../track/coaster/TwisterRollerCoaster.cpp | 2302 +++++++++++++++++ src/openrct2/sprites.h | 3 +- 131 files changed, 3072 insertions(+), 1 deletion(-) create mode 100644 resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_1_1.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_1_2.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_2.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_3.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_4.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_right_bank_diag_1.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_right_bank_diag_2.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_right_bank_diag_3_1.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_right_bank_diag_3_2.png create mode 100644 resources/g2/track/bm/flat_to_gentle_up_right_bank_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_diag_1.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_diag_3.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_1_1.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_1_2.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_3.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_1_1.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_1_2.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_3.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_1.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_3.png create mode 100644 resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_diag_1.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_diag_3.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_1.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_3_1.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_3_2.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_1.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_3_1.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_3_2.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_right_bank_diag_1.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_right_bank_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_right_bank_diag_3.png create mode 100644 resources/g2/track/bm/gentle_up_right_bank_to_right_bank_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_1_1.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_1_2.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_3.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_4.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_1.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_2.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_3_1.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_3_2.png create mode 100644 resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_4.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_1.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_2.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_3.png create mode 100644 resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_4.png create mode 100644 resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_1.png create mode 100644 resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_2.png create mode 100644 resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_3.png create mode 100644 resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_4.png create mode 100644 resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_1.png create mode 100644 resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_2.png create mode 100644 resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_3.png create mode 100644 resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_4.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 561997ab11..ed71e33a82 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -6919,6 +6919,774 @@ "y": -20, "palette": "keep" }, + { + "path": "track/bm/gentle_up_to_gentle_up_left_bank_diag_1_1.png", + "x": -32, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_left_bank_diag_1_2.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_left_bank_diag_2.png", + "x": -12, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_left_bank_diag_3.png", + "x": -32, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_left_bank_diag_4.png", + "x": -13, + "y": -29, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_right_bank_diag_1.png", + "x": -32, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_right_bank_diag_2.png", + "x": -12, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_right_bank_diag_3_1.png", + "x": -32, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_right_bank_diag_3_2.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_to_gentle_up_right_bank_diag_4.png", + "x": -13, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_gentle_up_diag_1_1.png", + "x": -32, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_gentle_up_diag_1_2.png", + "x": -32, + "y": -3, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_gentle_up_diag_2.png", + "x": -12, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_gentle_up_diag_3.png", + "x": -32, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_gentle_up_diag_4.png", + "x": -13, + "y": -25, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_gentle_up_diag_1.png", + "x": -32, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_gentle_up_diag_2.png", + "x": -12, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_gentle_up_diag_3_1.png", + "x": -32, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_gentle_up_diag_3_2.png", + "x": -32, + "y": -3, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_gentle_up_diag_4.png", + "x": -13, + "y": -25, + "palette": "keep" + }, + { + "path": "track/bm/left_bank_to_gentle_up_left_bank_diag_1.png", + "x": -32, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/left_bank_to_gentle_up_left_bank_diag_2.png", + "x": -13, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/left_bank_to_gentle_up_left_bank_diag_3.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/left_bank_to_gentle_up_left_bank_diag_4.png", + "x": -9, + "y": -21, + "palette": "keep" + }, + { + "path": "track/bm/right_bank_to_gentle_up_right_bank_diag_1.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/right_bank_to_gentle_up_right_bank_diag_2.png", + "x": -9, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/right_bank_to_gentle_up_right_bank_diag_3.png", + "x": -32, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/right_bank_to_gentle_up_right_bank_diag_4.png", + "x": -13, + "y": -22, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_left_bank_diag_1.png", + "x": -32, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_left_bank_diag_2.png", + "x": -13, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_left_bank_diag_3.png", + "x": -32, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_left_bank_diag_4.png", + "x": -9, + "y": -23, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_right_bank_diag_1.png", + "x": -32, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_right_bank_diag_2.png", + "x": -9, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_right_bank_diag_3.png", + "x": -32, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_right_bank_diag_4.png", + "x": -13, + "y": -23, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_diag_1.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_diag_2.png", + "x": -12, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_diag_3.png", + "x": -32, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_diag_4.png", + "x": -9, + "y": -29, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_diag_1.png", + "x": -32, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_diag_2.png", + "x": -9, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_diag_3.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_diag_4.png", + "x": -12, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_left_bank_diag_1_1.png", + "x": -32, + "y": -3, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_left_bank_diag_1_2.png", + "x": -32, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_left_bank_diag_2.png", + "x": -12, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_left_bank_diag_3.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_left_bank_diag_4.png", + "x": -12, + "y": -21, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_right_bank_diag_1.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_right_bank_diag_2.png", + "x": -12, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_right_bank_diag_3_1.png", + "x": -32, + "y": -3, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_right_bank_diag_3_2.png", + "x": -32, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/flat_to_gentle_up_right_bank_diag_4.png", + "x": -12, + "y": -22, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_flat_diag_1_1.png", + "x": -32, + "y": -7, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_flat_diag_1_2.png", + "x": -32, + "y": -7, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_flat_diag_2.png", + "x": -12, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_flat_diag_3.png", + "x": -32, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_left_bank_to_flat_diag_4.png", + "x": -12, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_flat_diag_1.png", + "x": -32, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_flat_diag_2.png", + "x": -12, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_flat_diag_3_1.png", + "x": -31, + "y": -7, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_flat_diag_3_2.png", + "x": -32, + "y": -7, + "palette": "keep" + }, + { + "path": "track/bm/gentle_up_right_bank_to_flat_diag_4.png", + "x": -12, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_1_1.png", + "x": -20, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_1_2.png", + "x": -28, + "y": -24, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_1_3.png", + "x": 15, + "y": 8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_1_4.png", + "x": -12, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_2_1.png", + "x": -27, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_2_2.png", + "x": -32, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_2_3.png", + "x": -24, + "y": 13, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_2_4.png", + "x": -32, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_3_1.png", + "x": -9, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_3_2.png", + "x": 0, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_3_3.png", + "x": -32, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_3_4.png", + "x": -12, + "y": -24, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_4_1.png", + "x": -26, + "y": -22, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_4_2.png", + "x": -27, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_4_3.png", + "x": 0, + "y": -23, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_diag_gentle_up_4_4.png", + "x": 0, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_1_1.png", + "x": -26, + "y": -22, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_1_2.png", + "x": -23, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_1_3.png", + "x": -15, + "y": -23, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_1_4.png", + "x": -32, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_2_1.png", + "x": -20, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_2_2.png", + "x": -33, + "y": -11, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_2_3.png", + "x": 2, + "y": -4, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_2_4.png", + "x": -13, + "y": -23, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_3_1.png", + "x": -9, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_3_2.png", + "x": -8, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_3_3.png", + "x": 0, + "y": 13, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_3_4.png", + "x": 0, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_4_1.png", + "x": -18, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_4_2.png", + "x": -8, + "y": -24, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_4_3.png", + "x": -32, + "y": 8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_diag_gentle_up_4_4.png", + "x": -12, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_1.png", + "x": 0, + "y": -10, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_3.png", + "x": -32, + "y": -33, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_4.png", + "x": -3, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_1.png", + "x": -12, + "y": -1, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_3.png", + "x": -12, + "y": -10, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_4.png", + "x": -19, + "y": -7, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_1.png", + "x": -32, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_3.png", + "x": -26, + "y": -10, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_4.png", + "x": -28, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_1.png", + "x": -12, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_3.png", + "x": -25, + "y": -6, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_4.png", + "x": -26, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_1.png", + "x": 0, + "y": -14, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_3.png", + "x": -32, + "y": -10, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_4.png", + "x": -20, + "y": -12, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_1.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_3.png", + "x": -16, + "y": -10, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_4.png", + "x": -26, + "y": -7, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_1.png", + "x": -32, + "y": -10, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_3.png", + "x": -29, + "y": -32, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_4.png", + "x": -27, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_1.png", + "x": -12, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_2.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_3.png", + "x": -10, + "y": -7, + "palette": "keep" + }, + { + "path": "track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_4.png", + "x": -29, + "y": -27, + "palette": "keep" + }, { "path": "track/bm/large_corkscrew_left_1_1.png", "x": -24, diff --git a/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_1_1.png b/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..1330edd67ba3c0b00baa6ddb97a5516e168b5b25 GIT binary patch literal 1003 zcmX9-Z;0D;7=G_>?p8oB8w0uU~bDD^@v=K%Z)nvAv+^ht&k5H^h3pn zMa!r&Y*oThu^-~CU}S|In1jN4Shi#9Bw*22BKEXsVH3lM(hoQInK5|Y_vQKWJ`X(a zdv0|lb@UwHW(4lo6)udOeIbYfy+a&mHNYHE6VdS+&3 zc6JuSu(`Rp`T6;HGMS`lisv~=5)>t)X=<@pG|gJ0;k4Ub&+~(TrhsEX6e5{SESF2< z3skAhnpLshkee;7UXyDf@)*=$eO@6>9j)xzmm zl8aMff|ZGsN~U#MF<7n27j2=^l&p^Ic-aJlQ>i2?k%GcxR9-EKrJ7uGRL9lZUd0{N z2jfnWXKF*c z=(o(VYolR18e<4DO*2`J&r4ESQL6cTqg-y)YOdo9x?SJ*5#TBiCPvqzd=r;CWOl%p zh8b&=Z~8_zXp9beV-z8yQ6?TwC6W?JDJ-iAVo45{6&mHrUcKS9-C)3hEMS@x)#Zed zBdZ0@E=kR5cF)#(t?H=P4uU&~14sjC00w{!um>>20EG~FRM3!ZA+IMApwdv`z)688 z0+Il!aa5*}B_bz>Iwj;;a6fnk1Rl~NmQ&(-o~#(Dx}`LmMc1`QBNv5QcoyhFgfrrz zm5?1m^;pBt*g?KIHaiE-0QGz#2227=QPB*S$Vqe|D;Rpts_0F-;()q26nWM!gA6oha{e1F?zqj7Lms_~~ z;k8HazJKJC!o?f=zrOgvEAQ@FXRqCQtbghE-(Ki{wc9*1M?dxSy~>8a_UY=zv;H$9 z?2W5eZhrR7m;Kv+jNjb9u>M8R;djn|9HD;N>cfw>?B|Y0FX1OPPW^NFz1979cK$PW zyMJCic>VbGo&M1yr@#N<`sszwzkB4^mCb+4$E;0eX7^j+RKELlXcCr}Ru(UxJoC~2 DLw~rS literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_1_2.png b/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4d9dc99466dbe809e439b72bb26d36b81dbee4fd GIT binary patch literal 1091 zcmX9-Z;0D;7=G{Ha<@7wt6I)}=xzNFF}O_P%(OyI(~&!}UAkq^ZN){6TVX|_MCqWg zs6~sEGq{RX`k}I%lo7Wco?D02bw|K{C|O^n+Js@)`1tt5#Dq5x2v8KsvWzJ5vK&=aC6!9$a)nZGpaQ2}}?K-W82{ z;&Fc>Nv1QwTwW-aq)Jt-+nH9|UcP-8b z5&;PYbP+2mST*Br7CpVX4|Pb?lhB5akQD$B03-}k+-}Y1({bDg2A2e(7K=4C?M|V9 zs#PE52{2w#@CPNFQ;3L0$$C)Dvni9$Rz#yNm7SQM_K{p5C=$F(M-^5{3+aMXC@W=K zvz)BmDYp7mHv=9KyfN@60oO6Q;N?nqw8|)UB-2uju5O_vf$+$*FToL+NU$ig6;-rT zax)R%3TW$}H6A_AzF>FE?JDwTz#Y5Ld`Dj0ospoq&v#^<06%e@wyf_vRcK=+LqaI zEYxe!JdetN96)H0MS39j2)U{m!QJ!UuO5CnHTBq7xL@7% z>DrO0(T!_6XC_1EE|bEo%QLU+Q?^h4dh@&8`h|lpbbs2aKRACYuw~XF&Rse4m3DVZ z_J&t~x u#z$mgrsO)gS`%&8y|3%5$L^llE^T|ts`*a;eRW_SX7|j6&cFWVC;tP^Ea3?N literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_2.png b/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..863557ffca1ced62b8bde4bdda06cc89271ae735 GIT binary patch literal 1153 zcmX9-e~i;~6n}TSyY4v15=Js{K*b5g6l}23D!bUj-epHBSB^sFnA{8vj5wfTk1S?{ zDT@rUNR^o^Fyho22dOa0MJmqALZ)8G5*wX5V-rVMWT(Uo7hA8g*=#*MJ-xlX zeSLixhS}}*{{DWK$K#=CisM*OAD4EvwaT(-g2?5cq*$&>4x~ z(HNCXc{5odUkDXTO2tgo8yZJqe(!+HyW)Oam57`|PbIig#$PGO)=aW#X>+Zz&kZ3G zqAaK)mY1n*ND06aBNajL0LpIEK z*-D$ue0{FuV8JPZD-3uH2o+;;E?&*<@5Dch`-+wB{O1@HqX04jhEFayxQ0Cga6D5fA?Lsm^7 zK&Bzhg5d*803-sET_{B(O+ZEjRg%ck;J)z;@ErIBEF!t$Q8KOi@|sjECQMUrHciyw za)*JA4X~<9(D0B!$d*@a1@(5cIG3s1GwP_;BAmeBn2&M`ssvoXz$>XC4FBVy0B#NJ3mZkmO?GDGqLu?N2jkXKQ{L3GX0q| z>7#wujy%0^QPlCl-LpTxwSFY9_CM#j6|=uhe)*X{JG5ij6R#U@M}+b5z58AZ%qK4f zDkrZRd#C@{IKJh^Ao1;E)$qRRfNZU>zdyD8!rjkD4qrL8k)I6QBrezcQ`>@4@Z#9N zkM9orc-{WoDSX|U({Fsk-28r*>ye?;`>ol)#O<&DIy)C_e0cjDTVJ_U9Na^39UWoA M$k_1t=U+bjKS4OMEd?R8@j6;l%FLY8y8uIMn* zm1acQa*ZrQg9}zvjLZ^kCn|BcqBa>itk|JLOD!tN%w&_euBq-fjLG-;_vZP&_&m?v z#s?1E7hw}=3Wp|QTDwlMN|yrQC_;^N|xk`g|jUs_s< zVVFQ5C@U)y%VaWwP>`gWrnN?+o@E)k-R^dKgTYWVnn$96A_^rL^Oy^Ahm*=!<1gJCMefO)J$CGOtZcm7e)OPE;1@577gyysr*JV z%+hhYG3jPA0edduo`?rfCMpyu<+zSen$)C)rkzHk$6^UOoe{4$9tx!siCiv+K*E6B zjS+q!8J5s7+>|CA8NDxS3Fo*(KA4?KPM`{0C{&8Y8mWxN6-Jec)lv>aVVO1PbPf4~ zsc1Z(R)ax{v9!=;kaA|+V^s$nbl77W3fPhnPc|9N=N}_AfDV8K-~a*uLjV~JP(c)l ztSk!nP%25ufg!-9hL8qQ6d)Q9BSuaF`6v`JqnHDweDD&y60{`fD9mgW+bp(jY6nbOU*Q4 zHEB7U+2^u_1Fm>9kWEEVKCRShQ3y~95Gt^66zpC}Vz+uS8KuYlN^C4f>h-kQY_wV# zLSa`b+-f2~5)rK;LE%}Q3>l=zCPy9uh14jnEgZjcS;gNkf1tg&frjcwx3?Gi%j;{_ zw$$xCHljb$wP`0ZVkrgb+#aOY4qz48m&N1OL3<+8vnu@S)*dyLNnW zZYus~NqSa6*@CgVtajnp@;xvvfG?{ST^ZZT8{D)T_6W}xRjql{VdEcO!q5Kj zC-0l!&GCyL)m0yD?__`Lyj}ck)zhC}J2NaCzVPIxs$tqF2dCOQMUApwwpUI&)zs0t zrn~&;41sLX)V;wgW3xui9Xz%)IxgyYtC7jN3zFR4@|KoM_-^*6~+qYqq_o6wkn=GlCJGF0e!OrDN&TBTNi{wv)XHHDc UxYU=pUVsbhYa43%)@|$hAAtuwCjbBd literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_4.png b/resources/g2/track/bm/flat_to_gentle_up_left_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..93060086cb9a71d38595feacd260d2c116476d50 GIT binary patch literal 1273 zcmXAoe{2(V7{#7%40|4q;Ha2fA%>|_*DwU<)z<#tG03~Q^ZC_tH6$(XJS(#F)EH5vwsHjk> zR0x7pR#sM3RcQ?d1CARhiey=uqB4GhZc-5J(rkK{jyb%^{aMlN5(f|MhfDJ(ewc4fA`A}3cnXWQS%5KlNTvMSC zOeA!;#z1O~jNW8J%>rg|;hfJT1}S%h_QzQ%ZHr~?dO~M38%!)lbA(l(1P|j0*+MZP zCcBbZznl-}rW0xsXjq`N1HBWVK7&PCG68Wi;w~ft({cn(Ce<1O#Vj~sCn*QZdO0rWa74Y{L?|T3V!6@LLZJYGP5@{C z!NY1Qu4B`fJx6&aty10*FZf1_(fn*?8rEQHHKEm-^#&F*awd~VGag&%nKSD3r^3-} zQZD95V51R{Rl96@ACCo{WW>Y9gZ5O!l}QBinPjmz1xWxb0Ehti0EhsP0$>sWumnRv zrwAhw%w`xA2srSQAZ7+x20#`-K?}V&lo%M}VcG+;5_n-e0cZ+X7=-7vE(hlKnZptn zkGo|#lF!Sqq@}Y1+*w2Vw2Y*;#ZVz@@)fL+q9Z;XNYBP{FjGJ^fY2jmquNU9c@}rt zX`hRi{H}P!FDE1UY!Vi81Wm&jfLQ=x$qP?O?j<_6GdMX(1OqP-(`m|TWqF=+ItAS5 zCX4|Rk5G7mHjXk_-eQ0@J#?Wkh{G5OW%@-T-l+NOMFx5{Z(>2ygFCxQd$^@}UHj^R zQ~r17o?lwqd>xK0n)mp%q4J5)qoX%g`HtROv+1 zp^=%N=NIw5+bLz+*}Rto?)}cH=g}L(KEZh<4jc}sp>h+^Brs6-(fn=UvxHqqIl4IqTy1w zJNkMZJx%>XeX<>-I{aMRl#j*OM kp}svc2ys^P0h{C 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/flat_to_gentle_up_right_bank_diag_4.png b/resources/g2/track/bm/flat_to_gentle_up_right_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..4ce40a5e4c65dd58e73c15764644272952f35018 GIT binary patch literal 1292 zcmXAoeQXnT7{`C@w%%T;vx^-Rax;x7a6pyA9HYb=+(wyYJF-I?Q=pJjPif2nWtLdv zgib3q?8L$vsn}^Viz(7A1FIB0p^}<3?2rY!P-Y{It2&_30*g-bvxMaPy#4ch|M)!5 zp^e?@}R8&@0R#jE0 zR4N2Ps;jGOYHGB4y&lJn6h$(Og=K9{C-3oi0)bF07EdO}v)N*)gc|{A0<@*hX45zv zsLO5i`b>c!9f{c!k~1y)a``ZYAy!izZ_x@?RAdbyCqC+-q<}RYKV+)noLd$?X{Pexnn+mDiX^k z+=k^oo%Z~`C#5CtFwKpp|GESiFD zCya(+HbWZ#j{`pm;%1Pg0b~H=wa|ydFb(4lnD)YK7(4(^01E}IG~!^jf(!GD=17=L zBs{VlEfi!}_R?_xch`}kmJXx#xPi}_#G)-)awTR0>DhP=W{L(4AW+0?RNF|@!QgJr zA_|VMUr0p#axz-TCSfT@SS&COU=~1FX5lT{J(SMl4(9VjFz`^$begi+7>9#(yLsH` zA&dbMk5af~F^0dh98J@FW*wEZ_qnW#nSnC(n_8u%E#MK+mcKE1j&G)-UhX*RN#%)i$dhsZC zZ$veCZm0?At2w!P>e_$GeREq+kL-~^3A2LAilj^(_mxv7#kvTEy5#dPl% zsw1~LMm}G%;Jsa6FKi#4FMr%+oUeQQ)273tqvdj4{~ zuWdQL=6uzuO+)J5ir=*t-a6TKe52pSH?8Yh)_6>@f{#7lbzt6b`(f*n6-U1Lw)UAN zW51%uZa%ti=LPqq?b5P;oUg^y4fCH{(3zgPtv2-zU7h;OEgMeg6#w8tR!cO}Gx}?`hw)ipI$uj~TX)biPzZ3OYNw+fT3EcJO~w C2Qp>= literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_diag_1.png b/resources/g2/track/bm/gentle_up_left_bank_diag_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b137a4861ea46e336ceb2819581165a12b01b91c GIT binary patch literal 1103 zcmX9-ag5V+6n=Nd(c>;;hW#<5i9;9DU^%8~LSw2F?BTc+uRuu_oKUcYotd#03z;~f zat#g~+UQJ*S&kWNoJoU|04X?No{gSyk?JluwF$#4Iuc^0*&i1K^K*pcd++7@=Y7fd zy?1=eL~QBsieUg)I=*RaTW_xK)x$#ry}m2FGYBvMTQ+as*rR=Yef|CY0|Nt#7A+ba z99+D3F@|A7LqkiJED1#-5sHd(94m^vEGJY|(RJN4i{-N8y7Ru@>2|3ounY+NNFotT zrNZe0_;m8x3va?O^-kyxA=QTUJ+4;wO3RH?H%S2g3cvf|HW+rG8Xabq}0 zB&1m|M69G>)m)%a3U+HaYDZC5LU#;=+z5aGAYqsi2xvHN5QN1rX9Zy{nQUmX zt2h;mu%W0BW+Wn}ka3NY4Mr_+y3OY+qE(X|KN+U+Xe`2rBrnqmg;TOZwkQ=H#ql)P z&wK4sbDP721XY{u`-dUvWgeaHC3x)xah1v24xyg$H-iqDal+#6+K;U zm}<+`J5_VRvr)?p1ZjedQ*@H$(xRA?_6bna0GAc8S$_rVkw=7f6<>yLe-}Smp79<{1 z#egP-jTBkPuy$6g6q0kc)~FWR4Y%99g;;<%fC^v$*Z^|?Eeuc(0*5jxvMuB{1OgNa z@+>$p@C863ASHxy6tV>5q);u3d<*UcPXo_ET)BUZBHN=5fPyWRFsPYX{1 zl^J1;kYI%+hfsXR=p^iJy0T!_?l?`<=nz4m!&odDNU-6QNM(||p{1<6Rt_`agf!*CYRpk8Rk#>G(H!ewn`Vfw7C|+TE{q z?%%gNwBm!0CYOD<@%8a*w+=u0;)zGxy)(nlZl8*8SjsT(py}kE`e=E~eo(u36#wh! zu|rd9o_h22kMDbDHjk}4_MQI6-kBRGSFTHu{*_tLpNGyIu1 zV#M-ahhILpTt4@%d4AS>?Z_;?n%a8X{rJG8SFTvb-=`)o*I!6U^~ThJ9fzjs-_~v( zdGC`SW*)C!z7!j5_Ya=f)cI3ABVc^v L#MtN0?4JG~nZ@Hr literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_diag_2.png b/resources/g2/track/bm/gentle_up_left_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..048c1714c828f242bfabd0b087209222fc62bad3 GIT binary patch literal 1045 zcmX9-e~8<36o25prkl>~0yCb2-T$MIr`Pyn#>Mybm8f z@10&;NKWpX+6MrW^M_}Tg>!#ciLs%uTL*rA9AF3*k1oxHbYNg$aBy&FXlQtNcw}T` zbaWKMu(7eR@$vCkB9WkJisv~=5>z#%>smgaFPE$Jy5o7X$m+NL}4P8ie@r+ zHb)hTY`G%V>Po}an|`s~v3L@b*$GXE88U9FL{+CZ^1NG?n{_SNDs%&Dx926}ppcN| zz?86>hPlN^s}}7yjGNUea@{x` zO>i+v#94(%YNTw?s>$jVK5q-9hGaDrCrIN=oJuBGi4;^OrSV!pEL4@MqdC6e1tq^* zYwx-d4x$po(tziHFfpbYOV){$%W1w`Z0lCf^w5S#MpY)BO_D{Kt*LxNm;AiiD(f9P z-*d~mzKuFwB+3w^OfzYY&q`8JRV&$Sy;yXsRo`*i+uOZf4?$c5qKwhC2;YcHO)}l) z3!RkJ%{F@GcE8@;Ywe;5G7@28u_T_5NJ?c{T@VXOxGYyMmbPm3!1McU4io{?rHG;6 zW`?ZfIJ+PR5@+hYx+d@H0BtWB~#DSB9 zKm;TK(qgDcBTGb11~m&Pu;6a+38OMwTp@$(p4$8hPKhyImiJTJbc{xe3mU zi59Lngch)7FJ9gA=#!{=ms&3ldCUzjiz%-u&#$(t&epKh8Xme`0Lp$_`roVENWdZ@u^Y z?}@4P;!~AF;;Cur$VZzi>++jd(Bi4&8{hmOUeo@*^ExhH`ta+Qe_MZTX6NMjVr=Q- z$J);wUB3{V9=t#G!sg{wJ1efu&f&M^Z?B%CS3lbv{&aS!cIch`D^2!f8mT}P29IYeHYq+`MHJJ%g?;{_WuZt%A)`P literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_diag_3.png b/resources/g2/track/bm/gentle_up_left_bank_diag_3.png new file mode 100644 index 0000000000000000000000000000000000000000..0fbc3a793771a1438654e59d91d920fe60e2e32b GIT binary patch literal 1320 zcmXAoe{2(F7{}kP+iqjB4vLo8joYkx;6)m9!pW+;ZMUVHhdbCU6jMzn6`EP~z)or? zu^R;n98jc6!7`6flLiZGWQmO_;o>^&ViOA4phy#&P^GXb1)FW+l-ClH@AK=Q=ljR! zdG@dC(l1=_^a23D!p@Gi?qY2&#)=AgF`r+X`4j*-Shu#Py*SEbvXYV#xm;daT3S|C zR$g9?AV@_;MP+5BN~6&bgqEf$j$_Pbqs_*#x5XdE%?lD43vTC3OSIGiz)MxN%~tXnjR z5k8W1#?szoE|{5<6ckW$KxF}_17IG66jk~#W|SyCX%I5DK;9FBBP^~olWMyj7Yw?f znU31Hq|2Q0*|H&5Uh>T)LogdtC`k-A5Tu2o?HnhV&3?N*EC`Y)CL@u|#6&)yhd|8( z%!d#`1szp$3EYyQ-C1KGXOHGR6NPYYJ~aocaD{?Ysr0CZ!?k9e&c?8AQ*oIiEO_I= za5|POWGG-_5F4j(noy4w_dBSNn~VA_@sKkm`E#jQp)d_801N=w0Pp}10w4}R76Gs* zmWB=+3x_oH$yg|tj=@5PWEdC$FbyCqvTzse9!u?V__JBk?|Up;B0(FCoYiV} zICw(qBDFq>2+@SZXeU@aXV5?s3Y{4A6EH%-BvU+o^2MtAkA9%PyNd(Ox2|s~_SZVw zT6#M6pYx`Vjn+TWJ`bhUf!V)SG`Ef>c5huVxgk`yZ1VSKq89Y_R&?d?<`Z$|NZ*$} z=E(YM?c;wwRMhldEZ_Fkz3#=$lX*y>Km_(DcVwF4YN5f7#P{qo02{{>20i0 zEjrz|^VHM@_wxGjO`WG}QV%|<4mUhoSStI$HPyf8DN)sV^SAB*|_w0owk_TaZ0Z+(9#Q2K&1-n9c2mOZzBc4^5Vc4oNnX0~RDI6G=V&vd^h*L422 zX1KNw#TM;5G5&>S<+fwjH~)S0XxS$Glt8aK%r@TN_4ST;--rC(&)#mDy1f?F%TBHo zLQQvG-LUVE13&Kaz4oAkY-*aX8N5@ys%498NnPSx>!GZ*cK3~`5BzNnSFov<$+Ln+ zx-mCZxmfni$o7pld*4~;zuNNrFY7;kYwoAdU%60LJ3ZFA+)r+s1@ko;4_CLB7_f}f zB|Sqkqf*KH4T+xqgTg;SfDBa(^jIQe%9=Ip;l{iF-5$L3Z%3mDwjbTucv1eK`bzV~ gvYzoL2U;J3yVZwBRISrDi?~5&dso|VYwxcA0cn{;zW@LL literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_diag_4.png b/resources/g2/track/bm/gentle_up_left_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..8eee915fd0b091386aa95aa4ea841f8556a39410 GIT binary patch literal 1098 zcmX9-acCQL6n<^mUb?ns5@*n;rv@ACDZyRo=}x)XYmMc!S9+DO=8qF@m};g6o+XS- zgNq|-kV7Nnk5pqlB&@eJLSYf(jBw5&JB?>)YM-Ur|J z-rEcF{;^%R?*f3axu<3pdvi~(9=F?ieRb+*1Ym=Orl}rI-Sku3x-j%tahhE`hcN<=SG4-XE=;U zqP|3uPG|UBUM!ZBikWOQHI~2v^oY#4VgX#0yjg|ZinFD3ppuuZa-wBv-L~O(gGfMx z0ad_qGFD1D>N#hp;zlhW>WFAZMab{~@Bku)$qq-%?N+^Bji$GFz8nhGW3laQ7L`hF z(&=GbJ|3q#q?ide8hIOX>FJ+we@5*3tLIl(8gVzwX`%$Q-N z%vP?^Ejbu)3g8L>9tE$8QCXKi?+un1*$gBbiq=*Qw8axniE>B$L^43xRnFxt!|XH|5IIZ{ z95E4B!$c;^=n0{i36=F&y_9LyjZSA9F#rJo1waMR0m=YP3{Vd|i=qnBHDuL!FUTaM z7%2F`;sFVOWEV=3NaIldJw3OE)5JQkK*u?Ue;{W(o47UQO=w^}CZX}Lo{ zMn@Rc#cQ}&@X8jgwu5>nQtYNHJB0?Sx4llFaLn&>1Q|RmkkJsQ#==@ER@76bp|>mp zbs7}Mp#mTa5b9--=*iuHJ08t6n^Y!!14^aB27^L4EJdR->5EgoG(+kvS>k*(o@fO; zNW@Xhi!vlCFv#S3$4@;p^7r*0cy)1Jfc=-xKi?x)=VqQ*dgR^HXR9~G?;ago_zziA zegEFF^6>i)5=);h|L}|PZR(?g$BNwK<>*dva-E;?VfHq2*O-{nF^#GcR<%eC^o_{pH=oa|d&W z=4a@YWOcIdo7L}T-`RZqy=lFAVfweP@3lq)W9u*4uZ^8qtcvcv8~1#5BqEEs^}qh? zOdVOdGLdN?zw^WT*soWV+GkU5J}Q4f%{Vf5y_{V*P~Eg$JiU8jd`0P|?z?tiU--7p zC(<1spz7Y^Q|1Hq^s({%hu1HjQs*|HkxT6SFeW3<)t0On@rXEvvwJNiF+ C%-(tc literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_1_1.png b/resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..f82bf610b43e9691ab906a1054b1c5410d262a35 GIT binary patch literal 1003 zcmX9-QHa}g82|2icj>LpA|1pTFlZkF3$tJzB19Hv?&yw;%W*k~S|v)jt7nlQ5&KY% zpmmm6C14MWS4XD-3kEFX9C_$NJj1BahdgvzB@Z2TuE@|jDpok~Z^q#FeILJ<@Atv) z_g&st&z?N-*a-kQxprY?Gn#x+M@-m)Irx_+A2)rzdnwB#Ry<9HW>&VqUADHIdW)pcH!KBhW zo{>mSrLsD$n2cs|Mnfn&Vyz?FJ=G2KBuiwnX-=j^jm_zTUXdzIwdv|^VESP#7`KKq zFUdnn20RaB2`CF=n|QWOY* z$HmUX>QCF_5Rs4hA36kXj!RUt#w=N&=00V9#j!Cb1Bnor}YCO1E2qi!= zARR|l2H6sF3#eB?p$+$qXF(J|k+6b>n?<^2Wm~q^>6C-O8IJ=LX%Tr~N(tV=C7V=T zN)I_}l5?iT&aB=$c86#%p;Ew-ST>W)@nk_}N_o*T3wF)yIJLlc#-Wd;L@DZhU|GoqI?BetqU(YjoIsbf@x+piP7{_6whBaW-Y>QY~2R}0g-+PbmpZD?c zz4z|^DPd&zo?!qOnVc9q(4Bj_b?>07+t;@y4*|Gf|5G#LUE0&r)7#tYa=H5Y`uh9( z2L=W(3>zFA92y$(`Tc&H4)8oD%c7!$HBHrZJ)6xJi=}FH)p6RL4jllF1xa*=!`@ho zh$jN6G@H#yg<_;!(Q0!4&OQ zIPLXwzJNrq5mHd8P?A;*R?G3aC1%R9S&NjMD8b+X!OzN+s4!ubS5s0dAIX>0lAWwN z8M{?zY*suRcxCWKfk*&pU`*a86v=RfQ|(Z?p_y%?ik2nHt1x(6pwc0>pzvi)wsobR z)tZ*xu4FfD3pJ}AFGErxnu&6JT$a;{l8eWS>2xKZw@anQ>T0{)Mu4k8W-+?p;mf#O zqoNHy)eM`hc)4w?c8aa7`X+Ky9uMR534~v!0t(A&qLhksmnDkn%u1o?RP9cKgNTS} zvL_iKj2M+ma8^n#=b|fCvR=ux>eWtX191Q$01dzZumDy7ni!xiBpxL+WSPjROC+c? zWH=}Z;7EXEK&lU=X=F;M6hpNXa!j}tJOd&RAqk5qzGR%r7(&5R%4OZQtyarMT`fEc zbi&OUKFK5^B~o=*qaC(7@$zQ2wpD7NdYkkDLtsL{6XuAROednEk&Ky{WZBBtRjcJx zQK!L(A}RrL0HJOcsjl2@;Cdq0Y%;m*ZD_R`9}dg0n371SbUbLB+AjK#35Vk9zXM-``WD^m^&~f!=Ck@k9Ns#lVib|-KVac7Vp+~+%bL`{q)9v z7y1uhnszPDjJz~^DcD$){vJ8A_q{8Re&c3$KE(NM25+oQ>^uMTw{LCy(^&ZWfeX~! z_Sj#+s|$ypxctI=@Ui!IO<$Wo)p>6E?Sp5|ZoBW?{iDYoS?p=^gNqZ&+0P&LZaf3M zugvxJ9OYg;vGm%xnVq3`o?Sm;ij5C`)%FoPMxXp+x9h~q$N7JkZw~a-j(>UN``L?2 z!oorQ3rl!>*VU8jYj=IT_Jh0>b5Bit5-$+wqu)PdgMYqW`>c2V$J5?BuZyGZ9hv8k ieYfqa;Ty9T@$v#DcId{q!(x(aBO!l=m>}1 zk*GJG@TJmRE-w^{a@k1K>RE=s0={mEbt(b3D&iTL9FH-@RG^%f%*lAe%+5ATeisM? zL}*ZXEGJ>bguR+`w8}2j@S>K0=2e7B9smwNz%a>fS6nU?$Fn})ILA$fLRCeX$z)Km z=pr2++Ue!oJ^}YjL_i@$)hDN!n8qdxe6}p;X2?ysync_5Cs>gRN{kfe;u#^MOS++y z%%suC)nCfZAA}tw#L`}{%)e;)#2!}|yB7Pzf@a06NAoE5{ ztfu6;7Hbw$vxbK1CA)*di2zB3XePq*2~kW(BKbt3n8_HrUaM4^%_ahu1b7M~b9ScS z;>$#+#>DHvY$H-=s+Cs0F<+fU-GtpvIh}sDhbO$E&nL57Txc(g<`c=uT;41htr`si zi^;rQ5!`B+NJnWc&KJ_5NlmF1(~WAW)tW&xKmb4nPysZ6Nq{;As11%mQ5k7jWL7yG zBodM|=zcIcKs+GHi4r8ra!3!OavYgixNkfKECT@!3yV%ALL^mxE-MxaF~iUr4Fk2g zTp=K%-L&fDvTi}gCDW%igIX(6m`#=E^%|-+aR*Rt%qajvR!r7!!(2_<; zYnUa}s!=S9bU-E`)b=9Yrh5QaESj#@sdVZA74_n$#Gw$a*Ur z(Fk~u;6@6L(j?MpWU%eyr=IS25i7g@4m>{J$s99CPm+ zwA@-hdi|p>Zv3$4=;a!7&GK4GxIMM;{4`aWcJ0u=+qq%+1T(TvTmJCevJ(#-nfa%0 zVxs%x{OjTU(>?eyI`QEh_8NdDR=@V;mr-+%WW5X}4l-?W3o%`S^ z^X$GW^2D7V`%hiu_cMK;|GBC4*1g9+GhSWu?_{pfF|uOKjm|F*u0m&AeebV!&RK0o Wi9MIDSvI#tg~5Ss{oicf_38g4ss611 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_3.png b/resources/g2/track/bm/gentle_up_left_bank_to_flat_diag_3.png new file mode 100644 index 0000000000000000000000000000000000000000..53ca24b47d9b35e764db24be5659cd402d484ad7 GIT binary patch literal 1280 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 Hy&wM%ySgGE literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_1_1.png b/resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..71790c76706fbbfe4f74fa9864f8916984f6b187 GIT binary patch literal 1021 zcmX9-Z;0D;7=G_>daJV^Dt4|PdQvb#oI!#Yy?n^c+^lEZWn513p+c0P#T5)Qn^pTE za7B7YnPK)r(Rx&gS|woF$}XFQ1OhAqW zL&WMT=9D7cdUVu|qXCIVGCD92a+3f8fQ(^kB%;UT29BEy(-efgOs1>r`?VT!oH!Lt zvN2LfFfyJ}2}!3EgVCy7!Q#s;(QM1MpGnYhGL>XRf>-FY%Be-6Sd(kEYJ0ltm%Tx~ zH+CW{L`8^YAdv^$!01{m)xgsZt9nwYr~k zKWz?jt)bBwH3kRWF$xor2px;15=oID6^7Axp(qE-@{Lk?uio%oZ`5N!<}po-=yJly z64g9w6~$IHvuEjDr#k4mqtQNM0VDtozyPoS_5k`Apa24g@*1*CkOd@1jwU=6PfT z@&TbBi((*m5Aj02+V9iV$~|c9HkVF|*{qV!s}xzF$qGwZ9Odw2M<51L63Gdqqg!qRUyUkiw}vV45~sq^2Lk3ZIIc(>|v!O)S0{-amQy)7xtw z{=R|dZd}tetn&KynI{&!JO93Y>#+stvl~ae^B*;~ zH~H;1=EwQsm2UB!i&r1MlU;o8zo&Qg=Qobt`u6&xTN~)f`x+NI*B0O1k$+ewuY7Uo VW9Rgj&A>LSoLF7{`k9wE{s)zD!mI!Q literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_1_2.png b/resources/g2/track/bm/gentle_up_left_bank_to_gentle_up_diag_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..04845ac2ee5071da20f8b9cc35f6d2ff383bcf30 GIT binary patch literal 1064 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 Gcl;08HbS@n literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_1.png b/resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_1.png new file mode 100644 index 0000000000000000000000000000000000000000..abf22cb7aeb292689d1c56e7e574de42b0826bef GIT binary patch literal 1122 zcmX9-Z)h8J7=G7my{vVn5K5Stq?khJPPysHPK|Kgt|jYk>y6#qfl+VlaH-4KIj;~$ zU{{Sb)Ts9%tFeR{@u-;#7~E{*$VME2g_#eBMwjB@!iX-ijs-ooDjojJ7(DO4FYg1- z^S(3t#siyr9_s;sO=G)8_IK)VCpOz{oxHStxdvc^eR~d!cE)w<)^&At*=)A;>(_7C zu%WxV8^bWW-M(?-Mwi#?B}sx|Xr5;!DX1uNEEY?pGWmR=T&|gB+plJlv*`%s9AP6DIYG7RETCGJfD!HbR?2bBubf#Q7ANOwRXFWz%7F>g^^hY zQ*`rHJk(&~&7j_j6x&+O%D2|)tEd-uI4GAZ;PLV}A^H6Z%f-dcvS>b$tYq_M*{~Wk zh%Bb?4psDMVLTnBb8)_y4pnk$y_9a%%a*l*XaE5~0nh+)02P2H2B-s$K~V+ebY#{! zAIKymX($B1D>hQpL3RngN4hu^zHG(I#KvtKE#h78_S}g;0 zxZEKiqrJ4|;&hK#@X4lMYX@^yq_~=@t`!=n-u5|x@?ZhN5u`m~o{WZAO%3ZwwU|p9 z51~}6OfblY!%{RVlSGUnQZ$)k$P!D` zIJ_lzk?29H52Z;|ppn6Lj-Ps}_pb*(Fu8x6hvA#cM>>7q*vO6p&waFz3@*h69vPiO zKf@c9C!YQ%;{4+M)Fy??SfHhJqe^5E5r&cCns z-k2Vm?Vr4M>w>)x`{vT0mnQC>48QZaaB=&DGW4VQ)(hV+js1J!iqN&Z5a@Yy?-}yQ z!jwW7qsIqNS0;vkojJYd#?f0p%=~fi#es$QzFXX4>pD9B%HWon!*^ePe&ETE+3B;p zb`M&Yoqe^%XFj#OxAnaQGd6d-I4yiRAK!X7KQyQa_HA#T7^Vi))7KuK`(?`dVE3`# zvDwdlN?+-=F87CD8mWbqm2(&FO_q)m%EbLc{oj6d;@~mt**hPewQW85TK}mNBz?6q dm4Ef7BRhWP-nPxB?stTOvC;97uXi4L_kYxZ>ihrz literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_2.png b/resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..564af32b3c78c5a10d509dc87e10a1c67a87a585 GIT binary patch literal 1108 zcmX9-Z)h8J7=HV2*EWs_VPfEiTC6s$_VuP~(=?If9L@XkkAy2G9HN%lp9d zyzlAJk-+-?!F~W(zhnFGSi5d$2hrQr&Yyiv9tG%v(U-@!wa1Q*j?T``uCA``?(UwR zo^|WiVHnoi+uPUI=k|KNBMdCNM_{(pU8+AQ#LKN zY$vTouC`ioGT;)x9R@rGJ{_Yn?m*rbDlxJZ)M`q$sh3fKCtMQci3SKQNarNBs0dbE zs-~2>5pR}KtCoT4Wv7es5kZm)Gi+24G)YQFqj^m$Wipm&))p3;%_ahm489ab=A3NN zBUFfRjZM@;*+#V3)E8R$##(h1IS8kda=Qb#S0MZnO)DIq5ZlXQc`Z4g%iCqERbxQp zFhy{xBCbb>bc`_)LNOhlH`Hn=-KdsZtviST2m&YoI)DK%4^YPdwZXF}rXVAW>?-dA znS>+*W&ms+kN`+_BaK8^9+?qTNgz854~(aPVMsXZ60oj01+lxe-?jbz!Sh`-P(y50~Dit;q5+V^P7L!STobsm_(qPFF=U?E7 zM$n5y9H~B(CXvY?i)$Z0wb}94gC96FHX^{*+c);N`_3K1FN|+GJ8_+REdInJJ)`$Z zTO!}hZhd~}z-y20etYbtW4C@kxxM$vxsA7H=cxO^~-9@zVj#Tz~L)X-ZO8t&g~g^^}~+2f0o?eemt`_csaP~%*m$)DSGnA*q4`P#F^Qh z%q2oQ;+Xj1-%<7Z{qIfP9mhu&hJMZ+eDm=?%F{O|mvcs8%c;dbHRABSi+6XOUb;E( zOjsB?esJe>=h>$lpHCcfa=qOn&%SQXnHWn4^^s@0gKx^AK}{jJ92`}}+Jd|!N? zr@OgHJFoc7VgSIrhWfgeT&>B)k|I$qPrA@c0Ej^I`qp*1F)uGKKR;h25)~8_6c!fF znKK7LkfNfZxpU`Al}aUsp(IJrw9aTWu&l-5aCkhvP$(RYP6$FKo5fH-XaJ=vF&HFf zv)pP!oi2^XO9etqglA)MS2E=%)rekGV$n(MdO2rQ`B-ewLGm7bEMyVJoN2*7lZk3& zfKdZ00XP~7SPF_twcd^yISuP29YLKtLi=M(STMarQ;4`!o#M5jtuXai3edSDwg0XwI0Jw1Zkydm(l38T0<@u@AJjO;pD_bCX<0c zW&tV>f(686L`KKdrX=Z18T@H$B*RT)L+RPX3@lNL#kf?el`CmAYSd_09pz+l%WNT+ zdn^zVqVa5!0E`Y{X|bJ=b7r;IMg*O7#A_N0+7rAtorq?$_aOm*9sm{q4uBv4V*sQO z0CS>9Xk%f}4}}D!0u~Io2@uu-fdY^Q&?1E{4EiY;Hp7?`3V!ecJPvdu&{K%nD79PF zZcZEU8zT`%JRVG^<1ptXGXcz2LU2;bFK5Cki=g2$hG5njneoJC!%3LPs3ZWFBU)5! zAmnBmvzc_9-RyVUBSCjO8cYjOm`&n39Sj2~00?s|oH@Ifk~wVNR0{WcUW$#yNP~ek zn~gS`1w$P;>LIWoiSasgf>NjTO328eT?M@u3==S}%N;*nRr2t~5A1GfqCw4_$@W}7 z-B7o-wZ8lGADj0?D@qHSAMw?)fz;`DiXKpv?E`e+>~Le#cgH%1zpk7=JM^gk!cKSX z1AdpG@65$E#ap9KyT7@96*Qdh`28R|@b*GocX7>^ajo{&1>I{nLVT)q8fl zwn4VNp!LMAo7H0qY&i;1Em1~L)@W%M5>Id49`4v^E`n@$Pxt7OYth`X#db@h{(^|Y%v|?}1Sw(bu zmfpMbUS*47wP-j`(T|n=!jiqus}6U8Va3p;-Sa-oug$BCjlS3T!;_QwPbz_xywq~jJ=I~_c2jcZL&-oE_-z4&7UGGZL{$Ic7 z<6`y@Bie;_)te5@KC|^Ywp1K%Z!1=SlXsphTJ}o1N>5izWA$jgkbZWo9Pb*x8odx) wQ82xAgwRV59^Aj~>c#;#+O?_tiMZ^DTtGT69=|*?ltT|1)-~1j*KYglf5eSOPXGV_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_4.png b/resources/g2/track/bm/gentle_up_left_bank_to_left_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..288fccc0f0424f33c4b580b1a0ad33f371b8c966 GIT binary patch literal 1097 zcmX9-acCQL82#3+y>@j*md?PUM2K*%XSqMldTz(Oxm%l+bG@xs7Hl@tacJ10J;rSd z66L_CHx1+dh+DK7Mtfkkg)PPEf<`=8$_i%X#AqWNTads~S1_v?t61@8%HVz9$NT4d z@E-5O10%l8o3?ENfX&1E_Kvph*4EHn?XCUGm6cBc+Tp;;pDGdKeCGd(izQvDuX!qW;h8{^ERzm${hd97|6tBs=1 z4M74TEa)PZkufvwsAQbYk{i`Y)C{6E9igHZKmZ70nCx(!h9%HQPt&i z8kwe>a(Y=8DR`J5?vn|>N=Z7Sq_|j?PZUI>6wKQp5A7y>UPdH%i4Mq|tO;5=n9j?2 zOD)<7tDdQ@nhqA6BDg}}i2|-;blT<1;Q^DCEq}bK7!AFMW(C42(e8+ki2Iq0#1$0L zib<8EQp?5~W^&caqFT}6q;bMe(IJ+Lh+-W z1bIvm9cs{{hlx~_&1zyH6`Ieg6*E<@6r0Uu!~*yM6aXC{3os8*!vM7)a44#vtby!` zfP+jyf`z;fYypr6NOqw(g$x1Z!>FVo+ko}pY2Z2V3s_iksSzTf`!a@9D8wu)Td!NF zrR5F*742blmtc5;d0e&`y%ESZBZbvuX)Rwxl?Ltv+JpH>M}YN&MJgKNbv0}x)Iv64 z6|;4_h?-TJ=TRPz4G6We&{}d2;f_U9wHlpDK7>*#ae;ss4olIfOp!5~OtMs#qfDMG z3q;-TML`czag?G^o<$bF-iZF5mGuss932s1_nqHfZ;{pEy)TWuaQ2(>{w=Ym9_g59 zr~~uoe=>G&=}Y}3?B4mN>r@?YUU%NQ_Q&Ywp-mUzzb_^)eLuSMheOl$bjR;|wlDA4 zc62fH_LDnq5A|MturM(`d@^_WiGyGLJvXrM@yy+;y;5;%MmsEBe@-0p?~m^L=*ZDa z@ASXAc<1rh__NHP|Md1xjr8B2et-E}_Uli6CGVd&c=PUei<3vrE*(0jO%7_4do*X? z<#XH1L$_XBI&L<$UhO`EJ@eQ$)12AWd2g`)!Rgy;i&qBD_xVB+yJbgGO(mV4P^I9p98#f5 z1BYowO)jA!RT`~&Lct1!4ZRl)bWn6JsuVY&BZn4JToZ@XQRV`L{462)KL6f4-xr_f z>FerbXU>>A0{}3yeRW%RwYFAcVZEW6``6}o0bl@KYuBx+j?<=1tEs6m7!1>=Pp_@5 zt*fg;5Tw4ozM-MPWU*KX!p1N(&)WsTDM_L%%i(Y|kk z^{4evwiwG#rBE6ed0=t_%m=IrLPkw&!s<-XV%8DNOKM3;!vPLA3Z&V~;z0)$6PTpL zXJsK5mI`sXlnPH}M~y<7#fNt^mMkI zr-93kNIdFyVTuQj_~>|mPe$BBaepoqDdy7U@;IacZ~!0ypa2jDUYHHCc`+LyvHN>d?I0!Nn4mE z;tY|p+eSFN=&(Q+2K`nTA)rRXti5{tHG&fJ&>#h0W z#U&jJd{5JXjywAYd&CXDwtb3)`o_E7kVEJ;?8Jgo_m%!SmTWxwlk>`V^A6q_UNYIV zd1)^4*Xz$q|Gqcyz98&fG$~Zyy@rj iS9;!@=UKC865W3Nla9gf&$d-bfc90LZO2#k?D-$=a3G}s literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_right_bank_diag_2.png b/resources/g2/track/bm/gentle_up_right_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..2e48e0bcf0fab86d31eb4e192168439d7043fbc5 GIT binary patch literal 1035 zcmX9-afsV=82xU&Ywmg;WmYLzwSzJvMhTKZlsK|8chn=><+z+wjgn)5^^g7$A(P?? zMi!;cqES2SLC4AntZHy&JGL+@1nl6z;)1JEA=9E2J3X|H4hx>_XU5=t-^cssdw;z5 zPOL1a=OPb80AOzExrNo>-XBbAIuz`Kf1JM$AOtH1*A@dhF)^`g*RD_~G&wmrH8m9u zhcOJBo}QkWnTe-TDT*RFjuk~-Q6x=M4a2BZYK?}|YIS^nI2utTunY+NtR%&9xn#aT z7E4T}D%2Zt)79Eusn@qS0?RP7Dj(M~NmIdV8ntO~ZY9%hsQy-Q;9KKiE1dwDfIJJP zh}BihEk(Qa*r=UA0}_p7v|}RFN&yG}GKQ(qsGdleIBqe_rXXx(vt3=^uGNt1Ca747 zjgvx>k@2)jWOPa~8Li40HeYUvR$F%bY?4lp=@cUpyh2MVrxt}`O|Chr<#L@ zu^VL}CPF+5$pYXeM%Uu$1}?d*>Sanj%^I35v?&lVg-+ztL@C466|Sj?o}qLrTHiK? zZe{G*sNaglXq?DUbe84vqF7RtYChj6mE2m*bDUnMGaL>PBvimF7*&sQ&4kz{vOTWY zm#jg)IW#+?#$cyAMzcgTO2^~rWJ)ARg<&*aD9XXJLZejPsyF`}fsuC#ZY9_kM97|=;9O-3a)nG>l(mN)gBRo0t!*=yMYzlBCUn&*)N z$OnW1FN%TOT_lV`wcn?!mAlZ|ZBCNJTuvzzREjicvcgg}N4Y%N5r{!1h2$jCaa5&{ z!y=Cl!cRXjd-F~Qj;=0?aNxHejs)cL(!%`OqaVI^O}f|EbI;Vu*uC`F?=S74zfRZZ zAD*vX-5~cH^qVh!EbabrF}F7&yf)ew7RvVD`@VP=9b?1Ky!}+lN64#bomu(s&<81c?$oj48xeoC^YnoWdvEQ3XZ^=QjR*==D>d@9w_Qee2ruC;z+>xxV)5BUfGsFW5KIzdq<({N~Wl7uIU>f`9ns k^S94DdF1-d)lYwk->!Xf_Ez@&pd$cFi^~h=o?SowKR*G&Bme*a literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_right_bank_diag_3.png b/resources/g2/track/bm/gentle_up_right_bank_diag_3.png new file mode 100644 index 0000000000000000000000000000000000000000..154857b6f292232e32274ad5120377efac121284 GIT binary patch literal 1113 zcmX9-Z;0D;7=C-byWH)zRn}p}IJ((EoMF}xByRbTo9XDy9GAHq>xVj{1XpHp0du3% zDA`?=a_dIeDpu^IVq_I6?cij^)zJ@`bW${qPAg`v(~eabQbz|>PW;(1c;0_s-UpuN zeV6ymh1aclbPWKk+dC85KdjTk*fQZB=9l~jy#Q|5H#@&)IJ#V}k&zL%+dVouIyN>o zK0c0N*u=!dcTmj??S+sUWZn2>etu>W#(Z&gqc!!pC0iWGLcuQl_XcoMjB2;s(|9l(U__Fa>8QdfDIt}Y@)f0G>z0$T zyM^|k=3&7rf-eSs4G06H^S*GIh}Kxej-=bF*)uG(B9LC0#uH&O9bpPGS5-wjDYvp} zr3sM$?adq%Tg?yj~5Xo~cBXrC|a4~S$?W*C(hQqpjlR!(Q?g|cJW{Wc2{kExfC028>dQorHa^05I@83ZzKm}ha#{ib3I!P! zDq(O0Kq4T;htd=>1yqTnMhZD5+&7*Eo`Z;h#buwKATvg|V9M2M(zc7;u8oFVcnm0Q ziZy(K>6a>m;xI-pTI?sPgKT59(nhTw;RV`{g@c|b>yL|+7UK;)Zf5jqF=JcBu4AEo zo91~`0ptKeLoZT8x(C3MTCUTfbJ+(_8x1ZR72|PP(-bP0q=Q+ODsohf4>kp|8wnuE zk8}d%C{$sQ%@2>C-ad8r{tqndpA%vF_RoigJ+?Qrdwyp5yXNi<$<1rWez<{N`|-(R z8z)^C4?q6Xmj`zIaZc~f9=q*%3!iOWFI`^$J~`9I)yc!Zln{1Vd;4tY+$-44?~k1M z;?!05$-er`?>k|$W!6h0cXxjH!Ee{YmzJfa(+}avdoOHRxJg}k=j*lY)2B9^*?)o@ zU0UlNY&&x1jRRNaW9JtKJ3r5Cjc*RA?DWF4>#CcX*>ryKnwz}!*k6lhu|v1U?!J2IZ*_fv Q80rIi_soS#&%M0#Ki2-?%K!iX literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_right_bank_diag_4.png b/resources/g2/track/bm/gentle_up_right_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..39bedc50ae4544a15628d755d4b12361711fd1cc GIT binary patch literal 1181 zcmX9-e{2(F82(^eZ|lH{#T0kbhE#L73MC$LWVIaZM#?y{!`(DCupe}WuNdpxc0&$nGyUck`p!Js`H zc1EI}SlpXTF_|2v=f$ECFIQB`jRd^y0_~6jPKC$PB7R1u^2tCkCz#{0s;N%b3VsxD zZV(}X!Xg;~$;WM_jJ;k&Vbufc9Gp=gEVuw*0N@Zru-POORWMBTde1P-cqmkoq^Wco z=JP0ScaaVc+elz%fg=Q*QGh83k#_iVSTIitMj&1m)tXX(XBfAgC(wxB9S?XjJf(}Q zA@ilASjoz@d~({z!b-trCop#aCqg6@Vc9s(ry`MDJf2Ud4NWUgPS$EQ2v7lFNd(W> zC>>>s?ogSERf1|YqSutkdagQCnuhIen~iWd{7x6^_V8Y>NHa06u`HU4C&n{5vtZQA zB;aU7WNi}XRKo65l+4ChJrx?yN~L_NS}N4*Q;-B80DuU90zejkaR4d^fDJGdjEXR; zLbJqRK)^wQ1ezb141g?vf&<2Js4`Fs!(t4YDtKr-0cZ*Y7$nR)q=-AA_%kZ6>#|{F zt5pLwxX=*5qwS>PU{oikVS?#ZYQbzhqE9D_Gg=vzYM31mPQ>rA1xaU^#iJowk-}<1 z(z6Mpkgb{pST7Sa4K)Bw0Aa(6ScC2nP&t~aRESja5yWDV3I^G5n2$yU+#?g7B#CD! zJWqQj8Fw|{f}9gd7);?%BcVYzj-OcEe)r)Iyfx6zf>k$v-r4BszTVY?D-M2nsCfRs z(mC(F3q$M|e=WMQO#8lX;Ol{1#FGByw`}L|i9@fwdLwX5Z1lsq@C!p|0OPSv|O5RPK5%bofX_?%F}PerfTIZoj;8*gW=x zF1`8b$+j!cj-X?o%{%W51oTOObO=#cN=gAdj9 zl_TBX9>4$m*(KN7Z{FTkd#s0BN_0`3JI^lvqr=}u|Fd;zs%GrDz;;+I=~DOniTBs- z!hT<vH@84k$9qit8 vobf?p@x^}=oA<8VYE>4WygO{&ymg^8WnD3r%M7h+Xbk$+^!J|X*>>Q6lw<`r literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_1.png b/resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_1.png new file mode 100644 index 0000000000000000000000000000000000000000..1889ac2359c33ba767b6dec07572d1e8d787cb4a GIT binary patch literal 1193 zcmX9-e{2(V6o2iyU137Snv__vgc3`*EFE0p4GuWQu@tD;O%A-7n%u?(Dpow?AcZv8 zv9c5_f}do=~MqF&Ggra^Gq<&JSNiy6fHoL-ep6p-G#Cs&9RvKFh>QVfpqRHx*%g?Wb}x>T8%h%ki&U(QN;DO%T4Q;nj>4gwBA z8WavoOIRUhsidvVvK`gks41Xn1)-u7fCUgROtM(QcDv$or6_8GWlMg4B^3IW1h& z<61pkohn#puySDYgChhk1tV3PC+qSRXi4K^RXNpAifDqxts-d;dhi%er9~z$b6P~K zB;;Bq(kLXRv<#{hEmqQn^91RqnIOl-L@^l*W@E8}s%p7hb#k)NXdtjl;7VXb+QQ`R zTp9OQnP|kf3aw?KY%E?%XZ51itkNKO zF`2W31&0#AlOZ}2; zF1sIyP$#X}*px%axg?!Z8oo?3n4e0Nr*l3~qni)f4P5$usrvQ{ILiARvjWya^@0s%1;k_dN%bSG#c!w?0p zdy>WLyb}oy6n3E`fpRp`yshIWyE^}V_yfB)_H(fM_K(|IJ->c!@1~xkC&ypfH8%h8 zzU%1PmqXW#D}QreU37HIvBdQ7;oq0tnE%SRtAr=+p1Go_-NS3lrDv;7kNM_>W4qss z%`0hNy*Lo+o9_9cTkdf#zx~hXg^w4Xp7X(R*OJV>1;p2z_M5kLY~AqAh6RHM_MG@> zNAI!0(}9H_=0<-xb>xMD^t$QnoN>7I{n9_)`uu6tw0(!+@UF{q#l>?*;3N0JCH)h| zPxwB9uVRQGB+UOvDYy9HKzvrcecTDl;78zzA_<8y>o4&8- zi1E|WYrS(z+yA`u-s+JH2JJ!je$7Yj&6@V&=c%rn)WNs8_ieqVLpzt9yl?w%-T9fz zPpGk>t^B=y*r9ffja}?LH{ZTx_M*W7yF+~S`n&uaV>c$V%@v-_xlTAszjs}YBtIhlD=|QHcPRFsVz2(9vnmx zLM*5PmXWbS+*ZxlTV)(I+^8j@wu(^E1;7J{7$)0n5gbCp<0B0Bo6{FJ*PnPf(SlRH!Yl_xXi)fZ7?GlZLJY?L*WF#)H2u4(@ zCY8D#Z5EP?hK}k*o1G>|A4LaPE+hzXNlJx6*?7E=P8+#gtx{<=n+R|jh$Kd3Y+N1} z%4DF%#p-^o5z05!N-NuFR~OL$X|vG|hsWs>NVmi=ikFXxon_%{JWCz{g`j$q@;W3DuL)q-z7pICVmyUjq zE?(L6g>~1$6T?$;Z{Ij@E2)czK3}%&&d}VsCug8Nv~J;MQrt0p`<8X+a^w1q9S@!T zq3h})W5jYz89p(#_nL9?O!GQD{%_ADZ2n;H`3qInEPaKeY|$Dcj0jV$xjc? z^d3ztpZIZj-?10M1ibm*q1EfU?mi|zF!tc|xu3rNZF1=L`&XZ~-+99_{!ywj@a^j} zdv~o_Key!euSZd3q60p4(r#uC+Pl6Z`_69sqZ_SZTq~&3Q}Z1KVaukiqsO1y GvHyP=$@}jB literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_3_1.png b/resources/g2/track/bm/gentle_up_right_bank_to_flat_diag_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..324fa0ab7ba6655879311257e91234c0c013f510 GIT binary patch literal 1012 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 DO!^@S literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_2.png b/resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..689c8cdadb839c573c4fd51adf27298c01b45a2c GIT binary patch literal 1073 zcmX9-VQ3q56n|;bUfM7+7ct_=QbaLKSN`4@{N8)~zPumr z{oecFcoWC?c|Mz#vTW7!^sn;=N;;DxrT;@+-|qW;~5?v z9vK}C$F_U@J{bi%1{~`Xgn%T4 z(wS(!5G$3rYAsnem8Ml_cQl5;5;3352D6EfDn=>_xs_wgQleRt?d^Qm)&{*s9ET(U zX&O`>tIC*J@VBageiKLCDC#HCu8L4248Q>-F--RRvpB9sB3dlA#c|uIR4bdkU8x|` z#K}OI4o109EE$Q*L?TOyYD_6JIh`%md99f=>{N)tqw#QzCs>gZWJb<&`AV{4$cB|| z*hQ;bZ4XR84FMj4DF|gCqGD7f7_UVHla{SSp{-~=wSl%cA|O(DI!+W4v8u?_72e8; zt&-Bwb3L;(uyoXE_ybggNRU*DX3{)g5XEvjT`LsKO2sma_RdbP*F%8I5Gi3~)z8#% zzDcCoOui#%-E_UD?(}Qj-PQp42)~~S2IHYHPejF7Okufv(rK2d6^h%{n%%JaZ5om+ zrtto3GNejGIYaAtzFtmk>)DoB?zS5J{%u49Bmfiu6+j2r2Iydb9B>TEC`i|k-Qpr3 zlTf6=h=a`m;sMD)R3MSYAwxpVJhC;oZ#)Go0|^e3#9%f}6xDcD6YKSyW$E3ng&ZwB z1!TrYt3gf+C5?z|$JCyn_tW)3skv*kQL7gT02RXGQNKWkB%aKqST!qY#cW+KS`EEx zH&DM#u`DtG*?^GaMc$En06do|cREzL^Z-h;$p`{3Nn$1=lhGU%EzzXTkR}`5;fQV` zjFKUgji54#3>sOibNtj%-<|tE@YbnC9;R>ISawKzVQ%L1~a>C2Grmnu?o_g`$72_jn|M0nkm)%Q)v4`LO`-eO}`}4h_ zRnNs^l}|S}*0C#}8EfaytZf{4s(bYCuZPdL&PuO+`~BT{xc+K!dGf}%{^K9Z&rlxM z-WzzD8s|Rw>5_11;%?*GKh^2ir}WkM3!7_<%Wo{WCMS>0ewlA_7lhj8%TLcd-`a0p zeUm><9%_C4&YdUsuDA4$|Gbc1ICS~LZMWtShZTib-TSD83Bd{o*PRf{HatZ zorz>~bfL(XE23Rh>Q1iJHdq3S(_=ChP~#z8!b=Lds{6;d_RMnkQ3012> z(jR655k5qVcvL3hDkFhOk(HP8@vw~erZkTGbTI@7yz1|LD0O9}&fDT{+Yyh+|Kz;Bm$|%S*klW;OkV(ih zU`4^@0SSQQ0Lqcb;E|O=^(=A?xEnkL91C$COGyDWP2}}x*^q2oa~!kNaZq0?m;^F2 z#^?dw2#FRhyR_a-n7y>UTd40@E!6DdexO2FG~!Dzp_D*olANxljJ#@_d8cM}+#2e& zD2_uGAQuqoXOZp8-9u2z6x(g8ShxqJUS|^tA(fIc8JUb|RHVR=CQDYiNP{Oj@h}oY zNX1c+L>7Y_u7CX0k+Iu%f8ca%UVvlUTc`S@IyZfM@$vV*{^06;+T{M3e~{?E6?^)m zaOu|38{4PW14j2CW<%pAzJK|n*rxqXZ1RNu;qilmBE x_15jP51zfYJoq2}#a{B??|vx%e&LZnJTES+q@BUa^L;BYH#0xI{LBmI{s;B}%1!_P literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_3_2.png b/resources/g2/track/bm/gentle_up_right_bank_to_gentle_up_diag_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..53defdfd1a4a3dac2f6a96ee1dd5286e71a4a984 GIT binary patch literal 1137 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_2.png b/resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..f5d3d219d93f2e10e4fb5d15474440a3776b78df GIT binary patch literal 1074 zcmX9-VQ3q56n|~nUbO7j5f$A$4IyPaLD1#d97)^+N-@v9HCy}s?mjcAFd@r zkT9cUlF3!`A!-}}uNw5A!BrL^Vm{yktK|dpsyiA7`PDu%=yp%5~B{NaA zGG@Eb>{Z+>ctr3SR}#~Rxv~ArmA42LY}Ck;SNjn=9jD zjf^z8R4c5vW95!k?-twrMi042x108QgFe4V24sd&c_Ag)&Emy$X17qZs%E#zg2ZF0 z=uSvJElTF%tdSDSxyY`OXjF3TMz!1BM=U@HKn2hM41isL76!{ewfdGYq z3=5?oSOOpskm5yY3h4qWMNut-9@JWm3x~yMRF20LDv+cDS(Y+5s=^2A0@)7v zk>o=O0_7-FVv)()$4{Sd{dM;T)|VDUc=FflFWcnjx#=^@kG{9@{>pfA%K4VPljq6U z$^ZUczP|ZNp?-M}JN?76n@>;w5j=Y-*k@M{SK5PX=dON1r0<_{-QJvg#`X2*B}=G&bE^vDYrc6xJvY6tTdul>IIelZ<&Yx#4}qDG8>(} cozs60T)S^;9e$ZOuxEw2nT6@?r&izm9}FSSr2qf` literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_3.png b/resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_3.png new file mode 100644 index 0000000000000000000000000000000000000000..bf75e23b5760c851a3832c97ddb5238dd71df2c9 GIT binary patch literal 1390 zcmXAoaZD3;6vuy1%7GOtR_&y0=T=PzH&^iD$|!oU0}Ix1!r^LCw?Z1}NVjxYOc{+U zSYtJvRtKZFV^%HLxT-ZG)~s_isfe?gWj0x7ZnI`xRyQMcbf%eTeycJ0y!Z0{dEY<2 z-*;e3v!ZB0$pQdCQBz}mYj)OVtE_;N?H4x3KLdaRwrp-|$gVj#Ik~yH91bThFOSRR z=I7@l2vSf`P*_+f6pO_;E+t8Vrj=T)+GsRbtyZVg<@5PNp(x9y(rH`@2sxmXJhfV& z*P|x0)Ml4E8Or0+1cJtJ#2!z$NeofRc?PA>qCy>7iOYyjSjnJM74{j}XPzO*mkT?*TOQ`Tk)Iq`!QQ6~0cghih6BH)U%0wmw zW>?8QS~6gyBUWw9X-s&nsh~3x@xnxiFOW$v6)w{eq=}~OS}kKT`Rw+f%N6na?xZP@azxX<C-bSOM-Z6IKcM7+sl1ZK5FI)IybghNQVQH@_>VC9aK+M6~7GS2Y4KMrFli2%q@ zL?Pv?2~$PUH0hd~3QYV3XNj#{OMky?*5Tj_0Egh!Ykd#_%;*f|`@d3EFR789qka^KV0 z6JOn67V7U$P2GQ@>K(h;D{f1Dy>7!sb{A-$eMPk}!d+5VhTQv$(tY>Jn`>9L)HQW1 z0ORPQ$2;pilH)ot5l^;)bG`{=$jhA<9GX1oQEIyWVqIuIkQ>pb< zW7o*R3ME>RQ_j0mCVr-_e|z%U=*MC4+3JhG_4IewR8o&|{@Syr8@}wtz*9>h*S+=> zd;ZYRJvDj#vCn_lcCw8rseEvTx4w$oUAK6@u}FNpMRz5CX+D4Jy5`KMyqOi-CrWnT z<&Lg6Lsy|-Z}*;xBz{#>Y}y^-CYHDF{WZVsx(p0F%^esOmT#@eoXds=G&MBWpL?f$ F&;QzYS2_Ry literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_4.png b/resources/g2/track/bm/gentle_up_to_gentle_up_left_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..a97983c19ed46e0863732d79ae2a8627e6d8e531 GIT binary patch literal 1288 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_2.png b/resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..c93071b43399784b13e1814ba6bbe33b74f7bc77 GIT binary patch literal 1070 zcmX9-VQ3q56n|~nUfNiL+A3DcQ_ma0|SGD zgF{0@7=}5W&f(!eG zjME-J=cPm+8zurO8I04i&T3gcVF>Axl&^(NTk$bC74WkXDacGn<<+E^%!PBNYFhD% zowizqMz`$dz$1ZI0bdLV9bTQIn@fL8d|=sSJ0YBdSnKV2FO&9Ey#RHldObX z&uC2}(Jp7YmVufTw}&CfAk8QoAC;t(EN7$9Vk%Y6>X-yJB@39E1f- zlicyJPmhq<7-uAUBGEBL(BqMOI$ko;R>f%9 z71U`kf`CjwHXzi?BH5FB06Y=PHk(W~^8i|{#)m>uBqGORDorIAD#OtRPnQL1T_jsU zKMMO$oIqI`nH;i&-tjYgU3c&Qz=wxsC78H#Yq3W*W~TPfKYjYx8KM8`ZYO^Q-TdP4 z_QmCoUif6?m*lJVOHZ90S#ffgZu{oGa{POPJneY=4e{Kq{mQmHq5Sju?nhj|y|{4o z>pzyio8J58LzCyeyv&=kBR85GpN&3wK1$uW;@|bt+#(@8lRkg%%wv}(?p}Lu^MbH> zYR{=3Cl`)gd-%x7`OL?EF8Mdd{u+B_F*i|N-TM7PZuqU$BD3n@Uf$p?9{umv?W4Dk zUzeB8j_>+=>$#=Zeo(Fl$G?5|#I|zWbFXpp^Y`7JeJjtOT=<~KzLPm};)!Q>4qrad bEq#yhpLf>A_hj2-&nL`G&rW?a`S$YvKTgrW literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_3_1.png b/resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..701953fe99a3a2fbd84573c7ed72204bc6be4888 GIT binary patch literal 1040 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_4.png b/resources/g2/track/bm/gentle_up_to_gentle_up_right_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..125c48f498f88984647a4e167f141e48b65db8e1 GIT binary patch literal 1332 zcmXAoe{2$G7{}j2E3MVhNen6~Hnc^>mbla6M%GiWmA0q7j_bt8+&QmGlv%20BuXPH zQ>N&yj?|ka6_q)nI5E}^l^L=!+if^W+Bwu)$7Z*&%_$nxZta$L7?bbw>!0WQ$LDzt zG&blaj-NIj05GwxwpyR9Q?pT(FU;mYjxSCEAOwxen`*LSPEL+MAP@?Lxw*M{d3oc; zjT4DP`T6+;1qD)tLV+M^3`0p0r)eX@SR4)q$9aRnP&7Ko^XW_mQ3F&92)xi}l$gzO zt4-~6X*mz!4^rU>6N|f&!#+$UGH44exYTZtv$WF7Al(iu!Wm*g3*YZd@xGCCR3`(J z3RqFVk|MuF6mf|Yen}=KgDEx4P;iWeFscB60DuySEMl=;CS#RKpH|yV5d9`o!fwCs z^}5EYz-Xzz^)H;QhRN=J7Xu&K_!s(^F zAxkK3kMiz#%AXvGh*2ORfz$-#HlSoh8n09rR2n0wC2nvf8DE->!frw(p*1qAPUSLa z{WKP4$hd<}aLjPPk&bX9@cjz%mffyA<9Y#pPULQExeXZ8v_|@c!Z0Mg_1ClR!V?IF4C#R zMpSMl5t|8T?Pj0b9uBzU(Ljoi!c0o;89wbyLg91`=XjeiH0z)W_Up=g4~7!0AgnOHY3moV5MMlYQ-Z`i&2wGw02D2U*>g-~I8Xts{I%-j2yVE5{4| z-mJNUZSLSYmQ7pP7q0j9?q9WN&x0#BdXKu7JsXQ|=g(|x-gRip)3LJ`M@=Uhn$e-F zty?Y(7#|)jigj+K7U*XrR@Pm)w!Ee6?S1A)JA2w%OLj5!eJxETok^~k9hh5ts#Lt= zqhBfyp4g)(t`eU#t)5?h=)IP=HuYARmiiZrmUf=4o&V2~_F6&b^%Vo2Z*v6B#7jfl zwp~7Xb)LB$t(l$U`&@Uf^UqUD7y7MFe*AiJPIFOh+3Xqf>(l?1bc!3!e6zbm(v^!p ztq|&6H>TpFbM_?P_;ptO<2AWMD=JChk^C~g7%LyU^&!~NNNmvy?;M(2-`tfe*}UQA zwdt!bS2Vsd;b>EG>+b2)`bqB|-~VOBWYBkxsk4<ErOVg_VyW1Q6G|Ul#zL!tb zta4C)+2?c!UjHGusN(uz=0e;1J-_RJ(hvBjbj2ZP5u82tNzs{$S@fW;rlI=$(zSd4 E2i&$wqyPW_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_1.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..07a3333c4969452142f1ae277fac8b8eee7f656b GIT binary patch literal 1167 zcmX9-e~8m&82;|gyWDx+vaPZXqw97ZOOLRH5nU!#;}%`LMNM~6D~8!^0Si_QBR6`| zVbBVls~WUwcT}#hOv?;f*vS>F7_hrlRw09P))827jBgd;d4K)$KJYy6 zd&IxlH?VNYLIA+P@P>6G?fO$1}l9Ud~%; z(N0?RY_(;g3~&g*83L{-z%_)G#S|nB&v$u(28)9Cma%uMSMge;LS>GK@qH& zR7oi{Bi1leEz5wlBI=-VB0$k0hK&e9LXy&vNG_2uGZ`zNug=Ug8Vv|A8Q>{|%A#xm z6Us!W%EoJ=UXK(S+DtQ7pRcrFKY^mO)9G`$1%i~kUWMc1!S=FfE|Dx{b9T{cRv8fF z5Jf=Mpi2uA=_q5wg+e-1GSrHhu2+i9<{V@I2mqh}paEb2Py(Qa0N4i4!l(ib9oiKh z2Qmec49NR{%>yU^C_7<-f;tcLVOWksTL;gKrvb-;0FQ(vry3!WnlGzMg+k1-jC$RI zZ7wVXsAxZ^*v!W=3!%{RVQ)G-LQw(LWl*y4Z zJW&t0VbBFt9HuFlXQ0KkkDq?K|KYPA7#-OxfVKDT>}vO`hu3|u<^5yFPR$)Z{Q9Dg z_QQa9@UPk7Z9Dw$+TUJD52Ws+`1s1Z-mh2aTlSC6&Z}L(<-g~CkQlnS{N~=9o!eiS zI5V`|GqBkI$Cu-^0~1>p^}cjbdVXNPhMVqYv;@Q#wP*u_Vm{7DbM{uVbgybH~sVJ*xq61ti-A>?p}N$OU|Oi zvY|&F`};qcpWd53yXxA|)Q_tU{=JR3dQ079PyLoXb$#yYYtu_d9thWe cSLZwSc}UNm-u)}us)FJ5o7Y|X@Uuhz0}LwwbpQYW literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_2.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..934de1995ac09d1cb7b7bb967fe399ebc925be0f GIT binary patch literal 1171 zcmX9-e~i;)82*lN^tgcwPA$2H6ta^_8kkrvMF%O+yW1_*D^heMB^gp+oC_&XWW<>) zFmQn$DY`Q?EO7}{hZ!;j;$jvUXM<;$FwC9qVgn1AVe0*{XfI48R3=H&cY1QsltnP5M@`)QW#{h7E&983lYmIGfZFA<#aX1`v=gw_! zZ=W}B9)chp9Ub%M&qqBT4@G%dmJtL_l0-$36N!YbXY%=iX^vY~)3zxuV0?h*oTBKC zMDS?Ln^b*zn$PA##gbC4sI|Jml1R|!lsPmW#5IY?DAeTyThfE&yljmn8l%)BTG@HnAsiI(%Lj^00)0o%q@d+d+(W1=CNj{kgWeRek z5;v_>rID>oms|{R3jhrRJO&62p);sIPlzQ(t_0PZVl*`qUgk-+L}O7usRn&ni7hHZ zB_UOHrJhSPOZs#r2kWNGO%r60qQeXu6$Dk1($Q#MRZE#nrBJAik2jl52rwBCIznY# zY!MU6WVpsA>!Q(!7Mt3*oo~!kr=gQ{xo8yi;~s(ZN$@ySqYSuC%n#1w7TptIiCDT`r_=fqDCIIMib5nJ#bPq$P0(JQp>ix$ z;=JQL*$8@I2#0Y3rYTrpV1;WPKfTiV*W({Jv}I5L8y-yVY4sZey&Jc#J$-s)=+g0} z3yyyaf8O5FNgUX|=jhoDzg=C?bMn!p3l|5c(Ho2JFBm1(;Q{HrAI|>sblh49a#qJ&WuxI%n;P3|vcAzV|6bCqYW$3}}HHslFTG1Ui^lsHL`S*^y*Pwc} zZG+z>EgtXr^tnF7pt_xR@ZsBM?wnuw)9mo^N!TAA=s7(2OyJ6ro+VxDKOg#YG-&k) fnJ>E5Rn2QddtVs+cQd)Or7Q^a4fbB#wBy+S*cSf? literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_3.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f5eb0565c8ff18fd3ad94329040fc27323a29c66 GIT binary patch literal 983 zcmX9-Ux?du9RJ?mT(3JjtNA!5|r);lvVtMArB{X8d<@D9o!^J9||7wGh^`ie!qNPzMn6A zKHt5|o4J+c7ncEGWn+D9E1u8Bb#`ek?)_-{BY-)$eCf)Cn9j`1%+Aiv&CSiv&o3-2 zEG{l$7`C*ult?5p*=&|!XhGm*Sya`6u4~n5wb^WUyN>4_hha3CFf{NSNMf>3NS8`P zxkA_KT(c#0x=PR0{h&S^SptRSxuhm$j67kgWLsyBs)F0h`&}*U*T$hWjl3KV3I$~z zOd0EFm|IT`I_ZgzqcM#p3OY3r^0ELDfP!IKDrMlfNs<=F9Z6EZSR5F}NxO|)7iZF0 zK0`|cr;s^~${UPoa(YXs+G3+8TfX9iMS{iYT$Yn5QDqC7pw*;WTWLF*6Bu6D2*#b^ z)J^e_mLXFFq5`CevF%K*OBP&S3-a}$ZbhbtjwC9rvUoX1)$?3O6?(cHRMkOKAKBH& zZB7Fljl5KvC8<2a7I~p8%XL+4mCN0F-EFr6#~B_UM^S_T*MMwdOeZDuaM`DdL!mY* zSmSapGLI+S@#$cSl2j_iW->VsJq|rI8M2~?96%u; z6njyN<(>ksR$8MG+iE_A?)yTaAeTyNrJ^x(m8F|JV+)Kc(#H}t&S#NAAcI6L201(m z#5nxy`Q$%Oe&EK|rVMZW`Cum|yBlk7Us=6%)fAueUOpq-LBGzvy7Fe?!S+wT5c`|A zXI@&rcR&H;kCaXuRcFqU)W9jc>S-NW<%T?e(}dZp3$cZ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_4.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..b82e9061820e88a26b61172d11b1f1feea0ecd71 GIT binary patch literal 1110 zcmX9-Z)h8J7=F{Vy{=u2Be0a7nz1-;aGjAIc#IQo^E$HjW-s(A`4I3r4i_cG8=NzY zP*a*poI#HnBxsa;I5q0Q;wa_Vq6QmWKg4m2fa!K(bioA~E}e19pv<2cgXjJC<$d6J z-uG;9CNMfYJ`4b(Q^zJ}dv&ZA`-Ysoth{vXB7hTu$LEgrMu)@E*VpHCI{W+k2L=WP z2L~|>8yXtgv15nF=krmNpW|3jzp(vHgYSl_NnmR{fA!bD3J&BN4lZm`attPp0HdHMt_C~5@>)m!GfP+Lr zj0H`^3JO+EyXpmZr;4MNA9W?Fi&>3b`5H=!_dLnTvpGV~~ zPPu)o$1ivpi3liUC_%{@qvp7z!DmXMUX@Hc;-ztaz{iLrFVkU#Q&K`IFXc_ev=S9N zW3>v6ZrR0xTLe!8ym25jjLv%kMIu~g6)Ti(sCrwgpjCl%%QPMfkm(Rpkhzj7T1mN{ zRhve#UCwqb12royH%*WsijJ^cOcc|yoQuVZ>2x`tw@kB9tF_y01h@i37NZI-u7rzK zGSc8u&9L5zmD*aZQ*3S5yJ&=TxoD3k;Pr{5UuGDU7gADhS-hCeY!r%i#p*Ozka$cL zT?xsnMaf*8HBw?J7uhfp^>VINuXH-M5DO3jPysXm17HK7i2>?C;80vehK}sIK!8F) zh6OVKwg5;3qwZldyR_bP}+hzmR+k_ivFBb5-!mKwcQt=3{C8ByJQ8F@C#c0_T z)M?N>k4!)|Ak_0B)uVd^JQ>e5n{+Pw2x_&;g~MVrD#zmr_iz{bt!}#IK>)hs_4}wd53xl7}-+iI_?!C4BV~($$_~p>wj?KM$Zw85_Z}9)# ze|$X{xc2guYuo+T-~Oot&iU~r=eHnZwHr4^H#eEf_n+~?*4&=ob}lccevRHexn&$S z))#i^Z@sqo$_J+=c3(Ju!TfS!;>oeiW8@zPF42X3{=oX~w0eE*o$puvIkYfn|Fv=9 z-c@ex4f+&6{q-^@9z1(wIHY|1^zVyzo_lq6I=%*@VPfAI?p9}U<)~V)!w#axnSFNaVPdeK2)wsz#@fJy$?b1;WkeFnK5|Y_vQKWJ`X(a zdvSFod+@-$2LRyU@)L_Eqj@B%xtWQm-*aR03cv)cKDo9O(Xp|y@$vDAiHXU{$*HNS z>FH?VLE)@E@zT0df$4OC% z44Wi{G$Y|zg~;iYY%pqrD_eZ6Bbr^w_6un`MP@UMNboY9S2(32RGL!LR%}mq{hBvw z4fdQk3keaD1xRav8yMY8X4`n)VHGb|9jIntxM)Kl5;C1CWr=EzX~|qi6}__Dud73= z960qo&q6~to}h6eN6`hAD~V!NmK&u~yIOUcP0zLmy@4^K zAQ6y~L{$oz0Ywu0G-CNWIWHNiz1~JctbCmHN9iiJl7ieE(!-U&m$X< z4+uqBR3f?CNR_q5a7Z`mx1n~sTs|)ri?XIE6j`RpI!jp`QGt(a!u+yWiAKJalw^ z`tCDt9)IhPo14dvjJ#y%T|Lt81 z-1RdHb1z@q`e*r*N1YGPUH$LSXIo#9H!uBsR=ZNWcI1OiIJKkw_{ewjbCFM2URqiF J{KO0I{0~puvqS&@ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..a9a6769e6b4959b5639789e35f9a201a5d58f2d2 GIT binary patch literal 1051 zcmX9-acCQL6n;(GUc0O$7%-ZMH;54Hu|;>38{Fiy*AeH9Ub`F3Mvzl(F4Ul>oDe18 z(ME|Hx6?+*FqQmq%s8TESmcz*f*dYx5lo zK0c0N*u=!d({XHL>1MT2{W>(^&$G(;k@%sBv7AB4vf#$g+)Myj7F!X0C7R+m0Cvfk;4_ z0ZqUvGS@O_B++1GE1vHvx}%wBgD3nF6-vj5e4MUGY+Vtotkfwg zy=vBJ6t}G^>X}|Y6(Qmzm1NkoAmk;flup<3`9`^H8Ai9=b{q#mNQOueBP(9E9uita zvdiXr3B8}LJ6d~C>+f{7k%#blsX!oxhXo=k(X_(xIdQlwQ_B~cm6~l@gDwLihbe+r z6>%*^lrl^;C)7*HW>xJpO8t&G7;GU1AP%4aXaH4!CO{7ZGz8D0jDo5W-i?(^99}goD zM`{F>NMta`;)cgh?e+Y5`v+b=IxoOuzg|5xB$p4*J$~%K>C-=+xa;*jyGIusb>`YZ zk8k|MbH2p~-riInsRd7daB07`=gOBp{LyQ_ymR*c_37u|^sTQg`F>ja{NdI7yT0{B z*QHwYOgXlE{6FXNOQ*gMUVqZ{_tL)K*1!5>_T%o%ap%KL*tu_Oer4*`{*{&WgRA)) zKc8#QUO1oGIzL^%=Z|xnpWglAl^?!6yKnDeYw9EBm4}v}F9RD_X{U^e5w6L z@ZRZXUo$TrIP&W6yDwb*Zuzg~MXW%-Zv;ohZ{FhetFvnm3 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_3.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..60ca129964e3a8eb2ac8d497c7830fc4a242ba26 GIT binary patch literal 1001 zcmX9-L5SRB6n?w2yV>o!PU$F9b`GgdZIoamq!Mc=S>zsxnnS>dLp#_&7acK&In2@=R){i{754C(rSQG?_%82z zyzjkFFK?Dsj;$U8fR&Bc*0<7n@+cNFX&!y^>s^2hT)wn@F{LvzGqba^nM`JGZf<^l zeqmt&!?4B0#igaCe6d)hX^Q7LNfK05)^*J^&33!n@4G>;8%4=jkGAPUQ}oU2yx zTAgY%*>*?l^%c+8hhcL(v3U|Jv&)*0H_EuB5?!6%F?qjT9`?0p(1;`ZAPGtZP)Mk8 zU`bd{!~AA;)XPnW1r$?gs-Qy)p`ZvL0w@@!WwS=1U=f7PvOA(Us8mLVvES_?-!IU) zBA2H`oK=XDMwSg)wOGBwn~u=(Bzvg1Q3YoTRH?{Hq@Xgg#%m3+(N(&x=7vTPwZgbJ zKJc>~JzfhX<@lJ*6qX!(2hvvRHjfXkv`l8ROg>-2ixNqxEUOD*LrI&}`_0y%*N=j5I_5wTFkQ+T3T{=& zPMvcalGmvW9Ao5n;!!Z2?jsJM44?y801m(aV1fZkA@ZoMBgaP3NF+d`p~Zn)f=C1; z0n+lQNh4cCZWRq1D6-+mcm@O>$|6=(^G1zqS*4z>dY&1EP8^3Q)hbkgt}k;|UbJz= zCA5gO64{y7yo2`e&>f>uLgawKu@aS)IlL;-^@?B_Rl8+)PAd$YI112o%m@N<0Y!jN z>O~`!dxU~n?@T64r~L@}aLCKDRIRG@x<*qbL$x{D;b~u>c11ES7m+zv{p=U--4IS(KlRvrx|0>(Tl)#le*D7h8*1{` zgD; literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_4.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..52a22fa1d2b3d0c6aa489ded4590378d2a8f299f GIT binary patch literal 1026 zcmX9-e~8<36o2Y9~QE%(f0smp_VxQS`+A5#eA}11ngt;HE{2oO;u*8H3MzkIz5v^LU^4 zPAxBqGrRWe0)UytrxsSCIu`{#H5TOu?>TV}U<{TI9@-z#k&%(n(b2K7vGMWoiHV8H z$w>^urlzK*r>B#tREl9}LEsfd(sk7|jY6SNsni+`uhrTL!@+RK(7b7oa2xKg>PIBm@fGX#s%Vv18JNoQ3@>RV{1vVL8?A)1nE-ObOv?{ZOBwYXYrg!mC{^Y7n-IL6!cET?74-3 zU)c^^)N92PEJ>vqHp2@!MJefeHJ59YN`9>tcwTpFYcLofzzrZP7*mf6Oy5A#47)sN5@srKOC#(o zRn7BmQE65)o37RItNl)EIJ}N{fHZ&!U<0@Sn*cowPy|^(c@wz~3Oh0h1_NatJP|?} zkOIg^q7s7~8F^XME~3zZTgI~>36Pette&)TRM{5mj^1n*g23(f0~BfD8DR1;-cHI6 zp?Rbca`r%Vhq>lLl8^@| z1cV|lijmxH;Dvm(*JG=d+c4X0K~c7y>j;L zxAfEhu8SW7ck|fAPhy#ujO57k=l5Q_Ab$P&0rKjEy7$q0uNn3~f6X}0%|7$%`i(EI zGG8!fxVeFRgsH`w`}=H(!um{dDbk?BvfM ztqyMg^N$V_|E?@9ky%$ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_1.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..8f80fe318f560a44286b09c69c6705fee877beac GIT binary patch literal 1046 zcmX9-e`p(Z6n|~nUVqp{$uM&fqeeL8)Dup*!BKAAwTtz%H*>?-<&PUZG`he}JS9k& zHyR}y89PRFK{E(=oB89!fK|^DA=9h|7UbNDWb6i6i8DgM*yWEXE&F<7@Okg?`R9H3 z@Okg#f%)*{`0jB4n4EiYCgRSA-SUrm+)nOny#e5X11}$(b?Lysz~JDZ$Kx3q8X6uR z9vKkREXqtMykCn3br~;qZYWd$>%Df(U2@B9;5?gIK+qqFViuFQ!+xPC>1TmvbCC% zvpc0$zv^YdCxSl?!4%*+Mi>3zG9Ih4iXF|iRHLic(6T`IWIB)x6WJ(JlDUd1+G)9& zSKDT~Tg~@v6SZqzAB_`HijK2fQWUeYTu3I%*=)5~v@NT(w$|--5d;*#^B7g~a+QGC zAmS}9(~cRPWTmUG^~#;CW*k zYJ%1Mf)SJ~TyYq^8#8;!N`j!>^L>l zYtcN9EI(iooEP2 zL8RfRKp~4oHt!xk{mjJX-5+=_GB3j3Kd-&%l1pAw zJ;Kt1Z#}j!{n_YIZ85Tab#d|In?Jt$<=daD=OZtjyK?=Vv*-Hs#>rc^u6B<6e&~Ux z7MA8Vw~zd{Z(x`1`RI?;sqbf->#toIoctkr;}`$p_73g;;t}rY^~W#l`8M*z zFL1wjYHD%%vYOg?^YqG&?e5CI&*x)jP79Y;e;Xfo=-8{9=TDsa>e~9*PcI&N_QrFs z-~MpduguT-!fom3Ki6~bPi6PNlH2;`lac@XN;rfBO+4-5T_Z?pP EAEa%^SO5S3 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_2.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..f34090bee1d10221fb1b70a79edc7755ea915e78 GIT binary patch literal 1060 zcmX9-Z;0D;7=G_>dh52%^|+$_kll*QBuI6EMOHNDrDt}FT;{S_Bx1xcD^v_FCsm6^ z>|y8nA!rZ!p_A&uEJwC0dSE|vqjMEbESj-Xdm3ETqCw^;(hpS*_A_Jfyzk5N<$ZW~ z-uL~Z3*3%v_iY1!9rK6d$Gkc1)s%0<>u=1B9R?VIqfZ{6^XSmf(D3l^$jHd(=;+wk z*!cK3hG9ORZ(?F16p2JAD$25qDDsLTX_}hNW{bsgwOVU7Hyo$e?^97=Vj%E-NeZS? zcsdi!a6En#~k#UTo_~$ z(hL|PR#CA=KG3cN`>il?qo^;VEd!xu1V8|gF-#2v^l;c92s0L26NL3-vaRbk%VpGP zgsEVJ2}K1wCKH@WCUi zEi&0*b6v@F)AgRQ(XYB&?E&(WfdCx}ad<=|qe?8M@j_1amSw8>!g{6ZH0^$e0hz}% zF`&!1ks?bO#>$EHQgYqW+l`XjZua{(5d)9_&;Seo3t%0fivjW=uqdM;%S29FAV8&{ zz(9=yM*t)OQbQ1ncHa1~Rj*R!^5xvq^ot#A^k zjGr+=f{DvDLUm$BPqO;y`k>g_s&!DiM+AY!F)kXA7(69XnIv!MDYKy0t%BXOT&Icp z9h&D+4Uhu}d0FHqK9lToQ?mW~z~%3`SoAKeg0HxWTH zj&uT*C{$yR&3ngBKj{DG&JQdeTM%L9&&?M-a(zDj`0@Q8y!D~9+T61}ei>an|K+v% z@)Yx{`|~3wc3)q7?4cKSMx+B*o@sr)I-$L1P0?rm`p-R7GL}xhUO)2Ftx3Fm|1!1r zRQn`xkn{ik&G*)$msiNMr~iI#Epz^hdv49_@sC`~eY~F=e&-K%^MR+n8~sZ8$oHnO zv~%`E{K8^;`P{y}uX3lcPlCf2SKPskS7y(CwkvW-ojx^psla~y+PQ}_`Grf1x6jNh z#W&Me@BQ?pl^fGne%ST&+rRAoQ9Cj(UB!L>KJjhqVCsUSj=ucc?V)EUL)-VwADHyq O!Tj7pe0BEucmD@+sK%WD literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_3.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..b3af42abfa1098f942e8648065051946b1acbb15 GIT binary patch literal 981 zcmX9-Ux?du9RK$I)2|=oyaL%6@gU|Q-;rsIaeBkr_ zUOu~BT03#-1OTjUJ-4xw@tLgdU!KqUog05_0?fnN=g(yfxm<2;Zf<^leqmu@adB~J zX$ixy<>lp-l@+2`EV3*kih`m@hM`%O={QcS)#>$uFdW5kI-9W!2t3Hrs;1>Dl|r?~ z)Ej)OEq8l*e_#!x#$@V=G^X;arbO6k!8NFk#qK%cprsCbX1rfdV(%yoOC;ztR0VJq ztZQO}20rfQXG0Pt44Uca*hMHT0>}V5hM72SlcY;g9?$Q|@_xBIw(Y}C2Mq=!n=c9k zBNup`Dw(uuvxduCZPD?iW?%7!dJvZj9Lbc5yh2L`r; zEjfv%@Zix0|I&W}fwL~{mzH5kmONks~+_I*=lMY%( zk&mV!p64i9Wx28-Ru!dT80~7c*JunnohS$;Px;zow31V)@wBPyS+G!W)lH)39}U3)(dWhZr23A zuJqgGecv7r+Q~Sa%?^) z$5#Km`vb4;Y%B20Z$H134bIlav*#Z9;GHYy?+YJ1x$zY`c;MP!kAC#cPT{Tc;04*MC{qgG6Hov8{^6b5KVIfPeEjsyH$UCc;ulNX|NIn;zkdt=(tqv1zNuEeedEHlU34`% azz<)!-h1-=slPKju(i3p@%j4h+y4XEXR7A_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_4.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..9e6d96a4878ff4536b62cbb51fd95e178098a085 GIT binary patch literal 1050 zcmX9-e~8<36o2#>Mybm8f z?=8=TLz6r9>;Qnt*#p5t?%eIxp0OdfpF4KqGQbeb9Xvea(t&}2!NI|yp`qd7;gOM% z(a}*1!^XzO#>dBffk1$!DW2yfNl=uirm5+4I-f6=%T}$nC`?r4)r^=a%0)}H>{QLk z*_~3WU-fX{mB1GRJPCx3F-2dfOhl`kYDcmy&FJbiv>}pSh4CjsWH!Q<6uzQKc3NrX zwYHh=R`Y$^MD3c#%MfIQW?~$lkff}l6cUMYHd`$gZOdwHZFRd{1b!8WJVuv1e8n#{ z$XJWdw4+8RQR(Viy>e%}*+&zk$HVx1Av_?Fl)|!_AZBEDS+bnX)k|fkX7^eg$O5KG zo|KI1ak7x)%#2hi#Oh|MSuJ#$wO;Qw;s7E58h{R90@MN87$6rSkCGZP4dgUM0#q7u z99SW6L_iWC)rYb)GDKv>Q6qyK1MUXTfWSjU#NvuCl^}C^sAMRWO4_!~PRB;BmOln` za)Q%+qJhg6p*pPIjhekgrJrwXTP@V=5?)|%EJS&t93GeGWK7UgaU++im^r&_r8eL4C51E+Ui9J%pd_}OFRs_)wu!k> literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_1.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..93e19d50b7032cedd364f76c21436dd853968745 GIT binary patch literal 1289 zcmXAoe{2(F7{}jj9k;Dp>g+-Z1?p%*2X$-UBqv_X$!?WGMi~cmqmc%St61Vi8iuBjI%-m|NF#NWq{PBXGK)4ZY|l<9;?3;iaUfAcba%38NaA z^}tR5fkDDN689>yVPz?$h6MvGncx{gfb)uYr+XAFpq&@9hMIiw%(t0I_sqIF+m&L;z z8M85IH<$I>@}j#K_s^t7m`^B_m`=~4n1vwi4CCdvfZZPPdgH-hIvUMoGR0yM0yPhG zegq9G$e5Z*=`A_ZlQ)G5_E=HKlp=+>>q~|s zQX*Z-5x`6#Hb&tzYXqx4;2=Z~6AM_9qB9#06tam@X$lemumIQq5C9MXNCJ>Y04$3p zp~D8n5R|gC4)7@O5g=*=5)B{&Ag_X66ozORwZfDKN+IwRJO(Hdury-jR8G6zCm6#a zE*5jA(_*2JhGj3c1)vT&A*kq(#vIl05-t=?V#ywx@u%jZIhZZ#lmOEpMuWmcXsitC zuuy{28uB?~qA#5g3sM4>au`LyD1Z`xu*||!wtFVE+Y!j;v4H=XY^fA!GBH*w=Wy_- z!HpUG1S*nfoHAr+eSy_Nvj#eKFo41+0n=3Z__0>`!>2#6x4)MGuTB2+PPvbEcdQ-g z8XP%k9do}>fAD8`Yq!|HwXXT$%FJb%Yu(w=**Ea|;IhJ^MMGw)V@k^KF?`>h9RW)&Z8KliKVY-PUj{o4`EiczNR zgTr!pEAiK!mI2x47f#*iJ2bX+Wepr8z<6TCr$;2v-MNahJ72C&VhyB zKUq7m?e9+;o14aFQ|lM4lD@=8$F0g~&-XCCA-Pmmq#^aUa)Vh7U-nB%&Vh`*+ z`sAiKJjmV~`pkC!>+$7xmv}wgYS+-jiMgiMEB9*Gdz6#4<7^H28`9Hwn0!6c(}tft zI!ZnIWc!jo2fJL4-)^Fh9%>AC44xkEzVaxxrL+I^?DT{A;?9=pYs+PZ=F@El|G0Y6 zJ92l!v5l=Oj!ow;ZPRwK(;v$&4<9;mB-`FG`=V)3+@Dvq9j~ugFjA^p`eSfY*fsTC z(+=6_VQ_i#2=~Pg{jS}r;JI*cLH(-Z;icsZ+gD$2`nSvzba(c4oNs^2^*<>f BIEerN literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_2.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..ba0ad07323ae2a496a5d87239adbf5867e60d43c GIT binary patch literal 1278 zcmXAoeQXkU7{`D1?WnAwhAHYr=}HzBNo9IYGEaAHuMMrIy~b;0DKog;DmpfA6C0wK z;KYSiww{(KDvd1O3`SJcsyNY*NM?0(x!Ag}N#c{@r86_nprKP21Wo6~% zECUT-iMj>Y1s)R-jY3kA#w2prIq(rQ&Z z99oy#==0;j5FLrx5=m!T^k;JdX+SKvlA|;pit%EK3Ni`^C>e5 zYzE*W0M8&14oUh|nTWcOMxktk1si-9e=y}8x)|g{@Ym(qZi$CiW@_Y&o(FQeZLS1Hq--1V2 zGT~%IFPjNEb5U3`Q2mofPe}6_>eV{=je~ zCZ)temH;*iaWX28P0KqBAvY2AF^Q0UIO@qHLvkinC`>{E01E(40C)hR01N|=LjWv_ zCZXF2qXLvNv>tF62oNA{1`-V*10bh?ehdmUj5}c32PFZ#25$ls2`n_?U^O0>A;6m> z0-H#9MKLPNA}o5Lc7VB+1h1h5tu3zSB%IG%qXk!DI+%VL&%#VzuLdS9Vm7L*gx0}e zZac+$974d8hz7(|RF+b(kTp>hi~}eE2#YLyMY}gbz3xyhX9@-1$eB))Rx9Ihux>Yp z8NDWBkieoOmZXehv_ZD$piK)sdKkiBoPZ)#JbqK1a_aRDY+u*Lfco)2HWmBRtxXLb zEqw<&t(W)Kyv0H*y1+&?bk!4!>zW(Ru6RoFtJfT@=$ts&-G1hSxHb2z%Xma!^`*IyM9RVHoEBe+{_)bB)wPx6c}@A=!Ll2JsAUs{*ko)$kolMs_}rG z>>bfH_KtgRah2Qn_GZO`?!oU?)n2&htNC&XZtV4*RALwI-N9>TeVD%@*s3R9kyDM! qF1=bcJ92$0`#`e=p1JzMH-#LqOX8#P^5;c}ptZTJ>1^Z1J^urg;y6M8 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_3.png b/resources/g2/track/bm/large_turn_left_bank_to_diag_gentle_up_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..b4c207b685964268be873ab1ba4893931a693575 GIT binary patch literal 1000 zcmX9-Ux?du9RJ?+?s9)PgDb3_Wt6RA*n;LHa6$4AxAcfdI_(=V8m04D^lTPKQjiO@Au2+<@@=- z=lk6~zbPy)KE4P5%Nx&UwxWqgbz(ji^>fF+`3)cj=U=$69?_|(sp;wISS&U(Gc!9o zJ2y9nVc7iq{KCRQBArgtG{y6rEQ_j|({-&}F4ybLcH8m1gCH1<$20{T3zE2$%f$wc1L@)q8$*Ftm6Q%d$(Fm@u*_Qze=@yCrs24eOqv8?vFyGib@TbYVH`G_$aRx+ zJk2F2Da9&;ppjXFR!vrK@MT-9b!4ljI6*$eBq<@y%A}|=IgQsUQl+Uh9nJ9#FR1xp zYcO$f4&pK-@{lS4VPZ@(A+(8{%V~bLI?%0=>7jjzjH^ttD3H}G+fwvQoQR>$ci~=Z^;*C?clIxS^!X z0@)~Wc17+q@?G2LyN$5#jmL+G1IPmC049J9&;=M`fFejdD(T3!P|%kM&}gV};0O>% zfMh^g0##{bNysUnUIhgfJP4ivk%z2=71V@LBx|P7veZte?E7{Y`Y6&$=7BCPab`lY zQi?-p0c(zO_PE%Y)O$zH0QE;i9GDa)Pq^!I}wcx`J_hUb3$;Zj6yY-G+}c+V$mdD%jm2uKe}H&-kk8hlQar*sl zw^^xlxOQbNWbb^xx4(*S{kgqD+O~H@&2Bm5CP!?r!GgC?LL;XZETc0A zD^N#)14>e6krEm$OJNm3F3>-kc+>gr_C|z@)Cu_NBGjT8n3!bhUhRyeSQ!gYL!4I%;EGU0r>By-ufVXlQ6`Y}D)Z z7=|@9H8nRko2*tVLD*@U;y8xq-G09i3WZ{^L?$CE%BZGQs#U@c6bUTT;&vN-K1(2I z4@byYoK0ms*_=PGMvA2*jbkpdMPN*#%Odf%gr7JWqH{46WK~qO zs9H`H$8!b>j2xJ}UcGh=h-C_!~aivDCpQqV~jH}Vd1z==m(WQwP=eohVX zg_ysT4pnloaW#!fioxix;V#1ArRV_1MR-0Q2xKCWTq2>$a&dIDQmG&?3t)?3M9M&C z&0HS$7U^)woh%2k6=}4ZDL*WXqZZs?aF|R^ik00|}(AyAS zws-j<`TRX)$MV5bUH9ee)HgKw7PV@w=`BXjB|Z~Fc8-}CQo zUfl5YyGIwC?^5iNbW=k0`< z#v9?A8_p~k)Y^V9_8Hgoe)8h&Irj%%-u=>kw*U62^-YuCpW8olYvJnNW7cbQ&UE9K7ug%)NqfNJ| z>r~wgMStMc5C0S@AJ0GBc|(8nx3~6PgUf@ui&NJ;Gn5G2JXYD>bA95uI~)4e95`@s z>gW19yB>Tor6(}$cxlVZGxer6v99Ot>3yvy`Wm0ux)BcUnS5dI+?D61A2wgr_5Y{q XD0zCWQ~`-Li6}H+R+iaj@tPmPv+Zy=tsc zZrjmj63S8XM_>_C2om*hnN|oGYLHV3M!jvFP3MVGBLC&E_p5ETxzP`Tx{{Df1 zfx*E+48w+ohK7fS{lQ?6rYWB1BuP*dS<_U*Ffy53u~@S04cBe8+cX6n3!>nWWnV0Y z#}iaC#b&Z%p%^Jww5pS;H}X7*g;|d(`1LSuDnw4BR}H?B30I4%yPj;i`A*9Y1t3B~ zoC8zB3My7fd20n$3(~u0*C++3{$;cJrFPnBG0m`qPQN7)^z<=E{7_W z0PPEMeoDmI2oX}ruudx`t7Un^64GTUUyYR9D9!|^P>_{KL1AQ-SCe8g7s-{>lB3&h z+G!T*or;$Op9KCW;0Yj1jLG>!MMAD{suNDtwS3F8(W*%L6ebW4k*P3SQ24SYIfhcp zXbsC~RWcpNLJiyNV+b-#Gf|F@OHxWvvhjE^m8#@&PN`Ji*l4v{2m&e)8H_G?`Eo$2 zlF>S!Y{>a$yxcN3+QsHht%E$I*UR|*Av`FNl)|!_ASNT-Wr<=cyGv)k=khyw@%XaFXF1+Wg#zyNh2@+hGpE05foNPtR1 znuAgZToI52NcE!>jq)NY#ZWbg+&tV4o&kY}u!zMJzaA&kW~h)?%4NfGtY*_eU9CVA z=!Aze{bC-ElnB*j&6aGnKs7T8r=jgJU7eD|2{Eq7zZU)MNRyUbfPXZ8cpR zwd;%^pb{V#5b9=;?8@Ciz(`~p4JMnp1Fc%+Wm$^FlteELg^w6$9tVNd`4z!uuh+V>s&_eptaYT}8x53N}v zeev3kAC!v@CyIQ(sXJ8dx8Jpzpbw>EkE9nub$mJ zxU@3nH%>l(`L5rm&pmw4H`k}$n(CjQ{Uf|bnYuQ9cy?vcILhAp*msYdnVb)d?pMw& zkB>&*G44)|brzrg`Pbz6_iwJ9pL^}=9}jImI=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_3.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..fb125a9a0e92036217c9b2a510c5d9aa96504397 GIT binary patch literal 5410 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_4.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..dcd90c0eaec97efddf916b4be4823d24d50e4818 GIT binary patch literal 5182 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_3.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..242cb02b90d4fe80c8aa9cd004946ba753c134fe GIT binary patch literal 1026 zcmX9-Z;0D;7=CZ}CwDtXc9z+>s#S|dFKCo(28@!q+*XgsWxEUtMvW|JKNK!XJPVdB za6!r}k{$g}q+r3oItbWpwj*X3t zkB?7GOkfx`IXO8sH5E^#QZ!BRJSRzls>-^qnWkB()EW)f_uFCE9}H*;I2J@FKSY)a}_kiDlSnO^6$rq@@xyonA9}uaapsv~a5!h4xP0PbWYj zAD=yB0!z3P1!VLb)l~EyWG9NhU$1Q>;V^DkE#WRuqdhrRHjGVEAD< zi0a)P59c5zK|Bk|0uUC))Z*y|A$yz_WJ+D#?pr=u6Ums$B=Tvplws>C-_)hRR67;D z=a_x3vJ*I{=i@PkATu06KsL-~em^^e{j}h&(Fj$gxq_5ed*}D0ASZ zArt{gfV4O&(a08&n?tQ43T?O>JOcs`84=5=aU)Nbt#sX1n@uwaoG1#=P%DuIx-iXI zanVjHE}@02)t8+?zPVFr?Ydpm=@T(vl31F;WiFYM=t5SojGSFInoc?JohbCtpvwpX zash>a&@hYQQ0^WQW}({aG1baF=&cqn%Tg|<777|onG99oXosggfoh9nlu02ai3|c& zY2a1aY2Hkw{E^WB$wysUOD~L>e(OU`^`u1J9_GlcSQJp>Er#^ z&CgC;`=s$RZY;ca;tT!F-tKRYB%&3sda!xy?{f!VnEeL(Tz{N&1cued358emmAF3g{A-U>odQ+c$pgiapU~bJI{ap*42+*VmFtg-OV;0 cQ?EtwU;X6^+QrWD&^yc@Uzq#y*xM`r1ACpi@Bjb+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_4.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..c77fc1f26a57559cafe3271a272869994d6804af GIT binary patch literal 1050 zcmX9-Z)h8J7=F_~yLNSEl0n1>8H;ju=Nh_G4?NiEt~It-dbL-GaA?G<4SI8jo*E?| zqB}>>Y#uh#dv1Ckq@VK5b2FpjpHWSh~1$@Lx~VsKm5!XJn#GRe0d)p zp7(ukZZ@`O_dUA-V9(T(6Z5@E^lINwf3HU>54{i24|6jMlRfJ5`TF|$`uqC_1_lNP z2Y2n-g<;sx(9rPka4-^ykYto)8A0GANmNxu)3idNRH<0Dz2Um;PKS&FLj%u^h+;sN z!>M#Mo1+UwzFbLEYiixeHCqNtU~zgx;ewfXSeNjUO0H;Ztq`wQ6n8c2xkk5b$3l=G zAjN<#U}XiX<@}9upi>VaFN!(|w4)taonKk6`o&BCL5W|R;h$) zwGbJIFu^DvrW1HfA>tWQ(rLBGY9^Pj3PwF)xydjUipCDwC;QUrH`Iib7n4GzcIadYW&kPXL5T_sB6dPf{U9Edyiar`P$gl7vCS)JS87K zdiKKXUq6+OT#Rqu{rY9!_^*H7Jm;Q2xxM=By4HQ`>g>S5cdm_&9r*Z-#TPmIX-`nq<}E+4wLX)he} ztg)x|pZ#V0lW#s)`tiQQZy&k%_3=CYUe2N)HeYR}|MNX)ZH}I#{`j)z38p4zC%!uR H+=>4I^D52D literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_1.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..4e83215176dc9e1227e16c7b690007733a73f166 GIT binary patch literal 1226 zcmXAoeQXnT7{{NjW49Ne(*`Owu_GNh$U!Qej^c}NqQP!(gZGtf{G~t*zB)G<9`#vu4ez zudl~2tf8Tyv9VEaGMPxy%(4v6TLr-`Nut;54F<#Ucp{yiRMm2&LYjf0fwMN-?K+ps z==PX>emWT9qH#wuC1rE|LNUS;n2l~0t$NvJR0KRMk;7g#6|`mJqMGrQ)W~!>Z83m@ z05<~)k3~f+<=5t;x=Pl7N@i4Xpcw_Bv5ih3hOO#+@4~@oXua5B4s6whB-nfPzJY!@Z0F9z$PU= z=N0lnsTlK?Q^Dz63>DK_9fcD%l5#Svo9F$45OTZYet#+)&Lt9s$;ooLjKClQ9>mC~ zmQ5P?Ea5D$zM?%+awp5mWF=mj$xowZLaU|pdW+G-6J~*?B`fE1RF`?;{y-)gSJSyl zfdPjVlX$J{Fe)x0WpD!NX=W5X7cn{#xTw-f*&eI7lheWMOrn7DWn2f85wn=JcE;%9NsrU2$gW60 zPR0VcbgZPNQKdjxttbIV1%#?z_^P;jGI%|qVv!03?@7vLS-YKgxde|#B+XvR9AwBC zOQx*mNscJlOvqtGGLAwdN-!vAtsXzMtohHoKd^J-dLG(uTsf8b@Re`&;E9}<;icBcI3O)EC>yZj_uxC&~_dV<2P1pX!~)`5Y3G&A34>#d!S+N zN@-->#Iijs)a>%DGQ80H!Pxm1`z9WHUh$5~KP}+lk7MaCSGA58w-4e(``UTEZLc(c zcPx3|)!FQ~bGEin=S+u2f0;Vd`O(aYp23ZyZQ?Gfr+upCoufluxOV&0`9+^DK0zFB zdijT`PrL{2e|N0*;N^u=nZX|2aLYxY`j_^de8knH{d#aGwx#c6`&;AdB0uj~c=Vx; zr|Gk=P4uYGEx(4nKez3`rM~TlMjDIrTAmnx;A2htnL^jL`hmkOOa6Ylsi$jv%kgbX zrfgO4#XHxPmt0+M)U2R2_=oeCOzb#&tM>5)%R-NGUkvRIJEv}CuF2rMQPKYO)zZqM mSKs?5``?8-SH$+q|6&&gyDto_9KT*Q1iDtQ?>ybHb^rgf4;YmI literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_2.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_3.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..a68968b1cf3301162d7cfea99e9e10f1ddc5ea41 GIT binary patch literal 5443 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_4.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..076632dbf442304a82fbd8d96f2b1251b4ab2414 GIT binary patch literal 5378 zcmeHLeN+=y7Jncb1eGe=qD4y@s?o-fj|t?97%(8gh(UsaqK6KXNr)ktG>L`}HCD8! ztW7Jc*y5Jf*u@noinURr8{0@}7i+Yr)MhCj(Ng<`U0QKbclITq;@O_F$8)y-nKQ}E zyYJrLz4v$Tdna$UWG~DZAMtDi0APHkJS_*_+3*`1J}Mw_-A#cvZ+ULMH3zj(O=d!) zE5WJOG80b4OLZCmO20B>`zLy-}4#>BiX*pK#LZ zS|;URyaT@ac>9v@aWg(IE@|C5Bed>0P5!4I$uv3f-2A2d?zz(k0SMWslgY9(WwQI} zz$A9BeM2Jmrc7-uR2|v#G)265rh4DP)r%&!<+RfBXBsvwnYJL|-i8_DGq+YduPig& z#14IT-o-KO zfz0xgO`9C+KQdgodc5hgic{AouBN-Z^%7%iew2`z{#g3kdli$)EqSoIQGepWVBMwoFbFM*f9W~P_wR&!}{ zBB;q`wMLYaHg6aLjwG~VtJNf8v1~S5f(=O^%vu&lC={~TTo#whgc?jsnbC@tGL4q_ z0K^bR8g9YNI+ImL7^wkFw1`+`mC$H#o_aq%gDETP0ld*N%mU_;@MI?Y3}9*He56HI4hAkh2)?jzdwa}O#*t*k6j8iB0} zgqN8np#}Vl)C8tei-M0rOvvZ3*&HTEh;W%aA;w{%0u*7Yaek5p#fxwaij9EEG+L~v z5yJye5IjK#anwmXl*?sfOav9GnLIAWW(pHEiA*-0#723ENr<`#9RZ;<>tI)+B_pE> zK&c@VClTTEFc?E3A7?Xp8m@pT6tH>BL>%WMLO!nM@rR;OW1@M4*?_`w>I|qBXPJ!J zppO9IqSWk635}b;ekjQLCL)ACJRS#S7NHt0GfBun5^)}%o5;Z*MYj+ds|_{dsanV*(>tl?x?fgR(1w#lsj;v+ezFk*{=c0)3_b-|sG^h(JZ`n(yjppXG}8Sth2$LvNqXY}Py$d$p%76~_Sjelo$eHi4=a^zT5YG@{(XHt>G8xO z(ect4mNHIUNY5Y`d3FSIh%I%p%0@+vTjgvobosS${8&~-yjaChVEh6?MpP-Q>I>^# zgv)35`fGf>4c!BtC@F|mffy}_s{nKdgOD;wU(a7%05r+fUlA4@kT}S>5M#tua(MdDpfUx)!A&#)zzN*dY{YH z-OrV`4Jm;#CY5 zCKg*1%Bn&LR?%Et)7H@J_xk#~rJztjv8bZ#g>eo&qpm{QSfz5;Y1^Mf#l}Piewb`}?_Vh* z#;nN)$CoEPzv=7;`@dd1eL+u+zDm%Md*r9ZjVs^mEgPg+?pnM0{wbcI-{@JJ(jMs#M{t+#zG-Q%RM`IaJ*3W9avi3q+*r(USwtie2b}oG!WBr1&izzD;Z(Iz! z8JoR$!{uXpv(&FMPHv&UPTl#2eAai!#Pskj3*VXZ%8aR9e>fHP_Oj?50{4V3pLz~# zTp2QlI&nHHY*Ozs!RdM7DP>{1yw1IeA8nI;vH3(z zW#56L+vrCN{C`<6%;jm=H=_pdrsu~kN-OH zqR_s5<#FbBw{(NnbC;qQ-)uqdxT4POjo$Axc-Br_hw@u57zX1$&$%uQlV9m>{#tSt Q77k>lFHC!X?n@i~1IAtU_5c6? literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_1.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..ba49b9186e82c591fec357082049a73c1ebc5b8b GIT binary patch literal 1055 zcmX9-VQ3q56n|~fUc1^I805-=-dMmBj+qZ9o_NBwUQ6t*_C~KGg;OJ*EFVHW@dgnh zJGNBf$cJ-;nPG&;juE?1)6vZ+QBS!KVa9nvCJ|1E5b&T?qXgCuRsW_8e(ybgU*3-& zzxOVkUXD#4Id%j9rWaqBUm4Ds!JR82M2&NT34~AtwSL0VFU?!*L@VHYv*DxE)DqCX*e**ejQjZHJjq zgeRgB$t9?mM#l|CH95T`WUFGKAzQ6P-Aj^eI2wy^GA*jCq6u0~%9Ru4x>k1$$1Avg zrMqwAJcMK*l0asFGBLJH#A=jc^O_sacXg|8I%r3tLn<3i$LM^VtEfUlm))$|DeApy zwr>~r-74xic!;IwIKw7+AuY>!RV}5{wS3+#m)&~3+iv&!eFR|*s3OKxaG?>FTXeE3 zVzDT$@MKD6GD*=iQdYreR12kwJa~Th;rnpYT${ahytXm@{n95NY=1Zdp{Gk9;iJ^P zLtkm*KPp@|80@@!qx{y|E5_@epK0doXP^0R?E2$L=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_3.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..bc0b19abc8ffcff18eeceaf01d939ed0f28d68cd GIT binary patch literal 1238 zcmXAoeQXnT7{`Bo*{)lMg_KaBNQX^Uu}Bv$@rIS$;6^$u+X1)ONJqMGuqKpvj8jXj zTD8+^F65A+W!9uIhpDCs4Gz3$2S;+kBo!`k$*Mb{EHzYRq>L&hneelOjXtY|bPN&oB^-WDp z&CSgSf*1^jmX;Qa-EK!w7eU|@<)vvq%QCT8ESXH_a-u9xscN-WLtOxO1JY~s`^}+{ zEgW&hId?KeW^#eN#1<5;R2B#);&U4ruO;fU@w6k&qT?|_O8N>pMxBgTRH0s#JysBK zf-nwv3dt~t#F>g2bFE;76&I`p-~tb!YzKe@Ab=o@$rQC(d51%AyT?g#G8imIqqov& zC`ne-Y{xAw(&i30JdD#9MQPs6rifV9o5)i_At0(j8)kKR>~6~Gr7=H4FmW=T4x~j! zRHCw)P%4>HT{7XoOaV&}*doBeBUswv$vONI&L}>v#0phjhU28uOk>ut$I1EJ8Jftm zloF$hNw%DgRi$KI$-=U1GGh*>55c?j^m_sS`o$4)Ks-vg}}-HM-o9Z zCL(X83eI4Oh?o6BC7iGFQ?*=Wp;(7Tr^$p_EFPPka=K`@oAr|MKx0`X$0a5+IaO9_ zB^(622uqow0UIB3rXqMYPUTa<$!xSJr7A_aR=Wjp0DJ(j0Pp~00hk1!i~!gWNx%pT zvjS9$qysQ0NZ>&90F?xg0+6vl4ut{<#SkpSp(=n!;4$DOfR98%v?UsLCU{Rqp!4~d zqGT%-1vb2_L4Zb#IBy{ZTR?O$s++I+v$b%(o-8bgC0MLF%mA|?9+%0F+d>o?33~Zx zNJvEU*@PlzE2<1@CCuxEB7iD@u)!kUuzM_PERrghu~hQ0*g}Eu`>9Zfjzk#L6~kOf z9L*A_#=O6vRYdiZX(0%jQ;YL5YwP({n*O3nf zc6=tc8|EJ5raSh`^)1~YEyI@R-pIf6$GJ1+;S-xy^Z(wzGwXRBXx~~$uiS9|<&MhW zb0cF9m~Q;f8(rr$%fB5ND`=%074#QrY!lCodj% z^rC&4VZ(2G*XG8zX|9~%DDCNu8!xV1^`bQW``CvMKa$HcZBtC^{A%qh9n0D>wqu)J z=I5`~$Bz9o@cFrx3(L2S-0S)3!j~t0ytCo$OGC>hUO3?5CiqXf&#&9m_kGu@CN1n- zvr`Ap6E}O?;@^yMohOd%J$gl-UNd-UH$8Z6WO%f*GO=#Yy(eZ3zZl*-eCm2?_^w7c zr2M`6T48$Pdg5wJI2*p)BJSgUTD&M`6i?PawGzks^)oA~zT)!1JQEgNpn7|ZS~cow}0T~Kf#W4$+d-tnq8KK(}yJDKm!igx~0G8)aIf0{|7#e9@GE; literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_4.png b/resources/g2/track/bm/large_turn_left_bank_to_orthogonal_gentle_up_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..b21d1e65b137a35752298f908dfa556ccc6151fa GIT binary patch literal 1390 zcmXAoacmNI6vuy9TUtBE99rV2qQiK0sJL8K*5Y>6Yeze@r@c-#aijHIF`_+NOvyxp z6DRGc;)<3vsAy41dTv;2LlqO8SXrbM6XI~vhzn_%amtibR$KEM#^m$f%lqej|M-4i z+q!Dm%o*>^007Lasw}U`%;HR8xmlTh{AdsXAPcNpQ(KW)SuEDHY16W@vZha;o}HbY zlas?{vvYHE^YZd|LZJ{v#W;?Uq@1FZS}kof8f`X*+wJlD!_jCml|sb;lLA7XuT*k1 z8i7tPHkqY1JK=JxygqF(WRAt1xQMNg=F@VXK_ReEh(n9^8F8OY5p>hhfGH7mrjvdd zAE-n?hXD)8cF}B~nG*Qe}?m z-DYdR<&OG8sTc-Sa<-P_7*qm_Mr7AxjEVHx)d9v3@!1m*e=7ADVgM)r&;noqfB_%? zK%5O=1_FnAEo7W98X*usqri#*j|@Z!07(F89yFuSNkESV22C*P1h0*k067j61Y1M# z3_6k3B6B$@uh$p~F^NP7X0-Tffa>!x3y*LLR33zmN-aqxlhS$9w&0{E1|vy?3nT)z zOw3VY0u71k)pCnLY=)#Uye$^Z*zI5N5nEW#rz#H|p*2xWsOIgEkn% zl}b{hq4ath6&odD8-_AC>XVDZgeaj9LX`j-5NJoC2ZJGbCj63R`OjYez^I7oz$C_RU2GYdH)RTDU33T4eC?yOuDe>!@pCBFK6?KsiFmAQ}0iyCYHYF{89 zEtpc=XsK^@SdZKuy1aM!!|_F5wfcKk=1kNH4w-j6xYbdT{5#I_7rcK(_qep_?#A2o z?87(t$$>{5S*82B^*6fmt6SVV&vuQ@CWHsMy`_3Ha^ShS=Ht+&;txCN1I2-Yz6`RjvhE#lfR}mx@fZ9xUZ|>V)-w_OOZL(toH|6uhjj1=8!!8t#zWa^1=64S@xwv z<42y4O;x9l{~5l%DG>A>8@}iooVTLl7;~xY>w%6B+|0AhLt|B;AByK|P}ZxHXFi{w z9BKHnXy$W@)>t{Vj+ZaiUvJB*=;Un=FB!csT(YHSPCHXDJkrozvnPAAebs&0+2NA! zcC)r_JNVJQ4Tn!Qj&ezBcae>v{%xJ8DvA`aLgxhi%{ykTSo-$H%MFdv)lGxV8ydzHB75Vw-pi^=WVa;E(6N5X)o>3$1hi*m}uRxU$|+c0{wdu4Mc=_h4Ih z;Ge^f?v(ZH;VfRce;{w(oon5fca<4;pSs(;H{u>$u80d>O}_KlAzsf^CN!X`qPqOo I)ph&-2Q*H3`v3p{ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_1.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..94a66b81b2753049da380ef386b456cf68dc3f0f GIT binary patch literal 1400 zcmX9-e^8Ql9RB+AMa@ye4Hw?1Fy9pwb#KLt8Yvp;TfXYsVnrL;dkz;l+)>9RyXYh% zqmA9Ds8}Pzh02s`rnKW46}!1&8xPvqd{rEUkS<*WL5^Joo(bdH#5wPg_-` zI6HG@CIBG2ysV@q!Aldfh?bJrRTG!<0Z0K=YuA@1WKvR6a&mG?N=j;KYFb)adU`s7 zAT$~+BO`;!;czgFClU!s5~nDsN~P54bY`>F>2!I$L&0D)7Q=WzC;$YWC6zK13btCq z(;Eb43t@N4+#Z$BZwQ5LA}%5kWGQi`R>C$?s8xma=|mp0#OG872lbJlEgtoXSwO}G zY9TO^h+T0XIAw&;%K?A@K!zYnI$g_R8Bx?G5cCnmpj;l%YA38# z=<%>H21m%`5p01B6)U+CEk+pyDvLt$`&_SAy~7LXnyz4HRWjtDOde$7=PvT%n<%Xfz4| zO9@ajg4yXJH;eRf_slWvQA(4h@@ERldW7Mp-V03-mY05AgJ0ALV+ zFalr#ga~R>&|!nY0D%G}224WW5`!QCAPJz72@M#u5zwW8K0OTDz>DDd02cuXfhZ`Z zR?RgT#daIzcI*6pMaBJX!dJ&rROY9 zCiub0r8SrIYlkX^e_+qPd93EwzQ(Ov|B4+Lz0v*bM08;90Us?_rF%N^Nk=T{-h~xv z{mJl|;pxTak*4>au->g!bj;i{(vR2ocJaG540XrL>S>GSO)EnC+MBbF*X(etcv>;> zfvB!?)gRWyIW4bVO%m?eX&X)LI(*^k^(!6T@#Sw7*+1RHdPw6ocKDdV^16)Tk=)(! z@dqWhE?#f==~#E$>Dg;G3yjkXE9!feeZO;_{q4%{MxAGKb&oc)_7{})qTiHV32(R{ z-_Oe1Gw}KX;&St>)BU}bnZJC&8*6C#YBI3te%p+cf<+G_Qm&nuUm$vJu+r@d31E=`f#ak-~jkLJ!>IUXlp z0q0MJt6ChZIP3Dn_%!lC=RjHZ_PqX8m0KR&-$(s3JAeLXzwJJV4zE8~w`WUwq&biJ zIVWG;yfXJvbJP1{or>GtRrR-b&8%qZmsfnmqS_0@WQ+fep1PBh*SwGaiau_ssECb3 z^N;wh9XirEV)7kaup_^y>+89k%dL0s&Dn@XmM}^S!NF0HI@G$Y_}NT6XL>@{j%AMa zY}Ifb!DHlHTIlmj40IA9S(+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_2.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..b017f22fc6b69ae8bedb95e10211ddf585dc1011 GIT binary patch literal 1274 zcmXAoZ)_8F7{`BGyWPrw4hoi8Ns+=jRgsBVL?V?+Yieq0 zYikh%sjI7#$z)26MuVby9LFe%plK`1GH$m!5D3L$@l+}!ip5e1)dS23NTS|qRX7}K zr%Uhk83REw60;?eY+CT;@?l(uSd8@yq2w%Tp4Ns~bl8n21D14*5y!j*F;zlWL<)YhrX34yAb`8^qmF!k?hRXNn@mR1Z}V~IO8R~AzLWU z#04%T`h`LyS5C??prC-#4%9B7>J+p=1=?_N8QC_pe#gTJ|$Nev^ooFuw%HBqI@(RbUI@`UosRD;_+N2Q!ExCP%%Io zK+uRBPpGK0&Yr`)d26`fOceP{DOQ-wmSMe4E;lHZCbfpr>1m^pB}lKWvdk6p`NtwL zF(s687_botOUXH#ns?}eE-dP$5<&Y|l*=ZAg>0%+x(hJ?EC8?o@Bl;s7y}@W09X-; zLl+C9VJK!vEnraK$3WZ!L=r#>Kt>6DC=8P@?tp186vN;tcmp7CU?C9)t>m0KKW~bJ z=|sXU2+=}8fE6#59iXmyj8~FjwJok?L?d6cMoZ2_Igp-==U}#|RRDt;G3n)2Ozogh zm!04_N7&CLqJAM2Er=;t${7d(#sL%ogcTOvirq7*+^%3gZwLmSiA|?*tCey%XqSsY z^=^YcfT2+wO%nPHsVi7C(58l*76wrm$Dlw|j^D7P{-38mu)C+50;n7=ypcO?fKCwms+Q9Q*_2MOXoF#!?I;FKs6VawDrrHTiZQcTO<9UOy2ND--D07ZajCn z^X)qiM|Y98m5Z4wCpLDcnzE}tZSUEk`8zq%(DJiohS>LrnmD;m z%Gr(cI(v@XVm3FF>~{Uk;6ziS`gHFnFOG`Co*Tey`k7 zcd0;a2!^-JIy<1~ANb|1S;wkI(CzPfzFatdW?=2X(Qj+5Y+LcOO^@5odd}Q@e5iNP zzk@HmGt@dizxdj|8;QrSo6Sd-99MpPaq7O}er4##oi88l>K@u$HMehXKr`rZ>@4qJ z(Yl8&WM=2k>2B6eVZgKm&0(rJq%enw z!JWgb&LQX^g9IEQ;)nqUy2YSDq6~BnQ%K9QjF93S1{`(4P)A*G4?j~1-+Pbm^1ctg z_dd9`RXV%&;u-*)-MqT7lTAFU3o8p*Uw{7oZvYE$?X}%28J(M(o1dRwSXfwGTwGdO zT3%kpFl=RIWp#D6P%IW%mJvlkQ6x>Pn5I#$*W2w*uNU$g!7h`IMs-Z~pe{!3@~~$lgT^%RPSSpf0F{QC z0FHun4J>Nnqi%jSB+!&WGZmdW2=$8qGJuL<29DbV;ZT&v^9Qm#(DjjRA9p$^iU>Ae z6bg(?@+ws_=(5df4sW_*-IrRS;tkax(MgVAN=06wC5@{XqS25W9kmk}L2UPvRy^&F zPa<4^yaELsNDC+j<2r>>kE%q15to}|(@UK`I*{qS#u2p=-7NE6O$<#Xu4|*VIq~ah z)IN!QH0k4cj-tyfrwd|DQJR|O)@r?GGwO8WAQ&GWrfG_RFo0@fY!??pLK)KfSZqux z-n15`&f%;#Jsq8(9F5~#p->`=3e9LdZ%T4Q&6ZicW^2&xCH;6d7C@CSQ^9SObgHy# z34TKfU47u&qsX0(`m@Uvrj*5lZpPGgj55jwC|PH+mcN2&p3 zB)pSW{8=qLX%A0>F&d>*9yk&!F?dBFs|suBl4DoBmL2-7xbIJsKAMd=NkRdj1Q5!y zXk>EFK-4XFGU43zGnm7nSg9!0s%BXR%hWlhEwH}GMiO%<)6;ShsU)%~?93lK Qxy%M^UfJ6CX8q>g|MN$q>;M1& literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_4.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ecd6d8fdfa7b1daa0e902a2a2a0f7eea2c25b187 GIT binary patch literal 1121 zcmX9-Z)h8J82&YFdg;Q9B}hs$Ni`o%JxX*Z-o`P{?pm{YvsZhC3~rjTQ!|Wm%1!bi zXvA}d8udP87%^Z*&zhD4^C5#+4;S^oq7e^PMqJO4l}s~MYwRM+XdORq44(Jjm-m79 zdEWWysqo%C!+QV#dnb>K&)9Xuj)z>mc3$ebGyrrqG^ib7(w7ANt9(dmn)P?6~kDwtahh^hX6$amT~jEHy#fp zlA&~l%;ni)DXLecnwe=dRT@Jgq+4WssYpN((1L`QWxAS+)JmeYnr>NYw{3*|Ac}zm z1r!b`ibyr%sTaMSnjf}8uoH#53WP=w02Y8Kf`}eZ%I{ZDR3*tW%dW;^^;BxJP=M8{ zANK|+Ux*EmQ8X-KkrXZ{q?D&+jmheqT8mb!Sb*?{!aO)LbOm3D`v{D zvSzE;=vF-x@N&Qx1A!z!6@)1G!X=ciQlc5jG$ggH7_iJ@UV-o@!dNCk76n?DI8zqt zIjO11?P{)TYOrZ|yab9xa3V(0369GMLOziwWir)5!K_poYisRx8v?%w&>VsnJ+$uU zYFMm6r<=UmO6YB6ty604*1OP+c|3&A7Y+nDEF_Sm#IWh8y)0SEWLJwN%P>0)3Pc%1 z;ykHnK#61dB&DS}Js(@uQuS)SRW~}FO-KO{0YCyk0l>DwDgaFcKpQL#lM>WaXw_L1 zh&aenpb`ca3m^xe=z|#?sw}L;VJ!_U72FY?01OQxED{%dsRWi)!bMfkb=fqvR?CDo zmp=yZq?=NFtQv?`P|+flHm`LOdN)_wtu$c0jd}qQK*AvpPX*!}o{TX{Dz0Wzx|TH! ztz{Xo(;yfIRsggBgtiuGo9-_Bax&j+68YR+NVOWx^ISYGB$FZ@l8I1`!ZjMNGNCmV zYej-E8h|Mj=5bh|pvl$f|@w@>Y?fB)Kr^9N()8_%BkVXVZf z!NI>Ty;atfeGjyopB>scyl_lDd42bd;bZqQ6W10y@AWw9BZGa#Gp}DZ#n~$t{`-A- zTpJ;t9({0zr%x`@^R6S04_q92b9w9R=n2=SPtcz~xBKMj4~I6CiU2Nf#Xhhc}{pICy#Er Y=MV5VHWmh3_MO1w#MJm#hv(k?A1U|kC;$Ke literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_1.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..28559cd57e40da9921d60923cc5b608ec148bbf6 GIT binary patch literal 1011 zcmX9-Ux?du9RJ>*UV5uX@G4doM}!VDjgmng@{ot9xuc$$mu(po*N3R_EVm*7BNizV zuyCCgjIL-s`%q>WRpPDFJBd2x@cgq4WSg#G)yoeaPXoIG)6IiyolQ`6JaGcz-@v$K&% zWNvN_!?0*HIzK<3NG6jk%ZQ?&D3YdS3_~v#i`8nq*>v0OUJ#5Y6P5vi2U&_`GVxrF z%omtanXlI5MpJEhM%OP7hPFs!X+EY)2{TPv8dW#g?V{*a)7_>XbV{SZ-XFJ91gJFR z1+WyXp<`Yd?>FL;E`df2nyBc&La3btkO5Q-({bD+2#ca@p5K<`PBz;&&71W)@;ri# zCxrwfle|i$bUJOan#CJ6vFJ#ZmST5RH^`D4!K9MBLQ5K#(M7!^m+ETW)m`6g2Ni$R z80>qv0C5EpSs)8QSr}JOq?%O56Ldda9vJr6YNKtLj%yr|PtoNx-_XRCq4-6uUp0nK zaqLz1eFqKOc$}l?G|OcLF|R0PO{?Ye&2rhR*L~L=^m^m*7y+RJRmIo_F184zOJ@gS zX_&D``PSI#O`4;F{yvJ)IL;*!DKe?hjK=eZB$w21S)p03bQ;Z|?N0^*s1jx zj;<91r=+xM*^XoOz1pbXo=k2c0U!-v09XJHKnGxm0SY0Ds9+$+MnPYuKxd&MfSZCq z2BZMe6R6B0TSjgUbxSC);ZE=zNFtwaVGiJezkkx4p4tg#epNS6oY33GN-VGtYn!vyJEJSir;odK^sj5oFpL^ zPyh&pS(HM#yC8~%+HlC#s&`>@yJ9AzLVsvA^&9z-y;h6?o#$pI;8i#g(Ne&m4RI%?qa%ix1rs`3C)T_I&=cH_q;C zK78@qy=&&~m81H`N;LAxeKEhZ_~=IL{HNLnThFCdKiYj@WAohl@x5Euqc=W2qOEOz zF3^iNj{nj7>dWAty{kLBROiZvr@qKauS~tP`P;W^k;C2P7k}8A)%V`n`~AwZkNvy# z%ldcn!t0&CZh!sWfB3EIFZ_7_u}3bwdhMBCFJHTKyS%f0_1zs~mzjTX1-DNey%3s( NmF3l?%TGQ3*8j#Nw-NvV literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..5314e915ab4499c00c2dfd659a23fe393961bc3e GIT binary patch literal 1031 zcmX9-afsV=6n=NTyWFiFRg3mm#ZIb52qTU#qRUuz=DOaQ<8oe3E7Xx;(1H;oMyRf6 z#Qsr6g*YnAFT zW-tt!ot>SVn@gnAX^J8_juk~-mh+mXmdj<+w3^LUr?cz(!_kN$fn`A8qxpPXQBuVc zS*bE+U1&6=wySl$YJXsJ1eRl>Dxc7EDMQ9BjoK=6u9@pLRez@v`1W|%$tFP}pvZzD zVht5@tFc}qKI$e>K%$X^_6>wOX#fF0!Z0-!)00U9$8Cn$5`>*Xp{MJ&EepABl8UF< z1SzB#3D2rTPN!sp(dt~;;cIQt?n*7ckfM`hHqD3xFVlIIQ!7HnlB|~6^7M{h^MXcy z?8aD#i;yTlssy-!(N-ec#Pcqzdbw&}vxi0pZ3#qNrjx}iQOz+8nQLpJSC)IGHgL*A z*BpBe8gycD8YglTU0}JQC{|^;UMx1NRoAk-R;$0eI~)!XBvrsojB3QVc2evTg+5mq zp`zG8r?=LKn_3yFaR8Y9e@D_D1^YFl7<```8@##m4X@ztt|Kg zAQ6z7KvfFa0%|F!TS2}JcY~*a=O8Cwik#4kM9s)HY`NVod!7>n9tyRR1)xe%)<_6; zN^0S%<nJGb*;nW_Q2UN4+5)2Remi$ylCEDI!%W@P@9~HNEZByp9w29W?6GJdav{ zd_XA7q7us8L$X||4+eDIya%n@T#y^Id{7FS>R-h6gw|Mut~pO{xpM1NP#%_>_ro_y=jSD#|q5}`1>HEf fy_ebk=TGe7m-F4j+b>C>0a(ebEnR-@%*X!&&&0UB literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_3.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..7f3a1bb0c997129c171e354bc23b65398e4e10df GIT binary patch literal 980 zcmX9-QHa}g82|2icj>LWWwT+{1}~GX}r!`}nT zRFv+#*Svq8yIfmF4|PWo%i8y&ehzlF1i& zq9hkMjS>x7wHV#z%&yRIrM9m)L(PjT1(qy{MNXk5oh=)J(UhA#t>+nDWQB1%n)N3~ z0nS5S0ipthI#4#o_6Tu6l>^?0)Yimw=5~m7Wje33WKE=7D%aNq-&CT8KJJ)Pw=oYo zN0E!BA)aR`T4mS@FVqyJrR&{VZP023yhL-$44kf<2XwYVxg$eC7t6;Np5QCvihLa-tQ0MFiIvoXcA^BxTO{BD&4K~ zZd38Qm3`M52i@5?Op-&y1E>HdfDPaR>;p_OKq+Ja)lK9&C?3lc7!0&|@I;7ZKnfs( zKrIG2GV-cu*hH}dkAi1G5h-$8lp1WQ!!xeH1X5`v(=)Y*v;wjy)Mb#zqex1R zpM5d+&!Zo>a%oF}R~|n2ASKr}H_l&v{>$y(4o>}Y`sDJTw~_nR$Mc_J=B^!I|M1K= z&t)g;&%XO)vY71T?jLsPGuLrK`u^to|C*=2yOIC(?*sVarLT9+;R|mcest%`JKOg@ zTRr}{zxUU}v%f#Rc5k#z96Z?D%ddR;#<@RK^GEUO)wiyj& YOHTPGZ>*mmrEXyJ!q&zQufBKfe@1_%J^%m! literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_4.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..c6935a54b77ec97732e8db5fb0f2f5c43e93348a GIT binary patch literal 1010 zcmX9-Z;0D;7=G_>dRIpWMdL1D#R?IE_Ct_-2oks4>>bg|aXAebM})xjLpdU5v$%+v z7Ae{fnG_A!L6s;KB33vsLY3;mQMsOGdPq0oEK*!Q3@o$YDJT5QF?inh<@xeH4?OSt z_WD}>#NyH-0GwD|S>A}}skoLBGjYG*VhCUc)}P)y8`G(&sp;wInVFf{+1a_dx%v5d z48szM#KOV?p3P=yI>+;zBng_P7=~UhmmR0kYWYEM5Jlt3gw6rSf+!>vC0#6LN@lK7 zWu3a%Y^m*z(F?1Cq03X4%qDdKx8#hikqv|1Df1mi?zQx&TNy>};W)?>pi)rcz?QJ4 zj&-W3eltDk5onY{6BQlV2nAUH5kSQ-J(aQu!X`vp4oIvs*eXE{74 zW>}TX>y&KKn#~$@zU&FLw&eCyKPqGxBA3sy5+!JiqVsx1tTfbyulu1DM740#92|C1 z9Hb?{3y?8^v@xcE=Ub%G;q*|h4h(l}2WUs6(i%gQ@>Er3n;PFXq_C{@9b@Q~#~tS| z^w2O!r5TcvX{NyOB}uAkTD??iRjZvwBlP{j!NGVuMnLF5IvCwd@ohrtQH23t87l6m z)E?Uhlh){{e~6M)D#hS+U@}-fmr}S)QKHR)U|U7EX0^Rq7O`o7@7#O(Um`tsqIovU!}-p9kI+?{>= zk7qV6-dbs&Jg3|^^~;sy8$WN|v-nx_*YDnY?xA;fFMmbSKPRl9QVi9jKSx<$LF8-`M~GB zGpj4f`MLY%0APM;abYc-d&9bSW+Lo+ZhUv*s%l!-wR}EbE?4XIMyu8F{b3L=H1HfqVkDi8X0!2} zK^KZ#xgyo-O4HTbUa{A=1qw@X5lxJlsko(*Rh`+$3vM~pu512QVc^@NVJk_1LP3rP zOU7y%<`(g8EgG~5G@wzSpdAaLRsui*P%uoxag!h{lC(K)Lz1>KnXYNxtX7fh5==C~ z$7m_eDP&TkQYNEXoL&*~j#z5Sc3WxqnK(<($pj};qROTwPCb zbju^pLH!mUWl1WX@*0igj|#+Vu|Gzqy)WqLxP zpSB0N=FsW{^}$Yegd!Aztu~u^&vOO?4~1Gp1{fp4TQSLw zD-BZfIcu19f?RV{ZtpaDs5>O1z{as8ji>o|R%VQhXqj2NWHz0W*K!7a3k5w^6j1|^ z4+w=>6hgT>Ao50~-)Af3JJ8#0A)S`9S=BH!hR(BenP(he`A72XFlFQb;Z=EgU+w@4c(vrg!BZy!+tMk^96~#PPkm&aVHt zNNqlP3cYSV^!vZ3SJyXw6Mr=Z7r$Sdx%Sjg+wUh{K9jw4?w&nwymNH_$#*}yym{p6 z^52_ZoLl?n{FNVL->oFi!s?SWwQqBK`#1zofBDwfiMzT+XaBVeyXz-DIr8}Z{kLD) z{m7-ZasAC&^T_A+2dBUJ^vY|CKK|kke(3o>=KnkY^TQt>IPgp9fsd5u{?cwe8~N~L WaB5Cnu9rgBuylB3;qo&ttp5*r#Jg+& literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_2.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..0a186983f26dfe449c802a895d00878a1ed022f9 GIT binary patch literal 1073 zcmX9-acCQL6nrn6Yr0L5l)YM-p9xH z-kVdCk>TAVy8&Q$;`rFKJMVLA-+;&MbN%l{0X#5uVrJZ>Jv}|UcJ12Nkj7m9qP7S|2AZsl6-GD~1ldPw4MB^pr0P)R12GOSUE)@zczobA}nD9MaT>S@BncPle}KV?^i>iGEFb>{Bk1ERFw5n2^of; z^aU9_%m?UrC?XM2g%nj_m)C`IJ+9e_0Ob!yg0w(zA{CQZDa&U|@scKKmSWm@ zt5a!h8(s!{0^kVkYR0)sNLNSAptZ1$!mmSqaOFZEdDSs+LF_o(2az?3SX!;c;8=+ASW?856p>dWm9nVo8Oy46Iu>%Z{0Sh_ zLyU^^(@L$#P!Nt9i?;c5D-M zTNKA34Ui28xmjdgx!dq((#3Y0Di&@-uGiUEOh_ihbXp?A87f?0$SO-3T)4p#ooEon z14s#>B8fBxS)6Mw_;XLs;b%6|6nlQ*tDy?M|)b#&v(%Z*RgKR2IY&KAx#7H6C7AC|IzEY9u| z=hrS3@adl({P4Gje}47)wdY4)KlOp}@uLo#Udf){(>nCeU+;G}{?tw{y#2=aTi-1F z{;Oy1IsB?VI5D|7bH`V!Pkr&wM{n()KYsJlxV3lx<-^~Ow9mhE@u;%(4pq9}_}at| zY%QMqwC~!N>%*@s-22(F2M)qr=Wd#tqa#yCI{!9|`7`hWw%U8+qW;~nAM4hC{cE1^ c#@@d@`Y1cPdg9%CT&plKJ~?*fiIcDW52)|kSO5S3 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_3.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f7b56c53e68a4077844cc5603d6c18751087117a GIT binary patch literal 1013 zcmX9-QHa}g82|2iz1;1bIVf5+4^^vV5VuSs#2H6)>FkckWn2c41(re3;>s2=YK1;z z*lC$n!{|fNf@Mam5?vndA!xnzp>ih{FR&t=$2t^M3n`7|%ejmS=@Atv) z`>vl|&mTVY$RPkYymltH5%-4uxT315Vlh)H z)72W+Xi9BQ>vYY2P#cXMfx;AS#Sqh$lCgENWip!;q1#aUo)PX;C!sT&_VNU16qI1%#i$gl*R&vG&)>a1!AMpde|w3cu9fz=D^!K6K! zb#We2GNcQTDFbO^Y%87jNVUrwfl?cp&eZOqO^HhBEK$l+HHB;ILdTSYiaunGDYhgXNpo)i-(oHT79SOg}ope@t}#ADdU!wv5Qo* z%)3>&(=6<`*09^040}|h&aBbj_eW?rB~!p=usn^ce5NQf<$`EiMW=3c+gYy@3(h_#m53O*SuM}cB1<4!|c-^MDXMD z=HkMWFa7bp_sWIn)b-i!XPuvwzedlxUg`7N$q$+HYpWZH3zr|=zVsWm^!>+sm8<_8 zpU+*|&%bLPd-M2L!O^cjGLv6CaNic%%iaBNVOc%1h5s}wKK|vMSAU4tg|*Y`xm%|$ GzV|W)S7T8$^sH zxJ=^=dTNxgWstgqW^lTI9Xq#7&Jm?*gsW7^^ca~&j8HXhhlbj*pDBayy~p>@`~LX8 z_YUoz3~w0RI0yh6#&?ZPb?2sT`3F4Re%H-2#{oRBdt&d-F74^*>Fw?Hcs%RYt?TRS z>+kQ!Fl=C8VEy{_zF;s&Q6Y|FMUj`~sH!UIbUL3emdj?fy5u-**QG+hG9d6n(Wo~b z4(>0J6+*6rRyBmGK>z_j!Y~ELQ+~fj5IV!m3&KJyR!^mti$!Ev ze##qUeIX&hNJLm6BPmMO7`4Eq4L(;9^_pZlu>kE4g@cSp@-iJ&I3*)wic-;3OgmL| za(1iK=vX)lUJ-mT2qb~fFuLdqmx-vwDt08>Q1!M}Me_pbm1%z>OlBiYN#-i5Xs6|R zUTqrbww3SL25MGuFHMjUijJ{dLKL&ITu3C!*{oG8+NRl9T57l32>c2Vd5kLIT*WWe z$XJ8RG^2VeQE6*SZn?Eu@1P+P$7!E090-bJNM;z77cx?JS+bnXEtJYm)pi>!NIa&B zcuERrak7wPjf_|+#1@QH-72)|Ro7icEI0w58P;zL;q=>jt2sFp#F4r|8Kz;h50u(<3?CCHo>F6nZmlD2K5)v{4n%O3+O zImBu{K@UhKp*W1zjv8*F(#h9W%?7Hs2`|tAEF8k4Y#=UD$r!Jt;(9JsF>-d*XgO8n zHfWwlCLjk8>Uxps%3Xs$oh&q)bRmBYYOTgaqhdTRCzA>lO4Fe{OBozx@u4MwY(;`d z3ZN8$3KTL~Wb@td)AtNrTDyV$QMcCkHnTdv^b8ow{`B z#MtP@#WNpb!=G(gncx1w+k@NiUt-gz?|$*h$#YvLpPxI?^WcSdzTMLK_{RIhd;gTb z`&I57TS+?mF8tGwmtQ6av$vdF+_mlX+h(tLwr$?XL z{QIqY=dOR?oIY|?x%kxnvj=`U-v8+${`vH(=Na>deXo=j*S-ae@0=Vv@zB!;{s)hO B;3fb7 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_1.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..33f550dbe72b02acf8c9754e98146003b35257ad GIT binary patch literal 1137 zcmX9-f5;Pc7=K>hAGg;R8NQVKJfWG z&*63Bp#}3FpAP^F#$Fj+->u8K@uaJ_n6XscOMYmM;{erLt_=VJmC>(Um`?k;b1{zOR`|6 z#9Bsf7^zk{)3FWIsJK0JfCy7`jA0XkpowBOktk|fIhV6dvpzG^YPAsfBnV_Ms^Dfz zKEWblbyjUe^36o4rO&jB&AD0!4H0fP?e&Imzd(>;Fer1p8tpDi7PWM>P;@GGyUswA z!(_p&L~%V%WRr}c3Z-nUYACgGwppvR+p~xP2m{CfI)DLC1!!P^y5L!ql#!7~PK^(M zL_wMXGXxF~NB|^xkw&3BkIXo-ROIC0f$=nOEQEP1E_#&&k=8?nyjUuwY};ryZPexR z#ehlSMOW*ZGUn|TP?ve-yOh{wfbQliKdO=cL%V5u@k&hSJt z>_<@?DFKwFkjWsM>mEP-)X?1rKk(lAaRFYuetCPh$Hzur+VI?wLl@@bnp*<&>TjuXjr&kbLKVAOwqS-adjq0wm6TM%YSukKZSxcSXuUd0IF243W z$!mKrEN-1oJ!-x6$DYZ{R)2hHa#))>vt{b-5mBC5YC3l&KED0!-L0p7+cna@KYS_T zpIGzDm#e>8v--jtSAV~G^`!dUpZCm!ew1upy#KfT8kwn{-ak72>z-vhc3oM#ebe;5 zZPv=W)3@CI-5(v>J#v`461g5ecIRK`{P7PiZT^0CG literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_2.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..a24e35b77dc994eaa3af928b501bcb1459e3c281 GIT binary patch literal 1159 zcmX9-e~i;~6#w2YdUxX-GU9-NI~iJ_k_ts?(wHK>OSvmhydIgPnkm&AvXCYeSi&Gx zCM;&0Rfd^n!9{w>G&L*%rO2WSx5%jrl;qR_C7HUwh^UPY*&nC*IzsY!?|t4s?~}aG zdv9;q%=Yyz>;(Yy4Q&`0Y1O5zSk>Lp%7?$1IRrol*s^hSu+_G;wY9gmcXV`gc6N4k zbCz4b;!{_p$LQyGO$!bk!FeFI1WX`Jw{hEYk72-^sDW-$vylhV;>bBl=N~{lr zFc77ICLlQ(DJI>OoTpLt!8#5bAvmK!SPB5Z0}w(G+3i++J`F{6iaNvdQ{iw$Rqtf8 zuvqjFo&fE|c|R3GSs4qegrreQhKU+S>&4@e2bkj0mt>pHQC>A8hFwH~-At_0jXf&Tp7PDE)G^^9oj^jY!lL4AWh@6`# z_=GYRt}=<5sMn(fN1JZs>ob)mbYX5c>GiVyfPmo=MJXJg2(^aA^2yXxE^n8tMwJF3 z4p9WR8uDuqEEA)Rgiy$Yrwp}H%+xETM&k~o0SE%10H6V205AnW4FRwPo`Eq18alKq zJPKq2q-bEWz~%uI0F=EjNkE;4W(1ZK(AL3y<4M3VAjl&T$*V@Ol*ZpuRD9jMhq@l&Nj-OoV`s@A=>>1fCfOWU7j!3LQwcqAc zPkcS^om=9>o@T*0{OrWe58TUdIwRTV_goWJZoIqy!u;(U_b*yJd;BuJY}0`;c7%W6IRO*b?9L|OfZ Up}n4)t!;v#!Oa7w*1vq{f8Emb6#xJL literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_3.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9fdcdb46e5d12b34b5c34d5d5f412baf67a3b81f GIT binary patch literal 988 zcmX9-Ux?du9RJ?m^!|*9J?St?hUJJ5jtl|@4I^r9)H8ZHmr0pHqDGg8A~}puqz{30 zqi%V~L)ohIp-7NE1T1o}JaiB+W2e_aI1cPINQDjy4pv4U3OnRykHP2r{qlMFem?N| zey{Ir7fvm|xC{WNw%*yiFrCkxRAz44U){hJfH~NC@8bC>otc@Lot>SVo134XUszaJ zTwKI3ER)GBEiL8p`8>-qq9`ber0c3>nbm5w(P(u#K@=S&$v90}1_T~tX+>4Dr4m`L zFg1s7H05?j>xNb@b_PRFq_HBuVoEu?NV+=Jve><<7&eN%j+yM&Mu|5WM+E{j8p;B= z3f4BU(82rdY}zBxh(W1_j$MSJJb(rDj*@yjY7ZtM zEP^exk86hL&1!T&cO1Nspn zVjm47Jj+pZk>w0QEGvqm>&k>be^{)xu#8*RXR?6zuifqI2{O}NtmVJwnn-ox>*tY zn$m3=`@Y=|o1=b|rjL*SPz105TmTW`@`a3oe>a8)2n3R^KG*DiT=yX)8E$R8yUN(Y=Ip#V?<2u-u7 zP34|}s8*W8A=hj?gVpPas;ZPqdZl8rOqF9A0_%%xC^1JeJu2prMk1R+O%??LilyoC za~ms9PJZC)3)>33`OkyPQ*vW#^R0`gZ@w>YJs+LTq$vFT-sNv@Q17n3zP8INAK%Sf z|8eP-u+;a~*QopV|GIhm%;eJPSJuCMdakP7{b<%#U)cQ9`S8xw?O)cfE?l}3e!qM0 z^oy^aoH;!A`Oe1U!@mz+I$WMzK*rh6zWZZ2V=Vsq^KJCo>cJI%%~{>OcJ1GnAAb4Z g)@#P&Pyd5u?1vBTQExn)x`M6q+nYbV{mGU80sUp9h5!Hn literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_4.png b/resources/g2/track/bm/large_turn_right_bank_to_diag_gentle_up_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..bffa7da90d5eca0070305096b4b31f5f41efabed GIT binary patch literal 1138 zcmX9-e~i;~6n}R+u6LX`lBtCoI*u7@XmpVtHae05Ju;7yE4dOUDLSRZ8D~NNE0qHO+zLQ8HAX5OdaMhUq?tj@7F)?lYBn! zy|;NHuxR1%LI7Aa{@mDPx8mJ+Y{1dYOD_I-6u<$SH*ML_9ea9udV6~v4o6>K-+~1T z`uqDa3>z327#tkLyd zL}R|B>Q86*Tp?5{D^*LaH*}W7g8m_y!{b4ZCJ|YMDkj)+I#?~pb|u-g^-jwSxFJMB zlmSh^axzv{owb~+U3H_T54A&RUPH+A0`LGK43nMCxZAA}gzonjdA<@3*W&S;*(@rT z-IUAA;6C2t4-o;G48|!*^D7xPk>^q+L9d1kJM5v|zJS*+keoz|GAk$fWHyvFWW$P^ zcFJnz>YcKa0ha)H7(6i`G>p#TfdV0x8QBV|bwzJ!CMxozOQPM;0I3H3If*SPf|ZbJ zX{C`*w94s@l}8QJ>7ofTNYP=2jS7M)NttN0psM9;)-sIx>};#mLg1ExNMlsa$(Gzg zl?>O}WJA=O(NasBZ5NvJwGJ90olY9Z10JtH`Xs+!;rL{zyDU~vQ!%gi@z z6SeC!#~}ld4G49;NOtM&!JUX@8Vx#=z6YgRWkpelM5I_urhEz7mu9FuOO-j_EKfFr zUKH}6IDs-0G8klW-Q%a97@E8L15=X|0<69E^Q+x{`S{qnEsuZn$)Ohy?O%T1{?q8E zOI!E82*ld;NBZttG6c5#bJXy+FGa{A-LOXo#w`%Aa)?7X#N@ZoJz@WSBq>vO|l$JiS) z`0huq^bG$t_aBEJo+h{B6G9 z5;3y6l@Uk43T5lGV3AI%R=htlsaUjQ9TbgvvQC0lEnH=TmC-*ccj(uS!RNil=b!h1 z&*#1K(^H|f!yAVIVD03=i6gx^-mAc%r`NyR_Rnzu4@@7LInbkheSND|t@3z0{r&v| z0|Tp9uf{NJaBy&FXov^|0yG`uc}|i9MTuydnn)zl>1?rRS1OCH+wOGeAaE>*!bl|I zjm7+NJ(x7vbVke<t!I#tFT2XbY$(EbzwkshY z$P~mmup}(6Vr3Jr=e?bp54D1*Bcl}yp-KQi1duUI#c{*uvq&<>vJ0YEjYjK+aVMKa z<+6|V1~?)p`dOI_sZ`jY6^qp}e4-$vN>Z*S+iuj)_=2GTD^Y^NL{wf)ipi{;wN=|O zDsIYY93Ph?Q&BSUc+oV=*{oyRjm5=wyN$r70-46>JkFPV zQjLl>_+&GZYsE`#Yq3*ot<<|{gu-!#AVU6tLXkvhR5P76)sE|W$T_i!J zA;p0m0#^hi0a6KM(kLe)JBDgWO7(W&Y;t|dtlW09ESVk@A#RmBlqtA!097X66{^N^-7N{PfqNc*>&OUdyz*fm!o%em+GoUr2Sr{~V!JoV`xcch4YeR1wWb@av)!_SPo zi68xK$8$xGcyeg(nEtwPd+ya|KfsnB`*G&sHJ-QbUDY>Vzx=}~IOm4UhJROtHyu(N9Aj~XUDebIMZ_hCJ#(ae7=A7 F%>Q;Z){g)H literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_2.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_3.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..ef2827cc5152b3ce3ea232d65ddcc1c6988350c6 GIT binary patch literal 5326 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 EA6GAl)Bpeg literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_2.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_3.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..24509ea9c80a59d86d82068dc67be09af9d96786 GIT binary patch literal 1035 zcmX9-VQ3q56n|~nUbA$>8C}p+ZV>S*w-MQWIQ2f9dTrBsvp05yC=pIPX27T?-Xuz3 zhs{bD8D6(cGL{dSo*Kr@hEe3$u5hpnD?~W4NQ4`NEnq%W4K=a|1^?a{{N8)~zPumr z{oXr!d?~qq-;?_QVE^L6>z|U{rIsE}Z0FED9p7ZI*$jIpEXdn<68yg!R zAD@_*z%XobaxxeUM&t1~MI|_n6-8c_)2gZz3WZ9g)@WGG=CU0f`#8OO1;iFm#*JYxnQX2)%siayB#oH?OJY(2zCSxFx zkYhm?vATjerEt3*8MI=kmp}sv?db?L;{XDHgkefJti@tFK^P3PAqZQUOk2}-YBl6I zF)9*gqX_|LBqFJhDUFhKMy+xMlP}w%(UL4LgVV7@GR}x3FVks-Q;I^dCeKnmyRUB#8oj;t5QWHan2tu1cw8hCGQ+66P?Y>;`9`U{Rd0ArchF%$;xSbW zYZ9(!$!eZ8i=ti4Y?)fysrK5qARhvU@+vY77K>coKYsd1X!pSnoI0^2!b`vZ_Kr_(EY7~XJahiz3;d&J4o!{wJ9+l+-I-Sx zKBR)@rk?-z;NhE}UOhVc-0jydoqU7d*&N2-Ja>IOkFQLxm%p4_-8dMm-WjfZQ9W|t zs~^8zebN4od}efZ{#fwrN9*?=8N0H&v2g1mzdZlv#n>+wuK)Bx=l;+3t?!>6Tt0v0 zv2Wto?xA)E} n9}#yqc`!>LgY zjoTqnvw3YZ8X;)FQzD!iw6LIY=EEWV5Vq3>P3wU{LXFT5VcuAvMSf-sp7(uuzP!(e z=Xu``=I6qDM)!>Zz@FKsrx$v2qE~x|UA=zz+v%$SE|@=YYNki~`uh6&`&};Az`(%Z z;NZ~E5QbsH!^0yZBVNDXPm&>)Wdwl}#i%Sxs;cI4g;J?(nswXmI1U*Ch6bJ+i$*<( z1fEnv=?tCA^TkrEQk82~rrFY20*laN66Z}ta7_#pWO7wytGP(6B-v}}wyk$NX4nTY z0+I}90#=l;YR26tdYqaMwL{2>p9yHh@&76|Axy~^`z@pvPZ+Ab7O zwdx~1e#RT(aXJ1o(JCWZkxWz8JDQ1BdBP)7zGRrlMChW(R%F3a z#YRqU8EU7R>skhCnQjjiAR;6cXV|15WJEEaOqMd4YN242%guVd)9E1aNf5|kWYNu5 zd_s+gH`#P6s<)Gsj#hU{?cGKfjS+4)<@JVfzd(dUnwB{}9qTPqN}23hv1FT;(_|pV zVY1*(#c(Y_`F6u}oNdGaL;z#}4Zr|c188A@df-{4$jH!<-QWWt zk&tDe90r>QBmk1UC_^HhN96>nrID?}E#oQRScvdgLiDDRL{O9eo z_)!c;sQ}88sLUXX>xG}17`uM!23}j36JYA^jWa#+&+POQrw%P$T<%*|@4sW_3i|Dr zprPD-VE;?;o7h)h>`U&PS)4lk@P{WI{Mz@Ix9|IJ^3Bdf-@RMdg=3e_t{eNccXo~+ z`u+W&)T}%>KK|IJ>)p50zaBHP_q_U0a^l%H&VBs4bZ{k4)%WHWznq>v^5@36&whMh zWzabv{O*;LKSwTYPwGpX|Ej?kwfQ2qH2!&pIP03-ymS4d(XGj$g9nZ`pSxk+{Apu5 za`f8N)?I~_)0?#M@(HE#$9szMd_H@4Irs>%apA}U6plV_Oop((20pp*%#|N@#)I^b ldDVE-d23O=cwKmx@q9ge`KiTR?->Bh&dg1J^W+QX{|5|;)NcR) literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_1.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..7f2837d7c8340da2563447793791d798fff3bba2 GIT binary patch literal 1110 zcmX9-e`p(Z6o37B?Xnu%l*KmIbjw&A$B68Na~|`i*O8SQyV{#(n9+b;*jS?lw4KqA7xUL2aHjD^Gqn=xp)SWDBQ6m->N9y`V)vp&;xgG#z95y%c%`Z{I2NF6BI{HFZcXr}C1OEk3dukzD_YC3nx${li+&e` zaEQ{N@mNO03UPZm<7kvzsOCeB5ZcrbDtZ7ofDnd>cDv$oXGJtK6pyn4859{Y#>LX1bWY5f zO3_M~wM=EBV5h;sgEI_n8N3=srk(z*H&~!WGZ3#xdR;4`1rB!zq$}#j;{hroFnNhL zRiT`es)kxGBsWY0Rf~29>BR#C8K#*i&&LHJ6^&-&@j^On=5m#lm3qC7z$Jn=i4hq) zlXvkYJX~R7)u3LB=Ih!@BU{@nZy+0Px06n%-|gXXpFmL(%f&*?V{$g0Sk7dvqS>g> z5MnWjw<{sH7Qs_8ZN&I|D!gncp(Crz zc|jx~K|{_D76*t2Bsx)?KstwV5mbsHONV>LlfW_%;IN3`RHAr7^JjD+pI1%OsMSo= z)N+M^kZrW)JxIGFJRyf!O^N6UC2u6m zqEWMos8JzV7Uck0fKbzmSX1skT&kR^R>@TIKBQ8K2?qH{M37~X@TsIPNfQP`6j>ky!FjM|G02r?zx`#{yVULYDj9`ziZ*fnO^m$<7&3|%Z};E|C}pE+^nf2`Q!mjD0& literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_2.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_3.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..29cd1e87e380322a60e9f8bbbd2f12c89dcea34c GIT binary patch literal 5442 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_4.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ada0ff145fff967e6c3cd78923f40187a904167d GIT binary patch literal 5165 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

NM(;ABcvSS7(HGE&A;EL$r% zDZ7!YZ5CY&xCQWp!50Hu$Eb`an8(E;qu8NjP0cp-5?bO3w@i7XK_VHVb23{{1v@TR z4Yh8@n?+;OHc`Fga#J`FBB?OLMg<`$%jsw|pG+1r8QZdItE!QwUuvdRX5Q9;c`(PPtfNVh=5GfD#s_J_Oe($nJVYl@>KLFlcoxM}WM+|5<#A9* zNHJgq!QlZ3fD{i(k|@g~D}pKsd$cH#(u29ITqwkC+iWy!)YkHb zfs73>x`)sDBnwv@T5pPGD_YnzDqB_!RhzgQC?6IKxJ1Sm5y)7W)3r!8r4`JST{0U^ z3AJhz#~}-l0|>RVNVMhdz#EUH>vbw^+<{uDu%akLB62LIkbyWAFc{Kg$s!k6<%vef zk0c+`aFiyI#UPt&A3wEwVEy(F9Gw^!;ORepdZkU8VK;P(1bmRP8 zKOC4i^ziGm`uwc#?B<@0l_BgU@w@A>Vsmxuv9*s*m48+S=hrWD2%Vfha%KLZ3m08qPYoR$e&JI7{@}cR ubMe`&X?8KqFJ5N8darMdUN+wUxAXV)sZZu=(n8xhjE#=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_3.png b/resources/g2/track/bm/large_turn_right_bank_to_orthogonal_gentle_up_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9076f6af53c03fd995f220b76c9fde06d1e73742 GIT binary patch literal 1346 zcmX9-acmNI6#lieLR%}HL|IEBOEJ=VDsI<$8l2~LZLr1lwAV=#6<4(A*mAKq$1H9* zu_H?DO);WjN;l?+K}AI7O-TdM(4yR;$(Nbo>2*aJWAfOQqAO0^mwOstdGQk(&-|-eqAucL^yjq;UN&dMp;0s#TJc})yv%s+G!<1PEEv5$NFr^m}fW@R!M*k z0VW)<6yHnpLv~@*D@sQsFsXoP9UNgH49fr@0nqXJv`}b~NLabtqf~a1WS_whwOEGS zZWszlP>~E5D@dtQCs)yk#)9fuCF3HjKD8rAc_O+%%pk=i3YAPrA!_(nS{@p3OR>4A54UWB212GP|Sc6CW^A_^)8diZ?}isZY~gr_xGn#DF`Gq zkUROPS4adUR0J`^30p$zNt%Kwwm*y3;-Ad5N5ovW#nE%Vl}%G3C!hu4JHyHv|7q& z)SJyTs<2`TCyx3EG^AGalSon{gE}d+$e{~`0UUDbO!%?s1rJ~Sz-RS!6qtYON>gTj zP*e3@!|WZcyS1NNXO68JfR}5t&m9|otVglGy^WZ5^~C5|!{Oo;<@ZlLm7IcS{Oeb~ z+&Q*sAMZtZ@x9&w)Ussm;;mHU%V{Ovvx{o?;oDpChDMj(GQH7T(mbP~`uU-6+od^| zlBELUw$sdvZu{fJ^t%hb?q7MjdG>dE$;gkr_a_f_{B?jgkK7tQQ>fgjC@=lv_U0+g z+N$$Ey{PK_t?N@JXoyYR*fBZud`;lS+QGJU_MX05;)?bO))kX3Ccm&g5r1>^;nJoG z-$3Fj^=#pPWtUGTE61L>+2qW++dVaV&k=5}L)?@)*8T6_Hym^J^R{1a8Ml%%ymgIx zr=v_KI5+D`?WK}R!6sp`uRXVC7qTgJc?0w2ocy7((OnOw$dSR9^=pfte%QRcup)om zz_Y#dYS+WvOP4=RR2JRjwcYki-_lx9+jxAJ-_p0?pQ$b1yFH&wo2cvAP8J*-omcns z&ep^6Cpp|lzt{e{c}KZXTBGf%4osM!y(g1g+%PygRomU_VmGTT&7y4wi(Jw9%NiC> zKB8>wJVCxIZK&*>b?4xhALos`)0jj;_19NDebm@-=w$|9swmykDQ@ zDurxhPC*U;U}Q!4-0Jk4nXWmU%yd^?%xeN56I9J#Se9NhGBSn@8l(-R3aop zfm#HNBw%R7qep@^ZjXnTjG!)QNa~|XTc5$5U_!8+67e(yYLtm= zN{L4!4H)RCMbqOj#JrY7(2iN)yLpKHeIvBA+)(xHqPXM_TC@Dmz z;hT*jJ0tVBHGzO78uiBGQJD5ZwE#Eek_?}6V`{%p&q|nt%9}I>QjW-De;@2g2zh|O z5Sf^(A~79}o3wJqtaIDV0k1t8^2XT^O!g6SIrIa_0tnMtSkrbdgj!6_Sd4HwUdRxM zNL4CYr_-2BdR%NF#10boO7Wmv+(n7vN&!@3&@6;b9QsKZm8an+igSma|G>Ix1r6T5 zbM<`yh8?Jw`_97h=5wv8hR|y-mG#2z0#dWM?%0Orw!$A3o{Yf5gN*~zW|!C0-r}qk zJnFw?yc>5Oec1Bdh5BX3#w)?cgky~zE7@ybb#;rJ*@is>!ik>`_h+meHErnt$_p{sYFc7FOx;@0vz zPog_gMU}myM=U?CoH;MPZtu1Vv}oH+Ui`?(l|PS9q-LJ@^7VouOYP>bJKI{?K7G(Jw7;@gI#gP*{@c@v`)4Z`Pu_j0Y{sL@&+^WnF)-sw zA8wt!wfD))V`Klmyd|DL#}Twxlh8$+7=RIP<%k!p`H} zKexV2pZMU^zP-1H4vd`q%a{$n|GBm@)U>Ss?yOVtLhN+cxM_!KLhXwtTzYdw1(FpW zT->~U{^1!_vFJSUkuh)Wy4u(=uy5|RmfDlr$>&y^T2`H3d1blpj~R{A-5cY%n`W`~ai+Los{j7Q(W8icZQlRFo;^9xYwo F^gr`6u?+wK literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_1.png b/resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_1.png new file mode 100644 index 0000000000000000000000000000000000000000..fe1bd7aef574e72319576b95e0542b162803c4b4 GIT binary patch literal 1134 zcmX9-eP|nX7=GKVy?!{O%OBZx9U09ajzdm8wwoUFYOifpuj|#_FzBgK4;EM^=XNU* zq6;;HY=nB0Orr)H^q4{77THD*&9)2z7MJO%k)?QZ0mF=}YS=Q{Vqrfs2G9HT&-=jh zyzlXeaqrrmjXeOcc68U!o>m=b#fC0hE6;6TC2|v*isU#}6nR;eR8@&aqse4CmotjRvSl@zO^O7T0fFz8Bu6ml z3Wdp7oJppHOwOM#s3kLAt?3+r`IugXcSd|JP4=W!>THxNBz>ivV$H|umcHC5dU5a* z5Mn_Sv5bNh;`U0$(JbMpPNJqCt!fAr-2eiBAHx*8J%Zz!$D=dMSwWZ&1S*lpVmgfq z1)OrYStlvD7{AA>5WWZ{YmA!WqFFwX7xj|gumUa`C%tY)BzT#Y6i$f=v9v#JD25p+ zS_!kBsV*1nEI34P2EY{tkA~4{r#I)33an!K;#E~|Xhn2ZARID{hrC4G$7EzKuZm_= zt|Zl3Hrgm8m(47y73~h%L-;5>39jB2^uXfzPu3V4zjm9cYq zTr3fRDi^CsdOehHXys%CVN_m-`CH4vxp-nele3Cuv&w>> z$5hcC@w>DjkqWcfn3zum=ChGXAyuywo6SYU0{8$_01Y4uFb`0}0JR`+D6FEaj;xB{ z0fmAD3x*dg0gwntaiTbdbO9MbREi->hkM4;z;oaeu%PUWgouRZ&FFGIA2rQvy>6lw z7ajmA+{D3)u^IM!{Y$jg?UN4#JYka6%O!PB&a7M`E0^0 zX6sfFHLEnwBLk2H2(`S3wdn2xkA_pV8l6hshgvFek|YL$ayYC|WRxb8ES2S`0#B9& zqV97ezY9e?C`BQIMJC@me)`egTlaq8@SbrI2L4#s*XsL5ho0HHWBTMz&wUWx{6NRV zQsG?tV5Pl#g`S!i*eLydK0Pa5IKTeHf8KMGcLN8u*ZCvF^|#G;7CV=I_;~T^l?%pK zb63CCC%bDMyFQ6;$-l7Mgo#`I+R@ifUD_wvU~7^M-FW2gll`Ls$M1JWQ^Mg(v+A>> z-+dmM`?>3(oBh^-4UZrECH(Sh$5uXM-y8Y%3i;+i?K5R=1Rv7>g|^MNpI_-&dgAt= z)wb!<`LQjJojR16;jix$2HfRi(r*FB$(bYjx6a<28+y?_b&Z_b8|<6ew(0bt-TNC~ z{-ci^U4LTi;+-?69=7k8B>P_ZbebIe=8KOW#D9JN#iD6z q-uQ7{?efzT<1eYx)7So7*Te=croSH;KFzg6gVEvfq0@t}zWYC4o9{IM literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_2.png b/resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..b508c1c835ac82bfc78bd13b4c9ee0ebeb59a44d GIT binary patch literal 1113 zcmX9-e`p(Z6n|aYTz^o4gc4j>g9OdoZJzAZ14B9WT4TA{+j^~0Zj$QFop`!qy4&I=*HMKJV8*?*pID zdmnC}3=a*g9{_-%i5JGEI(4`ckM?zU@*jH-&H;48_HEPSow2K{Yu&na-QC?iJw3g> zy)Ksv!?3=-zW)AxZy*pLNrGW$o@Yf-P*o+7NMtfO%PN%1D~{7@w@Cu%5OD0EAb4ci zABz*oR49|>@>aB1Qmb~V-Y^&(i-ZOh)~iMQx){u<2=Ni|KonaiP4 z$wztuw3p!gp=dCy;1P`!^^lrn5+<82@!V-mn!EO0;4}Qgzj6>1DLU;U1Cl#lmP)gB7|mF*rLVND=2~qP4dQM$<@JXB0UjsBP)KFDWVEv^Zl%(dyycYbcAbVO zi>bU@i~4mL&&Fvp$rrOy#nfu0Y_nEww{IdEAOfHQ=l~`_1)zZe>VRWVTt%jVoEjGd zg@iN>g)lfAARdt7MJW;)94g4DnnaEP_l&22Wgx;~vgp-fcv=tV4Y62E*tXeh+Ni_j zlYop5(z=&3{Lw;CaYA}aFx#=>YNonYsH0jd=mE-)g$cJn`(>VtORTQRMp`SHX}fGT zoib|IDV9YAKn@_(@gmuwyANL?o^3R!Z00`HYLyWLUY5mpTp@`BMPz8wWXKXrtZ;ZU z5Uq5_RL+dlo<^@fFCI<&S+m|t@rxiEicS7qAz zAhy49dH;#e=<^$PzV+Mduc@Q#jH`0|_(Qud)B@7`FIzLMvkz=o+H-1CjmIZl#?ce< zwU6dzWz%>1@YKb(kNvaf^0gg%7uJ3<_DKIOUYX&!k#C-O^+)>R9pUKp+g+!=Lb8x3^WHMQK zc{ze0a=E;sqC%zBYEjfc5I9YfENijbIhV`j^93T2Xd*G0PUi~+)BtcJpvX##MQO8X z98QDVWAyo{P=txa?Mcy-$p#5MVm4NCq>49d1XdTYqa!XN?lUJNTzbNtO9zYjgh>q; zJ#gSappg)V#65~sNLfg#Va@;x44e@lOlSe10ALV=Qz&?~TF~i&M&k%YO<1idp1&0c zz<6AZDz&)EKxvGO&cx}>Jjx12yPt4{NpFk}CYfm3s=?F-lh#P6I*|c9`@YvoXXH zF*_}~*p$zn4ZHGjUr`LhY(k;Lbb2$2S#iQa(;k-fI~);@Cmslh(P(CJGM~>wpyq(i zhoB(^5mVDiy){F)vzB1a5z7mcg-C8DRfLs#g#uHlOd2h%H?T&douu4MX_+(P@lJ#y z>4aFw;D8|!JFVaujbPLJop{(y$NbibFrSM1bE!n3a0}u9m;tZ@AOH{sU;=C1IVeM2ZccjMr|!2TnQ5=e7>G-k6%DYd0pl?+t4OU#gysp&8+FMq3 zx9$4o;+g}l`Wji+!}!uU><@DW%bwgYcMSa1H_^}Rm144kpLYEd`1te@fnRWIdaGp3 z#XjYh`guQn*Rf&VzJIIHZyzms+IY=L#oEv5hTpn%D>od7(+AF7?^(Bc?&iAt z<0wCR^pMuF`07w!u3f`!I=27xgPOG+J#8&S>+WU7=Q5*9Uf(placJq_xvH_+`)88f zPxdOC74`F*qsTTuogH0v_T=*SYwupFJ3M!UYI^A?OYc}X-dM3OdE(M-<+yCi>=wpx z?e5!O&Y#n*{~P&!H+xlPk=&D8ZZ6%o({kmMaxC>=wfym+W82BguU7BL*&Ures32jQ{5EC*da=$4LKsJUPC;#1yo*cD5XE HerMo+`W!Z3 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_4.png b/resources/g2/track/bm/left_bank_to_gentle_up_left_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..c3621238f8562d2a4eebfe3d3301d70232ff2edb GIT binary patch literal 1104 zcmX9-acCQL82#3?y>7K;7)PMdWg75S4vp?6*Lh=Sy_T%It+(|iaool^4;pNc18*87 z=rLo-B#fhm5l8-r>-`b7um#=b!Q#j?NS&daEbB6MYQV@&S7$aO6y4a*l)?MHkN3~_ z;62_ayC*^eYX;WlZ~& zH0qDVgUJ+~$@2N4R4S`gE7fQkEP;jTeueXDVZScpIh8z{V9S|swW!$hNyj#pTa}Ox zBm!a#=mM5kuyV>>&wJWcA98}IEunilLX`jj4o@S$tQDC&QwfG ztJrDF$v2kEZU#I8cq8DC1FmCK&KoM?Vwq8_aH^piExm%y@`OjGe6bLb3e$O+EvbT) zkn0(>SxB_XnPsbhniaQ)!ig|RMHn_F2q{_4#$v@(s+`MNrrD^~TCElWp8|LWBlB*y z5bRC=hVY}<;ThS98<2T{^ zoPW<>Il6F;crf|s^pkTVr=I)tnKz7?4OfOf-x$3{koNOij^COYsDJH0G&r>F4AbEaCS(-DM$rYVkNc;4c02p*3o5D3L$@l-0C&zCC|!T^*JSVm#7sO)yF z(`E4bjDa8H6V$?$?1LjOj$fv!fe7IUpnKWR< z!AXJ0VG#jK`jokds*=&5k^xn$s3szm(gCmlRtyuAO1DNM>h)oxag=4#He1f^z7Yzc zWKu(@bd=h_YK>OCNx;o+f)|aBAnl1V{sb4!SmSw{med$bIwOZOJZTYV!OMC>)=*rC zOYT(OFO?#NYEnsoiUYL`v@Xz#7#UKVVtPxG5+t*);0Tw+6dGl56;EoMCfsK>MtC~m z;3N;93pk2VPdOQ=N>NlyDOIE%Hxs0dqMaP)-|rK9d#GFZx`DwP|E0x$zO07QT&KpLQk0ji6ok;{Ri zVU*9YdJqWkQxG>no(04K64b~?pfHQ#c9ij=d>9^pCxM~C%wl$4?RMgR(G&^uiG)Xz zqNS3A>RuWf5H1BJs@bsC8rKVXqgb{?E6zkUkg3HBC|B02fYf3pgVI82?Hu8AOlgkx~HN{m);w*88FE&W??1hmRlV z+y32>=3S%ci-r8y{D$+Ed3!r5$p|9`l?fgn}|B z|7}rZ6H%SRAGy6qDZf4R`{t{cp|wT6z0mJ_t8c}EJN}O7u`^dz$tTF_@Ziyx z*6z8i{<35I%)hT+TsN-yqaDVsw=LcTBdZ@+c9BW^R literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_2.png b/resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..38ed74398b1dc6c72c612d3cf25f48a2d2b5f0cc GIT binary patch literal 1054 zcmX9-Z;0D;7=G_>?sgkxD`&+hRjSMG;;axQgMitYJL(y|9G4r#bu5E8>s^QW5Vdec zf~#7zNR)zgR4Eu{C&3jxBx2EU2066TjH_5N2b~lx-icxK!+{6>%osfH`|^BwpAXOT zyt%lLICS8y0|0Pn{)yS8;7$fJJvJ2V%pW(l0fu1lspYwV4h#$o4h{|t4Gj+ukBp3r zj*em&Ha0dkK0Y3a#bOi{=Qvgrd09@Ws*=y=%jIglZaGfN^Zb6FiUZ4lz)z%7;Y=o) z&BY5vrd$zfb*W*iO}E(T8XSownF)oDXvwH96IGR3&vSM;*{mzxW})X9d%lyvK_Vf` zf-Yh;1+$Bxb}ig*;;0u#eF^RB2stqT0YJhqB^1(dTqg*FVb%pFELdWQ8BvB_)HmkVFVn;Q6-9hUD8J1~0n;?rxrY3U@Rdn-myR3H2 zyl+lHN46wq5D9oqm58u>eT`6+j0t0X6};7@zR0P&`KWQ)WNg*ef^ptqyAYL>TBOmWYQ^Y&0WMxiqh98Ka~%%#!PvJPLN1rbjE`Rj85xi&vLvwZB`FScfm>iw^u z;s)o8pT1mqPk9)1;l|MyD#QjmB~5*;Jo4D`+SO-Ie|UK0uSI_Mo=NKPN6+8=)yXC9 zx0UP4WOntnSL!=QVs!JYyt?u|xlNwAa*Da~!0$KzzTlz!)PFlm?>I8|aKoGyIxFZJl#Cw@Lr{+NF7p{M;H&)j+T_^02U|KXWC zK0CNEz3R`@?&DgMNAaD}_b(g^_r%QFTI<_4q`^yL=P$3l6*LE6er{p*>f`4w{trkZ B#N+?~ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_3.png b/resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_3.png new file mode 100644 index 0000000000000000000000000000000000000000..cfea637c67aa01f0f4b4d7403edeec3513e34ad1 GIT binary patch literal 1185 zcmX9-e{2(F82;#f+{VOWiWb);C3JEmm(l5|2Rro!H_~lqxVal?q(H$FOQ`XJN365K zOKh;i29Kmd(PFBcvmvKcx51gzcwkLxXyRcS?c_olSG5SyW+}1}#Lp6v=l%81`y|iv zzK2J)c$O{gTnYeKHZ(Xe+Nk}Fc(|>pkM{pV9=) zkaA|+sHV#cx|ISp4%h?083w3~5GlJSgZgwzFubv{sMO>foMtf_PdGvzEaoNCJe?Ie zBf^&wVnvPA^u&Up!b;9+BT&qX69I}2aa@e&lc7*17SmHHL(|H|Vy#w#z##xMf#7K? zopo>pEKsJS6`xWKWovS=o~hn0Ex-=UY9;J;kJH6rZk{AXhK>3g%fgvhJfF^(Iip^t zfS*A`&MNtxau7>~DK*MvlYzV{mGoq_l&jaTLka*d03rY~04e}^04fN84X`u}i%?ad zSz=Kj;2=%`%>zspKn_5`4r4e}Sf~YIAqq_e+%=v63=O<266Ebt2#d>}w8Cez5yMcc zRRcD-907obJ1E)CDo($K3MMJnd}=+ET}TveYh_rfp*BD`5s%yIqntqw4+j`o3Mz3a ztHzC-S~YX9UM3g@Y5o2Hib4BH?7ELL?LSAQlR=&&LIWd^jxN?g-&dP`FCt zI^!;~Sk>!-ekYVrn8cw*L4#==Khe`MfA z%_BGUnddCmM&I+)pZMvi=GF1_LkGJzyz%PkS8QMQ?0cyE;+3Pq^3VU7nwq+nztP^y zOkz`eZyg>z%8makoyzqcd$6~wSG)Z3-XlctzMbf;iQzr70ME-ZF4z)2_Gv2VtuQcmMzZ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_4.png b/resources/g2/track/bm/right_bank_to_gentle_up_right_bank_diag_4.png new file mode 100644 index 0000000000000000000000000000000000000000..6c8fc3415254d36d88aba79eec7f6ece14dd743c GIT binary patch literal 1192 zcmX9-e{2(V6o319D-%jAtZ@YjHhAiZRW9z3jvR78hljh3W2>`~5>F^l%_SD7P|ZcE zX`sMO%B)F={i9~Zoveld)ih9&#!P6i(V`V@rep;wPH2`UEYjfD5|YpRmAt%9@;>h! z?CG}7p4C1J0A_FKTDz$h=htjSOGC{stuh+{8lY$6=5@8QuCA`WzP_QMp|P>Csi~>C zxf#Q-mX;QcMx!^GOeAS$7@FrbSq8MrX=ts{tGY zcxaG$EGA;9fHoh~RWb%tGNXzERb_l5-JcTw?`Q=yrxf{JOaj=~8WNjYi8!}9?_2zxy7Kp+)~WD|)(E>|v>5g0_kLl_y; zGD!oUA)E!qU$jR{o@80hRpO;;eg?G?S}mp5Ta6~3Fbfuoo8|nD+AwcC5FC%i)pWK} zpuxdnZeA-njIxUeduhebC&SKhMarkbrF^mfgN5WIUGGOB{m!OwCL{PTIqCzt1%Vw2Q zDT``c1}Bi-R$A6`QKKV)i>gH~+m(tZITOlM69tqn<2s;>nANPc(?%ChdY!B+xuQWS zsRXlWrKF}&r9iPPN&r#;p_&%{8r@?UeBN-eNQFa>;m%|jyPbEr1g}>l%|6N;qDh4z zQ>;115ha@mIgCicQJ6#t8fDqq@l(rMryu>m?oHi1tiJun_FCS*VeM<1R~$Kil|AQM z{6zEC`>C^P+js0QjZZF^=$toyVW{_E_ne#f^|@=ha@0isgCEX0&re&=96mg9@$TQF zeaG+qJ2d>y%DQuV_I#XN-*E3r!G*b(Pw#A-{rujWUp@Uzv-!`|jT6UE&qAa*?k`D`;b~X3Yxk1cx?#h*?zN+9 HwjTH&l!_6H literal 0 HcmV?d00001 diff --git a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp index 88d7763af2..49cbab0635 100644 --- a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp @@ -15274,6 +15274,2232 @@ static void TwisterRCTrackRightEighthToOrthogonalDown25( TwisterRCTrackLeftEighthToDiagUp25(session, ride, trackSequence, (direction + 3) & 3, height, trackElement, supportType); } +static void TwisterRCTrackDiagUp25ToLeftBankedUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 4)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 0)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 1)), + { -16, -16, height }, { { -16, -16, height + 48 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 3)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 5, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 2)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 10, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 10, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 10, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackDiagUp25ToRightBankedUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 9)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 5)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 7)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 8)), + { -16, -16, height }, { { -16, -16, height + 48 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 10, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 6)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 10, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 5, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 10, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackDiagLeftBankedUp25ToUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 14)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 10)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 11)), + { -16, -16, height }, { { -16, -16, height + 48 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 13)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 5, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 12)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 9, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 9, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 9, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagRightBankedUp25ToUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 19)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 15)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 17)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 18)), + { -16, -16, height }, { { -16, -16, height + 48 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 9, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 16)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 9, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 5, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 9, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagDown25ToLeftBankedDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagRightBankedUp25ToUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagDown25ToRightBankedDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagLeftBankedUp25ToUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagLeftBankedDown25ToDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagUp25ToRightBankedUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagRightBankedDown25ToDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagUp25ToLeftBankedUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagLeftBankedFlatToLeftBankedUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 23)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 20)), + { -16, -16, height }, { { -16, -16, height + 34 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 22)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 21)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 4, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + } +} + +static void TwisterRCTrackDiagRightBankedFlatToRightBankedUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 27)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 24)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 26)), + { -16, -16, height }, { { -16, -16, height + 34 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 25)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 4, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + } +} + +static void TwisterRCTrackDiagLeftBankedUp25ToLeftBankedFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 31)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 28)), + { -16, -16, height }, { { -16, -16, height + 32 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 30)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 29)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 8, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 8, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 8, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagRightBankedUp25ToRightBankedFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 35)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 32)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 34)), + { -16, -16, height }, { { -16, -16, height + 32 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 8, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 33)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 8, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 8, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagLeftBankedFlatToLeftBankedDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagRightBankedUp25ToRightBankedFlat( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagRightBankedFlatToRightBankedDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagLeftBankedUp25ToLeftBankedFlat( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagLeftBankedDown25ToLeftBankedFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagRightBankedFlatToRightBankedUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagRightBankedDown25ToRightBankedFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagLeftBankedFlatToLeftBankedUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagUp25LeftBanked( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 39)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 36)), + { -16, -16, height }, { { -16, -16, height + 42 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 38)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 6, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 37)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 11, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 11, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 11, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagUp25RightBanked( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 43)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 40)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 42)), + { -16, -16, height }, { { -16, -16, height + 42 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 11, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 41)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 11, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 6, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 11, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagDown25LeftBanked( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagUp25RightBanked(session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagDown25RightBanked( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagUp25LeftBanked(session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagFlatToLeftBankedUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 48)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 44)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 45)), + { -16, -16, height }, { { -16, -16, height + 34 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 47)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 46)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 4, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + } +} + +static void TwisterRCTrackDiagFlatToRightBankedUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 53)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 49)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 51)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 52)), + { -16, -16, height }, { { -16, -16, height + 34 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 50)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 4, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + } +} + +static void TwisterRCTrackDiagLeftBankedUp25ToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 58)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 54)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 55)), + { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 57)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 56)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 6, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 6, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 6, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagRightBankedUp25ToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 63)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 59)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 61)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 62)), + { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + case 3: + switch (direction) + { + case 0: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 6, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 60)), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 6, height, session.SupportColours); + break; + case 2: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + break; + case 3: + MetalBSupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 6, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); + break; + } +} + +static void TwisterRCTrackDiagFlatToLeftBankedDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagRightBankedUp25ToFlat( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagFlatToRightBankedDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagLeftBankedUp25ToFlat( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagLeftBankedDown25ToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagFlatToRightBankedUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackDiagRightBankedDown25ToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackDiagFlatToLeftBankedUp25( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackLeftEighthBankToDiagUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 64)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height - 4, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 68)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 72)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 9, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 76)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 12, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 65)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 69)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 73)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 77)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide, PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 66)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 70)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 40, 1 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 74)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 78)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 67)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 1, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 71)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 75)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 7, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 79)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 7, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackRightEighthBankToDiagUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 80)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 12, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 84)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 9, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 88)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 92)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height - 4, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 81)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 85)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 89)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 93)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 82)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 86)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 90)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 40, 1 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 94)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 83)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 7, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 87)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 7, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 91)), + { 0, 0, height }, { { 0, 0, height + 48 }, { 32, 32, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 95)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 1, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackLeftEighthBankToOrthogonalUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 96)), + { 0, 0, height }, { { 0, 0, height + 40 }, { 32, 32, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 5, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 100)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 32, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 7, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 104)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 9, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 108)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 8, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 97)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 32, 1 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 101)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 32, 1 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 105)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 109)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 98)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 102)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 106)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 110)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide, PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 99)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 103)), + { 0, 0, height }, { { 0, 31, height }, { 32, 1, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 107)), + { 0, 0, height }, { { 0, 0, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 111)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 9, height, session.SupportColours); + break; + } + if (direction == 1 || direction == 2) + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::SlopeEnd); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackRightEighthBankToOrthogonalUp25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 112)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::RightCorner, 9, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 116)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 32, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomCorner, 7, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 120)), + { 0, 0, height }, { { 0, 0, height + 40 }, { 32, 32, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::LeftCorner, 5, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 124)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopCorner, 8, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 113)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 117)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 32, 1 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 121)), + { 0, 0, height }, { { 0, 0, height + 32 }, { 32, 32, 1 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 125)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 114)), + { 0, 0, height }, { { 0, 0, height }, { 16, 32, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 118)), + { 0, 0, height }, { { 31, 0, height }, { 1, 32, 32 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 122)), + { 0, 0, height }, { { 31, 0, height }, { 1, 32, 32 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 126)), + { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 115)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 119)), + { 0, 0, height }, { { 31, 0, height }, { 1, 32, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 123)), + { 0, 0, height }, { { 31, 0, height }, { 1, 32, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 127)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 9, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 1) + { + PaintUtilPushTunnelRotated(session, direction + 1, height + 8, kTunnelGroup, TunnelSubType::SlopeEnd); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomRightSide), direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + } +} + +static void TwisterRCTrackLeftEighthBankToDiagDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + uint8_t map[5] = { 4, 3, 1, 2, 0 }; + trackSequence = map[trackSequence]; + TwisterRCTrackRightEighthBankToOrthogonalUp25( + session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackRightEighthBankToDiagDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + uint8_t map[5] = { 4, 3, 1, 2, 0 }; + trackSequence = map[trackSequence]; + TwisterRCTrackLeftEighthBankToOrthogonalUp25( + session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackLeftEighthBankToOrthogonalDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + TwisterRCTrackRightEighthBankToDiagUp25( + session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackRightEighthBankToOrthogonalDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + TwisterRCTrackLeftEighthBankToDiagUp25( + session, ride, trackSequence, (direction + 3) & 3, height, trackElement, supportType); +} + static void TwisterRCTrackLeftLargeCorkscrewUp( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -16542,6 +18768,82 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trac case TrackElemType::RightEighthToOrthogonalDown25: return TwisterRCTrackRightEighthToOrthogonalDown25; + // Diagonal unbanked to banked + case TrackElemType::DiagUp25ToLeftBankedUp25: + return TwisterRCTrackDiagUp25ToLeftBankedUp25; + case TrackElemType::DiagUp25ToRightBankedUp25: + return TwisterRCTrackDiagUp25ToRightBankedUp25; + case TrackElemType::DiagLeftBankedUp25ToUp25: + return TwisterRCTrackDiagLeftBankedUp25ToUp25; + case TrackElemType::DiagRightBankedUp25ToUp25: + return TwisterRCTrackDiagRightBankedUp25ToUp25; + case TrackElemType::DiagDown25ToLeftBankedDown25: + return TwisterRCTrackDiagDown25ToLeftBankedDown25; + case TrackElemType::DiagDown25ToRightBankedDown25: + return TwisterRCTrackDiagDown25ToRightBankedDown25; + case TrackElemType::DiagLeftBankedDown25ToDown25: + return TwisterRCTrackDiagLeftBankedDown25ToDown25; + case TrackElemType::DiagRightBankedDown25ToDown25: + return TwisterRCTrackDiagRightBankedDown25ToDown25; + case TrackElemType::DiagLeftBankedFlatToLeftBankedUp25: + return TwisterRCTrackDiagLeftBankedFlatToLeftBankedUp25; + case TrackElemType::DiagRightBankedFlatToRightBankedUp25: + return TwisterRCTrackDiagRightBankedFlatToRightBankedUp25; + case TrackElemType::DiagLeftBankedUp25ToLeftBankedFlat: + return TwisterRCTrackDiagLeftBankedUp25ToLeftBankedFlat; + case TrackElemType::DiagRightBankedUp25ToRightBankedFlat: + return TwisterRCTrackDiagRightBankedUp25ToRightBankedFlat; + case TrackElemType::DiagLeftBankedFlatToLeftBankedDown25: + return TwisterRCTrackDiagLeftBankedFlatToLeftBankedDown25; + case TrackElemType::DiagRightBankedFlatToRightBankedDown25: + return TwisterRCTrackDiagRightBankedFlatToRightBankedDown25; + case TrackElemType::DiagLeftBankedDown25ToLeftBankedFlat: + return TwisterRCTrackDiagLeftBankedDown25ToLeftBankedFlat; + case TrackElemType::DiagRightBankedDown25ToRightBankedFlat: + return TwisterRCTrackDiagRightBankedDown25ToRightBankedFlat; + case TrackElemType::DiagUp25LeftBanked: + return TwisterRCTrackDiagUp25LeftBanked; + case TrackElemType::DiagUp25RightBanked: + return TwisterRCTrackDiagUp25RightBanked; + case TrackElemType::DiagDown25LeftBanked: + return TwisterRCTrackDiagDown25LeftBanked; + case TrackElemType::DiagDown25RightBanked: + return TwisterRCTrackDiagDown25RightBanked; + case TrackElemType::DiagFlatToLeftBankedUp25: + return TwisterRCTrackDiagFlatToLeftBankedUp25; + case TrackElemType::DiagFlatToRightBankedUp25: + return TwisterRCTrackDiagFlatToRightBankedUp25; + case TrackElemType::DiagLeftBankedUp25ToFlat: + return TwisterRCTrackDiagLeftBankedUp25ToFlat; + case TrackElemType::DiagRightBankedUp25ToFlat: + return TwisterRCTrackDiagRightBankedUp25ToFlat; + case TrackElemType::DiagFlatToLeftBankedDown25: + return TwisterRCTrackDiagFlatToLeftBankedDown25; + case TrackElemType::DiagFlatToRightBankedDown25: + return TwisterRCTrackDiagFlatToRightBankedDown25; + case TrackElemType::DiagLeftBankedDown25ToFlat: + return TwisterRCTrackDiagLeftBankedDown25ToFlat; + case TrackElemType::DiagRightBankedDown25ToFlat: + return TwisterRCTrackDiagRightBankedDown25ToFlat; + + // Large banked curved slopes + case TrackElemType::LeftEighthBankToDiagUp25: + return TwisterRCTrackLeftEighthBankToDiagUp25; + case TrackElemType::RightEighthBankToDiagUp25: + return TwisterRCTrackRightEighthBankToDiagUp25; + case TrackElemType::LeftEighthBankToDiagDown25: + return TwisterRCTrackLeftEighthBankToDiagDown25; + case TrackElemType::RightEighthBankToDiagDown25: + return TwisterRCTrackRightEighthBankToDiagDown25; + case TrackElemType::LeftEighthBankToOrthogonalUp25: + return TwisterRCTrackLeftEighthBankToOrthogonalUp25; + case TrackElemType::RightEighthBankToOrthogonalUp25: + return TwisterRCTrackRightEighthBankToOrthogonalUp25; + case TrackElemType::LeftEighthBankToOrthogonalDown25: + return TwisterRCTrackLeftEighthBankToOrthogonalDown25; + case TrackElemType::RightEighthBankToOrthogonalDown25: + return TwisterRCTrackRightEighthBankToOrthogonalDown25; + // Large corkscrews case TrackElemType::LeftLargeCorkscrewUp: return TwisterRCTrackLeftLargeCorkscrewUp; diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index bf3d1810ff..6b779358a4 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1287,7 +1287,8 @@ enum : ImageIndex SPR_G2_BM_BOOSTER_NE_SW = SPR_G2_BM_DIAG_BRAKES + 6, SPR_G2_BM_BOOSTER_NW_SE, SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE, - SPR_G2_BM_TRACK_LARGE_CORKSCREW = SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 64, + SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED = SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 64, + SPR_G2_BM_TRACK_LARGE_CORKSCREW = SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 128, SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP = SPR_G2_BM_TRACK_LARGE_CORKSCREW + 40, SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 44, From 2c3b3ee34e97f0bc27f9b3398e24486c888b3ed2 Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 25 Oct 2024 08:38:55 +0100 Subject: [PATCH 016/139] Add zero g rolls to the Twister Roller Coaster --- resources/g2/sprites.json | 192 +++++++++++ .../g2/track/bm/zero_g_roll_left_1_1.png | Bin 0 -> 1128 bytes .../g2/track/bm/zero_g_roll_left_1_2.png | Bin 0 -> 1111 bytes .../g2/track/bm/zero_g_roll_left_1_3.png | Bin 0 -> 5332 bytes .../g2/track/bm/zero_g_roll_left_1_4.png | Bin 0 -> 1352 bytes .../g2/track/bm/zero_g_roll_left_2_1.png | Bin 0 -> 921 bytes .../g2/track/bm/zero_g_roll_left_2_2.png | Bin 0 -> 1047 bytes .../g2/track/bm/zero_g_roll_left_2_3.png | Bin 0 -> 1111 bytes .../g2/track/bm/zero_g_roll_left_2_4.png | Bin 0 -> 1092 bytes .../g2/track/bm/zero_g_roll_left_3_1.png | Bin 0 -> 1211 bytes .../g2/track/bm/zero_g_roll_left_3_2.png | Bin 0 -> 1268 bytes .../g2/track/bm/zero_g_roll_left_3_3.png | Bin 0 -> 950 bytes .../g2/track/bm/zero_g_roll_left_3_4.png | Bin 0 -> 5262 bytes .../g2/track/bm/zero_g_roll_left_4_1.png | Bin 0 -> 1411 bytes .../g2/track/bm/zero_g_roll_left_4_2.png | Bin 0 -> 1311 bytes .../g2/track/bm/zero_g_roll_left_4_3.png | Bin 0 -> 946 bytes .../g2/track/bm/zero_g_roll_left_4_4.png | Bin 0 -> 1103 bytes .../g2/track/bm/zero_g_roll_right_1_1.png | Bin 0 -> 1473 bytes .../g2/track/bm/zero_g_roll_right_1_2.png | Bin 0 -> 1394 bytes .../g2/track/bm/zero_g_roll_right_1_3.png | Bin 0 -> 938 bytes .../g2/track/bm/zero_g_roll_right_1_4.png | Bin 0 -> 1135 bytes .../g2/track/bm/zero_g_roll_right_2_1.png | Bin 0 -> 1128 bytes .../g2/track/bm/zero_g_roll_right_2_2.png | Bin 0 -> 1142 bytes .../g2/track/bm/zero_g_roll_right_2_3.png | Bin 0 -> 942 bytes .../g2/track/bm/zero_g_roll_right_2_4.png | Bin 0 -> 5181 bytes .../g2/track/bm/zero_g_roll_right_3_1.png | Bin 0 -> 924 bytes .../g2/track/bm/zero_g_roll_right_3_2.png | Bin 0 -> 1090 bytes .../g2/track/bm/zero_g_roll_right_3_3.png | Bin 0 -> 1177 bytes .../g2/track/bm/zero_g_roll_right_3_4.png | Bin 0 -> 5281 bytes .../g2/track/bm/zero_g_roll_right_4_1.png | Bin 0 -> 1125 bytes .../g2/track/bm/zero_g_roll_right_4_2.png | Bin 0 -> 1074 bytes .../g2/track/bm/zero_g_roll_right_4_3.png | Bin 0 -> 1217 bytes .../g2/track/bm/zero_g_roll_right_4_4.png | Bin 0 -> 1327 bytes .../track/coaster/TwisterRollerCoaster.cpp | 305 ++++++++++++++++++ .../ride/rtd/coaster/TwisterRollerCoaster.h | 2 +- .../ride/rtd/coaster/VerticalDropCoaster.h | 2 +- src/openrct2/sprites.h | 3 +- 37 files changed, 501 insertions(+), 3 deletions(-) create mode 100644 resources/g2/track/bm/zero_g_roll_left_1_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_1_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_1_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_1_4.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_2_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_2_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_2_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_2_4.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_3_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_3_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_3_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_3_4.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_4_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_4_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_4_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_left_4_4.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_1_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_1_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_1_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_1_4.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_2_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_2_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_2_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_2_4.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_3_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_3_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_3_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_3_4.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_4_1.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_4_2.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_4_3.png create mode 100644 resources/g2/track/bm/zero_g_roll_right_4_4.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index ed71e33a82..dd71d6eb70 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -8191,6 +8191,198 @@ "y": -35, "palette": "keep" }, + { + "path": "track/bm/zero_g_roll_left_1_1.png", + "x": -26, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_1_2.png", + "x": -13, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_1_3.png", + "x": -12, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_1_4.png", + "x": -23, + "y": -29, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_2_1.png", + "x": -27, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_2_2.png", + "x": -28, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_2_3.png", + "x": -23, + "y": -21, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_2_4.png", + "x": -21, + "y": -21, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_3_1.png", + "x": -22, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_3_2.png", + "x": -23, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_3_3.png", + "x": -8, + "y": -16, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_3_4.png", + "x": -27, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_4_1.png", + "x": -18, + "y": -29, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_4_2.png", + "x": -11, + "y": -42, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_4_3.png", + "x": -22, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_left_4_4.png", + "x": -23, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_1_1.png", + "x": -26, + "y": -29, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_1_2.png", + "x": -30, + "y": -43, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_1_3.png", + "x": -22, + "y": -20, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_1_4.png", + "x": -27, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_2_1.png", + "x": -27, + "y": -17, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_2_2.png", + "x": -16, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_2_3.png", + "x": -14, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_2_4.png", + "x": -12, + "y": -27, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_3_1.png", + "x": -9, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_3_2.png", + "x": -9, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_3_3.png", + "x": -11, + "y": -21, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_3_4.png", + "x": -24, + "y": -21, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_4_1.png", + "x": -19, + "y": -13, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_4_2.png", + "x": -33, + "y": -15, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_4_3.png", + "x": -26, + "y": -26, + "palette": "keep" + }, + { + "path": "track/bm/zero_g_roll_right_4_4.png", + "x": -26, + "y": -29, + "palette": "keep" + }, { "path": "track/railway/quarter_turn_3_tiles_sw_se_part_3.png", "x": -8, diff --git a/resources/g2/track/bm/zero_g_roll_left_1_1.png b/resources/g2/track/bm/zero_g_roll_left_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c01f156f08141ffdb6b01a25e49cb79851c38fca GIT binary patch literal 1128 zcmX9-Z;aD)82)j`(K{wI+!7buhp7Ylp=ggZSg|2RdSq}l^thf3GLK@KFyqhyMMtu5 z4L8kz0gW!Y$j}9=j|!_juqXV?R@yckrx5z1cNUOZ)lJ6=FRKq=;-Y1oIihl zS6A191q%=a>F)0C>FMzWgF%ucSe6k4PLd*uA}5o{Y&Kskn&tA0W57NwnTVOgRmR~fCoTC5E(^PzhA>Jou(&vz7mbrRCP9= zhnD3hy+OuD@Bv!HLNXp!NlBxX9Gf(_Oi9qIqUl5fl%EI%X#wXXDk8ITicjUmyeXTu zT6QvavrwP2PzHDf;ERGl0$>_K<$a+d7O@!F4yWsi?rLQ?!Q)ujnK(VOv-tIf2E&3m;u=)qBx^7%r6pnww+O)DIq65GoX#dM}pC^}`kRcC<6 zA&P*iVnB=GxddaRgisWWvK}K3)%qCMG+y=0=QGyfl}s-ZSg4=3-tz1&|PdMwmcMAQMqeQ)7BYEg2cR zY&4xRY}F}_gC>9ufUxaFs!jJ0{$wK8Xi&NALnzfM8;J<9n3PD!B$1?uEJGSBX>r61 zk2k|XCG z9Xx#L(kuV25Z)P_{$tP7_H}Ic>$@)wbZlF@m^j4T{?(n>aAgQPINCcE8-HWR`TJik zUUc-U`}=R0tIkxmjn97a@vd9{TwHbLuXDtSN$2LPqd!RBpFg$wcXi9BPcF%ZrIE=W z@4S3_%Icog^lz@*SaayzsmXKbuAvW}>y?kAsme#!f1$IZ-e>xjTx@P%esiqi%zjrK zdiv(l$?5BV&xt+pzV|OU#=g_j_TA!78@V-}l^^b1e(=wew+`6cKF`_%t9w1iK0iCK pa{tk*-%fWFHoCjF9wn~%eh&A)`C0m{lWn=crVX3>zgWL>?0u7!e|kBuMPS8l>vYg)VB8OhUOruqnIEj7FCab%vRYj#m7cF?im8U)~3v z=Y3}mjX4JTxAz0Ufb-?y!|l4e9Xorw+IjlK`XWFV96E4hq&;?YbaZxhc6D`icX#V_ zx}KgM48wYRd;9wOOjfIvAnXi7^E@jEZb=eDp-?QA$Yzy7p{!|*W|Oc3O##R1-EO1L zXYmK@;RqFrbLp%nmzPRvq*_ZcIOd}CB5Mk|EV5urNW?;j$;Vu!tf&>kbuG2gC^*dE z!NE_1%wuU0%SQ~Aw6R$-qq-e6J!nfts9*))06Z8b8Vo_RS+?0y6t%!{MX$FK46Y{< zD4#bIMk{Tya~8^DbBMSrNC+||#hFlsjpq1N$)jjq3u(4HtQ3#40_heRG0cS%o`fPQ zYOtV1)q1+RkvGs_><(~qlpYd zo#NhT;TLXr!|3<0p6N?>+p1sl#JD?7g!((e8E5;eAJ*|K#Ft2QR$; zclU7T6_Qo4C@P5;W3shP6%LglF&;orYmOZqCO=H2%a;xpgQ zzBpaKI^H)o`1qb*l9PX3z4Yowjk&4g3zu%4U78E4zbKB77@=wC*N+(eZ8`4^x1zMPHxn)9UYyX{rIgj*Zx3%nvU&D V&O4v@YOt*iI7h~Y=U;m5{QnjC@*V&H literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_1_3.png b/resources/g2/track/bm/zero_g_roll_left_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..c6eecb30c437553d6385a8eba460899a434a7b18 GIT binary patch literal 5332 zcmeHLe^e7!7Jh+B5Ukizjfyrg*ha-LNhTpA7$b(C8!^;SK{?$xOeQfxGBFbfN-M3g zf{mIgb?HjGXsHV|D&6Xe6)V3`=2>8 znR)Ns``vrLd+$4W*^s+1^Wmt;Q2>C4v$N6`!RHh3o)sAmzr!aKeF-1l)p-T>MVNzQ zwUGu>3Bj?ivJxDk+++Zt{4;ZI>e%pUkw*qzn#*83Q@+{%&+N)`y{s3_=MUB-b5t4A zf9mSnVhMj$w({beEA}p1Mw~Qkc)lU$qhmF^x7YopYxVI7VM{m6-m2S`K`-&K!(-0A zV-s$zh#Z(TqpI!MNjsU7V>kU88UJwne3otEfmaXgF6lz9OiY3IJj;Bl9zSJdnk0l-*iQmJyY zRjNDTz#v|GZi^zzJ8#NKoz}H0Z_2eDS6<#JznGprMLpiNZ0CXTOG^ds{usSoJbh;3 z=C#G|zwbV|+v(cBZ|uIcoSzw2u3dif8}1XoAu|tD-?)5;9r!`LAYcjg?zt_uw?b<%C4+#R_ggPA*49+6ay~QJg5? zrPrfhLkRBO;W^WQah7h(vrS!KYSP z>{vP9Ld6Fm1~JkI3b&c8b`xpg1TnE9ved5Na^X7Xj(=urPR=mAg&JZ3@`03NRz#R6 zK+I-jqy}YAFM}XM4*jkMl?S^NSwv7|sSPL6%Lt1-ek6n*AJ(^)+Dby<=y8N7Awq1n9R)1$sN`RQeZThtsyN)_C1nzli@B|_xKiE357G#5vV?ldyn*;*h9ilDkn#t zM&hMG_p;Lz+@O8Ap2SUhdFT}r8-xZCit}YM0_BSZQj9N45+(7Il2BA66A^k`P&5K6 z+d|nf3r+-~Ab6q);)s(B5*!l?_=03i&llrjjE_kP179LZ7A0c@t``%@BOo+36Rb+C zWTaO?C_RJ{8KkICk0JzGE^Ysi=;9_DoK_QV!bc~rN`wNq|J=MbehbV zkwB~#V`w2rxI8sCTfr423hvJ2mSA=RRDeBTvgk<%b$2PxWG1wBEXb!&Dv~9OQ3)zQ z#Yw^>$z7qvgpGo=7(^8c64AkUf{BsCa3HlsFNCQSASJ?>6PTKNFvP8iRI>iZU z4ln1xhSFnpEDf_05L6%%%Y_2DNRlUz$psR*NR}WF$^|3jNxjLi>VHWG+lMn}FzHz) z3ff;4ni}jWEwOTNG&n3Vg_?=O3AKeB!v{m4urfj)@)KeWF5$~Di;;l)$56rEnK%7T zF(hL}A`Fuz^U)##Z#z8JVK;Rn_Af1@kv?qQ0s zz+XTPcvL!j%~}SJ`5<>eUOGH(F&K=nu(0s(@P{6HXw;}t5fKqgCNnZJa`foYtoZnN z6h%}jrB z*+??mTrpjZv3(tJbT2~p>F5DBO?%@3&;X!gGRc^j%D6Z;kJpfrvR|WVHyXPtE3ekq z(`{{WXl%Tag=p9*I$kE3kY9=7?i8v{<@Bg)TD1)wx)#5YEsaAm<5RQ=YFt`Ks>mu$ zRlTmhg>3Ovdi^!N-p20!wiqRd)dH3guqy!1&6L)&GMjmYZA#LY@9L%+0&Xw8Uy~4v zOXD1w39kHU9PtJ zdS6RRcV}lH5THRE33#solEKgAs=^z=De`)fM}TDs}30529u+00BNrclW))}j?gwY##op{BCcQ{(e`di`Fy zuUo2C(=CAZ1Db}psDkDOuQ+E#T~Cj+u6FREIyzK^h1%j`yrP0c5vLTXRiYjh+NMT2 zH3_}>@wARjSMumOlx|VdJ~b?UDL?u~um|jm7HYw~uP?wqw*aF^otXxzM@`LwgVENk zC6KJ>*x=0o+h3aqCz0eP&+QuZtRfu2_F-$p+(!#k&V~)=z$X=MRl*YVw|w z^RIvZ9VLGc?AW)}ENA5X<6noijU9LE(NEqvGoU5DI5>XMvTgl;JN~Kj%)65I!`Y|L zi`MUCzftwu=a+nxR>oeL?>uzj@};LwU2bZbb?E4Ae_3ST7|}=E@7gPg bskfM&yX4eUW@|A_1;|ccn6_{JvbFyKnDyvw literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_1_4.png b/resources/g2/track/bm/zero_g_roll_left_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..791a4d058985ec3c18e6661415d29a6a6203472d GIT binary patch literal 1352 zcmX9-e{2$W9R2o}*IFH`B*TgImXVG*GBG{lHDYo)TCw7K&TESq)$2T!Y$QD!+_0h} z6_r%9H%k?jI?R}3_MF6;c~Lr1Sz0H{Fm?_V4K2(P*KO3YNKMu6FedNw>!0`jc<+E*w4lW?WveIn+|ED zfK~uA0XPcru}IJ%iu%NvuoR}0Fhj#B4#JQO01^NiL0FNsd8xC+!~E zBd|im8j3k1DPKGr6cIp70f_;i79i&k+#}KW<@zAOMs$w2$(!av@I0vyGq}{OQ8;ue zAEOSKsECb;x=cylmJYhI5gsN(A~7yk=rG(ssLd4RU>LXA>~}bV9#2FN;zL8}bQ%IF z3*;^Y^NG{}DHT>2;%a+R?@gHlX>KUvPfbO$uv8%u;Sz}kl~D>Mqf(i)q@B)@S^N&? zpwAx*MKW;$&|1VqiL5lr85M2|!P}{T+c3ymqd|8n8p>qGAOV05022Tl06YML03;Cr zb0F2wVuHLE#-gMguo!R>K+u2~2_OX^D}fFSdPyi4Vb~61UhvX*9B9=*MVl^wA zoW|#60s&hj!lzOZnA4IP0A?vAI0@-RX+h4$R9srmXUu`DD?BB{VKgll0~|#(N|ByG zjTB}vXgRCV>$C=VXC%a@Vj-A`<612g0E__$b6(hUa<3q@S=`Aa?smO`DI8Yo^_0=b zSS&22wBbq@f$?fAs8tS;ij+ST=fROKyKs zTfMw~WyfKs@rdoM8GG--TPw;=ZL3(-ZSSewz79Fj`}E;_dV$N`eU861&{R29d2U`} z;ErW-;s6{LCZF2kBiYG{_*MoTZz@jpJQz+7X;>axatACfcZfr=DkKDhs-UfG< zUbCJY-ej0*T>2TeO}pqti}_jKo@JfKU+ntpA>z#ue3CECAL$(}OM#O(epIw@al5E} zeB}Gr>QQ{f(A7eo7}Ot}>}#1YEjd0smz^zr^yGf?k(~o&X_)AjeA7Xju1tLN!rK2& zjcel6;HhcJ$_1}gjoA+v*U8Yv9;$0j-PZZd-*RP5*PkVlO|7eurWyOYewW$aM(6&z zNOxm>eHGfhr|H7=vF#0(#7~dt-Zy{j+<8do-cg)rNOg|V`&$l_e|LRQh%LXo`Jj32 z=8`{mjZ*(T82|Ei)iIK0Dmc>)evTYpx@&nweB+}2fxY!lpNm`WZMb|@_@lPVop}9W z_)G$AoZDD=@fTxF>%MErjbB%Es4*Juy3T~x1*MQ*ca_Ezj^VpMt1hW!?`$s N+M2rRvmZ3?{vTtrZ9D(~ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_2_1.png b/resources/g2/track/bm/zero_g_roll_left_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..94d1e3695c4065f0fab062bf094fa1353d68d4e9 GIT binary patch literal 921 zcmX9-L5SmI82x5CGwDnniuMpS3t8++4ncxMjgUju%`9<4)=D)bPshkym=kVB9hg7gqDNDp1jp+eDuBNWM@he3X`EWGdgc$fDM?|q*= zxR6dyUOoYU)AM)FE~|T|nv;61+SiYt`v;%~58iupzoL74d;9zQwOZ}q;NbA^@aX6W z!?1e2etdk4x7%%&WkgX>RoO5)mSqkG1K*#_W>K0hieg)qECT`$irnaQTD>0Gx0#{K z`(tG~)8oX-a(A^3L>klhhAHEYMtTM{vDmADnD|;YGmH6fQv|zhDiNU5&=zV~XZb8BX*`WJbA@7NdMKUG0*l04){p zE|4}*9>z^@X-0Jt!OS&xWd&O=MOO;lGB~0y(XPf%4KcRVd|)hnYaI@@iNDK3v`(8X zj-oY|>k49DRb9gv_xm%~O(v5(idKuocDqGDm_Yd$J8g;Pv4o7(!Zi*C@D^8YC1gHRnsw{?;-7^pad%RwA zWB(bfEE78&wbwIj+hmym$M^ypifke?3x(cjZKRXPq0pE`k$`f!DnIvHSW` zpT3G;eiO$JZ+-pJJ^OXz_oHv^hqpic`|`ghci(`Izq|Fzoi+1)B?;&EFV23r_ra(C E1Fl|!4gdfE literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_2_2.png b/resources/g2/track/bm/zero_g_roll_left_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4313b70eda660c0c1c8bcd8530c7271f992b30a4 GIT binary patch literal 1047 zcmX9-Z;0D;7=CZ}CwIHeD0OC<4;8v2YS4l~0!D}~cl6GT%e-tWQfG!iD^$!z#+8u| z5qr{&Zp5RE4vMQT(+UBr9ukinR>)=lGd}?wrOtHYN**H znOK4+l2V*gsFX&hO-8jiy($zOvFyoqOL4<&oF$W~1Siv?%4Re{D@w(hQgbyoF#WI` z^y;0RCeA}l1|kb_11Jk)YecF+WtzMeq)Q#$?pr=uk?5GplKB)}N^^Bp@N_vSsO^g0 zbqf7vWhZb@*T-WlMW-1y%L{o~E~#oYpKp{(%~~yR-OlD_zu!kdYCu&mrj839DYxis zM<{kPb}#Sst<6EBx7*%9lQfRA1d)m-WICyGoGwa5C0b@QO6B!>BlLqohX+N(bQw35 zxRs-;2JaMQubN$V%yzTdYx{%2HsS%&06KsL-~g-xbTL2?Bmo&Za%>c~B?>eK$~?F! z2qi!=AdNsJ2H6sFbEs8Bp$!j$XF(JoEnzv8F!OZTO4V)E^9n)W^m+k`w8$(l#w2eM zk{wrEN((uwpK%6xZ>Q4Qbvvltr((dyu~ZVz@bR3?7+KLWb9UMEoO0khz0gO44l9bt z1r!28Q5MBW?jgv6QSElwYULsHR!hiaVM}yi}i#n%b(wCkmn9;dGF3&^_G5G&VN!n&tIHdz1cc5b(dIu z`^IlmjJNpo_3v)K!#=jQ^65ucroZ(Uwog|tEnQ{~#g<=se`Vi`*Cw(jo}2l7_Ny;( z{lb{Bc<1Zmy{)Au7q>3IwRRHw{zPl-h1j15Z&?j>4gdLzjo~+#qwz{->hA6kc7Ju`*VKJAG6Zuo^V8oPKK1ecE|W5E)aI8F5`S!8fE zHo1v2R9)f{r%oJk(GiB8WC=xw+3AVX6gkY`n#%|yE)mUg%s2_euOlR%_v@ecNj{(V z4vvonmM^<^82~IFd1~|ac3stum3>|9EU&)fV}LFg-!?Ja9y>ZZIy*bNy1Kf%yL)+kP(`+Po<^s_7@2%IbjRaMb-J(*1B^Mz7r-nJXfCg}%;2A*>SgRXGc z8;Sa3aXOjevw6uZs%0x)tz}pO6KRLSxi!&i$aq>MXLPoh6w7(Vo{QD(Osi1}ct9c` z!hj)QSp_S`ot3PsS@xj1A2lU(!$7Fy1K@04jh1kOPO$H6vy#S-w%IqDljI0p-O4erJ&Jh6OSj;tVaENoZy+VU==q zyM&rmisMiLkPQg6y@<8xZo{KTQ?(kEO5TQAF0;X)5Dv@Hs6zU6%AaJ&97`5C|2$9B zMIVy9NW)QzLJQ`M;%MIe&E&ZV*+ga{lfF@zGr0friq8%-J96){_OpI!;9$L z<#!h1L-$R6u<2p*&}-8AQ;tUl>Qh$^y#4s%k--zGEBl{rX`|7TCVPEi?V2q^Up;eZ zcHrjl4`P#J`$G1x4z!{UE=P;jw_SBM}JC6;5Hx9Ts9?rbg$bgp|+{^#V`!EfJuj88sD>gqYyvwi0`?D_flXQQcK zj}hI&TR%C#zIZCW;tzbw#WP1t$HH?vt)O1seddR|-fKy_X7=p<{3v<)Ki_ZEHEivy WxbO6~sl#n`U}Sh~^Rb~_Z~PD1IpuZ$ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_2_4.png b/resources/g2/track/bm/zero_g_roll_left_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..a104413974c7339c2676743a69914e86d2ea26d6 GIT binary patch literal 1092 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 YEq?LTTkq_7wLt*%boX|RZsOV literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_3_2.png b/resources/g2/track/bm/zero_g_roll_left_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..1bcce0d160b61ec6d47e0fff64e254a1afeec442 GIT binary patch literal 1268 zcmXAoZ)_8F7{`BGx843QiRV zcCT4Y)mGP40|07URy3_E*4f3-R4R&j@vrZ;0iXbDR<<@5$C8qg($Z3eLQz&$R$g9S zQBi>)NM&VZRaKQ*tJUJTo+Jr|F>xGgxAShd+wTvC!*VP(no8yJd0Y<&BcM$+EUU8F zP={0R@f!UBIuy1YCVk_Ejo(F%r2Z0jP?NOmQ20~BgQRq%8D8^dP-|#FcW8Bd6M_go}eWt z^K!x!OZgJnP`VIR57P)&t(Y?R;=W^dXq=7bm=qA?X`&^Rc}Yc_^B zGGb>EZZ7G!XC!wn>MtZDn29M>1|4R`4OW75FpQVu0uD#m>x~A330Y2$j^=VX2sAv< z`4K#%BqJIoj#<;BC&P+aMETk&v?41T1=KtN?e`5Q3T(QH!kOQ$``jN_j`5;Ez9((=eISsel1RD7}&;P#c3g zttP=`6Me3T}M1WcHU$8VTh^Vjnq=w7#)0S#j}HWd5AElrKB zi+Z>C*!{<+Pug)CURmBaxvfR+Gd&DcUwPC1^eTDtdiv+)`I9azKly!D%v?5BUfbnk5Z z+dT`n->m;|?Cdt1?_mGv?cT!M!_2$MOb#-#HZIg=VKuh!LrmvT^Z~q^WBRLZQ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_3_3.png b/resources/g2/track/bm/zero_g_roll_left_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..656fa2666890346dd9830653ba94a45f86b585e3 GIT binary patch literal 950 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_left_4_4.png b/resources/g2/track/bm/zero_g_roll_left_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..4f65dc867b0657302a58d49398ff9871fcf5cbd2 GIT binary patch literal 1103 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_1_2.png b/resources/g2/track/bm/zero_g_roll_right_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..0c361f4699c95485f18be19ba66fc9d55ce91730 GIT binary patch literal 1394 zcmXAoaZr+X7{`B!il#%qXseSmDl4~sqwDVTJkLG`k)$Ve+eZC=zipFAy0Ek5Zm8B^ZOpS)4 z)d`Fyk=2GeTuP6Z@CQtxFe%~F<)SoP#?s3L zKG2GR8KXOJy4S=AI+!s(8%6{$ri9aG2z^`tPym#4I?iC|*=#e9M~Xx}C_1242le{< zc02TX*$9&>W(iP^NXe7pe7PP`nMH(6VsOeV9*p!W-ISUmWDBHR5yqFPgbG}O8&RWO zX?Nr9fZj)00ue`O%F7S~CI(n)z|jGonJ%=mq%NMqE5-wIQ-~m=W*_W9`An6Nt(Edk za*;zN@eo+RpbA=vu+tFrTBia|81^xkLLOg^2-RYV7Q;*`l})R4nM_{0J>YhShK8ci zCNsM6y8PR&8=AoD?G98?PX?zAl$YM!3T#PSJiA019H7euB zbS{%+z~Q2NfmlcklrlPjG4x7~S;M#K#7-mTv8e}~`k>bq3HoBO`%nyk8~_3UGXPEi z1^@`t0gQu6ppJk}5>i2w2XF*f#K0{D6bc{)AkKm&1d=FpYoOlTg*}isq%OXfq*j-3Bb4(TMZChn%K-jNsiLZ!zqzDs&K}%o++z;+8u(yD31w* z9J*A%P>4Ai4AH4&X1#{A=siwLz~_umJ{SuLWisdnkOC0Ky)ee*Ucol#Y~irbW_<nP3RzN90_n&auwzkGD4X5?_mrbBHPg^qdMJ8iXuv~6}vcKNt5hV9jlOaH_V5h^{|fF^fAN^!DZcn)mzB+x!mS z@Uo8gPVYK%ed}P~?Y{9@iS*V#4_TaclyIp}Kzm9s0(<88~Y{mk^Yrn@p9U)^1RlJ)iJkB0-F*Y$_a z9#@AK?=P5N^fzbnom&sINWXV*viHaTni83xjZB`qCEI+jb*z9ol>HUa-n_Z}AJ{&- zZ}d#_lLyLz0?kG4r#JttXd?Ump!CCduf48xPS<_a+V-<=33K~b_TR|6!>|=mV_599 R595ym%1X+M&lYWI`5zqSa*zN3 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_1_3.png b/resources/g2/track/bm/zero_g_roll_right_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e25ea83f1a4b7993d4aa74080f6e991700b4cc11 GIT binary patch literal 938 zcmXAoL5SmY6vp37XC|E;mkI>~6C_9vSqu^(U=9(ZW|lf+nXHqQ3Oz&&8rU3i$U=pP zQKJ;MBVj4nLt*O@)*@joIEO3*3=*Yak+>A8nuRI_b6BBB4;2Ren`Pm9@9|yU@9@3% z$>pQ^`E&c{0O0)LD+kBLe7dM7%B7-zaQnX)pahpMUAb7;jg5`X&COD&w6(Rhy}iA& zvx8w+xm@1e-NkFQ8p|@GC@6}gX-&&AUDxgP2BT4!B-1Qgu2w7q0uQpZ*KAe|gKXJM zyTkYT@^GX^u{B9M^MxzW=L3kA9^ZcnSk9B?KI1dH`6vqTxtqC|I zle|jRO}gQ*n#Wsx(G8?-r1%px%yg0?n0k#@Xi4Lmrf9b1_COtkW|%rj)=l%_d>vN= zs49T#K-xfg7&pM{BdQq-X4>e?Er01H=v1bw8b`G1bf>`&H8HZ3)YWD^YZ181xVKIN zv`8vdj-neZrwd|BQ97E|Z?#69PCOW-VK|>om&+vr!UU>^vBQcO5z2(t=VE)&^z&A< z^rov(el}a9J-SliaJ){|6q?a^-jd|DS}e0io$h!z%93<77eJLTOQ|?2=^1q27J{}C z_4RS!%;J7NOIE7~NC0R6SO6YC05AqvV1NqABC;(M_$Zsn6qqb@1qkbq$$%6!#;sWb)BP*_`+Jjd|6P84+0B*?P_t>&C0p%7382o+hh3)~|S zuH9cOxPI@EtjR=dHWkCrY};fRmt%SY8;EQyF;kh&8#Sbo$e~c5MWKLFsW^V_nZ3Us z{=l{4BL!ak^Ov^^^ZMbzOII%3xZ{1h3r{_^HFb=u$0wh^@O`9zck=u5Z{7dv`s4dw zUwHOTa`%t-ZeRO3FQ5Ey>(zgiUq5C>AAKh5bN{?=-~92L>&Z{ib8qJOYq!3<`p&2K dZoYft($N=BiudpSHYpfzc=71qtC!#S@P7o~l|cXi literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_1_4.png b/resources/g2/track/bm/zero_g_roll_right_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..df21e5782b5d1e86c1adc814ff16d72004301d4a GIT binary patch literal 1135 zcmX9-e{2(V6n|T{UAJWxEJ=wCUX~_Y@FImAaLB0#+@O%t9obX zBUVzi;F&a}iPcm*V>Lx9qR5FvB9qA#i=}FH&NS^-i}C}@fWQxiLhfi3 zkH!7T6qCsc`C_I-B4snP9Cbo3lyF)Z2D7;Ds;= zF%~ot%gb0L<*Mi1t(q5Ee$)!1WeuUK4?qA2W0>r6sa~%}5IV!06@=MHq^_z9xg4rg zyp-F=di(;;go%Jm231PZ7$wUk3VgaO>a}pmjNr7_AMi0E$xC!d=H#T1%!P9$xn!tS zGi_M;M!Vu-!7YL(0(cw<4Wo0OK#>SlSlI}s8j5afRdiM$-4gAM1;|v8$xB>W5sidY z&nV48!mec6MgcXeE;mh(L5hyBTuc;Gl9Y|bim6m3morMG#@w83+X%ce5E+chySTDf ztdWrhmu!Y~D^|9(xmM9yuD8)3>2lE?PXPCcq+enfg%^_H&a!whm7dKP&8pFAun^`k zMRciQT#J&~I9o`HjD8X z1!)#a0WbwXA|Tm=QWVk!REnZn5}7*OF`fpVgP?##C65{-(^?>}OXYIHFbbAspbnQe z0#tmE)jWcZhf9QPGMXJKv|{CUrnX#apt?=CfyS|b-xXrlyrxF=v|28tjcUO% ztEknWc^;JjnSfBoi)4rHF1(3&w%Me!nY&PGH7*nqqfsdymnnaO_GehCz)=<6KPQk@ z(1*e}QVEo$P>Dqb-#LEz!NKcye&FcXs0iDyUV6IIuh~1YWB=BZr+zs&k=U@JXWydw z%`=XPdw<@>J+a#{;#_&=M($$t*O$gupF8qej+y-EmeAhv&Zi^u^^H4z${zZFz4mTn za7J1G-_%#FH_g6BdaoW7|5k=uTzl19flKSxZ9PvMS{U2@>gB}HFe#vi z*6ZG#C!e*(H$B<^V$*qXdh+zp@b2QvGtd8db8@q5Y@lXr4qce|Y~uIPJ)h4X_~**f z`R9f&eyE>%z&?CtB*i=Bg>h$m@Xy&2!rl&^lU;1|X@qyYOs}`=0A5Bl*{Fu$& quwwX+p|v`*`S^tsx3|sSn8TGH_8fNhzHmo8*t=_VN literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_2_1.png b/resources/g2/track/bm/zero_g_roll_right_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..a24bd77c98c00c7c6836739524393911fcffad0c GIT binary patch literal 1128 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 DRuS$e literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_2_3.png b/resources/g2/track/bm/zero_g_roll_right_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..5060ed25a9996b2e4c47b02a98754a13dfd53e2d GIT binary patch literal 942 zcmXAoL5SmY6vp37XC|F3GXaZ4jS!)-QKCi+l0$^JW|qzvnJk+fi)0}}(1I0n$U>1I zkquZSV8ALBD%(R2MZ#L4NQ5F0a_FIl912?{NZBn|a1K>^C_0C~Sr)$c9^d8t4&QrU zTsy5ETzcvf034hgA6?JqlX>CALf$X`{Phf=0N38SaW%JFTU*=P+l4}5XJ==3cXw}Z z55urxvADm#PgE)uj$odnW@AXg|lU%tX60AZA zI$brHn!_2sV09%ol-naUnCMYfr+AXBRs@xi4PG-Pv!%3pdM`4g)Jd{-y6n$4F)l(` z1)>g=4YZH(J)%0GwOBOMnm4zCm7k!Y!jui3Y*rbsCiD$yWT~lZ%sSR0bXRd_lZI%K z;ANg>Y8+n|rKYNShS6;{2c8%AdTA8Rr_%sD3wm~HZ$9aONQWce94MDJErKRV~?19%F_Xk;$uID1?GG?i`qf>r^>Dpr0Qb*nT zICN%lcR5Se>vJRm)Br31A0Px611vB=xfBW6777ED%@i6;4%#9_Rmc=TDj<_U9)|)2 zMGZ7*p)7!h!Sf(XP*bpmK{!pO?N|GOF&epP8ZMV9%2{L`IJ+eJgc4ACM4Or5ue5O8 z9Bn$2i)fB!E4mCkg;iNx6RC#E*>%}>8bR9`h3zy6msx_=b6%EF1SkW9@+?|8?vY5> z?k*O5xAREWWFl#r+GrTIZE~#3vmKEOB`%iPslqI46{J(hp;4DZk%&?`KYsqj(mxM> z;MVn16<+`IxA${%^W^BtjVHdj`{k9xPhT$XY>+a1?>_s}nf=P$%Wogt`L6WgUJ;)8 z`}o$`@2|CIe|`J$_n&y1q5An({0HY}@4OVy_ijH=wthVP_rE`$d+f8P?-blOe|gq< fAU+tAzaDNWuRi|K#qkR{2Trb@9{upfySM)bfm@E* literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_2_4.png b/resources/g2/track/bm/zero_g_roll_right_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..80c2bae88b8b9e5f7e80852064d825b5b4fc34d4 GIT binary patch literal 5181 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 YJmEx6ZdaTY1_%oC*5w|3pz^W*0$=i#jQ{`u literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_3_1.png b/resources/g2/track/bm/zero_g_roll_right_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..895a1e3388cad07e96d99dd425cf5ee09780a382 GIT binary patch literal 924 zcmX9-L5SmI82x72naoUCa_Aw0L2~FJNRTY%5G9AKn;GjEnJk-yutv#Xz#e)CY?jTT zUFP zt9$3|TSu=Q0l=-Z_fPIum#pUKpjPcimw!A2sKLDtADmWnXJ==3cehrn)$8@Wy}kYY zeGJ164h{|v4~bT*#c`}8iK;4_rf%Do=Xt~7csh-JN^;GXNU#be z78~59k2n$3%Nd>#1nvn!mKeGRV-C!Zb~ublQxs2@_LFY&G}H#n4_wUYQQJd4yIO z-sEXUZoO38~JR&Qj{H^lo9|$JqgVu@$x)cuX9v+ksaWA4KW~;kTPQ0Dukfaqm7en zhx40wi54Z@1fIg$EUt@GSLJ#gIdHq-z)hk-o<-{-Lz^Wp%P0m^076w3{mSkYNUt|q zt@zRK73}$3(si}lHG4gaV?CZ7id-adsmxw0%vx(9gF-HiMjVPol*?85`8OLcUjD%2 z`{yd$dG_?PihOW(^6rDoIid1as6u#?*7gF z{NKO!KOg<}$(^^3PoL4hey6Xf?Cp!4&hh6L%`X8OFJ7NM$v(ZTRN?IO{N$Ir H7hn7j6JUkU literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_3_2.png b/resources/g2/track/bm/zero_g_roll_right_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..79683a3990888b4f0ceda5e60b86eae7989428d2 GIT binary patch literal 1090 zcmX9-acCQL6n<;kUb}Wg2^eh(8K#ioZDj5Shu$Bzd9ATr>D69YkVxZpbHS$Lgxd%s z8z(zw+~T}SWDz5aa!58JW^~wthI-gID~5S)nP%)Zf(tH#f^h^5qsq@4gYUh^_s{$I z_})7`H5uHpd1x~LY#D!LblRRiyPoQE*!{$%UylMfU}|D!%%+<*ZR+akayT5_-Q7Js zJ-xlX7>4!r_4W7nyL~<%K?E3v=6O~S!jdE^ijv9XibcI#u3A>B-6jG+Q^2tU;jk+f z^Trc_WQxjUxqLBFGNg)`sy8$S$3oPA$hzf_R~7s@iMXsVMkZ7#iq=}PX=$BSIp~21 z4sjY(9?OfEk#g4Zu6D(PngP^~pbZtFvh9Hbh+vrLbjlu&>i26Db(!PVqS2Zxujg{e zFg%3IN4o=@mx}mE}4tubWu0u zvXwTQ`Fh82(%|C39R+U!{3=G~+`*zhY|x?^O4TK;rIyiU4tEKpCmzI8Au2C0C5bl` zp_Y*v1*K(VI%WYi%1#&Q$3p}erI|R-rvxDzj~7!ZBbPIEycoaMdECV49iwSNyj;GaNUK2_s#WV}eripAV zPZWs60Ij+?%^T7EqD85#aG@P9buyI=y^d-vzY9n&77RGUv^T~Ri72beF)b~Z3Td-k zXj)~|u9GZ_bU+p$WM`4I0B#IDch#Lmzwc&EmQFYX;Rb(!YJzw%$u~ujN-%-@)LE>ab&G^}6`y&o`bKT$~#UotVD(+vJ&*1AiQ!UHEYOv+qv++jZsR^Fy7FYi9GYjz=bf9GoH!JWB-|LtrR|Gs^H z@%|ZWIh}ss+ILM^?pcyfYG=QECxy`PRmax#&%fVxY~wB4JB*J_j(+{p8z=t<8fxNW literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_3_3.png b/resources/g2/track/bm/zero_g_roll_right_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..0d523fc05305a854cef3bbde2e323f1ca6461f18 GIT binary patch literal 1177 zcmX9-eT>s|82-V1^ge{)EpdTj2JWP2g&`H{Wk}_E=QxU2pum7hYEsS_7wk!eiMv=r ziG$3eUWOTFmkcs+AyXzCNfU+^9I|*L)MUnKiY#$~#Sm%8A{RN#&k>U6{rcy9lIMBf zBO3<2vpVK=003qUtnJ&>sLwTGURzTm-~RTKWdJmR4eK}eH^vz=X3U&9v#F`6xw*Ne zrKPpC6+w`;wzl^6c8AO5A_zB4Qyj+#f?twEMN#7MWHzhi^Ci=?>UF{mC=XznPQTwC z3_3$$cO>eGC)jkB&*@Uph*qj88b^GdPLXlQKBp>RNr{+HXg%&LW<|3QshO!MEAK@C zkAn~eR1Qgth#s|-)Ao81g*7*<^Ke>)Fz*6@1%O8o(PooTRK>8A$1}mQg+QPz%XgDW zsOu-6xLSHyiXA*dcHK`R+1mg7=IUNZwu5_NlB9u8*&(l63tgpDNmq$X;H zoHt`eEnS(?Z4|I`z!3n>Fu+uVOgg+-%&$|T;fq$Jl%?k31dH1R5)FCrsLzuY=$ynE zicpSA)r?~4@hKw%t9hH9#Bd)$1}HkjaZy1?ghJV9R8J-iO{OD)y2wdwK{?8I$0(&6wrT^#NfJRXT*BYb07I2(->(pfWa)GHL= z8ARf2GVfG_cp^+?B3v#JC}iZao~V`c_4-{%0pJ5b0zd^I13&?QDgs~wEDggF%%q@M zW-%ZVAVvYr3rrS34nWZXqXbN`Pz%Ch1ez)E*mx2!H1M%VP;kg0Jf?cnDIu3r3?oyk z8L+{H1^^N6q*Mo+a`GA`njY2iXX>HcRJ=H?Rbbh|?0|G4UboFpIfEP#4lt@5OvU6} zCT8R_H8T(E6_R0~2A~NbY&nTS7uR4medKNk!N;jl=!71AB2hzw2W zjJw3*HJ=OePAFqAK|qay2Gclxa!Kd?$3O7lra=z8e&@G$8ohU*Z_Vb#V|z>O?<>pZ zv}~xrcMp&!uye27+8DUhedq$;(KlH|dxS+>qH_+`cMr+8AAQ;5-?!vn`a##}f4;Xq z>KPolvufY-w{~q`Fr>ePekv_Iy}9|PzpnHSudbEtD}TN4!LA(}t0z}pTe|+6`~4@j zUd)bj&NFYUy?yqnW5GS2AN-~JSl5wL_?umLq2D?czp~}l)zW_t*Ui29h}|>z^u6w~ z*t@v(_|+cAp8Z{$j(3c13y!{gX7vC)_TI(Im$#k2Gva+=`NO>n?32o&!(WNu`irs2 z(NlAJv1i6t?8bHsjf@@czCc}DICr{z_84PzUEh}e;>7OCXMZoAeg4m-ACvno`7bXY zpP1j;Gu*M_20r`Qj>7PR;hoqaH8%drTgPc;%}G3M{P4BaH@WiWtADJ!ad?00&5@n+ p^Lu~%{oZ!!Xj?N}wY73iUwB~X=kJt7T0>tj&_CFBw)gFW{{xkj|1$sp literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_3_4.png b/resources/g2/track/bm/zero_g_roll_right_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ec3f45229e5ed50ff9bf90b44bc1ae757888caa4 GIT binary patch literal 5281 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 n7DO& literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_4_2.png b/resources/g2/track/bm/zero_g_roll_right_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..d78be9e9c7207acbe16171882a917e59e7538d05 GIT binary patch literal 1074 zcmXAoacCQL6vtniw%4w9_eU534~>$sSk5lG`{O!pa%-<6*3(|;b&Zhe38&2;Vcs7% z%p|zr@<))M2S$w=G~j{x}Sg0^WNkA z^S(U3@4dIU5S}>j=m7wjn16n5sb8o1F*)k#=TA;A{s`cK#TS=P_1l4gfx*E+kH<4K zG&DRsJTfwZVc6*C=-AkpFAxY&REXnPQRHPgs;WvlozCZr<+5p6O~-M2Jt_n&0|GxD zje6s8eNlOc1Pz(EW(T{ye}2;YjUutQk67U%SRez#i?hyj=t+! zVFDx)5-eyUR#LE97H^fjy#|50A=H!5o`#SW01yBq3{!ACMG#srs54AO5bCj5E0wxi zETUSCpu7Rr7ZUu86bvh5Bt^*@qZYWd!RM-?-jGZu=BJ5JIKYS`FVj(lQ!+xPC>2e` zv{ROov%97CZVhL_D}pZu{v-r7j4t}ZR&`giP(>iUGEF4HWH!Q-WUi`; zc3N)b)sB&NYx!NFb$|{AsE@#*q>2n3IV~Xw z3I#b9%rH0tAQ6z_Ls<&x0y5*MkwK0Q`^MA2a}W`*xa>2kH2wr!)^wNYP- zhyj%xXEmRo`z14|IE>~-jb5U^<1iI%hT^)zBzNydg76xlL*Dn zK6O}la_eXDvDwkm`Qw}B3;NCPmX^P|J$Soo-JeyOTIb(7diAekfB$!Rr6hlTl+r+nAmKCATtuO9jL#7P*;u8h)M^hQ1%Lwp5daB*6aYB@$_RiOSQ`38 zm`Xsk$eMwGg9rs=J5X5wIRFJC4C64tLfH%RA*d$6i{J^s(7?eWUfvk+St61>ncy>- zV4;wzR0>e@LOlTYw^EXkO<*qBEU2VZb*5^*%uF;tE03hppbLWmGmPO-reJ~5j-OcC`sBqAe732F1FNU+?9_T;L+1yZR}2kB zoC85y^V%tRbL4jC_Q5r4-oq5r#@yhi|Gax9$DF%pYv&IumFC)B*gbS)|J%#22>rkP zbpFEZep&KwoA!P;{q2FXN29$Jc(1MbRHZ^z-&Z-{q$W8>FKmF3Tl$>vc8;E~Jy`kClJoAZk-`3f{)szZoI5pg{GIfPU(~j-mR}Ec%>BC!3@mNj*){z0 zP;J%V$%EhQYrK@X(bIP(viIus$CPbkw5R{+SnaEpElsIE+HXBS(XsvZuHpW9Q|bP# z$im(mi;i|ox1a8-zuztXg`AxK>bgx`E1uZS)`i^NU%q*7*>ukE^tfr?_4!ww$DWc` f$E72epTj%`+lg&=AN;pK%K>ay+tWF=X2-z)dm|dS literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/zero_g_roll_right_4_4.png b/resources/g2/track/bm/zero_g_roll_right_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc9a5450e260d0accee9d299d3521c1c3dd3fa0 GIT binary patch literal 1327 zcmX9-e{2(V6#wq$Z7WL$9qX`S+3HeAHwrtF0}H#sb#$|XgB@Dol$&d`V_hGAq@;^@Pr8^tFuUhMK)8kz%(2AT0-)9@AKY2@AJp! z^Ln>z)|Hk#R{{ViZE4oFWqC!mRu<)DyMO;g831`;OY63#?3$C4lbf5HmzS5HpI=Z= zP*_-qAV^VBQE_pxRH0CysG1;fiqad6G{>=ayWQpT1OmZGWIP^EXELZ7;2J>cMKmoj zo8=a(+Tql=+@vqSgu+}@a3+#oLWLMKB33W88RWcC>EX~JI}vsnq5(EO=19f8GwFy< z1{f8v;DDzPAB%*Y;+Rj8iOOI~4Koa!;8Hay*Dy*Qt1{S7Bd_7ygx#<23sK%E6O5bWm`trxXegE5h|w&;I!K3y z@dVkRV2i~2gp@Ba6Bgq@LIJ4>$gM!hBbZ033n=L@&I$%+g7c>N2pl3+5+f$F=u}RF z#%Cl#93|L|F&CHg+tXp!jNpgKh**LtRR$C@;e>^voJOPDVhK2%VUI@$1{34s>2w+b z84Hvy1oerDkc^6|ObNn~q`fIiD9w*&0;$>93>2xvVoWO4$rY4JZPaKuJ?UVw$E*Qo z-mipczITFzy9UjmLnV00t5<8>Kdj zs*l(Cyv9(-E(rcqN`P4{nF*j)5zb3Vubc@g*|>&J)BcPlG~tPVUIDjzgg(EBX3^KdbolIhG*E4X@C_&Sd z*=)30SyXMu)Gi$L6KGhk9w${Pg90*gXj4Kr3WGQl^x5!Zb)vtY{=f%qn<>!v$E~-s z^JI&5{kG=bfqr_}zGPn0QTX$YCAUsC=H3%Zb1wdNM|@9Ih99B|EfS``GHS+Kc5?1FnsymXn8|v3HHw9f#Xe2roRUb_WD|h`s`3M zH`Rarc0+jo!AGlK6%C&2KC$NH`bCE=m!|9fIa3>tHY7{SJ2dC_Zl5?19%~sme&gjw z|Fw%+t|ZsD?KspR*PmU=wmYw3*ZRBfZ>>F3S$$zu>tVO~!%L^>+H%DIR y+IV`Oju~3;WZmAHX-Rk0v|_Z3f7m)_dw^&q8yaq&I?<7J9keuU)(&oHKlndyvP2XB literal 0 HcmV?d00001 diff --git a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp index 49cbab0635..7184283d3a 100644 --- a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp @@ -18363,6 +18363,301 @@ static void TwisterRCTrackRightMediumHalfLoopDown( TwisterRCTrackLeftMediumHalfLoopUp(session, ride, 4 - trackSequence, direction, height, trackElement, supportType); } +static void TwisterRCTrackLeftZeroGRollUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 0)), { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 1)), { 0, 0, height }, + { { 0, 6, height + 32 }, { 32, 20, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 4)), { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 5)), { 0, 0, height }, + { { 0, 31, height }, { 40, 1, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 8)), { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 12)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 14, height, session.SupportColours); + break; + } + + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 40); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 2)), { 0, 0, height }, + { { 0, 6, height + 32 }, { 32, 20, 1 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 6)), { 0, 0, height }, + { { 0, 6, height + 32 }, { 40, 20, 1 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 9)), { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 13)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::topCorner, + PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 3)), { 0, 0, height }, + { { 0, 6, height + 32 }, { 40, 20, 1 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 7)), { 0, 0, height }, + { { 0, 6, height + 32 }, { 32, 20, 1 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 10)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 11)), + { 0, 0, height }, { { 0, 6, height + 36 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 14)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 15)), + { 0, 0, height }, { { 0, 6, height + 36 }, { 32, 20, 0 } }); + break; + } + switch (direction) + { + case 1: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 2: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::topCorner, + PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height + 42, session.SupportColours); + PaintUtilSetGeneralSupportHeight(session, height + 40); + break; + } +} + +static void TwisterRCTrackRightZeroGRollUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 16)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 14, height, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 20)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 24)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 25)), + { 0, 0, height }, { { 0, 31, height }, { 40, 1, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 28)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 29)), + { 0, 0, height }, { { 0, 6, height + 32 }, { 32, 20, 1 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 40); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 17)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 21)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 26)), + { 0, 0, height }, { { 0, 31, height }, { 44, 1, 32 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 30)), + { 0, 0, height }, { { 0, 6, height + 32 }, { 32, 20, 1 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::bottomRightSide, PaintSegment::rightCorner, + PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 18)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 19)), + { 0, 0, height }, { { 0, 6, height + 36 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 22)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 23)), + { 0, 0, height }, { { 0, 6, height + 36 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 27)), + { 0, 0, height }, { { 0, 6, height + 32 }, { 32, 20, 1 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_ZERO_G_ROLL + 31)), + { 0, 0, height }, { { 0, 6, height + 32 }, { 40, 20, 1 } }); + break; + } + switch (direction) + { + case 1: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 2: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::bottomRightSide, PaintSegment::rightCorner, + PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height + 42, session.SupportColours); + PaintUtilSetGeneralSupportHeight(session, height + 40); + break; + } +} + +static void TwisterRCTrackLeftZeroGRollDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackLeftZeroGRollUp(session, ride, 2 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackRightZeroGRollDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackRightZeroGRollUp(session, ride, 2 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trackType) { switch (trackType) @@ -18864,6 +19159,16 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trac case TrackElemType::RightMediumHalfLoopDown: return TwisterRCTrackRightMediumHalfLoopDown; + // Zero g rolls + case TrackElemType::LeftZeroGRollUp: + return TwisterRCTrackLeftZeroGRollUp; + case TrackElemType::RightZeroGRollUp: + return TwisterRCTrackRightZeroGRollUp; + case TrackElemType::LeftZeroGRollDown: + return TwisterRCTrackLeftZeroGRollDown; + case TrackElemType::RightZeroGRollDown: + return TwisterRCTrackRightZeroGRollDown; + default: return nullptr; } diff --git a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h index 3bf805ad27..9f4e238553 100644 --- a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h @@ -24,7 +24,7 @@ constexpr RideTypeDescriptor TwisterRollerCoasterRTD = .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Tubes, .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::corkscrewLarge, TrackGroup::halfLoopMedium}, - .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop}, + .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop, TrackGroup::zeroGRoll}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | diff --git a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h index 5880b6e87d..8334f6df82 100644 --- a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h +++ b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h @@ -24,7 +24,7 @@ constexpr RideTypeDescriptor VerticalDropCoasterRTD = .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Boxed, .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::halfLoopMedium}, - .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist}, + .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::zeroGRoll}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 6b779358a4..dee8b91898 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1290,7 +1290,8 @@ enum : ImageIndex SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED = SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE + 64, SPR_G2_BM_TRACK_LARGE_CORKSCREW = SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 128, SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP = SPR_G2_BM_TRACK_LARGE_CORKSCREW + 40, - SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 44, + SPR_G2_BM_TRACK_ZERO_G_ROLL = SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 44, + SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_ZERO_G_ROLL + 32, SPR_G2_MINIATURE_RAILWAY_BEGIN = SPR_G2_BM_RC_END, SPR_G2_MINIATURE_RAILWAY_QUARTER_TURN_3_TILES_SW_SE_PART_3 = SPR_G2_MINIATURE_RAILWAY_BEGIN, From e2ccc159cc01cfdf9ea6e55a95e1bd0f26cafbdd Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 25 Oct 2024 09:40:04 +0100 Subject: [PATCH 017/139] Add large zero g rolls to the Twister Roller Coaster --- resources/g2/sprites.json | 240 ++++++++++++ .../track/bm/large_zero_g_roll_left_1_1.png | Bin 0 -> 1358 bytes .../track/bm/large_zero_g_roll_left_1_2.png | Bin 0 -> 1122 bytes .../track/bm/large_zero_g_roll_left_1_3.png | Bin 0 -> 5479 bytes .../track/bm/large_zero_g_roll_left_1_4.png | Bin 0 -> 1355 bytes .../track/bm/large_zero_g_roll_left_1_5.png | Bin 0 -> 1268 bytes .../track/bm/large_zero_g_roll_left_2_1.png | Bin 0 -> 1236 bytes .../track/bm/large_zero_g_roll_left_2_2.png | Bin 0 -> 1230 bytes .../track/bm/large_zero_g_roll_left_2_3.png | Bin 0 -> 1204 bytes .../track/bm/large_zero_g_roll_left_2_4.png | Bin 0 -> 5247 bytes .../track/bm/large_zero_g_roll_left_3_1.png | Bin 0 -> 908 bytes .../track/bm/large_zero_g_roll_left_3_2.png | Bin 0 -> 5277 bytes .../track/bm/large_zero_g_roll_left_3_3.png | Bin 0 -> 1500 bytes .../track/bm/large_zero_g_roll_left_3_4.png | Bin 0 -> 1280 bytes .../track/bm/large_zero_g_roll_left_3_5.png | Bin 0 -> 918 bytes .../track/bm/large_zero_g_roll_left_3_6.png | Bin 0 -> 5220 bytes .../track/bm/large_zero_g_roll_left_4_1.png | Bin 0 -> 1562 bytes .../track/bm/large_zero_g_roll_left_4_2.png | Bin 0 -> 1679 bytes .../track/bm/large_zero_g_roll_left_4_3.png | Bin 0 -> 1175 bytes .../track/bm/large_zero_g_roll_left_4_4.png | Bin 0 -> 1093 bytes .../track/bm/large_zero_g_roll_left_4_5.png | Bin 0 -> 1192 bytes .../track/bm/large_zero_g_roll_right_1_1.png | Bin 0 -> 1396 bytes .../track/bm/large_zero_g_roll_right_1_2.png | Bin 0 -> 1710 bytes .../track/bm/large_zero_g_roll_right_1_3.png | Bin 0 -> 1202 bytes .../track/bm/large_zero_g_roll_right_1_4.png | Bin 0 -> 1085 bytes .../track/bm/large_zero_g_roll_right_1_5.png | Bin 0 -> 1251 bytes .../track/bm/large_zero_g_roll_right_2_1.png | Bin 0 -> 929 bytes .../track/bm/large_zero_g_roll_right_2_2.png | Bin 0 -> 1100 bytes .../track/bm/large_zero_g_roll_right_2_3.png | Bin 0 -> 1388 bytes .../track/bm/large_zero_g_roll_right_2_4.png | Bin 0 -> 1178 bytes .../track/bm/large_zero_g_roll_right_2_5.png | Bin 0 -> 910 bytes .../track/bm/large_zero_g_roll_right_2_6.png | Bin 0 -> 5167 bytes .../track/bm/large_zero_g_roll_right_3_1.png | Bin 0 -> 1304 bytes .../track/bm/large_zero_g_roll_right_3_2.png | Bin 0 -> 1291 bytes .../track/bm/large_zero_g_roll_right_3_3.png | Bin 0 -> 1243 bytes .../track/bm/large_zero_g_roll_right_3_4.png | Bin 0 -> 5329 bytes .../track/bm/large_zero_g_roll_right_4_1.png | Bin 0 -> 1444 bytes .../track/bm/large_zero_g_roll_right_4_2.png | Bin 0 -> 1122 bytes .../track/bm/large_zero_g_roll_right_4_3.png | Bin 0 -> 1457 bytes .../track/bm/large_zero_g_roll_right_4_4.png | Bin 0 -> 1378 bytes .../track/bm/large_zero_g_roll_right_4_5.png | Bin 0 -> 1230 bytes .../track/coaster/TwisterRollerCoaster.cpp | 361 ++++++++++++++++++ .../ride/rtd/coaster/TwisterRollerCoaster.h | 2 +- .../ride/rtd/coaster/VerticalDropCoaster.h | 2 +- src/openrct2/sprites.h | 3 +- 45 files changed, 605 insertions(+), 3 deletions(-) create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_1_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_1_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_1_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_1_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_1_5.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_2_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_2_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_2_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_2_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_3_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_3_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_3_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_3_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_3_5.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_3_6.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_4_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_4_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_4_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_4_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_left_4_5.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_1_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_1_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_1_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_1_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_1_5.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_2_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_2_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_2_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_2_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_2_5.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_2_6.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_3_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_3_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_3_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_3_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_4_1.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_4_2.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_4_3.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_4_4.png create mode 100644 resources/g2/track/bm/large_zero_g_roll_right_4_5.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index dd71d6eb70..7b2079f8a4 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -8383,6 +8383,246 @@ "y": -29, "palette": "keep" }, + { + "path": "track/bm/large_zero_g_roll_left_1_1.png", + "x": -25, + "y": -47, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_1_2.png", + "x": -26, + "y": -51, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_1_3.png", + "x": -17, + "y": -52, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_1_4.png", + "x": -17, + "y": -42, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_1_5.png", + "x": -21, + "y": -29, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_2_1.png", + "x": -25, + "y": -44, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_2_2.png", + "x": -28, + "y": -34, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_2_3.png", + "x": -32, + "y": -26, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_2_4.png", + "x": -30, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_3_1.png", + "x": -9, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_3_2.png", + "x": -17, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_3_3.png", + "x": -31, + "y": -41, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_3_4.png", + "x": -24, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_3_5.png", + "x": -9, + "y": -9, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_3_6.png", + "x": -27, + "y": -23, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_4_1.png", + "x": -18, + "y": -55, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_4_2.png", + "x": -17, + "y": -48, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_4_3.png", + "x": -10, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_4_4.png", + "x": -9, + "y": -39, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_left_4_5.png", + "x": -23, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_1_1.png", + "x": -25, + "y": -57, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_1_2.png", + "x": -32, + "y": -51, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_1_3.png", + "x": -32, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_1_4.png", + "x": -32, + "y": -40, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_1_5.png", + "x": -32, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_2_1.png", + "x": -24, + "y": -32, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_2_2.png", + "x": -25, + "y": -30, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_2_3.png", + "x": -24, + "y": -41, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_2_4.png", + "x": -19, + "y": -31, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_2_5.png", + "x": -8, + "y": -8, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_2_6.png", + "x": -8, + "y": -23, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_3_1.png", + "x": -19, + "y": -43, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_3_2.png", + "x": -14, + "y": -33, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_3_3.png", + "x": -5, + "y": -26, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_3_4.png", + "x": -25, + "y": -19, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_4_1.png", + "x": -23, + "y": -46, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_4_2.png", + "x": -21, + "y": -50, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_4_3.png", + "x": -32, + "y": -51, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_4_4.png", + "x": -29, + "y": -42, + "palette": "keep" + }, + { + "path": "track/bm/large_zero_g_roll_right_4_5.png", + "x": -25, + "y": -29, + "palette": "keep" + }, { "path": "track/railway/quarter_turn_3_tiles_sw_se_part_3.png", "x": -8, diff --git a/resources/g2/track/bm/large_zero_g_roll_left_1_1.png b/resources/g2/track/bm/large_zero_g_roll_left_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..583894dde0689dad33adf36997fe961a3e816619 GIT binary patch literal 1358 zcmX9-e{2(F82^2E-oo4DJ?B6D=V8Z zV+MjC<>loS6%{h2Qi-A(g1{+C&oD-gW9@dk$Kwlygjj4ioz9CQssXqbkoroaQEE0T zELM%fsr7itK!}b+xkS>L$@&R3V$fEydYR3j;2D*VL&J6=>M0B8hZB@&xl&Z|^@tu{=Oag!-!vyJ(D zFdCJkQY9|akP0oW(y?lT4P|&O=Oyexy(>cb6SR;vDKNQ4r_@qvJ%brpf_0D%AMF!Z zA!&=HUCCS^GZ~fOKuQ6b2`H>U#Uq$crVFWzQJhU0oEgra=VLHTs-+Ajx9HSPgEqhr z5spgQnUsgi2JQK%XEGUt*_cF%sniA(GvS1VqMQulwOB$%zl?G5_BbF!CX29#SEs`Ljk}vfUuy2qd@l})x-?fr|P&+D;Ts{QDAlosk z_C}}RzNDZ1-wJ%wx8sXWeU!&8@tbNJ&P{ANEVd8RJI}uNf^N>(>l4b>>0Nfkk6&&S ztQQ`dJC4@4V_8*pUQgdXY{Y$L&0I=Ey>vHqp!r@~jkju`PElGja_obbkG3aHQX1m& zP-6}6SpV_DB^0{d-#0R0TzvJu?7pe>&VgI^I;QMw_}b0BVt#PLZRf?CjiLG9+;(;# z+R<|9pgT6Q#@@8=(^2!XIfJ2t^?iGUclJKfKj#@QMgG|kerudj&0Tu^wV{=t93wXN zcU*7jykPCl_(lc!^z!WbzPmk3dx-D=SM_2q)1qFUJ92VWKQ>gMjGnqB+hne)>FwSq zc?z#OzHQILzvE2dDBftTjO_mGl`!}Gz~%*S=cePtvcGzX@U_#6TGR{Q+_B?&V<=pG z??JTe=OvfjahZ~@zH;?`$Je{>oHUI7I&*7f^#fn~Ab#8(_iSD$RhSa^hsyT;u78#U z&z|T|(*KqvM_gk?U+glB-l;qP>h#Len{aonG_C?*9S)N@zR) literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_1_2.png b/resources/g2/track/bm/large_zero_g_roll_left_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..39e123df82738b68804f983c1b7f1c0ea9206245 GIT binary patch literal 1122 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 NLC&J=eOW7N{{tA_9x4C; literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_1_4.png b/resources/g2/track/bm/large_zero_g_roll_left_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..150aec64a2eda63b2040baa1f9005469fd2456d7 GIT binary patch literal 1355 zcmX9-acmQH6#hZk+ELgUYSM+`POVbH1qz(xNDeq%H_NE(#%@qag`$Vlv@th4v2z70 zme7q3id5)GV=5NtutL#=)ve6S?8v~9m1HbMDi$nI>@*eXn7F~u5|Zz|@4bKC_s93X zw)#5l%;~eI0{~{$uBvV*@`7R!5>c^-+wgS&h(P@tjWxw}%9JTnr%n}#MAN2CD=8@{ zEiDy`#S)36tgK9~R4Q>?tbOjd`znV zMhsXf;AX@@PAs^PWKdR!D_~X)3r0BMhA^fCfCj)Q7IO$7rf(%5X{678KJ`TIANkRR)%r0tj}rd$n6hja~F4v+;22-;n$?IsRv3SfDc6kPa z;Z!V9NK?S56Y~sWH==F}=Ce^DClmFV21E9w;L9dsg~BML0MG-#1KCptVJHAoNm>Os9C#=Y(Sj5WAOj#Lhb|ljXc)1;xD%!V;EC}B&}o347F$@k-HLhK z+F*cCPKM1#5KN8=r`zVKT3h0Rk0k)rf&Y zEevim>D+cpz+;bwJc(E+n~K3gn$YQB1i%!4u;_)eDEAZ!hs~GC5I*ly@bS3DU|=j3 z)@I{ywS!Q5DLkaX1)X}B#RokJ%hVQ?9en!og@N)0k%HNK(&iiT|vD_8l1`I~><`w}_B~2)aUu9XT+W+CDsE^8PC6%N3j6V<#U2{$xXQ*M{*& zmHFEjG9z0qbyGL0E^_CVbpCk0XU@d0+Q#&a%g&Au(AvJdp$jR|wC{X&?9R>*Qn}}A zO-oH*bG~!sz&z^Ov7gPsQ}Tm3cFWtX68X~hi+k;R?b`n$YuleyEvrv0yMLxS)7?s*mQ)b)hnnil11k<~^!DnM?p*zus@%Y= zCFNM9bZ&p$t&Sn{$$`%|t@Ui1ET0?dd-3MuS1MT9nwVhrk9c>=a~%(NG{}A#$(>w} z%`b1%**d**BxT~I%ZHiuskjD4L!bZ7@_wwm);yqSQa82Ve&*hr z-Nz3vKCq*;y7%}(@}<94?oRqn-+SkqD_4%n_m-``-mM#62;)K1*`76s zt)~+eN>7;gS#!Ok=X)M(UiicIPpOa+F?Z@0HP%P7+@6M^zR|!xJfElfkJgx#=(1(S Pj{vnbb=9Y%$haJU^bg^9HS_bWoeFc2mdR>(EMl+Zzc^GW3oCeHXgN$I44_$Fy)WY!6d7soe9ltB8-^LY-LfJBOE-%2be&_8AZqiVO{4BS6(~5AqBmKRv*mcPnybK8RHq{h2Aj#uq8Mkj3N#aN)|UC=QgAXF*VIfo zPXZ^62&_(Ynq&_e_K~pwn+&@rV`459F6Pv7`8Fg0umd0fAOjEsU=n}=0$@!H1$_dH zDNxHX7Qo{mNP>h7XbgZXfV=@pI8+#z@W6BcY6^G^o&Yoj>EJ3f*Cbd)Kpl`6EqDI0BQij8jC>9?um?kU${^p!l5S;(rL=!U_Bnr=i_nAPhcSu zk5PDv#*)L0Se{cH7+mX@FBWpg&a?-LgfpE&as82Z@u>VSFp*gbvkYVrboNw;IL zG;oQzUzfi%f6X8^aAVJCL3+0Lgs@<{?D*}y=R|hP{_>*xe=Jx!)NZ(PHaB%%y3}^( z*em9f`1jrL?cWE>&8{CuuB97)T{1nh_3xVpj=DBA7d}!0m2UUE;?z|A*oWSZPy3qP zb1HWZpc5BdFAk2pk=CDCuo2$f@ba2z?~tTckLnb)@2d3r3+Q^~@^>?Qf380){IYlb zzTKbibsagp*nNBEVH3M!VaN1Ky~pvJUly~swzB=7eQeesijtjdSn-;cJZ@sy5<+$t4#Dkvkhn@e%#unWjNRB>JBDej}b=q&A zDqY^q-rIN1F*f$!{c>Ns>%=GHa}SV@HVmB}7~gfcaqeWeXMAWy*V3+Q1M#z1VVvT; zy9#|f*AP$Vt_#7fd;JHi>HRt1rY)V@_xyYVA4*&^4Szk7k6cu@z4a)xu{yJDL)Y$9 aC(NI^IQ>O?yS0W6tXi>l`8V&n_Wut9-a(uI literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_2_1.png b/resources/g2/track/bm/large_zero_g_roll_left_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..3fcfec8f4d079b7c5982a2e975489dc81e652af0 GIT binary patch literal 1236 zcmXAoe{2(V7{4meC*iaC}E1&bD_(#VABiZ(LwYYEBc{q@iL{PE=J zS+&yEqRwBT*)ia;0T&Rt*)3aT-M&WFv1k1{`LQv&Ovmpg_wJM>fUhGr>|mUM(v&6L6ux zM*)#V5YK@cRAj4$b?pz=+7K=ey zHsJ;fWyBaW>9X2*)Dgfrk@QAsA!!e%*?86^<=tk&gxM@4i`qHD$!X zk`Jq;M4>9{DPUlM(GARgU=4BcK3^&nl4CJdk_w}v<#HJU6A!Er1W)Mc zw2954?gAYwI^!i@x-5=XQl*Jp6*i)JJz+H3%oY~KIFj_*nV_ro%%2K{Gl^7QQ7Z)s zxa^3R)dyT=(St_)R5Hk>qwY*HkdvdOoKmTbK?(o|0A2t@0FnS?04O2=)?jGp_rhcx z=5ve{@HhxlK(c{610V|^Z-gNn#u+GiU^WQzaq!4^0@!KbU=R;y4EWHnXiLPobXri= zWT~XWnwH58aDO8u8kxA+C0Y4ADVCkdiZ5M_WGAEo%$2PMK$sC5rgu_i4~zTVb}`_I zhXd(kSXGjxyaFo)!fuBWfO!C6&5K}7?lC68A1xM%Xyh^8Y?gL9S&xVF`*|D_2rNS3 zNg9{!*eHXR92V#@!+;e=aVSwxwLeP4+{Qm2W#FCFD_OAk_SG%5y}NTs`wVYiF8sGEtNUo@6TO{=W_iVyqjd6z?BLKh|L!{W*|L4}yP7Xw*h~3t(T0at&)vR7jQlJs*EOfVLR9taxxSVKrI|ag+N9NYd%7;nJ9A*$ zqAk}JZF}qWb({S=`d_%WBXalbp04G;PTOb+wUU<(tut>}->^_Pa{AU@ZLe|T?!PvB zzSb?9I^)2@PczYDzr0UqJL}xtM|6Lml#VxV=>JJ9UWx1(Z_#AWEIU4D=E%_g>92Bc z4}C0cpMC%EQ*FlwES|QFmGPHa|5?8E9y-gmx9QH)ZPkOBwd+STP3_95Z}$tck@SN* z{)VXAJ{`Ig~7#>S{Qb1>$)&s!JPtO1=%S1uWNc~kfQ-FPb1 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_2_2.png b/resources/g2/track/bm/large_zero_g_roll_left_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..2e6d0dd1d3a41730a45decbc440050e4698bd808 GIT binary patch literal 1230 zcmXAoe{2(F7{}jH#%)X}W?&NzJxzh?3RXDeG&LM>on<@NF>awObrv|Y8Y^7jhJ_S! z8C422%fU)Gv@s=|rjZ(}o6@+#npnexf(H(*?4~s-p)Mm<=|)3_do3aPKEM8XzJGk4 z=ji4Z`<&SeX9ED{G;OeLsnmu_EUVE~@?zUa7XUi2d1G5+Wvr^InlWRBPN$nWb7pmQ z^{iR55Co~Isj024H5iRX9Jf#u$+9%ZIR%0D`~9*UiN_P^^suHCOC{U_NGo9II;XSV zOCV^K!%Q^pN~VO28qDPt%8WRybv$hl9hk(KA_Cs;r&6*b6X&&|KtWT=#k3s- zE;I0wKw^<7kEDY7Y_z_VL1DoHOD;GiL6|lIzyRPv5MHkrQB*RS6sxtLVTRo9tSF90 zA~2Og@p>a^urQd_WwP^Thlq2MRR~l57#&KoO2(DY+!%pc>_#hVra8jNQ+$94L|l;s zpHRiL7E%k*TsfsDK|Ko$Zh-lKNkWK-!5%j`QzWlCf;mAcN@>{7nCm$L_1eurhc(Jk zNr6@UTvitHF@G^7m(>`|r}g!O$?U)hH%WO}Hpp>duQwhHrXmqFk;n}X7mGy*P#&0M z1dr;eB+6#Y?i>}!JC%YrS(JuL@xoNL4C~B#Jz+4|F(YfXa8|28GXYm+nJ*p;4MpQx zS}o;B;Gz+M)r&4n@|eRuG8SNyVfRo>%%;MHY`Rn$ha>@U08If0gLpWD=rxBVdsN|) zNx!Pb3I!Ebyihm5eRZT{U=+-iF!7pIDmr5&Z?Y_BrV=@rEt={9fgyH_-brE}7WcVn zN%SZoF&PV~=~zKa!%~i*X_x>|0}xhN1S)oqh5CKre4Yr)k0oR>l+($2Je<$R;}$<* zkx4v8;VIfO%$N%fBXnU;8T816^BMSg`iaZ=IF?V3TcK+bcai zH`|}`Kl?=W=KHCat4HhRbw6CS*rG(Hi)WUHTKfV0zqU#4v9Dk|d@5vi|ZPT{9_kP`bwijV# z;(YTvD|Zeoei-KEuEfb{Z|B6SUFR(8uHgCjD$}XiEzO086Qldb-&@Ewtn6w>C;M_e zmu%?zTguMXyYbAZxL}ie`wL>vlHUB?6*XfQ z3#+})O}0)idQEc8-?w}4!nHRipB}q6I&u6$M{Z3`-;K!Xz`l>iu6J(2R#2b(<@o-e zn?BvZTiDWtch>&5|9tzJ*3;Vj`?r@o*;u?iX&pTFQ}^vXnZB!IXGPun(!mzB_uY2= vAH77=jgbTL?*j|YoeFMEK7V;l2dp}Lyk{`%*AlIMBf zef@o8=Pb)C06=H&tDb>IUC;=7o1u~CcVRsM7(oBp!PSkisi|qkj2Q-lp}D!arKP2{ zwG}~-wzjsJGiRFZb~}bS2?A#risO8Oz=y-(cs!ZS%DG%o*K74U<^;GK&{Vt6X9@&t z!H_c&b;lEQI?F1mP|%{~N{VnGUUxfBnMJQn;?SgkoeC3b+*`=wcTd>Ll%M#zAo|A5ZWRI+A3QGB0al zPLFBTba_fO;=sfJvme+(0F@9|(oAMipNjLEH(C}_H7N&A(GC;mvIa><)ay=jgd#9n zm@CDFN+w)W<5OA&R&qv@3w3xgmmepB3=`$JL@=0*M%83eljU-;SgX|_u<`(nBUsu< zC|0K6@Rx~5#h0oEm6}wnXRFhtDcJ5X8eL{HX|pp9C+Btx6dhq3%R<>`ET7KmIjvsC z0ZSnQV-#7N6mTR$cqYOq34cB#mefSGl&jY#Ar62S0096AfD8b604fN84bTJ(2{4m_ zdWl8>kAWBtWD@8!fDC}V8AdUfqM;msg$UGB;F0kzKoP)8BLU7V1|2bpOs6ov|NUz8fpSA8$vpbKHL^yu#lgU#6T)0 zDw&v;%T)Cote0IB1!Vwr0Aa(6NQ3S%tl?0iQgJ2Xk0BHagwMwW0$eD>W6rS48ON~< zfvJ?UNIR-tJ7jH8L}3DhG7dGWar~}D?ROsi!1jSY2E1}>d~>7U)azL}xb(oDQQw*H z+>VxOSHvwt-NHdnH$FB0+J<$3`bKYDxzzNP2j9A5#RY%U6a5d}+txSNK6}|@{3bea z{5om)?!=X6<;w?_jrg8AOWs(M>gnBo@w{d8yc@sun=3o-qSy$2tgYt_*s53gJ7dwT=u-6e0`EWW;LWIMOy>b+%O z9PI8m_F&Ey;@4G&JVR|)2TF!bFIm0RqBn-{O&<=^8rymRQE?~e}VyB91UL5p3Ve|mBjz5j@cU0ynGwho!5!L_z literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_2_4.png b/resources/g2/track/bm/large_zero_g_roll_left_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..604d2f4143cb517ecab82566e8ea6d5f0d40eb5a GIT binary patch literal 5247 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_3_1.png b/resources/g2/track/bm/large_zero_g_roll_left_3_1.png new file mode 100644 index 0000000000000000000000000000000000000000..808a681081d1e12dbe8492a2f9e1bf4783541fb7 GIT binary patch literal 908 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 Q8Uav{za(#W?i0`b2UtnX{Qv*} literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_3_3.png b/resources/g2/track/bm/large_zero_g_roll_left_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d5203f821619ca384fa0aca5bcb4e77d3012afe9 GIT binary patch literal 1500 zcmXAoaZr+X7{`A~`Ic7PMHdxktg&LnC9b#iTI_nuR}U5IHD4VSZq%`&3+t_@<1Wsl z#w9sgR7_c8MTO?{?ZmW&#)^s>ce0I@CN{27vZ8cFj?`^Af1~T}^E}Tz|2*G6zR$O& zWUX{+`kZtCz|_Kmywc>vk|mkMO7^Gzel`FsP*Pl$pIlQ?Qc_b>SuECs2@@txoS2rD zh9JnKNs}f|p3D^p1Sl#d2%Ms1DwRU3rHw|T&E{~q+&*7-I2=zTP%*$IfRtq@6da9) zuhWZ7W{J&CHoBA^uQm`gN1{$bgvccsw2W(z^DQc&LyNW>39n5aaM5AEDHe8)#(h#A zP>O&K2Nnuxq!F)~9cttx0z4QK!-NvPwm|3;06+quL=c+IHt={Bq0lLjw3DP?tqvIs zgANDudU+^EfOEwpU!oLBX_4H3sw@(%oiH*otA}z1l?Iv9W?mD)?lnLGU{dHfI|VU8u0Z%XhARsSLzZfyf__{n|UfXDpfl(iug9$})6jS4bj-t#em0hQEnay5@Bj|QVy1V1? zI0QTz2yF=3$R<2IDj-rv2vbzyjOjdaOLxK*dmS2u86q|t<8q~Z0VNWvBoeKRG%1tE z^e(g2-{=baf{6$Ylrlt1u?>}o$_2zl+XkS~!Kgg5|l0JH#D0AK*{ z0}w?3OhOV+uZ4^ghC`$f&?vCtz%2z~5{F(4y=oJ2G# zu0bcVTBMCmmB(WY2ANna2$NboH9++lxP?nP`AWBt4ofU?1(VQuMs0!D?g$LUg&ctK z5viE1!1)>q)vIL|gT`q!co=KY$Hc-un22C98FT{}1`sB_FeT;Q!ZYga(I{rOy+s=c z5DEpQ(Wvx#8WkHcu?gWx~!n)RGsE1lRf3oeb~F=7$TdOvwM2IzS4c~>CyCs<9C+iNBUN-oL1Zo zFOL1Q<^7uj@lEX+nhw@@4nI2eXvgmWJ9l?1bY|0`xxZAgM(SqR&-?qMtvOe*a}{kB zhLmNG(z&nAeg3n{QwM9eV>|t|mKSrFn_F&5*Buc#dt`rp_f5;*iJZq>{ojgO7s?A( z>V>&is;;CpW!B`cxqaQ%yd&#HS(#(-cFvvDxa95JGfUcO$}wEu z8ehHQK;F+C`h;Jgqr)G|z4w zg4-@O44-Q|FnHup^OGKO@kV>WY|Xi%y1EZD#~;_y7y2@Hw4MCEX$9wA`^?DgEYCBl z2`_*Cyz5bOWoz#2?w-93m~KmtNk8Ch%Pp(dJP?oXsaeC{$9sCErY8HyuFhMY`U+OX zrKwq zw5_qtZYg~E@8j$l#l7=8s<+H2N2<@BX?WGDyHS+6zA5Kr!5Y_B^H}e#{Oj2HwC2`3 zwao)R5w(l{F229y#-8q6LG7G^-x>r9h6jF)F21Vyr0Rom)9F(C!S>#+{aJfvHSLvo zs=L~Y`-hG{GnX$eo6CMNRxy@w;(39!{D+Ze;*tlP*}TU;&VA@z)wJ*CvyVpJ9ZB0@ z%MjhGUQ~53M?QS!*2mMXZLchv*VZ$KNU-QB(+d}-w#+@8HFo5nC-=nVZC1j3_95dh z-S>`hR#DaP`o5`ZeckqTT{`+9nXMjAN3#XjZhc16o7*~0?%Z@@Xy&pVamMh+s|&;P TN$hs=ML}Wy+Ps$BO`rb{4jr;S literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_3_4.png b/resources/g2/track/bm/large_zero_g_roll_left_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..32e54b4a2123a384b5531a3e399eb0bce6d7562e GIT binary patch literal 1280 zcmXAoZ)_8F7{`BO8#frNkg5fWG*aS$CpLJD4vui(4a+F*<_;*ViPfB}!@js=H))_q zk&cvk+0Ic+m5wx8T;mSbkQu8~SEVeCR&tIebmm|U4(V`)vh+n^%luhF@_qijdA=_` z&(qb^Xj;5*#XZrM*F0 zFv>+`cS7;Wxp1}^SCK%?0F52!TmTgjV^Cv?pw>9a$rd5Yhw@?q4$+vJHENwEOt27P zmWuI=>|ry0enRr(lVJpw4LF?QD zegqGzsF;>XVfHNLov?;-&RAYd7b3aYOc7RNDwR>AG3oRSW?%_|H`88QX_+e`_>$p> zl8_5o64=ZLrso#?;iL`v4A}(xij%VE|Vw}rXUG`1ppoZ5daB*Bmff#fF;os zbn#FMK_x?@fWv{01W^-EXaE@iISmwW7@}d+0aIS6guqkqMqs9Zg+?5##_hy>qA46= zV=<2`OSzm3OI}(#z+Kg(sG&nTTNLFKLd;vGf-_e1r)HyBn8~ARVALTdgUU+k91QNV zn?<)Ht9AT`mqc zc#H-=iAxk7HyhG4mb2)gO$Xg54B#+ILfKq8e&hP;>8C%?(cH*@?f1u8OZ{L&{f@nL z-QDLLXaCt=b$SS1{${RY|JjY5pYFNw@vZCATP#nO#{Np)-Pp8zucr6t<29RveW$n8 z|1vQA*~7{HnN{O82lpL@R9tt6@7eJ6IewvEGjR35nR|WapTT^aZ?Gpm zSXa5O-@5y9=KQLWAKu>e_e|w$;bn=_tC8xu9bdH69PX-lVJ!6PSG^;h+k&Uk#G)m~ zHY}+{-%B>?|68H$Ti!<;n;Y2t`OOa0^;_HK>xJi<2WwZf6pk)i)$q_>9DR9-{lKM> zn*CjE_ow$?I9wck({THZPGMZ=Y7O`@@3$^}Y3$$ggF`>Je|T=!#qguwx0a7IbS{rh zJ)llnrz*y0A8ETj>3t;V7WKaPmC7w!LbNv;E5K zL*>Yox31m0b7pOpS^50!wu3$E>yR*CcW|y}P!e9h`{m5{?@YE|Yo5M=kM?^fXTJUJ zquSkDj-rQre_mL!LIRQGxj$=#jJgzNa1PwbI>j&R>_tgK(B0;VI literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_3_5.png b/resources/g2/track/bm/large_zero_g_roll_left_3_5.png new file mode 100644 index 0000000000000000000000000000000000000000..f62f82740d0e008a72feb9226cc5d43e035f1018 GIT binary patch literal 918 zcmX9-L5SmI82x5CopiRl6sZ_6hoC*=5S)NHLg3IPKa3E0CNa>yYI21{fa;ZgZ4VQbrDKC01AMPVP>mk6NF1q0ngtk%Cg_z*!BzGM@d4k?T&ym3d!q~ zWYRsGHC*1BiB2d_V>MXmQQjvxf{{ABO3MbPnW8yX#=h=HW|Y}!KFx~x_K>s$Xsdwt zfgAzlVw{gl3rb4_GwV&ZR#3Vrx>4x1!4X4=p7i*+A;y-PImX7bcA--y-XROoE^W0r zite#oUl50?Ix&pdaJZOE65r3FXuDpQWr=_=f$}hR-V$R%UD5rmINoVNF^o%hypcIHd;)k%lRTtv;9^8UB)c6W$UCnpl2f?9INrHzYOh7 zGAlOee*Xdq06hQ;zy$~amH;~pPz6OqBMXHA$~OuHCJR#mA_;N@kP67e(S${Tf}#Oh zjZq%J%iuYXMd&Hmz`*SxJ$0pdV8pSLWnocdsPZEEz>b=Niz@-CN0gcKZmEU)VSMmb zx6u}DN~#SUiAhXL6Uc$ej{34|4}z&3htn(#i#$d9Ehoz;0+a(nRTksQ?iC1UG~4aC znfD6TY9(r#Iv5zEk;yU+$9Mu8ifke?YlSX)9i)@UrqGN67BE-w)=+U&V8_pWQz>{|bHi{O#^Pce{Un)5Om| x>He!YPm1%8uYa!p`hD}eUw(WYe^2_Y0dIUpJbm`==YFLJmk+MGKi$9n`hS4!gr@)i literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_3_6.png b/resources/g2/track/bm/large_zero_g_roll_left_3_6.png new file mode 100644 index 0000000000000000000000000000000000000000..cb1caa331d4144874a3e3d73a7ee594120ea05c4 GIT binary patch literal 5220 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_4_1.png b/resources/g2/track/bm/large_zero_g_roll_left_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..222bc08d99e14e164b9f008c9ebaf6af42890f8f GIT binary patch literal 1562 zcmXAoe{@oH7{ZVWVcC2)T>?-lhe?# zi5qT|*sxHUVdEqz>O?H;kmDRzk+JrR3Kfes>a0Y?+MGYW;pv>u`@ZM>=Y9Top0{yX znW}K&6B7Xdg{39R^4y%CD>a9m>qUXVRsh&w*=s8n=hnQuJQj<^X0!A2^T&-FH-7wh z1VK0)&V&gQ1Y)rm!%&3+CrLF$X&HvLSS(Jb+wTuXBE5-3CY!}jfXe})=4!QkgF$38 zp;nvR=_0&-T`0^%W42_rMlDHYH!=eZ~HBmpE=(460o{>yMB?LMt zFyg>YB3>E^+jwy=KN}UoGzzmic-IbLL<|4{fDS=u9?vWk+9eW?T;4$tU3z`oY#w&I zVK^+r_+ngu5+b=yqN1f5Ge+6vj7wqhsU0EG6V(M1dXY?ss>E_qs-|RGT0vV0t6S#| z(!rQHl5oV*-sDJ_hXXzd1bQGc0f`-vxdke}L>tEGn8uc5JQ;fgb`VlNB@-G|QkzEZ zr4%8Cj9I9-lS%n3nXq#t=7XsSk1vx*HJD6~D~u#*qbQfr=(pLzZg(sgO!oF>G8qVj zG>|wE%*#`Rgk)5zPb#b_ttV{^W$e9KfBJ5G1ahT3o=hN6iNvH7rQ~u(O;~lgVvW z0Wb%lfF=g|JTMU_B!I?%0|!ABNDu&$0MY_z!=Q(NK?96hVZs9*8ZQHC1<(+PffAUF zQiomT^-!UZB^L9g(=nLS66yhF;^KAz;SuSA5;`HbXSBYoF*M?g-VG*UJR{))nFvv# zJS{FVkeErYwwnzehdJbP#3H_QA_B8XnOY5l044y0IWMd^x&IMbOs-T)=5qcI6OAgg zTGC*kOePvbEi%-JV?G5IR-?UyG_4Usod}vG(1pPu4rA(E_+<;YHy{4M*77nEyfpOF zS^!wzlqz3dQPTKf>#EbKnFWh~hCO3*iVjyy9{Q|u^0oM9d+LY8qQ1fxzx?u>slRQw zk_^6Ta5)ddSs(WH+&|EIBAb7!O8;rJ_yV;^LiD(8(h z>n3K~Hve#K;w?wusX3zZrtP=L%Y#LyEAI5QF0Q=UvA+1i+{35#vpWA+dSypR%S#)* zXv5JxYHw4bbJgAVRU6A^9}j&Vz_-Y^v?!Yfad}?v<(fr;BkUy+bXW1e#y^+V{rXEk z6?mYW`Sp!Z&z|?iCDIGkogG&Ps;>(ty;Ze(c*&&JL$ki78qPksRN1z-`GXA$M+5U6 zCBndu123dIiqCD|rR!W#x4#Mbw0}3faIB`F^oZcc4=7$MxL-cEymv{I1OQMa##{YdTLzTqv$xfU0<_V0^>L(X+8?_Fy6>EpE<&W7_Z|FyEM zu)nfoqj+=;`;j*iy9UZPmsQ(;<8-5rV`~~Yd(rjhyZu-Cv=vPi-|fg`FJ9!j*Df7q zSCv++8Pp@Af#po;^{=ogo3`yZqC0VhdCxVyIB&|?-S_AX-zIk(qM`%2M`x{p0Ovf#l#1=$Br ze^GsK+qcd`lD3(@J6oDp#}4>6#s#c`&YnO!|K!ct;e`ftUd57^{}}k!+~GV}cQVj7 zm5@JIz}eJ&yYJ1ld+jyKotAd~+k!Xu)}+~G4X?8{vFeMqzc8lU)mi19-o{VuBqv>4 zG)8pocF&tue{c5m+E12E+Hxu0U$y$qGjEUIm+TzC&Oc{7ccU45cmCL8-uh|vjBE11 ga@ibZoh%Aj)-#hEgHK_}T);u;;xgrlSKg@m4?Qc&#{d8T literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_4_2.png b/resources/g2/track/bm/large_zero_g_roll_left_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..b76cb1e205354fa3e17cbff004aca98d26304873 GIT binary patch literal 1679 zcmXAoe^gWV8OFc-GCk z`Qv#%A8oFX&&r;k4FH%`URGL_oUbLTDl;wFZ{_z60+0qaZ``sjxu&F~q^72(rKP2( zr)Okj%$PBQ#bRYoAU2t$HaqU}sC|B2h%rZpotTKFl(H!W*Qi7+q|l*5+iA>iQ-(ZLBxs67 zoRjf@oCnk*pqBv)!E#Y7znK$uLM|pj$mjqY|{<9>A2rE$++QgfRif`ij=5CBg6CrVJ1ntUhgrR{SF7? z^+pE<;_)~HJPHVHEY!upd^{o~(nK-Su*wha=%~a10uB(CvhgFfIfX3am2Vm4gTlAORr7g=Q2wap={;kO@Yd;HTgv zK!E`z&eD=xqh4gS$X!m-=c5_M9g8tA>BZ9k)WDWmxVRHhdxca)YKg1d3B7O97Mk`( zVK^?#1rmfM7jslHL`$FsjlyEoI;}>Z+sXvou}Atb>xtGm+`aervW@cGM>WhLu2o=i(W9`k)j@1^JH1)p_X?3Q{z`}51nGnLOf zn!fw=xa0Af-Ub=AggnRJIqUso{^}ouwv15Z%vkUGq zXAV7j(C4}M@b;OB{Dxim^{p33*R{h9q`0*uM69%aJU=V1(|A(e{2}tM?6gyhDSWKZ zRH@~ceBH>^O?_V9^ss3Bf`BJDTJUi3c;95}hpvt%zshJR_-N~o*(c{TtT6oWUj1*D z9P(j??evD_Vt;>K&-o3@V)x&;^a*>v{jBMc?b?pIkv8kbZ`{{*76~Q`%8R>RU3J`g z_UVD$RxtB-r2hS&23_1F9vQr=8Cx}{eBkYun{Nkp2kV;N&%62Moj!Wsf}E=_{dH5n zvU$@754wWJ*PF?@tj5WnJbefL9PB-PWo62?+0C!BB)$K>{7+=wRc&Rz;Fm65{6PM* z{q5#X9#XVBt6Y4b^9|1{f=5l>mhV@n@2>Ym8vg#E=a!``GxgvGMSJ$i;P}DLA6IX# z{{64VGtX_AxO8N5hu60vvFGE=*ZRZO>UTT)_V9wkgU8P{em8pJlV`s$H{U7DnDMC1 zvcGTpUG_%bz3gv^$7>4zvdeYl7+2p_xNPid-?g@b_1|1?FIiM8Oj}>^wZXqHKXCa`$A$5OLlm*fMvWq09K&ymPsW zFWvE<)R*qRdYC`9>3DJP>DqI3PkvZmlg>RTzQi=rqme?S<6QTrySe;!{GCm0G;{g-k&?%{34HejvyA*;C}9G% z<1G`ZQ?Cr&F6zci(d!6YIdYUtxSovc9p{e9zJI~mrOS8J+%NMdsRHHeDoQV}efQY^ E0TKTMm;e9( literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_4_3.png b/resources/g2/track/bm/large_zero_g_roll_left_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e73b45b87c7c9eff3f5121eb8a705966887b4b82 GIT binary patch literal 1175 zcmX9-e{2(F82+|y+`2gnDWuUF8>pni3taF_4m|aM+fv4v9@`BYsLN??SfzxU9MFVH zPN~vB4F?pdrjY`dr9fdN{Hof-GuAk>Dklypa%hQ-HjY4JI#^_r&k~a7{q@iLB+v7{ zyH|VM?X6F?0sz{(S9bQ+>w*w|HD3I0h&ZuuPlJXAJ}# z!4MXSlJNwa%J4Z&D(KNtS*20LOSXxOP4+qz!IhNob75MGdkY!S7>QI2b+Vdw+X0V) zAO#c-Nr{LSwG>m6l}tiS zv*T7LWy4qp$-CSl>XmUpA*BQzPBXC_rxy6E;dc;r%*w3X_TmYqa{hLDtUO0MXds154zE)mrMzCPU7^i zP>f6EbhxU;C-pQe=Pg#kg?e$qPtie+iwZ&_7|cYYS~96;v!$`IYPAZ1T?DQ;f~PEW z&dwE3e~FHieQG6`t14r)Ol7J#3ENPMg|OM&4kw3V0!c~?8{zBALYZi6B$YApdaXnO zoO}={*km?)Do3qzE-;hDFD0xNB}4RqyZQKpo{=m2TQ|{1k)-s zimVHWIEYao>jnl3AP1mmgHar+EX)RAAp#8*JT#sF3=O<25)f>15REDBlq%$MVO>vG zDmtul+5G?ywNZ+VRULfRB^sns^`&dU++@5kl`X+y)nx^Q194*(ALR&ec*xHvazKsA zxpYj=rz=Jt)=C7!z$}0UfUxdGq)zt;_HZasE)$9PBS?h;?elSgfDj6aI2ITQc!2=$4@M5`{&^gZ0YrIVA)^S-mLds-JQ$(R_^}z;POqT zxsP>y0WUXR^JKoc_V?NE_VuhY8|z~qO-zhTBixw*+cYxt%-a2jyU#narV~-T*pnEIDTl)s~e8(+`Ht$#il*)U6_4m@%33p&Rm_NE?Hx? zJbrms>uAS(&u9DN5BAPH-LX*~p4t4t(1II>u4SFw|Kr+4J&(~GK2=lP?<=u7Y3efrAQU%tO&7EfFsf2Xf~$Ejt3(OEy4 z2m1Tg-g@!bKMrV}Kbi)&Q~Q3K?*08Jd;f(a!5(sAs%b;Vo$8%=?2T0Kwx#_m-?|<6 rZ_(t5=U-d(^5y}J-SX7^%D>3KP;lFv(XFTI>VobrPv`K8*LVI8yYmQs literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_4_4.png b/resources/g2/track/bm/large_zero_g_roll_left_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..e8dbb2f18aa19c0b2041e1dffd3994876cbc201f GIT binary patch literal 1093 zcmX9-e`phT6o0ipuC}_sB1R2s>H<6KvBmCiH@MN$U2ANw_Of2Pz~Xj=gJzn_$<8f| zDA~*(nPlUHxJAq)j%!IV*y#M@q?u&w1_gs0uH90+VgATi#1678l#X@qT}1f2_xSwt zK79DRcfmL2-QKmQ3jnqc9~~TT&c0^#ceXbBY5Mf50IlE~ofvA;mX?++Teh^ewzjpk zwYRr-baY@C*4f#)b?a7#+wCSv56d!wz)4a-QRG-GmP%#vdEGFUEvw#WkRD)Y;JNNV zz#a;@!VynAL8sDuHZK;6O36%Asv1jRe!5%c98teZmGF#0-j1=wl)sdht)+O)(l+Xb z*9js4VFpwI%gR_WVJm0tjgk}9Jg6a}O%)--4Zs747$)0nQKwVIagC;L^ZZgUSdK>5 zG8t4XI!U{mad>zaE#h98@JC5WrIj=r%W=tqpp``33c4t#$LppAf|IC#%*t^-o)I&; ztea88N}9E7Wus_gz%GCz2(Ad=Dn?}--aH;CGP3DUR1~eQ8t67p*d@vt_7Vv{ot4;v zBA79$oKmW}SiP9qFmtGC*z6Qe_(>|ruwg++NK!f+&LO}QLLnVo%0+*x)&@SkN`+_pah9D9_b-eiX%&dr@>RevEb*ikmQJliKObyYEq#PGtFGB zW}>E+GYDj)n^7IS<`Q*WwrI5;$Th-+jZ|q*)`i86Oki(C@3$P0|=1JUnsq!WS#tb4KsB zHeUtJe0guFzQJ?<^v+y9d~e(M^u?afe{vi(T4!JR5kGRZ z@gP3lyZ@H{+qua@j|aLhE&j28`>&giZ~k)s+IuJNPVfD>>xG+N9bE4}d+*xJgFD9- z-#L`sytsD#;lUo?@^zxzI|p?!Z!yH}1sId*^U(aQ1bqjz?G@-;Jmcje=O9S{4SAK8l^nAo>x zq+k1HcJh{QZfgGRp+{$Yqfc&p@4L|zf9;JO-wnJqHb47c`_9!XN3OnTyVSG~!$V_( J3vW)H{~z^t+t&a9 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_left_4_5.png b/resources/g2/track/bm/large_zero_g_roll_left_4_5.png new file mode 100644 index 0000000000000000000000000000000000000000..1f4fd496bc130e937dcde5fa03ab4383fb20ae21 GIT binary patch literal 1192 zcmX9-e~i;)82;|ZuDjdeFcTJ8LXQlx;})4xq~HwY?49E*xx)2ykp&7=oN<8?dpN^L znlR185h@NXVIh+&I-q(pLZ~|8fTBwrT!|+srokmnZbvS<;1UPnkIxa3=l%81`y|iv zzK1rA2IloF>Hz@E8`&^4)~c&p(QoZ&<%59-od9%zO&iCDTVq>WTYGzZM@L6zXQ#zt z>FVl25X5S=c6WC>-EKFA`ACvr7>eUUg22b)aaqpf^Qxvzn`XVyziSuLx>|C5I%E5A;H%p0{nQhj!fD5o* z5G8=bAUPf>ChbPf(I~rM%?BGSd?-PvxdEU7U=f73+eMd4@_4d-|2dj2g~Ns@&Sf&N zSae|yH{tZrsGs!&cyCa|ILR-h$+$wL3QV@ls%99)UA}g5Ah_Qpc5H3qw=aQ zYGz8W8D}8x2^9%m4<;)@wk~P#9PM>*xGNg)CWHPQM-~J| zk8_4BRF!zWC^vNlRyDf=_jrRC9wx{r!z4K_9gXIb$zmp>t7>I>x?ZnC;NpQtMzEZn zEV!7mH(VhT)ljw;E!3syM!xpYXhNIUZpWR@0P1GEKF;qKC_2Hmmc{bPR4JD?HN8Pyi?aP(=W2fhJ*0fJzpc z2JHbn22uo21HhyKWB}xyFp0q|4b=!NC!m=HkBr9wMS>uWL^!7y^`@jiF3S}Paa~tx zH66CNTw#F4Y=q>bvnZ>2c+)S{LrNoBXv*b>Y6Ti~j|1Q+67bnW1R7zmSeTN;NH!%F zl$5S1HB*C)3Qkc_1<(W#w!BER=pMrrkEN?sJS{(lP%e|95EF@Tu^5l};Qw9a@n>xJ9{s??*eCd8~he->^$ zGiIa1yj7`s88#wb-x4CvjY4t+# zt$|;(DdYa^cPC~>-dO(cyQ3#BNbB~co7%O@x91(N9bUF9v%0o>bC>Tu^XT$p$Hw}8 z`@1l6M)h$@I002;@ZrR>hkOWJ<8? zq}K~05fRFlU_v=5RvM%#TBc=DBd26MxII9)!jvy&2qjHog-EWFC@C3XROo1&c90IQ z!5gAOaW5O>2@lYr=HkQd` zAP~_&>gJ(-1P_a-n9P*I9pgG*+8WMqW7%MOE-?dZWC)@V3RPkWC6gPKN`@dEhN74) z=yZ+xgUM(-o5FyB;4u`!8pNDM=CNS`2Nm|1Mgwdj;z=i>+3Y050MG)!0Kfqd0ALh= zaUOt0kT|q4FyMp91SthH3S1ZnsX&qhkOGhvLMIA+Bn(+#%mI@=@HBV@AaI~1c^0FP zwaQ$a%I`CV!}fSQkWR;8(Mx0ksI3O$grrYw2ubOrlFR4O6a=SwA#?SzcMhN*BDNAc5&>)7a6nan?!eE>zmS3^1X6oq=?CETyz?O+S zy8$R&souU-)6#SFZQ`@&^4i!uw_#P+$NlBC?;KU<7C&4PoER}Ty!h+;q1GY&Y}d;> zUO&}6w99c&-~8{RU5A#1Yb(ODppG8-eNVsPfPT6+r)BiQ=D|w$lZ_*=WPR6EZ~9zb zgXN4DZzN`~(zgzu+1l7!;D#jjlY18}(^A}T{da#{IM7x&`P1Xlnb8TY>%j|?Yx>TA zQ+mT&sK03Pm|sEIv&%0F7P!Rwm*$Kut|sKl!f%nn&yhQWmDe{-WnByR-+jIelbLzU z-2DrKEhlQ@nP29%Ep^u)njUFwyr2D|X`a%YUj1jv)^X%=d~<&;M9$a08fhAacSX0? zG|tH{ldb<;68rwxy|!-p5;>b6>>lE73+@cIYDSUMRPVM%EQgz~Z5r5`%7+Fn=fKOR+jY-Q2eQ%(kwB{{v+_ BeWw5b literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_1_2.png b/resources/g2/track/bm/large_zero_g_roll_right_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..f635df1b5c7637c29127479ba62ad536e151d5e4 GIT binary patch literal 1710 zcmX9-aa5A`8vcnUptsPlL+e}PDseH$Vf#{c$BOLJONPhK{F-!P3y)N+(6~3cmy=BC zNE=ROR9I*!^ZNj#f~tybWyv)qC51pBq^72(rKK%e zv?x72ok%2-NF*|uOk*$@Fw8{|0fvcWGKos1)ai6)v(@QzdA;MIP%IvYxj?`Ns3=n+ zp(+$~wT7!V@XZ#~?v%PcDu2Kbj@S?mQOwU&ifCFf-6&&ORq!<(;xUW;PG!iakA`fC zm{$k^DF>(pz=#p;N}|U=3EHV~KZHlQcwCCl8*$vr000F*N+c>N6fFc9Su7i$e+@-_ za(Pgzov~VRj|YOO3;~Uc()m)BP{|Q%VVRMyvLHH#$mGUseyJ-Yr}H4Lkio||A{kGj zM3j0|Z@PZ4VeN_dpO~t2mloWG&!Ja0Lw_^S!qHiOX3kI17bs1Ws4cT_%)P6 zmGL08kYf<@?J~rz!U8&3(5#9$bTN-P5pduUFNMlual|lBEOoZ(e#0_D7jy#O$BNAIw?T#78afO*tZMPscks_vtNN


K zziN7h>2F21vulG06rJ9~?xuO7={?BA%xde?o&9;U9llDGRdZ&=*_v7S5Z0f6ark;( z)8z3r1&hxP`p@;S2{#pHCaw_+V<&7aw^02$!KInFT{rJ(aEbA(vZQHum z_6owC(tke5d*kCBW4F7C^IA@=DO#C!s=amN9uZ>xvVrmIrM=rn%C=N7O|CT~6&u$R zZY|^u4UFacu!bD+QrVFwQxlO(0}Rq%J{|ejSpN0>`}ohdo?UoQF|y^DsCRh{SZygj zzvt@oT8va%HL{Yhg8|(>P?@_9{4m`4de^SrR>GkRV&>I>?5!Bf1f5vLKoqc*LzEEPM-dLaCv^!gk zJ?mMrq^R&4p&WWtvmG(C->55Q@)|-ZKXF?xw%@QXyhdqxKKHI?Z)*MF_vp}i=12q@ z8p9+99wbgC+UlX>Q(s*ip3D2UoRK&ASakHcl-kfnRpmkw+}wC@92MRqXxp5KWt}xfA0(agT0xb9BjNpxc6Dmbop;{Br(bK z^8Eko=NmKbb`LK7>pPp=ce#YgRd>5zWe+X;`@PZ)xy!%U@bbuoK~#{s8{jjKBtQ0+ fH@6=}nawHiq1S(jj-4+`h7OdMRhIT{s%`l{=1v3e literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_1_3.png b/resources/g2/track/bm/large_zero_g_roll_right_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..6a60203ec2deff9e97284d5c603956bffb5cbc06 GIT binary patch literal 1202 zcmX9-e{2(V6#s68-F`?K(}gCKP+gaFT#6!<( zd7t+_?C)ciG%srg04(X<+%sTurx{(17Bgr4Y8(Iy=zn!^quJKg)z#P6TP&7Eixw?j zyttvE0YQ+)#>S?mCcDe!!f}kIDV}Eq!7E8(I2?}0lj(FOpPw;|YORK2fFc3Mws^g^ zK)@LcVUZ{qPjIQUFPoDJdbCtlX%z90Eh1}|Jx)b%CnbC;Oy}aBLRvJYBNaoPujUyC z@Sz|`0fk3WB9e<*iz!>J;D8kj)_ib5fiUj^fCIpXAfnYOI~XVnG)!% z#Oq<97?;XgxSEU4>l!TQtv14qdT_!|(LtV%3PK_nOh==+WKz#$N;5OnY83*92;6Z5 zPg&`#gD;@|5*;af)k-j1Rc31G%0h7-wxCukVYf3*7ms2BNlGji@tMOy>1b>^l{WHv ztwaGIi%7gx_BoXRng~%^gwH1Y)0$k&B`U>yt#$`e0C)h908jwX0GI}#i~wkYqhUyb znhK2~=LRAUVid?Qz~BJn0Tk^pibIuynE)(AprL}t#uI?0frmo^f?W=xF@;H~LN*)L zb*)m-p{eEY13c71DRxeE`Z8|OAeE|Ds|B<3@xnr;1dCO-4G>O*!K_}&8Q}4dpH<|5 z8k4hHOwVf-BM)mOf@NU_Km$N%dJ!?@p1=_fCCX(Y5q|=yP@uhDJ`fN>ArZ&I1Qw@o zjmC2zF|_{Z z_s=xmgIuDwb*}T`j)TjWzPEGN`maw7jjSFEkKcZ3_itUHrn!4{wugU@AHRmQU;d+R zQ`_BJBjoJ-ijy}^`1_u_P44?*`JZp!3Uwm?fXK1hz~s%3Ey**p?IziK7~wzRV`~Katq&0GSTxNo%b#oX$=gt1r84pTXvmWj(ze# z>mM!5)otI}{H?l8ufO|ZPk!!@?f&qw@$%X)AH4SZmcfCPbGGoqp3Mh3_Y56a$8kT( z?{1h~@fBrlZ@afm@c%o0dT-*W^_S;ACobcYN3@-1jzj`u)3(XxcFV)hn59C;_J-oV z>zCrTZ!SE2xcg$8Mr>``PaR%1{04RP{!b^4MapkIx}yH|?0=Rc*zOPbv-=Tq@t}8O LU(cBhqlf+ntbGaQ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_1_4.png b/resources/g2/track/bm/large_zero_g_roll_right_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..ca3715a209737919707fa1958fb0b59263084486 GIT binary patch literal 1085 zcmX9-e`p(Z6n|~nUVqpH%vkCoizC*c*Lu@KuJe@Jb{$!{+AF(iz#zAI(|{3g>xrqv z5x3LD8OGrPJ0aWRh>$-H8l}QHP8Mzc=roKQ3mElQBE%WBN*GzKSmbNQ;Pc+&^UwS6 z;q%_<*_qJr;PycP7@j&Xd9X7d?bH+fu1-HnAAJ(Q1+&w0`#ZF&tE;=a+vRfg^z`)h z_V)GlVHnom-#;)g;0*)#iCg*R~@I-Zj%HsH1OO|B;tw1 z{P6^lO4E9lFBC<$kV`6C(!-Ua?5w1kPJW|R4*5XD zAI#EC6BSHaMz&VME$gG^=Q#mnb%BGzx zI~luKsBe_q40r_aM!}zepoUR7Z>SiIlo;6#r|U|-rIpbVk9#D_7Z2g-FkO&XOA%~U zs_9C@P+KK^!!}T(?DkMWJWNtihK&nCT9UHycrl$W<#M)Z)~nT4tA)TPLr}-af}6E` zLIsc3*;FHvZ^o^bR&5uXo3#xzguC68*BkN&1e}m)TH*MV*jbh+rZX#rqEoipbp}KZ zQv`QX^lLFZn_!HTU}d8#MzU7QHf!Z}dkrxFVE_d{126zq02&ye4tN$N6lCO)Q{#gm zlaOJ+41vP~5&+3wlqON0M`jFFQpm}}-QX$USP1i2O!6kGIrT$ zI%U+ZQyhm(Kn@_($s*N}y9b||$Tk{OR=)?OQeh(zAr_Mo37I5RiqIL-V963kRC&A^ z4j|Ewl0lRuk;x#N>l{BdK6Lx;54?GBMu0uP{_tvttW8bsojY*)%#FS0)Lr+vW>?W` z$H%Yl82xh&(I!7aapW6$+2OwK?3 z{Lh!Kc)qmSS6|tD=Z)WQ&E;a(e_QA9;2<``sfiFORFs z%S+CD|MrWkJ!50fSl;dzww*h6d+Xo!r9-=0nevXQZ?;|Dwff27!+MW(B>l@nKb_q= rcJtfB!#@rqV&Vg@`KjCa>+JhzJ$ms3liDM6Y{S(4naRa{hfe+vO6b`q literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_1_5.png b/resources/g2/track/bm/large_zero_g_roll_right_1_5.png new file mode 100644 index 0000000000000000000000000000000000000000..2900f8586fac36aadb95261a756c955ee3479996 GIT binary patch literal 1251 zcmX9-acmQH6#i|4-Pne8bfjPtOQ@!77k9xkyTob^xh-Wm+>PC!)q*!Uq(}+JylELV z7AZ-Ym7G{f6KYbks?9i{WJ8*G!HaaVVTHpKEU}rD%~%knNF9w3_*r7|z4yKM&-?!P zzBk;{ZChCXL_GjtVb_|D-U_!@%2HQT>0%T8BLFp^XKi0+Wv!~Js;;iCsi~PaZ{Ga* z^J{Bs5d^8Lt6Q*Ofx&Dx<2Xi9B+Jq~?-WJB@Arqp(L^GdN@a4nVyT2AnE+A@9myPR7X(KFPu*AXp5`-x;01N;ef(SaD&uEk^mYCH#&M=cMSJvmd z8I3|!HR5_RX}}nhm9y9c)b7K1$tp%Dzf6Y|HkRg+IhTnrVm7mtMQNUJ3X~9F0#PoS z6q1@Rl?!Qwc)qOaNT6qd!39iSV380aYOp0NPL&iidoVA?ic$)WGpL>?j2;^rv|Hmm zrHHKN=d)pPR`wUwa9NY#Y)YpmET|nPTqNaT*&xqHJf1`_s79k&GMUe0ip3%XMgdsD z2p-o_ijhsDt~?c(b;b%Fr6^@eiNgJC88)Cg9bquoOlB6vc&k;UnE+Qg=1l}clkr3@ zrIqp|;Ali-bw17{xzUK1lmo01aZSp;tQsj~Q>D^PNCIH5WB>pO02zQu0A>*YD_|(- z6`>r1xh!J=0uDkXNZLS-0gweyFu))VV+>5XVLAYFG4RNE0?-t&Gl-iv_&jJxvc+S( zqWCpUE)+Ca(K5OK?rk6?0~0fGNsExPN=2t!@+jqS`hGGGvqg&@5GKTi>71m=&Ej4c zE&1HBkWZ0AT1qbDQm~XKXc{H~%mD~1UIZ#~|HJ6_MrLP;Ncew<=``hZvTir;^$IxV zC$KPy%M`BCScX9hb~EHm&}V@W941Mq(UtHM&oun~=m!RSyIHX6_p4hg^P#Sem-^NW zAHM7y^Dk?x?JujRG9N7e`r{+}Be-SRhIR5C@}KYC3kCbvzo^b{e=U2x|^1t znYbFSBhC$Rj;ZI{A1FSINkncn{7NoGaoxtBv&KYl0EcXqR{edM?p#@g@`$~&LE-m^*Ey8GCU*2tcr$<>>j(WM(ET(0rqa&Jq!XQ$)F?s%{7 z-IXn0m6e_YUBt>2$P{s8$=t>pgCot##t(O`07J#*b>6FYM`!TI_C9VH2ppYbueDa) z9^Kz~{pgu9i$+d3-^TTU4O{jtI{4e%rXAQD57sVwc4oBC8~o;C6Suuy_~V3nT%1B1 zAB;wAGuJ<@0!{ZqSz4>PQa7+zqrYelA36M|@@4ZtUwPO2O7p=v-L@aDtatnx*j{l8 Nbai%joLJqz?>{XsFTnr+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_2_1.png b/resources/g2/track/bm/large_zero_g_roll_right_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2ab00a9f28d3c571e15d8e9287ead10999eb6d56 GIT binary patch literal 929 zcmX9-L5SmI82vh(nRK=c6^mq@9I`uI%pph)LE{o6?q+toW0uLdS;(P>EC%eMhk#KE z<`A@pAVsoJA%`A%2vQ_q4X!|l;QOL!#f2nl}cM%Tjg?jdwY9lXJ>bJ z7sIehrLwoThc_AxmSsdyP!vhmTc&CBdOgn@O(tQI%(85?Ub74cJjhbD)v9+oWY=Px zKJN|X@kEPabDH)SOJAfhm9H8SZmXoLQzMf->xr?aPA5io?&O)jStU&ZG#a`BxC%Bl zu()5FkL&9xfpP||HFW7Blr#Wj01d;8TFoX1m!f>0Ka=J2c6)By7o!o1V}h+W1e}pc zUZa`@t=g>a^5#(N1=1i={HYdZZIUCHW`kE~N#|OIXgIPn(ng^XrgoAI(tNzw#5Dox z3gB%ZEudVC8{y3f)rtipRr?FmU%3f7lj*w75#1);SNX9nMy8VX^top)gWf9kHfeyC zNv+ONw90aALF_6@U)P7-?xf$3N24?h7qi)FwL(A`KzSHDu89$$OzHMQbe1hY??x+k zww~md^9`!fwHk-xO|qfTjL!3>Bs*FmW=;Bo^YJ80()B_BO~Op2W^1I|p@)_bI7&2Z zp9l6l9_I68y}m#KfC^v&xBvmbIlvMFR6rJyWum}G*<7Z;U|}FY*n~_5qyRE-)Mt?| zqp*Xf4$6FZ9y|w<2&#;AblmRJ1GhQ$^(gA4X^`hBD!hm`uvS%YaoH!ekTNpfUA2OB zH`;j9%W#3_E2<70i8Yy8OCUQ6YqcfU?)U>c3I=Hs=41>X7lw+{*;A0OR%_|_MH41U;$YnAfv_8X_p*X8eSNr%^;Tz>fY-JkFODZTpU zS1*5ZulnAjXHOpAeZLbO{`hw3l^Y+IUi$Ca?TejHUpxNm+k>aSdZ$+I-n{zL!QC%! SUjL<#hT}UYN8j9j^x6MXb%&1t literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_2_2.png b/resources/g2/track/bm/large_zero_g_roll_right_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..7bee0039e6e161dfee46e9e8b889776e0bbd654b GIT binary patch literal 1100 zcmX9-Z)h8J822|tUBgC0ODnYX~NH@3m)<7S}DS(QFbvKvRHY9l@Y0 z9QH(_J~d7yQ(QJL6b!j+#;dgqgChaTA+c^H;L$`ZEfcFT#z+RrdC4lNbt|*mDEd(# z;2=T+jYqN)V#J-5tgBf@VciFt0^HLeEP4Up01yyFayk_h)i5kWQL7wR3WX|)vYk#t z!$1j_mv;L&4<%rJ2@fcQs8Mo?iRIWtfzOl$-3oa~)aUn7JkE+_P+}yNQ`16PmvmDp zS_!kBt?n958n}4i4gpUTU>ZWE-TpilG-$~T#H(_qp%vjOhr2`)jrj3+fXa$YLFUbv zSV_vYT&!Uvcg-BE6`d{;!vh2vqL~QK$3-y}iR9yPBb_#Ny}G{MXfz-|C4eOnBI{%d zC||}yRYt7^GxbQJp{+Ob^}Wh2bl^@W>2~`)ULN;}6eY8qD%i`S`FNs~&09sYS*3x% zA~Nq(1dkTRQ&Bpn@`Y5Wlv653s$MBJo7<2EAOL_2fCfMg06Pga1V9@c1EVs`WuR5z zFdz{iK?B_nEDk^(K*+c<}tzoijH1XJlyb#IbYdehK!*4)5<6 zzi&MA=>4ffSA=ipT7T>Rb8|8D{Y!Tb%*zv_hh9H=W%X$9&&%I5-+uDU^_Dqlct^dx z7U=&{{I0M6-iOQkUpuuW{`l$Q>hUj5k4}C5w8*Z^^v#U?QR#hbXKDB1@{)UF{@`Zm z{N$=rn$$<)@C>#gPHUH-lBn$t};O5c&I! z&$d7L_1TvfPThKI*7(|ScMQ9B@}0?R|E4cqnEL(Wo0F0fa&kZ1{^+X>`wC!Wcx-6p Ih12u@1KGdddH?_b literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_2_3.png b/resources/g2/track/bm/large_zero_g_roll_right_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae6c454faed44afa9003b021c41e876aa3cf052 GIT binary patch literal 1388 zcmXAoe^8Ql9LK+khDwcVv{*8Sj_WWVliD+7jq+)tL!)}kr$VDi^;DRYPxX{sV;xtl zn9@egAGpY4$~h`J>DKPZqwTpJZMJC9qMMaa!ZQs##_xgN3_xb1Z{^R}r zwAC(EOv%a30RT*?sjjR`&9YRzm&Ho;3k|C}0bqgJ#mlQwYg$@bdU`sG#mdOY$jr=~ zG-(o>&Cbfo%FfQ_i$o$6mB{57K`2R5P1BUgWU|>D9*@`W9|?!!i3BPEm<-@bj#|yr z>4bWN#B7n-?6}LL@iBBDXo*Cfa)hmtaVRCmzG;B7-0~&8wE0hW(3XzOJl%!Nm$tg2# zc4!=4${RHL!yUnxE0Scm7~m0ruLVK_5L?+&2Vdb4s~L<6sw@%O8Mpf3DIDREQh{E9 zSX43>DfiJt&_sr8bkuE%Gqz;V4WoW8Pbx-Ks8ox|^#oxdNxNR}u~-;~Bk1);Mn>ZC zI0OO;h;3}t#g+R6L;%r7?L?9AUCZmVvONuSRY47y{nAWUfqv;Z}5Fe@K-3N>Ca6_#1!YIj2KOWFbx-UtlE#XKMt zvK11p8WZXW)Sy*bjXGzC(dX_6`rWaxA0{GFr4o7p3Go5E{kMjzTX6gUVF+rL#GYUi`q0x}^kI zcxQAY0O`3kmG3XFZtLw*p2Fujfdn$$bz2#d>zl=(Yx|W}(TW9#|oL&8}NU>Q_Jg$-tuO}+reT%)0`TgwKJO4Hng>uvPEPVRRNM@C9 z9U_kH?>cO%n5cR>zdf)2{F9xNS438fufHhVQuOuO0(D>4pobN@cEY{3VBf(9Pad%@ zOkdPozd>?$rK7C-i(R90K5yM?*nRPg!`QS~JaeZL8l(-v+rRNwn*XBDs6-y|aL7q2W@T-bVOLFY(c zW4-E~0Z_21b>^3s7VVqUSJpbWX@1Y;x@!7-Sx;~E_0hu8f%<;$;HrwIeb3k2DMrSL z=0)?$=T%)?C!7B52WfW)?ggg(T6m*si6y7fk~s1z|F+{3>7Mb8WcO)sX-J)GJH{o9 z=eT=xovff~Ka)9F+c?hOye%|~ePEON!~EGjck>&*c{ue){ZwQ2>i(x67ghxe%}i!V z-DC2=F~#oES8mk)#lJ$f5B>M%GLxaY^ugSL>zwwXuD|o*0%pU2Joi@pE2+qUnyRIh JgB5G`{twa&WmEtF literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_2_4.png b/resources/g2/track/bm/large_zero_g_roll_right_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..5f264c23e61c4bdec3306aa05aab3c082d581256 GIT binary patch literal 1178 zcmX9-e{2(F82+GaHyBIR5=yAykcv$>vBCvUZO9=vIO;7s+>sS&e_*`n0YkRrvxMY%fBo}5$@9GL zdmFpyjyVhG0027t8#;TM6>A3CW@~2u&eMJXY+z&8rghD6#*7&=XU??QY_n#~YH4X{ zZEZymq^+%O_UzeCx7&^5UWy_)juC{QB#E(DES1XS^94;CHw@FVa4#TzfMwc)K}R@@ zMxx$$!k0?3xjbJiNfkX&t7j<;3HaJY#wiC-Met-Kd?ZGdQh`cdG|KUYk)1R(+68zF zL`a};NKQmb341l?uqrOt@Is4+QwoHd8vqsn9zjIAU3R$?k00 zba53dRHNecV73t{n##D9Z%kDuVLN8G6HX_Mx;e}%_#`)&5Xg-lF=kkW8TQw5! z3?gxMnMai{mX4BYoGYe7WmT@0(v7NSS=S*6KmY&<00jUQfHDAe1i&U(3PvTUW}#7K zJwU`kk^}`B7%YGsfT9y7aF}IbAq*>VXk@`%;|ah}AiyGF!6`?uq(bMiLa`Xrb+ysZ zVUx=h0(i8YRGe%Uiwe~(Z5_t8>%Eu2G55Hg^K*pYE8#^=i_f_?)M;D*Fvg_S1cTOz2^Vk=k zEnC&nN1oa>fAIaEss(f3JKOFI^puN7jnf-#{ri-mZ_nMDSbB4C>r2#V@5`4DrpV7P zJexeTzvI~I?SnU3TURvZO?Bs199eR8>}=o34~M5a9DOTe^zyTRUFjV-_V0XK;J4}9 zM>an-w42+YelzdKQHfac$o3si?;TFR{>R}mHcCu%^uN*D)&9x;zR~M{pD-)@@vr^Q zQ}Ll!NObhp5(NV<+xkv?gzTu0>q9NpWw7zvc o96sd7_ncQw@;7}yyvDob2Zv*;FVg(Aroh0zuDkQAwJ+}bA1wtA_W%F@ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_2_5.png b/resources/g2/track/bm/large_zero_g_roll_right_2_5.png new file mode 100644 index 0000000000000000000000000000000000000000..9ee4ba0c92deff781e12eada001440e467ecdf23 GIT binary patch literal 910 zcmX9-F^J@382xrvyp6jS6NV2UY%Mi?+f z#2|x2NHIc?5mTg?BIpQPq)3s26jKabkSXRM$RGm-JtauM5x4lwaqzzH<2COU?|olA zxbEM*^ZFeCxO;W~@?mpdYv$~<)$Bih@h<^d@ZiHo_ZoU|aBz5d*lM+oj*gCxk55ic zFbq3AJv}=+!+X6R%QB)UD2k+ML(?=I$MOAOv52#5T@+PavkVA4$WnVa?2bm{*kUFw z@6Y7UK8sZoMK<$)H+Aw;n=S4?qS`G0f<6Y=ZD8D&+YaSzhY;#q z`UX9)SLqjws@+44$*obpGE2eol-|o|n09^%e z9Y_l(590#7zo3SxVB`aLYlfAVp&Oa*Y8)}{)9!$uYhq$5xub1-a~C;P>hJRi?Xpgn zqv!$4>4G>`6j#$`c)MO#RfT{sfbubR-VqZ*S<(7doa}~SIZi5XT`$Vp z%^tPsPKU$sKG{=fM&o%?k|$~-W-Z+5a=s|Cyxt0+N|>p1Y?bsz^vn{XiIU9pWn^#C zS-HvT`Z*E+1^_022M_@)0d^Rm2C|4O6Gb5^HZlbU3sV8&J`^$_1(1OwmqnqB;t^U+ zP!Yn5;5m>)7|7U2!|gFW_4@NrOA;r~qq59V<3;GeT5Z9@<&ack$|!iR8baz>)lfy;_uI^o5{`kS;Fa8ItQ-W{+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_2_6.png b/resources/g2/track/bm/large_zero_g_roll_right_2_6.png new file mode 100644 index 0000000000000000000000000000000000000000..908cad8ed5a9e9462cec3ddb5de990cdebb80d72 GIT binary patch literal 5167 zcmeHLe^3*57XR`?gK#ZaoJPc!7;Ixrlg&>;0x{Y^1C0=lU?b8tZZ?~k3(3YLk|^hK zlCxmbF;&`w5iPc`QBk9z4L&DvEKb+ z&fN38(G+V+N6z8;>O-gWYw;n&w#ACh-Px*FkG4LIY(Bmqd5!n+o$b}*H%7_%?sb2B z#k=EE`Dx7x@%67lY0`gmtUITeZ<;^%$VWc9#U1IJ`sb?t?yS^hTn%(*Uz~mJ>)Nd2drBS!AZe>fF0U$= z%WozFQ`o(EhqNrXeBqE*y{~%d{on5W@}<`r-uAwb#@_crXo-H5AQ?tm|NXgRR=R;{me$!8OO+woiSo$%kDr@LDbY)+jZl<^=EK zZHGHTy)V44xx#Ix(L35Y-emB-wTHL&HoC8DqJCBTUG&C6&r^f?-zyex=YH1LDrz+r zu=Y$WTi^Q1BU`WRc7L!p;{lodS?fe@bZ0O*{HvVNOU3J3S3mwk->1Pp*Z=9*$zy2g zCrh-)57mD0?ojRiQ?=1ouW#Mb{LaoVBqz9w`~I-FI%|=Cd-_{_S^HMy50&h?JkGxH z>)|eX`^p39^TiKVdD1`p-a`(?tS7$wm%iw+EXt4C`fJ$2i{B>if8NrR7iqYVdU08b zX3dD!oP4nB4bhP`SJLL6naw`Xzw2GfGv9%r>WIE<`?-CO&GR0;ma|#?aN6g|Hx4xr zdp7T025SHPo2#=63sdQjeDs`a#! zWX8mLx@=i`v0DNGEVvV;xh?fphr}(VCvYY3J}yS+w1kS&ETylmsG`XUJ5Cd@1#Awh z)NN|u(U+yuitT!Xq`KtEX$bfvrLS{3Z4v}=xm;`)pH0|}2v;l?BOD&Wu?g;9b#FuTd-G!a%>923`9y=AKZ7S``(N z5(3*053jsLN{{=O=n2fEmn3dE+yacJ!%!Aaq$^|z3Jn|<6tILs3}*>M91%-r5aTSpn2%z7j#!8B1T!F1b`$JM zw0>q(aVR~6(hK#4d;@M^VLA?sMr6QPI-w9}aZn)-y5MnePC)`nk4c^+>=qQ3(_}%7 zIAXIJ6AN*|B`d1RrF0&fb6ZkXk2(#|0M3BPswZ5I+e_e*`GpDdcwrwayyPX340Ae)Jy5{plET+ zTgw%2p!BE{EkT_)1m*Aq5-vx=6V~uJ5&=iT6)-tm31@~rp*I;e{x9wL_|S@{ie6@N zK>r&PqN$luRvjnKXz$z5!1uU)z7xFMYzd*p%-HGlX3{Dqn$5$93kB}?apb4&M zOQuWp*q!>Wb$GlEkTMpR!@5nGkd90zi^O+~o7om4|HVgfLSe=h1MQ|{aO;9QA#!Ug zoaQUO>HLD9={o#^9w78RCwIl~J-Y7Ebyp1BmGZsrx<}VtF>qJP_qyx9<49A}g|04g zU?7*DoiC#zs=OjCLqRY#O?=E(Y^%o8Fd3PBCPR_Is7qSkUXejW@DmU zmxAfl6m?_reup~j!A9C0<2|0(K>K94ha3-PW{Vh14PRuG$z5u-7sEPTu3oQqpsOn! z2#lRP8H>e8kV^nYJB8n!Deuo!hnU7OdCPd6KkDj_`A$ysMz4)bk{Qg*Oc9l;$jetV z5v-`lp;WbKAy{Ltw{5t)Hxdj_jLCpjNpYw%o3wd8GqbZ%*3+Wy?=%kgG>r^&Mn{4Z z6BkGs02%-s0Qdmt0bm$_aS9;ep^}r04zkBjMn+T&K=47E3eOa4*4Rk!5swIIm+^b#`~f9$QpJpF z@=0wT*~B0_`D8#whLy1SMXZeP<1^r_u2h5NU!R8mZGj}6Qc(h0XFXH~ALiJ~Y9Uz} z+3_<8?Akpa3MtO=ic-q?^qlM^nayYSd;>+t%S%?&ED3M@_@57YXlb+8j*+7Uea7}^TAVZUwq@Cz(;TG5=+y}{^y=huh04F%|d^%g}wUH zspng7?A$HkzW!v*ftRH}U3xS4^3sB?rB?^8KL@zk+V(Q&=>%ctAU zmPwA037RHNCWF<=IGs+f*B=V;(dd{cX0lmK4G0aO$Z~^0 zYOyG6cD2i`@%pG>$QX`TVOkewjVw z_QZlAF)Cz}1Td0_m6kY+3f7|X*$K`?hkfQ4=SW0+=|nV}oq+@ZdH}2dumErX!~jSk z0Omz$q1_6(02C7x3K$G{2*B%rNC8L#$jG1@g8>Ti78rLyF#w)|#{sDYdJ3_aWDc9k z!|H+oQ#kAt1TLKxVBSk^2AI8^U}aQ5VdPOp)UX)?m$ij+-uN7!goz9)1-JsysU-$N zVWBa*nPeT7fX5N$JVKO9i&2{o`oxK_e^r9-Iq$?KJPPG<8iIQKwB&( zyPd(*PF(FJFiwj_Nc9+{O6!%-sDKU>`Y^~7P$2Wik5`vJeEI_&J6dS4X>zE7|K54w96-hMCl?X}vQS8g46wY}ne$EI^gpXF|3@8!d1Pd28V-9uAzP0J6C^sx5^ za#LmJY;EHe%NJFTZXe%zWaRcqbLY5Xs&jacTG=su^PSWeef-Q4|AuYvn#)eF>Q=3v zAU97anZ%U+{BUeTT_iD8+p+qMAAMbao5#rZ!M(<%6W<)_oU9iI*G{i&EDO4x><%~f z9IX4}6#3cY_nqzg7Ywt-xyrr!53JeVf2`(yU4P#Yw{`ljJz)0v$D6AwvvnIkd2kC4 zH&*o?YD+vx9a(PV`mUbcy0-1Ns>)rQWa#vl7c)zKkKFotMJ_2Bm_^@~zHphlJ>gzo z>1Q6EXg9}@^S_|cO6P*vm33#Nqsm!UIPin7@}H8bU0-GT8*i+5<*1_T_~#>=$kAm< zP~F%%a(MW9Yb>~7ZSC~+DR*${!&4_pcPrNf2iHX#&V1BTj_T@GUwBctl)M6N9Ibio UwPmHXdAy*xp{0J{&G!%e4;9Exf&c&j literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_3_2.png b/resources/g2/track/bm/large_zero_g_roll_right_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..1e5038341ae54ead7220779b8790d926c6c21e09 GIT binary patch literal 1291 zcmXAoe{2$G7{}j&Emf*);z|`$G&sowW#%?dC3?E6JL?&*_MA*f#Cj^3xZUiz;DQTA zy0FUJb;FD}RHkTf-W1#FE{G1ZtEnqdwsne%4OvLU)f%#4L$qe^FecyU*FVqqkI(aT zwyYs0PM9_U05Gw6Wm9XV&Z&f{R$j@on(pleKn_|~uUklR;}L#%B9{g>0l;ln5=b z8-WW0JgtbbilkqaiKo(JS}kudL@btGit2YbG9J&P za2O_&T12hKG-gU?u^R~1X!RfrZ{b3?S0DokI+C)BS%(hQnhCvyHj)f#V{z6;`NHQv?%5V2aClb1X>mt zf(j(6!V_9LWpw0lU)~lexDrKvuoNqdWy(-#RH;ynhS2G0qnWW-IFj<&E6dz5f1p1a z%S!1|4g+>l!O<#@UB^3(AvY%Y=tRiTFL*M^P$46gN{=80fE54^03HAVfPMh-3IHpj zaOmcs5P{hYWdJM!0vHepkfi{m0c17MkH828MJG)8U^W6?fJXs|11qI)G8&J|7~qL$ zgh?d4>9kNNq+!KN>i~#biSZgLqO*$zHf!OFHlgH7l!K`;F$Xh6gBqYZ1z}d%FrAY| z+zyiWI3od1LI|WKp^%keDTk6I6amZv2rDdn6}y+xdflOX9t{Owic6(%n~iol8Mm87 z%wE(S#1H{TlB9W%G8U|QXxBlH0frDLVlYisjvt+?{O83F>~38{gJloyY_Ih3=BDNA z79Ko!Xl=VRqpm3qZ*BA*ZM-(4>mgy4E$)7F@1edifQD|Z>WkwaespP5?1Q&<#zgCiM$=+xX!)d$zInH& z-*|hdLI2ws?)bxb@JZLla^}yQUGE<^p6j0C?(BIT62qG&Ef7A}PX3W9_P9<}1yFoXLJGNWa%pxUTM#XMk#!VY( z;t>id*pQ2KP)U^vCl;wv-t;n>r6g5KC~_e~N_Go{6|B6thFo-kL4KBye4n>}p6?%@ z=h?Hq%~n5i{!9QseQQf|N4YL8$D-OCHl*Jlj`iExCDC0xlApH+hSf<&Q+gQ(@~2EkzxSxc11&iJWR*pW?eY9>%rrO8s- zW&|!2cu62KNQ^^LL0vAU*Rn=fv_j1Vr$h+TW&mgaTnNJHbb`?+S}YPloT2HA+np1H z2hk`@rHq)~Od71TiEvqL9O@7-RwVcc<&WD#Nk+=LWYulLjaHkPU{E`YJ2{FA(1EBc zDs!?Tq}7m8jO8a&Iuhs^U~mJI4_HJ5j~Z+Vi!()XiX)ikrIMJ2XJ}N<;zq9x4LXPz zOC@Kfjd;C@U@#SpDzcm(87Y-Y5EwaN z2_slcM$y~&a|q9uw`xk*@y>U6llU^AH+)XEYBZ>IyU@-kl{7|O&F zYFg3qByiagp3w;|ljuPsJ~AF)k`Z?%F62^?VlJ&|4}7NV%vVc_23j(?WDBPfV#yiTyvfOMc1q5}T*;ybxCyaYbxzXcVKATD zE(#tgBqZY@B^@uSX{hCKyB*2^ssO?=i$K}#g^Ye*q)@;k;TPhwS<2~TJRa8P<1niq zw}we9PGKp#b%aKX4l{I_pkRR!49X-_?B(OfU$1@i{09a)+8D6Ft+StqV)K}!ul<_;kEsJhwFO2)t=7THaO?ffN$@zcOa J6HS|T{154aE^q(< literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_3_4.png b/resources/g2/track/bm/large_zero_g_roll_right_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..cb4089fca5d6ec7927d33a769a8ac63d05a35834 GIT binary patch literal 5329 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_4_2.png b/resources/g2/track/bm/large_zero_g_roll_right_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..83e7d366dbed98a1dd47b8d30417b51b87ff8b6c GIT binary patch literal 1122 zcmX9-Z)_8F7=E`gZd-wZ4K`4v#>!4}nv)&N$@<~cD|YkdZsTSeR+7_Pw3rf3xsfJT zb7W^yvB1UjLk*2-pdlq3P$Ni`? z^StlT>8bGgp{+vzuzq4Zw5MCiZcGpKb@NZhZ+-#L2h)?YySrmgPfu@eZ(m>Enl)?s z`}^0fU5jDZz`(%Z;Gj1U2v8KsvWy^bk`z@GS<|#^HeV{0tJNjjcG_)<1SSYP=ZZ!> z@wh*cBva{NHpdrBV#QQyR=UwFumlzfx@69)M*O;j=N0Ob#+unktt8uvsg_;nIMuKZ zL;?~F=mJ)hF*EJ17d`Eo54A|t7STf;p=tnt2M{q#cDq%dPsi~>FnEdQ7h|!ys;=hq z$TWSFC%||~-X9e4uuMc$O45T$j@1kL6rakA`LbNL z)T*7aTE#}kbTi-)z#9X95^x=(^WJa?kD82ZMbZtW;OJF!i6=Y~?MsA-bR<}m*oq=p znpDp!O+$0cY{xQCv+DNHI1!=f7{ew6AuUO{M52^VoB6y|E;p8z9LGW6lL60SRME{= zd_s+gHP}=$T4*IIj=t0`wI0?x$VIr_wAUN<2LytYfVq~nU z(Xy+k-Jm%Rl>ym+P}hr8m+moqS~Ayc(z)zoD76|JjSBI&luXJLsnKMXp$wKXIdX|7 zT9E(}{Yb@8jzVPySzPz{>6cs&9{s@lo+$xdy|es&x8FDsdTn<6=%0}r8?KU+U`>fQCXSC&6K@)z~P z=z+$rxsfYx-keF9XMf*&e188gccdSu|DlFIo}5(2gCt8v1U7=kS$np2LTFxNG0{Ph87DgLQ>heMEoC$sEf$;0<@Wgo7$y>pqC$X+03l0PDA*be zPp21}%p!}GaJZBnuht(hhlcGE0U{TrQ!9#e3Od+PKNp6DFsg(TG=#o900;n-2tu(~1}>N8^X(#07eVx@)j@+{ z)MkTTFBfI!;T$2s6Dj#pN+36&Dq5tqN{mifn}@Xfm2O7O!?;3eo`@94RG5O2P$t4; zQ`+2=J7DlJZGo^OH11{LfK3998u0XhPa~L(BX#i=UYrWZ%^|HlLi=DBAz-U8u1+d2 z%S8^A#G@qxMpe+F9d;TcUdwpE35R_wHpUmoQA~|XbR=n3sjNDk%WU@AYyr1BG%yf} zL?GZ&fNw!i2TS7Nl74|YBry#u>|vcJLJve;;fdflOc$_N7>6U}<&grRN+i?)7P7zjAS;Q)+jan%6Tr{gq-u=A8|KE;UWh{74wdB!dN33mtvBYZZ% zc!*TUQs6udiR#rd+Muzw89dImfX^9bd@vfqWHRUmkO2_JyfDS&-hpe>TZe}+tK}WE ze!oPaAT=75UQeMyBPO)qs8fP^Wx@eM5SHgbB@Y_-(27Dg4g<1S_^}Vt|9SfZ&9zk| zSn~MpS^(me6-!I&R_-|_XF4AhPwI#8URg!MtEqQ}?k&@ZIKQpS7cbrp8oq4*x_2X~ zdb96koe$sSbJd`dA>28I2TNFEAj1HyF!FkTAnt5?sFI{9DWu>x9 zoo4X!DrZqjb>g{j)x!l#x;w?7r|9v<#q{Xv)?6&>hM3q<=Wkw+c0+u65ivF=Sl)R4 zaISKa+41^n$BOUa>%NZszCA1Y^=NtOoyvbpGwV-fB&P<>dpRSswqlF6;Z;?^g>7bz62x2|7JX_;Af|8U%f zwhtQzmSi28{_W>~a9f+BXZ9V;-jm*5-EAtHIlIH3)tW_5p0VrK_}Y1mpJMl$X0%s~ z9JKUa7&+fqQ=6Z5&tXki3$thDgtFZ0*vkqwNnTAnnp-^4V(+^;#4-18Kham1Kk^Nd z!*ttEIx_ot9a~#?ys`rg)7kdt3#n5_gtPbbE&S-h`n2OW3(JV{D-Sx&-+guR+T7C& z&bUrHroPW?1Am?vEy>!P5ZK)GwkKXgs=br literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_4_4.png b/resources/g2/track/bm/large_zero_g_roll_right_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..a80a818ce7d33b7becb4fb45931ec8b79160f7ac GIT binary patch literal 1378 zcmXAoe{2$W7{D8VIDx0|B#L1THWDXlt zwxSYc?wquuVU}%JaiNyP+JIupCey~SNVKjPsX|9Bo1J5du4>)B!|ZeCtq zettfJAO!^lg@uIzu~>|vGP#_fX;Pz6>Gh1+Y_{8-Uav0{8jQu#nG7le1P&;&Sf%3Y zbRvUMX0hUS2j%vv13`T_VvQ$Vaw($3iy2a2Qi@oO#HmMn&GMjK8TK-<0ZS_8nn;Hf zLZFrc0|8hXaWhEJ%8R=BnXnM1WH6(KlPrWGF#r?*Y6M|;Jd;q!N+d2E@1>{#tu|^h zjXRw%7!;y>F(HsqB3vy|FjA!n)v&nUAvb$STYz?j)xMZkgb8H|F-}WK4W?q`jD@l| z)lMJdi9OplPc{<1iS!R%_7djQD)K7wWa0!+lZc+?nbaayCv_MJkA)66v;!VfH0Vf0Lz&DtBmhtXpa*~jzyrVl z07(SEER-A?_0Z#ju_z@03<_)n@F_ry0+0rf5kM;nT@>``VAujts3lpG&Sf(NJhn*4lZu64CXSIL^Z^(H5N5rwWaXYCG#eesB<8R`M;{K$ zRVrGi(-@5mDl=m;JAr!SXpoc*Qqq)C4AmlNl0XLveFTh<+3;hP#rK~5z^BcPG! zd5`MSkKX@cTU%>?<ztW%B z_~yyI2ZSek+BXS{{8!edh2GP5^0=O8&Smqkzvj|D0cZB3ob{Y|sKK*t_2sFRBdv;R zS>pEGr_~P{uC1vIA8~(Y`srzR^_@}XvV2FIq7qD-v*A%|=c4yU^-nxyYif=kaSpAu zCCHC|=l|G_{k+-Z_fIW++}%Zfez@V$lJ5SmmwtoKXgbfUTR83E{H14?wXJRSm%np! zy8XuV(jB+V!;Ag5wu6etClrE2N&m&oTk96i{I+P@m&KuRLwjl_w&CB^ub(?rE`!{f zWAn@Yx!GD;Gsi!k!T0DsI&a~^F@8eYHv-FtPu(~Rzo$rknN2rqxck5S@{o!Z9BR4$ z;UA0HEj+`@mNESA7TA&IR~^6I${~)<=-b^at$e9}vL>XzvSw48ikT~WU=sC|&O*=K z-5ze)f2lP&?TpQ`tzxknj@ddBL+|gR(<^_eB3?Vz<=WqJyZNug^e1=QCyF7J73ecS&rYHWxA literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/large_zero_g_roll_right_4_5.png b/resources/g2/track/bm/large_zero_g_roll_right_4_5.png new file mode 100644 index 0000000000000000000000000000000000000000..79546f9954fb4051d538602a3398bbf86909b7d1 GIT binary patch literal 1230 zcmX9-e{2(V6o1>;Zd(}@n%QVEH7QWBuu3kbBt;K6mNH5>+>JEQVUZIXZ00e~q+o|t zsx(mL{%D|NMM`X9qX$+X(t#uLZ45^?v@~*$#jvSi8EfyFNBFG&D9gHZ?U(n>MYv zxw)mK1;en`*4DPRHoeJY!f`7}5;W~(7&phUp-?CmOQh3cHd|1Xs;c5vAnZUnHEy@g z=QH{P)^Nlgi&LqzCnIrrIZ`SoNekw(Ygnf~=rZz*Il5ZOkJ-UmTtS@S?OdD;3C?JSPUbzL;x*a~R)@(>Tbzu|&5~@G3MV`X zkrm}&R*A}$RH-Iu3DD7?_kuA1W*)O8^p3RIEfK8jij=rymCvG+ltstb41R|t;B>~GhBOwf)~44xj3(M*W$bp&NrgT2Wr1`gnoFgX ztgMy@@HjD!)&@OB-e-vi2q8>o;@+GPEK2c8F{`R~5CPx<-~f040U!rZ#sJkpkto0+ zA&HbCWd;_9C;_4a6bcXxh}EMAj*=7-eJCGBN)nz2Zv!U@E(-H8`k>zuB9?{GycE0KsRDY%x%TI|VRIHkHU^8M4tJX~zeKa2MI{Bb4 z84YHHsGJolN*1Xlo70IzKnfsK&mvs6djUfz5HFW)@z@J+`8?@%(>@;)2(Y*{WV6Ny zTp)4DX)REeipzvNMiexoIF3XD$UyYW#j?J|-|ZiL z??CAF>CI~&NpEWw|GoEXQ1Kq<>}z?lmH%U8$L=qCr`j8?Othbvx1*IkonEqf(lsXC zc-G;)J6QSr=*HZ=tL!_*seQ>;0{2Ja8{S8w?+!BGZnWNXW$uS-Fz|Bs7x(gM;lGud z@0IaO%--RP;4VY1?99sxM~AQUpRsQUb*hg)zA>C^;V9UtElllt_3zVzeK z8T%H@@1C5H_Z#*un55S4D$SXCEjRX9M?Kth-2eN(>U`&=oo_wzbq!Sm181lwtA02? zv@TaOMdMwj#F6_m=#nOO{oK&<&9~R*ZobiZchTj}CNX&7kXM+!ZvMW>+VS5m_n+=x z)%&zfg+kYb#{-TB=1aNkwXsvfTect5d5DL{{+an#f7cA#SCjL8-9mrRXdD|E-`R3& o+x1Uo;i-+o=T7`oIJg5%XzOzQ%wx~QdMMD-y=KKP%Qx-%ABcS~82|tP literal 0 HcmV?d00001 diff --git a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp index 7184283d3a..3bab58bd50 100644 --- a/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/TwisterRollerCoaster.cpp @@ -18658,6 +18658,357 @@ static void TwisterRCTrackRightZeroGRollDown( TwisterRCTrackRightZeroGRollUp(session, ride, 2 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); } +static void TwisterRCTrackLeftLargeZeroGRollUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 5)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 96 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 9)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 10)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 96 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 15)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 21, height, session.SupportColours); + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 88); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 1)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 2)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 96 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 6)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 64 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 11)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 64 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 16)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 3)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 64 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 7)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 48 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 12)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 48 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 17)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 32 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 18)), + { 0, 0, height }, { { 0, 6, height + 40 }, { 32, 20, 3 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::topCorner, + PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 64); + break; + case 3: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::topLeftSide, PaintSegment::topCorner, + PaintSegment::bottomLeftSide, PaintSegment::centre, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 4)), + { 0, 0, height }, { { 0, 26, height }, { 32, 0, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomLeftSide, 0, height + 25, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 8)), + { 0, 0, height }, { { 0, 26, height }, { 32, 0, 20 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopLeftSide, 0, height + 32, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 13)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 32 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 14)), + { 0, 0, height }, { { 0, 6, height + 40 }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopRightSide, 0, height + 36, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 19)), + { 0, 0, height }, { { 0, 18, height }, { 32, 1, 30 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomRightSide, 0, height + 37, session.SupportColours); + break; + } + switch (direction) + { + case 1: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 2: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetGeneralSupportHeight(session, height + 40); + break; + } +} + +static void TwisterRCTrackRightLargeZeroGRollUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 20)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 25)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 26)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 96 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 31)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 96 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 35)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + } + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 21, height, session.SupportColours); + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 88); + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 21)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 27)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 64 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 32)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 64 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 36)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 37)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 96 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, PaintUtilRotateSegments(BlockedSegments::kStraightFlat, direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 72); + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 22)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 32 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 23)), + { 0, 0, height }, { { 0, 6, height + 40 }, { 32, 20, 3 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 28)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 48 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 33)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 48 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 38)), + { 0, 0, height }, { { 0, 30, height }, { 32, 0, 64 } }); + break; + } + + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 64); + break; + case 3: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 24)), + { 0, 0, height }, { { 0, 18, height }, { 32, 1, 30 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomLeftSide, 0, height + 37, session.SupportColours); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 29)), + { 0, 0, height }, { { 0, 2, height }, { 32, 0, 32 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 30)), + { 0, 0, height }, { { 0, 6, height + 40 }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopLeftSide, 0, height + 36, session.SupportColours); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 34)), + { 0, 0, height }, { { 0, 26, height }, { 32, 0, 20 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::TopRightSide, 0, height + 32, session.SupportColours); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 39)), + { 0, 0, height }, { { 0, 26, height }, { 40, 0, 32 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::BottomRightSide, 0, height + 25, session.SupportColours); + break; + } + switch (direction) + { + case 1: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 2: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetGeneralSupportHeight(session, height + 40); + break; + } +} + +static void TwisterRCTrackLeftLargeZeroGRollDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackLeftLargeZeroGRollUp( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + +static void TwisterRCTrackRightLargeZeroGRollDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + TwisterRCTrackRightLargeZeroGRollUp( + session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trackType) { switch (trackType) @@ -19169,6 +19520,16 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionTwisterRC(OpenRCT2::TrackElemType trac case TrackElemType::RightZeroGRollDown: return TwisterRCTrackRightZeroGRollDown; + // Large zero g rolls + case TrackElemType::LeftLargeZeroGRollUp: + return TwisterRCTrackLeftLargeZeroGRollUp; + case TrackElemType::RightLargeZeroGRollUp: + return TwisterRCTrackRightLargeZeroGRollUp; + case TrackElemType::LeftLargeZeroGRollDown: + return TwisterRCTrackLeftLargeZeroGRollDown; + case TrackElemType::RightLargeZeroGRollDown: + return TwisterRCTrackRightLargeZeroGRollDown; + default: return nullptr; } diff --git a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h index 9f4e238553..8bbc15a869 100644 --- a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h @@ -24,7 +24,7 @@ constexpr RideTypeDescriptor TwisterRollerCoasterRTD = .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Tubes, .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::corkscrewLarge, TrackGroup::halfLoopMedium}, - .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop, TrackGroup::zeroGRoll}, + .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | diff --git a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h index 8334f6df82..9b7124caa4 100644 --- a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h +++ b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h @@ -24,7 +24,7 @@ constexpr RideTypeDescriptor VerticalDropCoasterRTD = .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Boxed, .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::halfLoopMedium}, - .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::zeroGRoll}, + .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index dee8b91898..f1c63a15dc 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1291,7 +1291,8 @@ enum : ImageIndex SPR_G2_BM_TRACK_LARGE_CORKSCREW = SPR_G2_BM_TRACK_GENTLE_LARGE_CURVE_BANKED + 128, SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP = SPR_G2_BM_TRACK_LARGE_CORKSCREW + 40, SPR_G2_BM_TRACK_ZERO_G_ROLL = SPR_G2_BM_TRACK_MEDIUM_HALF_LOOP + 44, - SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_ZERO_G_ROLL + 32, + SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL = SPR_G2_BM_TRACK_ZERO_G_ROLL + 32, + SPR_G2_BM_RC_END = SPR_G2_BM_TRACK_LARGE_ZERO_G_ROLL + 40, SPR_G2_MINIATURE_RAILWAY_BEGIN = SPR_G2_BM_RC_END, SPR_G2_MINIATURE_RAILWAY_QUARTER_TURN_3_TILES_SW_SE_PART_3 = SPR_G2_MINIATURE_RAILWAY_BEGIN, From 1dcb05f072c3628b7471496d781fd72f8327dd89 Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 25 Oct 2024 10:10:33 +0100 Subject: [PATCH 018/139] Make pre-existing new Twister RC track pieces invisible --- src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/park/Legacy.cpp | 76 ++++++++++++++++++++++++++++ src/openrct2/park/ParkFile.h | 3 +- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 0c9016e54a..d8095e0b6e 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -49,7 +49,7 @@ using namespace OpenRCT2; // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -constexpr uint8_t kNetworkStreamVersion = 0; +constexpr uint8_t kNetworkStreamVersion = 1; const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion); diff --git a/src/openrct2/park/Legacy.cpp b/src/openrct2/park/Legacy.cpp index fa05855f0f..7bd6716041 100644 --- a/src/openrct2/park/Legacy.cpp +++ b/src/openrct2/park/Legacy.cpp @@ -2563,6 +2563,82 @@ bool TrackTypeMustBeMadeInvisible(ride_type_t rideType, OpenRCT2::TrackElemType break; } } + else if ( + (rideType == RIDE_TYPE_TWISTER_ROLLER_COASTER || rideType == RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER + || rideType == RIDE_TYPE_HYPER_TWISTER || rideType == RIDE_TYPE_FLYING_ROLLER_COASTER) + && parkFileVersion < kExtendedTwisterCoasterVersion) + { + switch (trackType) + { + case TrackElemType::LeftEighthToDiagUp25: + case TrackElemType::RightEighthToDiagUp25: + case TrackElemType::LeftEighthToDiagDown25: + case TrackElemType::RightEighthToDiagDown25: + case TrackElemType::LeftEighthToOrthogonalUp25: + case TrackElemType::RightEighthToOrthogonalUp25: + case TrackElemType::LeftEighthToOrthogonalDown25: + case TrackElemType::RightEighthToOrthogonalDown25: + case TrackElemType::DiagUp25ToLeftBankedUp25: + case TrackElemType::DiagUp25ToRightBankedUp25: + case TrackElemType::DiagLeftBankedUp25ToUp25: + case TrackElemType::DiagRightBankedUp25ToUp25: + case TrackElemType::DiagDown25ToLeftBankedDown25: + case TrackElemType::DiagDown25ToRightBankedDown25: + case TrackElemType::DiagLeftBankedDown25ToDown25: + case TrackElemType::DiagRightBankedDown25ToDown25: + case TrackElemType::DiagLeftBankedFlatToLeftBankedUp25: + case TrackElemType::DiagRightBankedFlatToRightBankedUp25: + case TrackElemType::DiagLeftBankedUp25ToLeftBankedFlat: + case TrackElemType::DiagRightBankedUp25ToRightBankedFlat: + case TrackElemType::DiagLeftBankedFlatToLeftBankedDown25: + case TrackElemType::DiagRightBankedFlatToRightBankedDown25: + case TrackElemType::DiagLeftBankedDown25ToLeftBankedFlat: + case TrackElemType::DiagRightBankedDown25ToRightBankedFlat: + case TrackElemType::DiagUp25LeftBanked: + case TrackElemType::DiagUp25RightBanked: + case TrackElemType::DiagDown25LeftBanked: + case TrackElemType::DiagDown25RightBanked: + case TrackElemType::DiagFlatToLeftBankedUp25: + case TrackElemType::DiagFlatToRightBankedUp25: + case TrackElemType::DiagLeftBankedUp25ToFlat: + case TrackElemType::DiagRightBankedUp25ToFlat: + case TrackElemType::DiagFlatToLeftBankedDown25: + case TrackElemType::DiagFlatToRightBankedDown25: + case TrackElemType::DiagLeftBankedDown25ToFlat: + case TrackElemType::DiagRightBankedDown25ToFlat: + case TrackElemType::LeftEighthBankToDiagUp25: + case TrackElemType::RightEighthBankToDiagUp25: + case TrackElemType::LeftEighthBankToDiagDown25: + case TrackElemType::RightEighthBankToDiagDown25: + case TrackElemType::LeftEighthBankToOrthogonalUp25: + case TrackElemType::RightEighthBankToOrthogonalUp25: + case TrackElemType::LeftEighthBankToOrthogonalDown25: + case TrackElemType::RightEighthBankToOrthogonalDown25: + case TrackElemType::LeftLargeCorkscrewUp: + case TrackElemType::RightLargeCorkscrewUp: + case TrackElemType::LeftLargeCorkscrewDown: + case TrackElemType::RightLargeCorkscrewDown: + case TrackElemType::LeftMediumHalfLoopUp: + case TrackElemType::RightMediumHalfLoopUp: + case TrackElemType::LeftMediumHalfLoopDown: + case TrackElemType::RightMediumHalfLoopDown: + case TrackElemType::LeftLargeHalfLoopUp: + case TrackElemType::RightLargeHalfLoopUp: + case TrackElemType::LeftLargeHalfLoopDown: + case TrackElemType::RightLargeHalfLoopDown: + case TrackElemType::LeftZeroGRollUp: + case TrackElemType::RightZeroGRollUp: + case TrackElemType::LeftZeroGRollDown: + case TrackElemType::RightZeroGRollDown: + case TrackElemType::LeftLargeZeroGRollUp: + case TrackElemType::RightLargeZeroGRollUp: + case TrackElemType::LeftLargeZeroGRollDown: + case TrackElemType::RightLargeZeroGRollDown: + return true; + default: + break; + } + } return false; } diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index 61c19360ed..69cb1289a6 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -11,7 +11,7 @@ namespace OpenRCT2 struct GameState_t; // Current version that is saved. - constexpr uint32_t PARK_FILE_CURRENT_VERSION = 42; + constexpr uint32_t PARK_FILE_CURRENT_VERSION = 43; // The minimum version that is forwards compatible with the current version. constexpr uint32_t PARK_FILE_MIN_VERSION = 42; @@ -33,6 +33,7 @@ namespace OpenRCT2 constexpr uint16_t kPeepNamesObjectsVersion = 39; constexpr uint16_t kWoodenRollerCoasterMediumLargeHalfLoopsVersion = 41; constexpr uint16_t kExtendedCorkscrewCoasterVersion = 42; + constexpr uint16_t kExtendedTwisterCoasterVersion = 43; } // namespace OpenRCT2 class ParkFileExporter From 0e9a64d20b2de459e74b38c6c751e0ef02db9cf2 Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 25 Oct 2024 10:48:08 +0100 Subject: [PATCH 019/139] Add new Twister Roller Coaster track pieces to changelog --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index be76fc6ce6..8d1d041a3e 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.4.17 (in development) ------------------------------------------------------------------------ +- Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. 0.4.16 (2024-11-03) From c0810ed159a21f3711bb09796261d58bfd2e3de4 Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 25 Oct 2024 21:03:21 +0100 Subject: [PATCH 020/139] Make large sloped turns available to the Flying Roller Coaster --- src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h b/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h index 3a8ef02700..e1b61c3e99 100644 --- a/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor FlyingRollerCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionFlyingRC, .supportType = MetalSupportType::TubesInverted, - .enabledTrackGroups = {TrackGroup::straight, 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::inlineTwistUninverted, TrackGroup::flyingHalfLoopUninvertedUp, TrackGroup::quarterLoopUninvertedUp, TrackGroup::flyingLargeHalfLoopUninvertedUp, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes}, + .enabledTrackGroups = {TrackGroup::straight, 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::inlineTwistUninverted, TrackGroup::flyingHalfLoopUninvertedUp, TrackGroup::quarterLoopUninvertedUp, TrackGroup::flyingLargeHalfLoopUninvertedUp, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge}, .extraTrackGroups = {TrackGroup::booster, TrackGroup::slopeSteepLong, TrackGroup::flyingLargeHalfLoopUninvertedDown, TrackGroup::flyingHalfLoopUninvertedDown, TrackGroup::stationEnd, TrackGroup::verticalLoop, TrackGroup::poweredLift}, }), .InvertedTrackPaintFunctions = TrackDrawerDescriptor({ From b95e1bbf6b9212f6369c99e83c9eb11c7df5197b Mon Sep 17 00:00:00 2001 From: mix Date: Sat, 2 Nov 2024 21:53:10 +0000 Subject: [PATCH 021/139] Make Twister RC zero g rolls available if trains have sprites --- src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h index 8bbc15a869..e69594d296 100644 --- a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h @@ -23,8 +23,8 @@ constexpr RideTypeDescriptor TwisterRollerCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Tubes, - .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::corkscrewLarge, TrackGroup::halfLoopMedium}, - .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge}, + .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::slopeSteepLong, TrackGroup::curveVertical, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::corkscrewLarge, TrackGroup::halfLoopMedium, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge}, + .extraTrackGroups = {TrackGroup::liftHillSteep, TrackGroup::brakeForDrop}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | From a56d2eec2c6d271c432a12a813fc9258afee5c22 Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 6 Nov 2024 02:50:59 +0000 Subject: [PATCH 022/139] Add large corkscrews to Vertical Drop RC extra track piece list --- src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h index 9b7124caa4..da5422f8df 100644 --- a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h +++ b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h @@ -24,7 +24,7 @@ constexpr RideTypeDescriptor VerticalDropCoasterRTD = .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Boxed, .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::halfLoopMedium}, - .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge}, + .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge, TrackGroup::corkscrewLarge}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | From 2e591a7382c49e721b9ca478439855b61cdc7e36 Mon Sep 17 00:00:00 2001 From: mix Date: Sun, 10 Nov 2024 21:11:19 +0000 Subject: [PATCH 023/139] Make corkscrews and zero g rolls available to Vertical Drop RC --- src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h index da5422f8df..a24af87074 100644 --- a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h +++ b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h @@ -23,8 +23,8 @@ constexpr RideTypeDescriptor VerticalDropCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionTwisterRC, .supportType = MetalSupportType::Boxed, - .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::halfLoopMedium}, - .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::corkscrew, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge, TrackGroup::corkscrewLarge}, + .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::liftHillSteep, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::flatToSteepSlope, TrackGroup::slopeCurve, TrackGroup::slopeCurveSteep, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::slopeVertical, TrackGroup::slopeCurveBanked, TrackGroup::blockBrakes, TrackGroup::slopeRollBanking, TrackGroup::curveVertical, TrackGroup::halfLoopLarge, TrackGroup::brakeForDrop, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeCurveLarge, TrackGroup::halfLoopMedium, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge, TrackGroup::corkscrew, TrackGroup::corkscrewLarge}, + .extraTrackGroups = {TrackGroup::halfLoop, TrackGroup::barrelRoll, TrackGroup::poweredLift, TrackGroup::halfLoopLarge, TrackGroup::quarterLoop, TrackGroup::booster, TrackGroup::twist}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | From 936d89bdbb226d497b2c1ada20e80e4cbd96afc2 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 11 Nov 2024 04:02:13 +0000 Subject: [PATCH 024/139] Merge Localisation/master into OpenRCT2/develop --- data/language/gl-ES.txt | 55 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/data/language/gl-ES.txt b/data/language/gl-ES.txt index a407b8a8dc..0d021996fb 100644 --- a/data/language/gl-ES.txt +++ b/data/language/gl-ES.txt @@ -99,6 +99,7 @@ STR_0094 :Montaña rusa dun só carril STR_0095 :Montaña Rusa Alpina STR_0096 :Montaña rusa clásica de madeira STR_0097 :Montaña rusa clásica de pé +STR_0098 :Montaña Rusa de Lanzamento LSM STR_0512 :Unha pequena montaña rusa de aceiro cunha subida en espiral e coches con asentos en liña. STR_0513 :Unha montaña rusa na que os pasaxeiros permanecen de pé. STR_0514 :Os coches suspendidos baixo os carrís balanceanse lateralmente ao virar en curva. @@ -183,6 +184,7 @@ STR_0604 :Os pasaxeiros viaxan en ringleira por unha estreita vía de monorra STR_0605 :Os pasaxeiros baixan por unha sinuosa vía de aceiro, freando para controlar a súa velocidade. STR_0606 :Unha montaña rusa de madeira de estilo antigo cun paseo rápido e áspero, con moitas caídas, algunhas forzas G laterais e deseñada para ofrecer unha experiencia "descontrolada". STR_0607 :Unha montaña rusa en espiral de aceiro de estilo vintage intenso con xinetes montando de pé. +STR_0608 :Os trens da montaña rusa son acelerados por motores lineais síncronos, percorrendo a gran velocidade curvas pechadas e viraxes pronunciadas STR_0767 :Visitante {INT32} STR_0768 :Manitas {INT32} STR_0769 :Mecánica {INT32} @@ -3609,7 +3611,7 @@ STR_6537 :Permitir que as rutas normais se utilicen como cola STR_6538 :Mostra rutas normais no menú despregable da cola da xanela Rutas. STR_6539 :freo pechado STR_6540 :{WINDOW_COLOUR_2}Grazas especiais ás seguintes empresas por permitir o uso da súa imaxe: -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 :Colaboradores STR_6543 :Colaboradores... STR_6544 :O préstamo non pode ser negativo! @@ -3730,5 +3732,52 @@ STR_6657 :Terra Sen Propietario STR_6658 :Establecer que a terra non sexa propiedade do parque nin estea dispoñible para a compra STR_6659 :Os invitados ignoran os prezos STR_6660 :Os invitados ignorarán o prezo das atraccións e dos postos - - +STR_6661 :Todo ao chou +STR_6662 :Cores ao chou para cada tren ou vehículo. +STR_6663 :Trucos de data +STR_6664 :Amosar trucos de data +STR_6665 :Trucos de natureza/clima +STR_6666 :Amosar trucos de natureza/clima +STR_6667 :Fauna +STR_6668 :Trucos de empleados +STR_6669 :Amosar trucos de empleados +STR_6670 :Comportamento dos visitantes +STR_6671 :Amosar nomes ‘reais’ de empleados +STR_6672 :Alternar entre amosar nomes ‘reais’ e números de empleados +STR_6673 :Translúcido +STR_6674 :{MONTH}, Ano {COMMA16} +STR_6675 :Nomes dos Visitantes +STR_6676 :Debe escollerse polo menos un obxecto de nomes de visitantes +STR_6677 :Engade praias arredor das masas de auga +STR_6678 :Fonte do mapa de elevación: +STR_6679 :Chaira +STR_6680 :Ruído Simplex +STR_6681 :Arquivo do mapa de elevación +STR_6682 :Xerador de Mapas - Xerador +STR_6683 :Xerador de Mapas - Terreo +STR_6684 :Xerador de Mapas - Auga +STR_6685 :Xerador de Mapas - Fragas +STR_6686 :Relación árbores/terreo +STR_6687 :Altitude mínima das árbores: +STR_6688 :Altitude máxima das árbores: +STR_6689 :{UINT16}% +STR_6690 :Altura mínima do terreo +STR_6691 :Introduce a altura mínima do terreo entre {COMMA16} e {COMMA16} +STR_6692 :Altura máxima do terreo +STR_6693 :Introduce a altura máxima do terreo entre {COMMA16} e {COMMA16} +STR_6694 :Altitude mínima das árbores +STR_6695 :Introduce a altitude mínima das árbores entre {COMMA16} e {COMMA16} +STR_6696 :Altitude máxima das árbores +STR_6697 :Introduce a altitude máxima das árbores entre {COMMA16} e {COMMA16} +STR_6698 :Relación árbores/terreo +STR_6699 :Introduce a relación árbores/terreo entre {COMMA16} e {COMMA16} +STR_6700 :Frecuencia base Simplex +STR_6701 :Introduce a frecuencia base entre {COMMA2DP32} e {COMMA2DP32} +STR_6702 :Octavas Simplex +STR_6703 :Introduce as octavas entre {COMMA16} e {COMMA16} +STR_6704 :{COMMA2DP32} +STR_6705 :Explorar… +STR_6706 :{WINDOW_COLOUR_2}Arquivo de imaxe actual: {BLACK}{STRING} +STR_6707 :(Ningún escollido) +STR_6708 :Intensidade de suavizado +STR_6709 :Introduce a intensidade de suavizado entre {COMMA16} e {COMMA16} From e6ae0a9bc00dae635aec26b8be1f5d9443064246 Mon Sep 17 00:00:00 2001 From: AuraSpecs Date: Mon, 11 Nov 2024 21:16:53 +0100 Subject: [PATCH 025/139] Hotfix: Disappearing large half loops on BM track --- src/openrct2/park/Legacy.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/openrct2/park/Legacy.cpp b/src/openrct2/park/Legacy.cpp index 7bd6716041..4a5c34cb23 100644 --- a/src/openrct2/park/Legacy.cpp +++ b/src/openrct2/park/Legacy.cpp @@ -2622,10 +2622,6 @@ bool TrackTypeMustBeMadeInvisible(ride_type_t rideType, OpenRCT2::TrackElemType case TrackElemType::RightMediumHalfLoopUp: case TrackElemType::LeftMediumHalfLoopDown: case TrackElemType::RightMediumHalfLoopDown: - case TrackElemType::LeftLargeHalfLoopUp: - case TrackElemType::RightLargeHalfLoopUp: - case TrackElemType::LeftLargeHalfLoopDown: - case TrackElemType::RightLargeHalfLoopDown: case TrackElemType::LeftZeroGRollUp: case TrackElemType::RightZeroGRollUp: case TrackElemType::LeftZeroGRollDown: From 5397c816e2e103a2c8f7abaf7c5acac6b33d0476 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek <1478678+Gymnasiast@users.noreply.github.com> Date: Mon, 11 Nov 2024 21:23:06 +0100 Subject: [PATCH 026/139] Add Galician --- distribution/changelog.txt | 1 + src/openrct2/localisation/Language.cpp | 1 + src/openrct2/localisation/Language.h | 1 + src/openrct2/platform/Platform.Win32.cpp | 1 + 4 files changed, 4 insertions(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 8d1d041a3e..758103600b 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,5 +1,6 @@ 0.4.17 (in development) ------------------------------------------------------------------------ +- Feature: [#23166] Add Galician translation. - Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. diff --git a/src/openrct2/localisation/Language.cpp b/src/openrct2/localisation/Language.cpp index cc4bff6696..ccd9649785 100644 --- a/src/openrct2/localisation/Language.cpp +++ b/src/openrct2/localisation/Language.cpp @@ -39,6 +39,7 @@ const LanguageDescriptor LanguagesDescriptors[LANGUAGE_COUNT] = { "es-ES", "Spanish", u8"Español", LANGUAGE_UNDEFINED, kFamilyOpenRCT2Sprite, false }, // LANGUAGE_SPANISH { "fr-FR", "French", u8"Français", LANGUAGE_UNDEFINED, kFamilyOpenRCT2Sprite, false }, // LANGUAGE_FRENCH { "fr-CA", "French (CA)", u8"Français (CA)", LANGUAGE_FRENCH, kFamilyOpenRCT2Sprite, false }, // LANGUAGE_FRENCH_CA + { "gl-ES", "Galician", "Galego", LANGUAGE_UNDEFINED, kFamilyOpenRCT2Sprite, false }, // LANGUAGE_GALICIAN { "it-IT", "Italian", "Italiano", LANGUAGE_UNDEFINED, kFamilyOpenRCT2Sprite, false }, // LANGUAGE_ITALIAN { "ja-JP", "Japanese", "Japanese", LANGUAGE_UNDEFINED, FAMILY(&TTFFamilyJapanese), false }, // LANGUAGE_JAPANESE { "ko-KR", "Korean", "Korean", LANGUAGE_UNDEFINED, FAMILY(&TTFFamilyKorean), false }, // LANGUAGE_KOREAN diff --git a/src/openrct2/localisation/Language.h b/src/openrct2/localisation/Language.h index 505133bd48..7930999302 100644 --- a/src/openrct2/localisation/Language.h +++ b/src/openrct2/localisation/Language.h @@ -31,6 +31,7 @@ enum LANGUAGE_SPANISH, LANGUAGE_FRENCH, LANGUAGE_FRENCH_CA, + LANGUAGE_GALICIAN, LANGUAGE_ITALIAN, LANGUAGE_JAPANESE, LANGUAGE_KOREAN, diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index bf70e6598e..905d21cf7a 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -597,6 +597,7 @@ namespace OpenRCT2::Platform { L"es", LANGUAGE_SPANISH }, { L"fr", LANGUAGE_FRENCH }, { L"fr-CA", LANGUAGE_FRENCH_CA }, + { L"gl", LANGUAGE_GALICIAN }, { L"it", LANGUAGE_ITALIAN }, { L"ja", LANGUAGE_JAPANESE }, { L"ko", LANGUAGE_KOREAN }, From 3e2e8ceb3a8e5765914217edf637857789cefd70 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 14 Nov 2024 04:02:18 +0000 Subject: [PATCH 027/139] Merge Localisation/master into OpenRCT2/develop --- data/language/pl-PL.txt | 776 ++++++++++++++++++++-------------------- 1 file changed, 388 insertions(+), 388 deletions(-) diff --git a/data/language/pl-PL.txt b/data/language/pl-PL.txt index edc6a9cd0f..8071877878 100644 --- a/data/language/pl-PL.txt +++ b/data/language/pl-PL.txt @@ -3,22 +3,22 @@ # Use # at the beginning of a line to leave a comment. STR_0000 : STR_0001 :{STRINGID} {COMMA16} -STR_0002 :Pajęcza jazda +STR_0002 :Kolejka spiralna STR_0003 :Stojąca kolejka -STR_0004 :Podwieszana kolejka górska +STR_0004 :Kolejka podwieszona STR_0005 :Kolejka odwrotna -STR_0006 :Dziecięca kolejka górska +STR_0006 :Kolejka dla dzieci STR_0007 :Miniaturowa kolejka -STR_0008 :Kolejka jednotorowa +STR_0008 :Jednoszynówka STR_0009 :Podwieszana minikolejka STR_0010 :Łódki STR_0011 :Drewniana szalona mysz STR_0012 :Bieg z przeszkodami -STR_0013 :Przejażdżka autami +STR_0013 :Przejażdżka STR_0014 :Wystrzałowa spadajka STR_0015 :Kolejka bobslejowa STR_0016 :Wieża obserwacyjna -STR_0017 :Pętlowa kolejka +STR_0017 :Kolejka zapętlona STR_0018 :Ślizg pontonowy STR_0019 :Kolejka kopalniana STR_0020 :Wyciąg krzesełkowy @@ -45,7 +45,7 @@ STR_0040 :Symulator ruchu STR_0041 :Kino trójwymiarowe STR_0042 :Wirówka STR_0043 :Kosmiczne pierścienie -STR_0044 :Kolejka o swobodnym spadku +STR_0044 :Odwrócony swobodospad STR_0045 :Winda STR_0046 :Pionospadajka STR_0047 :Bankomat @@ -55,29 +55,29 @@ STR_0050 :Punkt pierwszej pomocy STR_0051 :Cyrk STR_0052 :Pociąg widmo STR_0053 :Zwijka -STR_0054 :Drewniana kolejka górska -STR_0055 :Tarcie Boczne +STR_0054 :Drewniana jazda +STR_0055 :Tarcie boczne STR_0056 :Stalowa szalona mysz STR_0057 :Kolejka wielowymiarowa STR_0058 :Nieznana atrakcja (38) STR_0059 :Latająca kolejka STR_0060 :Nieznana atrakcja (3A) -STR_0061 :W Koło Macieju +STR_0061 :W koło Macieju STR_0062 :Pluskołódki -STR_0063 :Mini helikoptery +STR_0063 :Minihelikoptery STR_0064 :Leżąca kolejka -STR_0065 :Kolejka podwieszana +STR_0065 :Podwieszona jednoszynówka STR_0066 :Nieznana atrakcja (40) -STR_0067 :Kolejka nawracająca -STR_0068 :Wagoniki zwijki +STR_0067 :Zawracajka +STR_0068 :Zabójcza kolejka STR_0069 :Minigolf -STR_0070 :Gigajazda +STR_0070 :Giga jazda STR_0071 :Obrotospad STR_0072 :Latające spodki STR_0073 :Krzywy dom STR_0074 :Rowery jednotorowe STR_0075 :Mała kolejka odwrócona -STR_0076 :Kolejka łódkowa +STR_0076 :Kolejka wodna STR_0077 :Pneumatyczna kolejka pionowa STR_0078 :Kolejka serpentynowa STR_0079 :Latający dywan @@ -89,42 +89,42 @@ STR_0084 :Nieznana atrakcja (52) STR_0085 :Nieznana atrakcja (53) STR_0086 :Nieznana atrakcja (54) STR_0087 :Nieznana atrakcja (55) -STR_0088 :Zawracajka -STR_0089 :Mini kolejka górska +STR_0088 :Kolejka zwrotna +STR_0089 :Minikolejka STR_0090 :Przejażdżka kopalniana STR_0091 :Nieznana atrakcja (59) STR_0092 :Kolejka z napędem indukcyjnym liniowym STR_0093 :Kolejka hybrydowa -STR_0094 :Kolejka jednotorowa +STR_0094 :Kolejka jednoszynowa STR_0095 :Tor saneczkowy -STR_0096 :Klasyczna drewniana kolejka górska -STR_0097 :Klasyczna stojąca kolejka górska +STR_0096 :Klasyczna drewniana jazda +STR_0097 :Klasyczna stojąca kolejka STR_0098 :Kolejka z napędem synchronicznym liniowym -STR_0512 :Kolejka górska ze spiralnym podjazdem i łagodnymi pokręconymi zjazdami -STR_0513 :Kolejka górska z pętlą, gdzie pasażerowie jadą na stojąco -STR_0514 :Wagony podczepione są pod tor kolejki górskiej i bujają się na zakrętach -STR_0515 :Stalowa kolejka górska z podczepionymi wagonikami z wieloma złożonymi i pokręconymi elementami -STR_0516 :Łagodna kolejka górska dla ludzi, którzy nie mają jeszcze dość odwagi aby wsiąść na wyższe kolejki +STR_0512 :Zwarta przestrzennie kolejka ze spiralnym podjazdem i gładkimi, zakręconymi zjazdami +STR_0513 :Zapętlona kolejka, w której pasażerowie jadą w pozycji stojącej +STR_0514 :Wagoniki podwieszone pod torem kolejki wychylają się swobodnie na zakrętach +STR_0515 :Pasażerowie siedzą w fotelach podwieszonych pod torem, pokonując liczne, złożone i zakręcone elementy +STR_0516 :Łagodna kolejka dla gości, którzy nie są na tyle odważni, by zdecydować się na większe atrakcje STR_0517 :Pasażerowie jeżdżą w miniaturowych pociągach na wąskotorowym torze STR_0518 :Pasażerowie podróżują w elektrycznych pociągach na pojedynczym torze STR_0519 :Pasażerowie jeżdżą w małych autach podwieszonych na pojedynczym torze, bujają się swobodnie na zakrętach -STR_0520 :Przystań gdzie goście mogą popływać samemu w różnych wodnych atrakcjach -STR_0521 :Szybka i pokręcona kolejka górska z ciasnymi zakrętami i stromymi zjazdami. Intensywność na pewno będzie duża. -STR_0522 :Mniejsza kolejka górska, gdzie goście siedzą nad torem nie mając wokół siebie zabezpieczeń +STR_0520 :Przystań, gdzie goście mogą samodzielnie pływać różnymi pojazdami wodnymi +STR_0521 :Wagoniki w kształcie myszy jadące po zygzakowatym drewnianym torze, przechylające się na ostrych zakrętach i zdradliwych zjazdach +STR_0522 :Mniejsza kolejka, gdzie pasażerowie siedzą wysoko nad torem, nie mając wokół siebie zabezpieczeń STR_0523 :Pasażerowie podróżują powoli napędzanymi pojazdami po wyznaczonym torze -STR_0524 :Freefall car jest pneumatycznie sterowaną atrakcją z wysoką stalową wieżą, z której następuje swobodny spadek wagonika +STR_0524 :Wagonik jest wystrzeliwany pneumatycznie na szczyt wysokiej wieży, a potem swobodnie opada STR_0525 :Pasażerowie jadą w dół po pokręconym torze składającym się tylko z zakrętów i zawijasów -STR_0526 :Pasażerowie jadą w obracającym się obserwatorium, które wjeżdża na górę wysokiej wieży -STR_0527 :Łagodny stalowa kolejka górska, gdzie można robić pionowe pętle -STR_0528 :Goście jeżdżą w nadmuchiwanych pontonach w pokręconych półkolistych lub całkowicie zabudowanych korytach -STR_0529 :Kolejka górska ze stalowym torem stylizowana na starą kopalnianą kolejkę -STR_0530 :Pojazdy zwisają na stalowej linie na której poruszają się w jedną, a potem w drugą stronę -STR_0531 :Kompaktowa stalowa kolejka górska, gdzie wagoniki poruszają się po wykręcanych torach i pętlach -STR_0532 :Labirynt zbudowany jest ze ścian lub żywopłotu o wysokości 6 stóp, goście błądzą wewnątrz dopóki nie znajdą wyjścia +STR_0526 :Pasażerowie jadą w obracającej się kabinie obserwacyjnej, która wjeżdża na górę wysokiej wieży +STR_0527 :Szybka kolejka ze stalowymi torami, zdolna do wykonywania pętli +STR_0528 :Pasażerowie podróżują w nadmuchiwanych pontonach po zawiłym półkolistym lub rurowym torze +STR_0529 :Kolejka górska w stylu górniczym, poruszająca się po stalowych szynach stylizowanych na stary tor kolejowy +STR_0530 :Pojazdy są podwieszone na stalowej linie i poruszają się nieprzerwanie z jednego końca trasy na drugi i z powrotem +STR_0531 :Zwarta przestrzennie kolejka ze stalowymi torami, w której wagoniki pokonują korkociągi i pętle +STR_0532 :Goście wędrują po labiryncie zbudowanym z dwumetrowych żywopłotów lub ścian STR_0533 :Drewniany budynek ze schodami w środku oraz zjeżdżalnią na zewnątrz do zjeżdżania na matach STR_0534 :Go karty zasilane benzyną, sterowane indywidualnie przez gości -STR_0535 :Łodzie w kształcie kłód do pływania w kanale wodnym ze zjazdami, gdzie woda tryska na gości -STR_0536 :Okrągłe łódki do pływania szerokim kanałem, chlapanie gości przy deszczownicach i dreszczyk emocji na spienionych fragmentach +STR_0535 :Łódki w kształcie pni płyną wodnym kanałem, spadając z pluskiem ze stromych spadków, aby zamoczyć pasażerów +STR_0536 :Okrągłe łódki pokonujące szeroki kanał wodny, spadające z wodospadów i przepływające przez spienione bystrzyny STR_0537 :Elektryczne samochodziki do zderzania, sterowane indywidualnie przez gości STR_0538 :Wielki bujający statek piracki STR_0539 :Statek podczepiony jest do ramienia z przeciwwagą na drugim końcu, buja się wokół wykonując pełny obrót 360 stopni @@ -139,52 +139,52 @@ STR_0550 :Pasażerowie oglądają film, siedząc w specjalnej kabinie, porusz STR_0551 :Kino 3D z projekcją filmów wewnątrz sferycznego budynku STR_0552 :Pasażerowi jeżdżą w gondoli podczepionej pod wielkie obrotowe ramię, kręcąc się do przodu i w tył STR_0553 :Obrotowe okręgi pozwalające gościom na swobodne kręcenie się we wszystkie możliwe kierunki -STR_0554 :Auto jest rozpędzane na stacji przy pomocy Liniowych Indukcyjnych Silników, potem jedzie prosto na szczyt, skąd swobodnie opada z powrotem na stację -STR_0555 :Goście jeżdżą windą w górę lub dół, aby przemieścić się na inny poziom -STR_0556 :Ekstra szerokie pojazdy zjeżdżają pionowym torem, aby osiągnąć największe odczucia nieważkości +STR_0554 :Wagonik jest wystrzeliwany ze stacji za pomocą silnika liniowego i wjeżdza po pionowym torze, po czym wykonuje pionowy zjazd w dół, z powrotem do stacji +STR_0555 :Pasażerowie jeżdzą w górę lub w dół windą w wieży, aby przejść z jednego poziomu na drugi +STR_0556 :Bardzo szerokie wagoniki zjeżdzają po całkowicie pionowym torze, zapewniając pasażerom jedyne w swoim rodzaju wrażenie swobodnego spadania STR_0557 :Bankomat dla gości którym zabrakło gotówki STR_0558 :Pasażerowie jeżdżą parami w siedzeniach znajdujących się na końcach trzech obracających się ramion STR_0559 :Wielki stylizowany budynek zawierający straszne korytarze i upiorne pokoje STR_0560 :Miejsce dla chorych gości, gdzie mogą szybciej dojść do siebie STR_0561 :Pokaz zwierzą cyrkowych wewnątrz wielkiego namiotu -STR_0562 :Samochody z napędem do jeżdżenia po wielopoziomowych torach przez straszne i upiorne efekty -STR_0563 :Siedząc w wygodnych wagonach z prostym zabezpieczeniem goście cieszą się delikatnymi zjazdami i krętą trasą tak samo, jak wiatrem we włosach -STR_0564 :Jazda na drewnianym torze, kolejka jest szybka, twarda, głośna i daje poczucie braku kontroli nad przejazdem, jednocześnie zapewnia uczucie wiatru we włosach -STR_0565 :Prosta drewniana kolejka górska tylko z łagodnymi wzniesieniami i zakrętami, gdzie pojazdy trzymają się trasy w oparciu o tarcie kół i grawitację -STR_0566 :Indywidualna kolejka górska z pojazdami poruszającymi się zakręonym torem z ostrymi łukami i krótkimi stromymi zjazdami -STR_0567 :Siedząc w wózkach podwieszonych po obu stronach toru, goście podskakują gdy wjeżdżają w strome zjazdy i przemierzają różne inwersje -STR_0569 :Jazda w specjalnych uprzężach pod torem, goście mają wrażenie że latają -STR_0571 :Okrągłe pojazdy kręcą się w kółko podczas jazdy tym krętym drewnianym torem -STR_0572 :Łodzie dużej pojemności płynące szerokim kanałem, wznoszone w górę za pomocą taśmociągu, gdy zjeżdżają stromym zjazdem robią wielki plusk żeby zmoczyć gości -STR_0573 :Zasilane pojazdy w kształcie helikopterów na stalowym torze, sterowane pedałami przez gości -STR_0574 :Goście trzymani są przez specjalne uprzęże w pozycji leżącej, jadąc po krętym torze i inwersjach są na przemian na plecach lub twarzą do ziemi +STR_0562 :Napędzane wagoniki jadą po wielopoziomowym torze wśród przerażających dekoracji i efektów specjalnych +STR_0563 :Pasażerowie jadą w wygodnych wagonikach z zabezpieczeniami obejmującymi w pasie, pokonując wielkie gładkie zjazdy i skomplikowane zakręty, a także liczne „wzloty” nad wzniesieniami +STR_0564 :Szybka, ostra i hałaśliwa kolejka jadąca po drewnianym torze, zapewniająca pasażerom niezapomniane wrażenia i dużo swobodnego spadku +STR_0565 :Prosta drewniana kolejka, pokonująca jedynie łagodne nachylenia i zakręty, podczas których wagoniki są utrzymywane na torze tylko przez boczne kółka i siłę grawitacji +STR_0566 :Pojedyncze wagoniki mkną po torze z ostrymi zakrętami i gwałtownymi spadkami +STR_0567 :Pasażerowie jadą w siedzeniach zawieszonych po obu stronach toru, a podczas pokonywania stromych zjazdów i ostrych nawrotów są obracani do góry nogami +STR_0569 :Pasażerowie zasiadają w wygodnych fotelach zawieszonych pod torem i jadą zawiłą trasą, czując się, jakby potrafili latać +STR_0571 :Okrągłe wagoniki wirują, jadąc po zygzakowatym, drewnianym torze +STR_0572 :Pojemne łodzie płynące szerokim kanałem, wciągane po nachyleniu przez pasy napędowe, zjeżdzające ze wzniesień i w wielkim plusku moczące pasażerów +STR_0573 :Zasilane pojazdy w kształcie helikopterów jadące po stalowym torze, sterowane przez pedałujących pasażerów +STR_0574 :Pasażerowie trzymani są przez specjalne uprzęże w pozycji leżącej, podróżując przez zakręcony tor albo na plecach, albo twarzą ku ziemi STR_0575 :Zasilane pociągi zawieszone na pojedynczej szynie służą jako środek transportu ludzi w parku -STR_0577 :Wózki jeżdżące po drewnianych torach, zawracają na specjalnych platformach -STR_0578 :Pojazdy jeżdżące po torze składającym się z okrągłych hopek, strome zbocza i palpitacje serca +STR_0577 :Wózki kopalniane jeżdzące po drewnianych torach, zawracające na specjalnych obrotowych sekcjach +STR_0578 :Wagoniki jadą po torze otoczonym okrągłymi obręczami, pokonując strome zjazdy i zabójcze obroty STR_0579 :Spokojna gra w mini golfa -STR_0580 :Wielka stalowa kolejka górska na której mogą być łagodne zjazdy i podjazdy na ponad 300 stóp -STR_0581 :Okrąg z siedzeniami kręcący się powoli, podciągany jest w górę wysokiej wieży, następnie następuje swobodne opadanie zakończone delikatnym hamowaniem magnetycznymi hamulcami na dole wieży -STR_0582 :Sterowane przez gości poduszkowce +STR_0580 :Wielka stalowa kolejka górska jeżdżąca po łagodnych spadkach i wzniesieniach o wysokości ponad 100 metrów +STR_0581 :Pierścień z zamocowanymi fotelami jest wciągany na szczyt wysokiej wieży, obracając się powoli, po czym spada swobodnie, wyhamowując delikatnie u dołu przy użyciu hamulców magnetycznych +STR_0582 :Poduszkowce sterowane przez pasażerów STR_0583 :Budynek zawierający krzywe ściany i korytarze, aby wywoływać uczucie zaburzenia błędnika STR_0584 :Specjalne rowery na stalowej pojedynczej szynie, napędzane siłą mięśni gości -STR_0585 :Goście siedzą na parze siedzeń podwieszonych pod torem podczas przejażdżki przez pętle i ciasne inwersje -STR_0586 :Łodzie stylizowane na samochody jadąc na torze kolejki pozwalają na ostre zakręty i strome zjazdy, zjeżdżając do spokojnych części z rzeką powodują wielki plusk -STR_0587 :Po szybkim starcie wagonika napędzonego powietrzem, kolejka przyspiesza na pionowym torze, na szczycie skład zmienia kierunek i jedzie pionowo w dół na drugą stronę stacji -STR_0588 :Indywidualne samochody podwieszone na krętym torze z super ostrymi zakrętami i stromymi zjazdami +STR_0585 :Pasażerowie podróżują parami w fotelach podwieszonych pod torem, pokonując pętle i ostre zakręty +STR_0586 :Wagoniki w kształcie łodzi jadą po torze z ostrymi zakrętami i stromymi zjazdami, a także pokonują odcinki spokojnie płynącej rzeki +STR_0587 :Po ekscytującym starcie z wyrzutni pneumatycznej, wagoniki wjeżdzają po pionowym torze, po czym wykonują pionowy zjazd w dół, z powrotem do stacji +STR_0588 :Pojedyncze wagoniki jeżdzą podwieszone pod torem z ostrymi zakrętami i gwałtownymi spadkami STR_0589 :Wielkie pojazdy stylizowane na latające dywany, które poruszają się cyklicznie w górę i w dół na końcach 4 ramion -STR_0590 :Goście jadą zanurzeni w łodzi podwodnej w podwodnym torze -STR_0591 :Łodzie wyglądające jak tratwy płynące leniwie przez tor rzeczny +STR_0590 :Pasażerowie usadowieni w łodzi podwodnej podróżują podwodnym torem +STR_0591 :Tratwy manewrujące zręcznie po wodnym torze STR_0593 :Obrotowe koło z zawieszonymi pasażerami, na początku zaczyna się kręcić, potem jest przechylane przez mocujące ramie -STR_0598 :Odwrócona kolejka górska, której wagoniki są rozpędzane na stacji, aby wjechać pionowym torem na szczyt toru, potem z powrotem przez stację, aby jechać odwrotnie na kolejny szczyt toru -STR_0599 :Kolejka górska z indywidualnymi pojazdami i łagodnymi zakręcanymi zjazdami -STR_0600 :Zasilane kopalniane wagoniki jeżdżące przez łagodne i pokręcone tory -STR_0602 :Kolejka górska, której wagoniki są rozpędzane na stacji liniowymi silnikami indukcyjnymi, aby szybko pokonywać zakręcone inwersje -STR_0603 :Drewniana kolejka górska ze stalowymi torami pozwalającymi na strome zjazdy i inwersje -STR_0604 :Goście jadą pojedynczymi wagonikami po wąskim torze, ścigając się po ostrych zakrętach i zmianach kieruków -STR_0605 :Saneczkarze zjeżdżają po wijącym się stalowym torze, hamując, aby kontrolować prędkość +STR_0598 :Wagoniki tego typu kolejki są rozpędzane na stacji, aby wjechać na szczyt pionowego toru, po czym zjeżdzają z niego, przejeżdzają z powrotem przez stację i wjeżdzają siłą rozpędu tyłem na drugi pionowy odcinek +STR_0599 :Zwarta przestrzennie kolejka z osobnymi wagonikami pokonującymi gładkie i zakręcone zjazdy +STR_0600 :Napędzane wagoniki kopalniane jadą po gładkim i zakręconym torze +STR_0602 :Wagoniki napędzane liniowymi silnikami indukcyjnymi, mknące przez zakręcone inwersje +STR_0603 :Drewniana kolejka górska ze stalowymi torami pozwalającymi na strome zjazdy i mocne inwersje +STR_0604 :Pasażerowie jadą pojedynczymi wagonikami po wąskim jednoszynowym torze, pokonując ostre zakręty i mocne inwersje +STR_0605 :Pasażerowie zjeżdżają po wijącym się stalowym torze, ręcznie hamując, aby kontrolować prędkość STR_0606 :Drewniana kolejka górska w starszym stylu, oferująca szybką i twardą jazdę z licznymi wzniesieniami i przeciążeniami bocznymi, co daje poczucie braku kontroli nad przejazdem -STR_0607 :Intensywna kolejka w starym stylu ze stalowymi torami, gdzie pasażerowie jadą na stojąco -STR_0608 :Kolejka górska, której wagoniki napędzane są synchronicznymi silnikami liniowymi, aby szybko pokonywać ciasne zakręty i inwersje +STR_0607 :Intensywna kolejka w starym stylu ze stalowymi torami, w której pasażerowie jadą na stojąco +STR_0608 :Wagoniki napędzane synchronicznymi silnikami liniowymi, mknące przez ciasne zakręty i inwersje STR_0767 :Gość {INT32} STR_0768 :Dozorca {INT32} STR_0769 :Mechanik {INT32} @@ -368,12 +368,12 @@ STR_0973 :OK STR_0974 :Atrakcje STR_0975 :Sklepy STR_0976 :Toalety i punkty informacyjne -STR_0977 :Zbuduj atrakcje transportowe -STR_0978 :Zbuduj łagodne atrakcje -STR_0979 :Zbuduj kolejki górskie -STR_0980 :Zbuduj intensywne atrakcje -STR_0981 :Zbuduj wodne atrakcje -STR_0982 :Zbuduj sklepiki lub stoiska +STR_0977 :Nowe atrakcje transportowe +STR_0978 :Nowe łagodne atrakcje +STR_0979 :Nowe kolejki górskie +STR_0980 :Nowe emocjonujące atrakcje +STR_0981 :Nowe wodne atrakcje +STR_0982 :Nowe sklepiki i kioski STR_0983 :Badania i rozwój STR_0984 :{WINDOW_COLOUR_2}▲{BLACK} {CURRENCY2DP} STR_0985 :{WINDOW_COLOUR_2}▼{BLACK} {CURRENCY2DP} @@ -383,10 +383,10 @@ STR_0988 :Nie można stworzyć nowej atrakcji… STR_0989 :{STRINGID} STR_0990 :Tryb budowania STR_0991 :Platforma ze stacją -STR_0992 :Zniszcz całą atrakcję -STR_0993 :Zniszcz atrakcję -STR_0994 :Zniszcz -STR_0995 :{WINDOW_COLOUR_1}Jesteś pewien, że chcesz zniszczyć {STRINGID}? +STR_0992 :Zburz całą atrakcję +STR_0993 :Zburz atrakcję +STR_0994 :Zburz +STR_0995 :{WINDOW_COLOUR_1}Jesteś pewien, że chcesz zburzyć {STRINGID}? STR_0996 :Widok ogólny STR_0997 :Wybór widoku STR_0998 :Nie można utworzyć więcej stacji dla tej atrakcji @@ -500,7 +500,7 @@ STR_1105 :Jedzie {VELOCITY} STR_1106 :Rozbija się! STR_1107 :Rozbity! STR_1108 :Jedzie {VELOCITY} -STR_1109 :Huśta +STR_1109 :Huśta się STR_1110 :Obraca się STR_1111 :Obraca się STR_1112 :Działa @@ -550,8 +550,8 @@ STR_1155 :Znaczniki wysokości chodników STR_1156 :{MOVE_X}{10}{STRINGID} STR_1157 :✓{MOVE_X}{10}{STRINGID} STR_1158 :Nie można tego usunąć… -STR_1159 :Buduj scenerię, rośliny i inne akcesoria -STR_1160 :Twórz i zmieniaj obszary wodne +STR_1159 :Rozmieszczaj scenerię, roślinność i inne ozdoby +STR_1160 :Twórz i zmieniaj zbiorniki wodne STR_1161 :Nie można tego tu umieścić… STR_1162 :{OUTLINE}{TOPAZ}{STRINGID} STR_1163 :{STRINGID}{NEWLINE}(Kliknij PPM by zmodyfikować) @@ -564,7 +564,7 @@ STR_1169 :(Brak) STR_1170 :{STRING} STR_1171 :{RED}Zamknięte STR_1172 :{YELLOW}{STRINGID} -STR_1173 :Budowa chodników +STR_1173 :Buduj dróżki i kolejki STR_1174 :Baner blokuje STR_1175 :Nie można tego postawić na nierównej ścieżce STR_1176 :Nie można tu zbudować ścieżki… @@ -585,9 +585,9 @@ STR_1190 :Usuń poprzednią sekcję ścieżki STR_1191 :{BLACK}{STRINGID} STR_1192 :{OUTLINE}{RED}{STRINGID} STR_1193 :{WINDOW_COLOUR_2}{STRINGID} -STR_1194 :Zamknięty -STR_1195 :Testowany -STR_1196 :Otwarty +STR_1194 :Zamknięte +STR_1195 :Testowane +STR_1196 :Otwarte STR_1197 :Awaria STR_1198 :Katastrofa! STR_1199 :{COMMA16} osoba korzysta @@ -595,8 +595,8 @@ STR_1200 :{COMMA16} osób korzysta STR_1201 :Kolejka pusta STR_1202 :1 osoba w kolejce STR_1203 :{COMMA16} - liczba osób w kolejce -STR_1204 :{COMMA16} minuta czekania -STR_1205 :{COMMA16} minut czekania +STR_1204 :{COMMA16} min. w kolejce +STR_1205 :{COMMA16} min. w kolejce STR_1206 :{WINDOW_COLOUR_2}Czekaj na: STR_1207 :{WINDOW_COLOUR_2}Wyrusz, gdy inna kolejka trafi na tą samą stację STR_1208 :{WINDOW_COLOUR_2}Wyrusz, gdy inna łódka trafi na tą samą stację @@ -727,9 +727,9 @@ STR_1332 :{VELOCITY} STR_1333 :{STRINGID} - {STRINGID}{POP16} STR_1334 :{STRINGID} - {STRINGID} {COMMA16} STR_1335 :{STRINGID} - Wejście{POP16}{POP16} -STR_1336 :{STRINGID} - Wjazd {POP16}{COMMA16} do stacji +STR_1336 :{STRINGID} - Wejście na {POP16}{COMMA16} stację STR_1337 :{STRINGID} - Wyjście{POP16}{POP16} -STR_1338 :{STRINGID} - Opuszczanie {POP16}{COMMA16} stacji +STR_1338 :{STRINGID} - Wyjście z {POP16}{COMMA16} stacji STR_1339 :{BLACK}Oczekiwanie na rezultaty testu… STR_1340 :{WINDOW_COLOUR_2}Maks. prędkość: {BLACK}{VELOCITY} STR_1341 :{WINDOW_COLOUR_2}Czas przejazdu: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} @@ -750,8 +750,8 @@ STR_1355 :{WINDOW_COLOUR_2}Spadki: {BLACK}{COMMA16} STR_1356 :{WINDOW_COLOUR_2}Inwersja: {BLACK}{COMMA16} STR_1357 :{WINDOW_COLOUR_2}Dołki: {BLACK}{COMMA16} STR_1358 :{WINDOW_COLOUR_2}Całkowity czas „w powietrzu”: {BLACK}{COMMA2DP32}sek. -STR_1359 :{WINDOW_COLOUR_2}Czas w kolejce: {BLACK}{COMMA16} minut -STR_1360 :{WINDOW_COLOUR_2}Czas w kolejce: {BLACK}{COMMA16} minut +STR_1359 :{WINDOW_COLOUR_2}Czas w kolejce: {BLACK}{COMMA16} min. +STR_1360 :{WINDOW_COLOUR_2}Czas w kolejce: {BLACK}{COMMA16} min. STR_1361 :Nie można zmienić prędkości… STR_1362 :Nie można zmienić prędkości startowej… STR_1363 :Za wysoko na wsporniki! @@ -823,7 +823,7 @@ STR_1428 :{WINDOW_COLOUR_2}Cena wstępu: STR_1429 :{POP16}{POP16}{POP16}{CURRENCY2DP} STR_1430 :Za darmo STR_1431 :Spaceruje -STR_1432 :Idzie na {STRINGID} +STR_1432 :Idzie w kierunku {STRINGID} STR_1433 :Czeka w kolejce na {STRINGID} STR_1434 :Tonie STR_1435 :Korzysta z atrakcji {STRINGID} @@ -859,7 +859,7 @@ STR_1464 :Spirala w górę (mała) STR_1465 :Spirala w górę (duża) STR_1466 :Spirala w dół (mała) STR_1467 :Spirala w dół (duża) -STR_1468 :Obsługa +STR_1468 :Personel STR_1469 :Atrakcja musi się zaczynać i kończyć stacją STR_1470 :Stacja jest za krótka STR_1471 :{WINDOW_COLOUR_2}Prędkość: @@ -880,9 +880,9 @@ STR_1485 :„{STRINGID} wygląda zbyt intensywne dla mnie” STR_1486 :„Nie skończyłem jeszcze {STRINGID}” STR_1487 :„{STRINGID} - od samego patrzenia robi mi się niedobrze” STR_1488 :„Nie zapłacę tyle za {STRINGID}” -STR_1489 :„Chcę już do domu” +STR_1489 :„Chcę wracać do domu” STR_1490 :„{STRINGID} ma naprawdę dobrą cenę” -STR_1491 :„Mam już {STRINGID}” +STR_1491 :„Już mam {STRINGID}” STR_1492 :„Nie mogę sobie pozwolić na {STRINGID}” STR_1493 :„Nie chce mi się jeść” STR_1494 :„Nie chce mi się pić” @@ -908,33 +908,33 @@ STR_1513 :„Wandalizm stanowi tutaj duży problem” STR_1514 :„Wspaniały krajobraz!” STR_1515 :„W tym parku jest naprawdę czysto i porządnie” STR_1516 :„Ta skacząca fontanna jest świetna” -STR_1517 :„Leci tutaj miła muzyka” -STR_1518 :„Ten balon z {STRINGID} był naprawdę opłacalny” -STR_1519 :„Ta przytulanka z {STRINGID} była naprawdę opłacalna” -STR_1520 :„Ta mapa parku z {STRINGID} była naprawdę opłacalna” -STR_1521 :„To zdjęcie z przejazdu na {STRINGID} było naprawdę opłacalne” -STR_1522 :„Ta parasolka z {STRINGID} była naprawdę opłacalna” -STR_1523 :„Ten napój z {STRINGID} był naprawdę opłacalny” -STR_1524 :„Ten burger z {STRINGID} był naprawdę opłacalny” -STR_1525 :„Te frytki z {STRINGID} były naprawdę opłacalne” -STR_1526 :„Te lody z {STRINGID} były naprawdę opłacalne” -STR_1527 :„Ta wata cukrowa {STRINGID} była naprawdę opłacalna” +STR_1517 :„Leci tutaj przyjemna muzyka” +STR_1518 :„Ten balon z {STRINGID} naprawdę się opłaca” +STR_1519 :„Ta przytulanka z {STRINGID} naprawdę się opłaca” +STR_1520 :„Ta mapa parku z {STRINGID} naprawdę się opłaca” +STR_1521 :„To zdjęcie z przejazdu na {STRINGID} naprawdę się opłaca” +STR_1522 :„Ta parasolka z {STRINGID} naprawdę się opłaca” +STR_1523 :„Ten napój z {STRINGID} naprawdę się opłaca” +STR_1524 :„Ten burger z {STRINGID} naprawdę się opłaca” +STR_1525 :„Te frytki z {STRINGID} naprawdę się opłacają” +STR_1526 :„Te lody z {STRINGID} naprawdę się opłacają” +STR_1527 :„Ta wata cukrowa {STRINGID} naprawdę się opłaca” STR_1528 : STR_1529 : STR_1530 : -STR_1531 :„Ta pizza z {STRINGID} była naprawdę opłacalna” +STR_1531 :„Ta pizza z {STRINGID} naprawdę się opłaca” STR_1532 : -STR_1533 :„Ten popcorn z {STRINGID} był naprawdę opłacalny” -STR_1534 :„Ten hotdog z {STRINGID} był naprawdę opłacalny” -STR_1535 :„Ta ośmiorniczka z {STRINGID} była naprawdę opłacalna” -STR_1536 :„Ten kapelusz {STRINGID} był naprawdę opłacalny” -STR_1537 :„To kandyzowane jabłko z {STRINGID} było naprawdę opłacalne” -STR_1538 :„Ten t-shirt z {STRINGID} był naprawdę opłacalny” -STR_1539 :„Ten pączek z {STRINGID} był naprawdę opłacalny” -STR_1540 :„Ta kawa z {STRINGID} była naprawdę opłacalna” +STR_1533 :„Ten popcorn z {STRINGID} naprawdę się opłaca” +STR_1534 :„Ten hotdog z {STRINGID} naprawdę się opłaca” +STR_1535 :„Ta macka z {STRINGID} naprawdę się opłaca” +STR_1536 :„Ten kapelusz {STRINGID} naprawdę się opłaca” +STR_1537 :„To jabłko w polewie z {STRINGID} naprawdę się opłaca” +STR_1538 :„Ta koszulka z {STRINGID} naprawdę się opłaca” +STR_1539 :„Ten pączek z {STRINGID} naprawdę się opłaca” +STR_1540 :„Ta kawa z {STRINGID} naprawdę się opłaca” STR_1541 : -STR_1542 :„Ten smażony kurczak z {STRINGID} był naprawdę opłacalny” -STR_1543 :„Ta lemoniada z {STRINGID} była naprawdę opłacalna” +STR_1542 :„Ten kurczak z {STRINGID} naprawdę się opłaca” +STR_1543 :„Ta lemoniada z {STRINGID} naprawdę się opłaca” STR_1544 : STR_1545 : STR_1546 : @@ -975,27 +975,27 @@ STR_1580 : STR_1581 : STR_1582 : STR_1583 : -STR_1584 :„To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” -STR_1585 :„To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” -STR_1586 :„To zdjęcie z przejażdżki na {STRINGID} było naprawdę opłacalne” -STR_1587 :„Ten precel z {STRINGID} był naprawdę opłacalny” -STR_1588 :„Ta gorąca czekolada z {STRINGID} była naprawdę opłacalna” -STR_1589 :„Ta mrożona herbata z {STRINGID} była naprawdę opłacalna” -STR_1590 :„Ten precel z {STRINGID} był naprawdę opłacalny” -STR_1591 :„Te okulary przeciwsłoneczne z {STRINGID} były naprawdę opłacalne” -STR_1592 :„Ten makaron z wołowiną z {STRINGID} był naprawdę opłacalny” -STR_1593 :„Ten smażony makaron z {STRINGID} był naprawdę opłacalny” -STR_1594 :„Ta zupa wonton z {STRINGID} była naprawdę opłacalna” -STR_1595 :„Ta zupa z klopsikami z {STRINGID} była naprawdę opłacalna” -STR_1596 :„Ten sok owocowy z {STRINGID} był naprawdę opłacalny” -STR_1597 :„Te mleko sojowe z {STRINGID} było naprawdę opłacalne” -STR_1598 :„Ta sujongkwa z {STRINGID} była naprawdę opłacalna” -STR_1599 :„Ta kanapka z {STRINGID} była naprawdę opłacalna” -STR_1600 :„To ciasteczko z {STRINGID} było naprawdę opłacalne” +STR_1584 :„To zdjęcie z przejażdżki na {STRINGID} naprawdę się opłaca” +STR_1585 :„To zdjęcie z przejażdżki na {STRINGID} naprawdę się opłaca” +STR_1586 :„To zdjęcie z przejażdżki na {STRINGID} naprawdę się opłaca” +STR_1587 :„Ten precel z {STRINGID} naprawdę się opłaca” +STR_1588 :„Ta gorąca czekolada z {STRINGID} naprawdę się opłaca” +STR_1589 :„Ta mrożona herbata z {STRINGID} naprawdę się opłaca” +STR_1590 :„Te faworki z {STRINGID} naprawdę się opłacają” +STR_1591 :„Te okulary przeciwsłoneczne z {STRINGID} naprawdę się opłacają” +STR_1592 :„Ten makaron z wołowiną z {STRINGID} naprawdę się opłaca” +STR_1593 :„Ten smażony makaron z {STRINGID} naprawdę się opłaca” +STR_1594 :„Ta zupa wonton z {STRINGID}naprawdę się opłaca” +STR_1595 :„Ta zupa z klopsikami z {STRINGID} naprawdę się opłaca” +STR_1596 :„Ten sok owocowy z {STRINGID} naprawdę się opłaca” +STR_1597 :„To mleko sojowe z {STRINGID} naprawdę się opłaca” +STR_1598 :„Ta sujongkwa z {STRINGID} naprawdę się opłaca” +STR_1599 :„Ta kanapka z {STRINGID} naprawdę się opłaca” +STR_1600 :„To ciasteczko z {STRINGID} naprawdę się opłaca” STR_1601 : STR_1602 : STR_1603 : -STR_1604 :„Ta grillowana kiełbasa z {STRINGID} była naprawdę opłacalna” +STR_1604 :„Ta pieczona kiełbaska z {STRINGID} naprawdę się opłaca” STR_1605 : STR_1606 : STR_1607 : @@ -1013,7 +1013,7 @@ STR_1618 :„Nie zapłacę tyle za zdjęcie z przejażdżki na {STRINGID}” STR_1619 :„Nie zapłacę tyle za precla z {STRINGID}” STR_1620 :„Nie zapłacę tyle za gorącą czekoladę z {STRINGID}” STR_1621 :„Nie zapłacę tyle za mrożoną herbatę z {STRINGID}” -STR_1622 :„Nie zapłacę tyle za chrusta z {STRINGID}” +STR_1622 :„Nie zapłacę tyle za faworki z {STRINGID}” STR_1623 :„Nie zapłacę tyle za okulary przeciwsłoneczne z {STRINGID}” STR_1624 :„Nie zapłacę tyle za makaron z wołowiną z {STRINGID}” STR_1625 :„Nie zapłacę tyle za smażony makaron ryżowy z {STRINGID}” @@ -1027,7 +1027,7 @@ STR_1632 :„Nie zapłacę tyle za ciasteczko z {STRINGID}” STR_1633 : STR_1634 : STR_1635 : -STR_1636 :„Nie zapłacę tyle za grillowaną kiełbasę z {RINGID}” +STR_1636 :„Nie zapłacę tyle za pieczoną kiełbaskę z {RINGID}” STR_1637 : STR_1638 : STR_1639 : @@ -1059,7 +1059,7 @@ STR_1666 :{WINDOW_COLOUR_2}Pragnienie: STR_1667 :{WINDOW_COLOUR_2}Pęcherz: STR_1668 :{WINDOW_COLOUR_2}Zadowolenie {BLACK}Nieznane STR_1669 :{WINDOW_COLOUR_2}Zadowolenie: {BLACK}{COMMA16}% -STR_1670 :{WINDOW_COLOUR_2}Wszystkich klientów: {BLACK}{COMMA32} +STR_1670 :{WINDOW_COLOUR_2}Łączna liczba klientów: {BLACK}{COMMA32} STR_1671 :{WINDOW_COLOUR_2}Całkowity zysk: {BLACK}{CURRENCY2DP} STR_1672 :Hamulce STR_1673 :Tor opcji blokowania obrotów @@ -1192,7 +1192,7 @@ STR_1806 :Awaria hamulców STR_1807 :Awaria systemu sterowania STR_1808 :{WINDOW_COLOUR_2}Poprzednia awaria: {BLACK}{STRINGID} STR_1809 :{WINDOW_COLOUR_2}Aktualna awaria: {OUTLINE}{RED}{STRINGID} -STR_1810 :{WINDOW_COLOUR_2}Nosi: +STR_1810 :{WINDOW_COLOUR_2}Niesie: STR_1811 :Nie można tego tutaj wybudować… STR_1812 :{BLACK}{STRINGID} STR_1813 :Różne obiekty @@ -1213,10 +1213,10 @@ STR_1827 :Popularność STR_1828 :Satysfakcja STR_1829 :Zysk STR_1830 :Długość kolejki -STR_1831 :Czas w kolejce +STR_1831 :Czas oczekiwania STR_1832 :Niezawodność STR_1833 :Przestoje -STR_1834 :Ulubieniec gości +STR_1834 :Ulubiona atrakcja STR_1835 :Popularność: Nieznana STR_1836 :Popularność: {COMMA16}% STR_1837 :Satysfakcja: Nieznana @@ -1224,14 +1224,14 @@ STR_1838 :Satysfakcja: {COMMA16}% STR_1839 :Niezawodność: {COMMA16}% STR_1840 :Przestoje w pracy: {COMMA16}% STR_1841 :Zysk: {CURRENCY} na godzinę -STR_1842 :Ulubiony dla: {COMMA32} gościa -STR_1843 :Ulubiony dla: {COMMA32} gości +STR_1842 :Ulubiona atrakcja {COMMA32} gościa +STR_1843 :Ulubiona atrakcja {COMMA32} gości STR_1844 :Wybierz rodzaj informacji do pokazania STR_1845 :{MONTHYEAR} STR_1846 :{COMMA32} gości STR_1847 :{INLINE_SPRITE}{11}{20}{00}{00}{COMMA32} gości STR_1848 :{INLINE_SPRITE}{10}{20}{00}{00}{COMMA32} gości -STR_1849 :{WINDOW_COLOUR_2}Odtwarzaj muzykę +STR_1849 :{WINDOW_COLOUR_2}Włącz muzykę STR_1850 :Wybierz, czy na tej atrakcji ma grać muzyka STR_1851 :{WINDOW_COLOUR_2}Koszty utrzymania: {BLACK}{CURRENCY2DP} na godzinę STR_1852 :{WINDOW_COLOUR_2}Koszty utrzymania: {BLACK}Nieznane @@ -1273,8 +1273,8 @@ STR_1888 :{WINDOW_COLOUR_2}Termin ostatniej inspekcji: {BLACK} więcej niż 4 STR_1889 :{WINDOW_COLOUR_2}Czas przestoju: {MOVE_X}{255}{BLACK}{COMMA16}% STR_1890 :Określ jak często mechanik ma przeglądać tę atrakcję STR_1891 :Nie ma jeszcze {STRINGID} w parku! -STR_1894 :{WINDOW_COLOUR_2}{STRINGID} sprzedane: {BLACK}{COMMA32} -STR_1895 :Wybuduj nową przejażdżkę/atrakcję +STR_1894 :{WINDOW_COLOUR_2}Sprzedane {STRINGID}: {BLACK}{COMMA32} +STR_1895 :Zbuduj nową atrakcję STR_1896 :{WINDOW_COLOUR_2}Przychody/wydatki STR_1897 :{WINDOW_COLOUR_2}Budowa atrakcji STR_1898 :{WINDOW_COLOUR_2}Utrzymanie atrakcji @@ -1306,7 +1306,7 @@ STR_1924 :Wyjdź STR_1925 :Nie można postawić tutaj osoby… STR_1927 :{YELLOW}{STRINGID} zepsuł(a) się STR_1928 :{RED}{STRINGID} miał(a) wypadek! -STR_1929 :{RED}Atrakcja {STRINGID} wciąż nie został(a) naprawiony(a).{NEWLINE}Sprawdź gdzie znajdują się twoi mechanicy i rozważ lepszą organizację ich pracy +STR_1929 :{RED}Wciąż nie naprawiono {STRINGID}.{NEWLINE}Sprawdź gdzie znajdują się twoi mechanicy i rozważ lepszą organizację ich pracy STR_1930 :Wł/wył. informacje o tym gościu (jeśli śledzenie jest włączone działania gościa będą wyświetlane w oknie wiadomości) STR_1931 :{STRINGID} stanął w kolejce do atrakcji {STRINGID} STR_1932 :{STRINGID} jest na atrakcji {STRINGID} @@ -1340,13 +1340,13 @@ STR_1959 :Nie mogę zmienić liczby okrążeń… STR_1960 :{WINDOW_COLOUR_2}Cena balonu: STR_1961 :{WINDOW_COLOUR_2}Cena przytulanki: STR_1962 :{WINDOW_COLOUR_2}Cena planu parku: -STR_1963 :{WINDOW_COLOUR_2}Cena zdjęcia z przejażdżki: +STR_1963 :{WINDOW_COLOUR_2}Cena zdjęcia: STR_1964 :{WINDOW_COLOUR_2}Cena parasola: STR_1965 :{WINDOW_COLOUR_2}Cena napoju: STR_1966 :{WINDOW_COLOUR_2}Cena hamburgera: STR_1967 :{WINDOW_COLOUR_2}Cena frytek: STR_1968 :{WINDOW_COLOUR_2}Cena lodów: -STR_1969 :{WINDOW_COLOUR_2}Cena waty cukrowej: +STR_1969 :{WINDOW_COLOUR_2}Cena waty: STR_1970 :{WINDOW_COLOUR_2} STR_1971 :{WINDOW_COLOUR_2} STR_1972 :{WINDOW_COLOUR_2} @@ -1354,10 +1354,10 @@ STR_1973 :{WINDOW_COLOUR_2}Cena pizzy: STR_1974 :{WINDOW_COLOUR_2} STR_1975 :{WINDOW_COLOUR_2}Cena popcornu: STR_1976 :{WINDOW_COLOUR_2}Cena hot-doga: -STR_1977 :{WINDOW_COLOUR_2}Cena ośmiorniczki: +STR_1977 :{WINDOW_COLOUR_2}Cena macki: STR_1978 :{WINDOW_COLOUR_2}Cena kapelusza: -STR_1979 :{WINDOW_COLOUR_2}Cena jabłka kand.: -STR_1980 :{WINDOW_COLOUR_2}Cena podkoszulki: +STR_1979 :{WINDOW_COLOUR_2}Cena jabłka: +STR_1980 :{WINDOW_COLOUR_2}Cena koszulki: STR_1981 :{WINDOW_COLOUR_2}Cena pączka: STR_1982 :{WINDOW_COLOUR_2}Cena kawy: STR_1983 :{WINDOW_COLOUR_2} @@ -1365,213 +1365,213 @@ STR_1984 :{WINDOW_COLOUR_2}Cena kurczaka: STR_1985 :{WINDOW_COLOUR_2}Cena lemoniady: STR_1986 :{WINDOW_COLOUR_2} STR_1987 :{WINDOW_COLOUR_2} -STR_1988 :Balon -STR_1989 :Przytulanka -STR_1990 :Plan parku -STR_1991 :Zdjęcie z przejażdżki -STR_1992 :Parasol -STR_1993 :Napój -STR_1994 :Hamburger -STR_1995 :Frytki -STR_1996 :Lody -STR_1997 :Wata cukrowa -STR_1998 :Pusta puszka -STR_1999 :Śmieci -STR_2000 :Puste pudełko po hamburgerze -STR_2001 :Pizza -STR_2002 :Kupon -STR_2003 :Popcorn -STR_2004 :Hot Dog -STR_2005 :Ośmiorniczka -STR_2006 :Kapelusz -STR_2007 :Jabłko kandyzowane -STR_2008 :Koszulka -STR_2009 :Pączek -STR_2010 :Kawa -STR_2011 :Pusty kubek -STR_2012 :Kurczak -STR_2013 :Lemoniada -STR_2014 :Puste pudełko -STR_2015 :Pusta butelka -STR_2016 :Balony -STR_2017 :Przytulanki -STR_2018 :Plany parku -STR_2019 :Zdjęcia z przejażdżki -STR_2020 :Parasole -STR_2021 :Napoje -STR_2022 :Hamburgery -STR_2023 :Frytki -STR_2024 :Lody -STR_2025 :Wata cukrowa -STR_2026 :Puste puszki -STR_2027 :Śmieci -STR_2028 :Puste pudełka po hamburgerach -STR_2029 :Pizze -STR_2030 :Kupony -STR_2031 :Popcorn -STR_2032 :Hot dogi -STR_2033 :Ośmiorniczki -STR_2034 :Kapelusze -STR_2035 :Jabłka kandyzowane -STR_2036 :Koszulki -STR_2037 :Pączki -STR_2038 :Kawy -STR_2039 :Puste kubki -STR_2040 :Kurczak -STR_2041 :Lemoniada +STR_1988 :balona +STR_1989 :przytulanki +STR_1990 :planu parku +STR_1991 :zdjęcia z przejażdżki +STR_1992 :parasola +STR_1993 :napoju +STR_1994 :hamburgera +STR_1995 :frytek +STR_1996 :lodów +STR_1997 :waty cukrowej +STR_1998 :pustej puszki +STR_1999 :śmieci +STR_2000 :pustego pudełka po burgerze +STR_2001 :pizzy +STR_2002 :kuponu +STR_2003 :popcornu +STR_2004 :hot doga +STR_2005 :macki +STR_2006 :kapelusza +STR_2007 :jabłka w polewie +STR_2008 :koszulki +STR_2009 :pączka +STR_2010 :kawy +STR_2011 :pustego kubka +STR_2012 :kurczaka +STR_2013 :lemoniady +STR_2014 :pustego pudełka +STR_2015 :pustej butelki +STR_2016 :balony +STR_2017 :przytulanki +STR_2018 :plany parku +STR_2019 :zdjęcia z przejażdzek +STR_2020 :parasole +STR_2021 :napoje +STR_2022 :hamburgery +STR_2023 :frytki +STR_2024 :lody +STR_2025 :waty cukrowe +STR_2026 :puste puszki +STR_2027 :śmieci +STR_2028 :puste pudełka po burgerach +STR_2029 :pizze +STR_2030 :kupony +STR_2031 :popcorny +STR_2032 :hot dogi +STR_2033 :macki +STR_2034 :kapelusze +STR_2035 :jabłka w polewie +STR_2036 :koszulki +STR_2037 :pączki +STR_2038 :kawy +STR_2039 :puste kubki +STR_2040 :kurczaki +STR_2041 :lemoniady STR_2042 :Puste pudełka STR_2043 :Puste butelki -STR_2044 :balon -STR_2045 :przytulanka +STR_2044 :balona +STR_2045 :przytulankę STR_2046 :plan parku STR_2047 :zdjęcie z przejażdżki STR_2048 :parasol STR_2049 :napój STR_2050 :hamburgera -STR_2051 :trochę frytek +STR_2051 :frytki STR_2052 :lody -STR_2053 :trochę waty cukrowej +STR_2053 :watę cukrową STR_2054 :pustą puszkę STR_2055 :trochę śmieci STR_2056 :puste pudełko po hamburgerze -STR_2057 :pizza +STR_2057 :pizzę STR_2058 :kupon -STR_2059 :trochę popcornu -STR_2060 :Hot Dog -STR_2061 :Macka -STR_2062 :Kapelusz -STR_2063 :jabłko kandyzowane -STR_2064 :koszulka -STR_2065 :Pączek -STR_2066 :Kawa +STR_2059 :popcorn +STR_2060 :hot doga +STR_2061 :mackę +STR_2062 :kapelusz +STR_2063 :jabłko w polewie +STR_2064 :koszulkę +STR_2065 :pączka +STR_2066 :kawę STR_2067 :pusty kubek -STR_2068 :Kurczak -STR_2069 :trochę lemoniady +STR_2068 :kurczaka +STR_2069 :lemoniadę STR_2070 :puste pudełko STR_2071 :pustą butelkę -STR_2072 :Balon {STRINGID} -STR_2073 :Przytulanka {STRINGID} -STR_2074 :Plan {STRINGID} -STR_2075 :Zdjęcie z przejażdżki na {STRINGID} -STR_2076 :Parasol {STRINGID} -STR_2077 :Napój -STR_2078 :Hamburger -STR_2079 :Frytki -STR_2080 :Lody -STR_2081 :Wata cukrowa -STR_2082 :Pusta puszka -STR_2083 :Śmieci -STR_2084 :Puste pudełko po hamburgerze -STR_2085 :Pizza -STR_2086 :Kupon na {STRINGID} -STR_2087 :Popcorn -STR_2088 :Hot Dog -STR_2089 :Ośmiorniczka -STR_2090 :Kapelusz {STRINGID} -STR_2091 :Jabłko kandyzowane -STR_2092 :Koszulka {STRINGID} -STR_2093 :Pączek -STR_2094 :Kawa -STR_2095 :Pusty kubek -STR_2096 :Kurczak -STR_2097 :Lemoniada -STR_2098 :Puste pudełko -STR_2099 :Pusta butelka +STR_2072 :balona {STRINGID} +STR_2073 :przytulankę {STRINGID} +STR_2074 :plan {STRINGID} +STR_2075 :zdjęcie z przejażdżki na {STRINGID} +STR_2076 :parasol {STRINGID} +STR_2077 :napój +STR_2078 :hamburgera +STR_2079 :frytki +STR_2080 :lody +STR_2081 :watę cukrową +STR_2082 :pustą puszkę +STR_2083 :śmieci +STR_2084 :puste pudełko po hamburgerze +STR_2085 :pizzę +STR_2086 :kupon na {STRINGID} +STR_2087 :popcorn +STR_2088 :hot doga +STR_2089 :mackę +STR_2090 :kapelusz {STRINGID} +STR_2091 :jabłko w polewie +STR_2092 :koszulkę {STRINGID} +STR_2093 :pączka +STR_2094 :kawę +STR_2095 :pusty kubek +STR_2096 :kurczaka +STR_2097 :lemoniadę +STR_2098 :puste pudełko +STR_2099 :pustą butelkę STR_2103 :{WINDOW_COLOUR_2}Cena precla: -STR_2104 :{WINDOW_COLOUR_2}Cena gorącej czekolady: -STR_2105 :{WINDOW_COLOUR_2}Cena mrożonej herbaty: -STR_2106 :{WINDOW_COLOUR_2}Cena makaronika: +STR_2104 :{WINDOW_COLOUR_2}Cena czekolady: +STR_2105 :{WINDOW_COLOUR_2}Cena herbaty: +STR_2106 :{WINDOW_COLOUR_2}Cena faworków: STR_2107 :{WINDOW_COLOUR_2}Cena okularów: -STR_2108 :{WINDOW_COLOUR_2}Cena makaronu z wołowiną: -STR_2109 :{WINDOW_COLOUR_2}Cena smażonej ryby: -STR_2110 :{WINDOW_COLOUR_2}Cena zupy wonton: -STR_2111 :{WINDOW_COLOUR_2}Cena zupy klopsikowej: -STR_2112 :{WINDOW_COLOUR_2}Cena soku owocowego: -STR_2113 :{WINDOW_COLOUR_2}Cena mleka sojowego: +STR_2108 :{WINDOW_COLOUR_2}Cena makaronu: +STR_2109 :{WINDOW_COLOUR_2}Cena ryby: +STR_2110 :{WINDOW_COLOUR_2}Cena zupy: +STR_2111 :{WINDOW_COLOUR_2}Cena zupy: +STR_2112 :{WINDOW_COLOUR_2}Cena soku: +STR_2113 :{WINDOW_COLOUR_2}Cena mleka: STR_2114 :{WINDOW_COLOUR_2}Cena sujongkwa: STR_2115 :{WINDOW_COLOUR_2}Cena kanapki: STR_2116 :{WINDOW_COLOUR_2}Cena ciasteczka: STR_2117 :{WINDOW_COLOUR_2} STR_2118 :{WINDOW_COLOUR_2} STR_2119 :{WINDOW_COLOUR_2} -STR_2120 :{WINDOW_COLOUR_2}Cena grillowanych kiełbasek: +STR_2120 :{WINDOW_COLOUR_2}Cena kiełbaski: STR_2121 :{WINDOW_COLOUR_2} -STR_2125 :Precel -STR_2126 :Gorąca czekolada -STR_2127 :Mrożona herbata -STR_2128 :Makaronik -STR_2129 :Okulary przeciwsłoneczne -STR_2130 :Makaron z wołowiną -STR_2131 :Smażony makaron ryżowy -STR_2132 :Zupa wonton -STR_2133 :Zupa klopsikowa -STR_2134 :Sok owocowy -STR_2135 :Mleko sojowe -STR_2136 :Sujongkwa -STR_2137 :Kanapka -STR_2138 :Ciasteczko -STR_2139 :Pusta miska -STR_2140 :Pusty karton -STR_2141 :Pusty kubek po soku -STR_2142 :Grillowana kiełbaska -STR_2143 :Pusta miska -STR_2147 :Precle -STR_2148 :Gorące czekolady -STR_2149 :Mrożone herbaty -STR_2150 :Makaroniki -STR_2151 :Okulary przeciwsłoneczne -STR_2152 :Makaron z wołowiną -STR_2153 :Smażony makaron ryżowy -STR_2154 :Zupy wonton -STR_2155 :Klopsiki -STR_2156 :Soki owocowe -STR_2157 :Mleko sojowe -STR_2158 :Sujongkwa -STR_2159 :Kanapki -STR_2160 :Ciasteczka -STR_2161 :Puste miski -STR_2162 :Puste kartony -STR_2163 :Puste kubki po soku -STR_2164 :Pieczone kiełbaski -STR_2165 :Puste miski +STR_2125 :precla +STR_2126 :gorącej czekolady +STR_2127 :mrożonej herbaty +STR_2128 :faworków +STR_2129 :okularów przeciwsłonecznych +STR_2130 :makaronu z wołowiną +STR_2131 :smażonego makaronu ryżowego +STR_2132 :zupy wonton +STR_2133 :zupy klopsikowej +STR_2134 :soku owocowego +STR_2135 :mleka sojowego +STR_2136 :sujongkwy +STR_2137 :kanapki +STR_2138 :ciasteczka +STR_2139 :pustej miski +STR_2140 :pustego kartonu +STR_2141 :pustego kubka po soku +STR_2142 :pieczonej kiełbaski +STR_2143 :pustej miski +STR_2147 :precle +STR_2148 :gorące czekolady +STR_2149 :mrożone herbaty +STR_2150 :faworki +STR_2151 :okulary przeciwsłoneczne +STR_2152 :makarony z wołowiną +STR_2153 :smażone makarony ryżowe +STR_2154 :zupy wonton +STR_2155 :klopsiki +STR_2156 :soki owocowe +STR_2157 :mleka sojowe +STR_2158 :sujongkwy +STR_2159 :kanapki +STR_2160 :ciasteczka +STR_2161 :puste miski +STR_2162 :puste kartony +STR_2163 :puste kubki po soku +STR_2164 :pieczone kiełbaski +STR_2165 :puste miski STR_2169 :precla -STR_2170 :gorącą czekoladą -STR_2171 :herbat +STR_2170 :gorącą czekoladę +STR_2171 :herbatę STR_2172 :marakonik STR_2173 :okulary -STR_2174 :trochę makaronu z wołowiną -STR_2175 :trochę smażonego makaronu ryżowego -STR_2176 :trochę zupy wonton -STR_2177 :trochę zupy klopsikowej +STR_2174 :makaron z wołowiną +STR_2175 :smażony makaron ryżowy +STR_2176 :zupę wonton +STR_2177 :zupę klopsikową STR_2178 :sok owocowy -STR_2179 :trochę mleka sojowego -STR_2180 :trochę Sujongkwa -STR_2181 :kanapka +STR_2179 :mleko sojowe +STR_2180 :sujongkwę +STR_2181 :kanapkę STR_2182 :ciasteczko -STR_2183 :Pusta miseczka -STR_2184 :Pusty kartonik po napoju -STR_2185 :Pusty kubeczek po soku -STR_2186 :Grillowana kiełbasa -STR_2187 :pusta miseczka -STR_2191 :Precel -STR_2192 :Gorąca czekolada -STR_2193 :Mrożona herbata -STR_2194 :Chrusty -STR_2195 :Okulary przeciwsłoneczne -STR_2196 :Makaron z wołowiną -STR_2197 :Smażony makaron ryżowy -STR_2198 :Zupa Wonton -STR_2199 :Zupa z klopsikami -STR_2200 :Sok owocowy -STR_2201 :Mleko sojowe -STR_2202 :Sujongkwa -STR_2203 :Kanapka -STR_2204 :Ciasteczko -STR_2205 :Pusta miseczka -STR_2206 :Pusty kartonik po napoju -STR_2207 :Pusty kubeczek po soku -STR_2208 :Grillowana kiełbasa -STR_2209 :Pusta miseczka +STR_2183 :pusta miskę +STR_2184 :pusty karton po napoju +STR_2185 :pusty kubek po soku +STR_2186 :pieczoną kiełbaskę +STR_2187 :pustą miskę +STR_2191 :precla +STR_2192 :gorącą czekoladę +STR_2193 :mrożoną herbatę +STR_2194 :faworki +STR_2195 :okulary przeciwsłoneczne +STR_2196 :makaron z wołowiną +STR_2197 :smażony makaron ryżowy +STR_2198 :zupę wonton +STR_2199 :zupę z klopsikami +STR_2200 :sok owocowy +STR_2201 :mleko sojowe +STR_2202 :sujongkwę +STR_2203 :kanapkę +STR_2204 :ciasteczko +STR_2205 :pustą miskę +STR_2206 :pusty karton po napoju +STR_2207 :pusty kubek po soku +STR_2208 :pieczoną kiełbaskę +STR_2209 :pusta miska STR_2210 :Pokaż listę wszystkich dozorców w parku STR_2211 :Pokaż listę wszystkich mechaników w parku STR_2212 :Pokaż listę wszystkich strażników w parku @@ -1583,9 +1583,9 @@ STR_2217 :{WINDOW_COLOUR_2}{COMMA16}°F STR_2218 :{RED}{STRINGID} na {STRINGID} jeszcze nie powrócił do {STRINGID}!{NEWLINE}Sprawdź czy gdzieś nie utknął. STR_2219 :{RED}{COMMA16} ludzi zginęło w wypadku na atrakcji {STRINGID} STR_2220 :{WINDOW_COLOUR_2}Ocena parku: {BLACK}{COMMA16} -STR_2221 :Ocena Parku: {COMMA16} +STR_2221 :Atrakcyjność Parku: {COMMA16} STR_2222 :{BLACK}{STRINGID} -STR_2223 :{WINDOW_COLOUR_2}Gości w parku: {BLACK}{COMMA32} +STR_2223 :{WINDOW_COLOUR_2}Liczba gości w parku: {BLACK}{COMMA32} STR_2224 :{WINDOW_COLOUR_2}Gotówka: {BLACK}{CURRENCY2DP} STR_2225 :{WINDOW_COLOUR_2}Gotówka: {RED}{CURRENCY2DP} STR_2226 :{WINDOW_COLOUR_2}Wartość parku: {BLACK}{CURRENCY} @@ -1596,7 +1596,7 @@ STR_2230 :Pionowa trasa STR_2231 :Hamowanie podczas opadania STR_2232 :Wyciągarka linowa STR_2233 :Informacje o parku -STR_2234 :Najnowsze wiadomości +STR_2234 :Ostatnie wiadomości STR_2235 :{STRINGID} {STRINGID} STR_2236 :Styczeń STR_2237 :Luty @@ -1611,25 +1611,25 @@ STR_2245 :Październik STR_2246 :Listopad STR_2247 :Grudzień STR_2248 :Nie można zburzyć atrakcji… -STR_2249 :{BABYBLUE}Nowa atrakcja dostępna:{NEWLINE}{STRINGID} -STR_2250 :{BABYBLUE}Nowa sceneria dostępna:{NEWLINE}{STRINGID} +STR_2249 :{BABYBLUE}Dostępna nowa atrakcja:{NEWLINE}{STRINGID} +STR_2250 :{BABYBLUE}Dostępna nowa sceneria:{NEWLINE}{STRINGID} STR_2251 :Można budować tylko na chodnikach! STR_2252 :Można budować tylko w poprzek chodników! STR_2253 :Transport STR_2254 :Łagodne atrakcje STR_2255 :Kolejki górskie -STR_2256 :Intensywne atrakcje +STR_2256 :Emocjonujące atrakcje STR_2257 :Wodne atrakcje STR_2258 :Sklepiki i kioski STR_2259 :Scenerie i dekoracje -STR_2260 :Bez budżetu -STR_2261 :Minimalny -STR_2262 :Normalny -STR_2263 :Maksymalny -STR_2264 :Budżet na badania +STR_2260 :Brak funduszy +STR_2261 :Minimalne fundusze +STR_2262 :Normalne fundusze +STR_2263 :Maksymalne fundusze +STR_2264 :Fundusze na badania STR_2265 :{WINDOW_COLOUR_2}Koszt: {BLACK}{CURRENCY} na miesiąc STR_2266 :Priorytety badawcze -STR_2267 :Obecnie badany +STR_2267 :Obecnie badane STR_2268 :Ostatnie odkrycie STR_2269 :{WINDOW_COLOUR_2}Typ: {BLACK}{STRINGID} STR_2270 :{WINDOW_COLOUR_2}Stan prac: {BLACK}{STRINGID} @@ -1643,7 +1643,7 @@ STR_2277 :Nieznany STR_2278 :Transport STR_2279 :Łagodne atrakcje STR_2280 :Kolejki górskie -STR_2281 :Intensywne atrakcje +STR_2281 :Emocjonujące atrakcje STR_2282 :Wodne atrakcje STR_2283 :Sklepiki i kioski STR_2284 :Scenerie i dekoracje @@ -1934,7 +1934,7 @@ STR_2707 :Otwórz nowe okno STR_2708 :{WINDOW_COLOUR_1}Jesteś pewien, że chcesz nadpisać {STRINGID}? STR_2709 :Nadpisz STR_2710 :Wpisz nazwę pliku -STR_2718 :Up +STR_2718 :W górę STR_2719 :Nowy plik STR_2720 :{UINT16}sek STR_2721 :{UINT16}sek @@ -2186,7 +2186,7 @@ STR_3144 :Pokaż atrakcje i stoiska STR_3160 :Wybierz liczbę obrotów na przejażdżkę STR_3162 :Nie można zaalokować odpowiedniej ilości pamięci STR_3163 :Instalowanie nowych danych: -STR_3164 :{BLACK}{COMMA16} wybrano (maksymalnie {COMMA16}) +STR_3164 :{BLACK}Wybrano {COMMA16} (maksymalnie {COMMA16}) STR_3167 :{WINDOW_COLOUR_2}Zawiera: {BLACK}{COMMA16} obiektów STR_3169 :Nie znaleziono danych dla obiektu: STR_3170 :Brak odpowiedniej ilości pamięci na grafikę @@ -2199,7 +2199,7 @@ STR_3176 :Nie można wybrać tego obiektu STR_3177 :Nie można odznaczyć tego obiektu STR_3179 :Przynajmniej jedna atrakcja musi zostać wybrana STR_3180 :Nieprawidłowy wybór obiektów -STR_3181 :Wybór obiektu - {STRINGID} +STR_3181 :Wybór obiektów - {STRINGID} STR_3182 :Wejście do parku musi zostać wybrane STR_3183 :Rodzaj wody musi zostać wybrany STR_3184 :Atrakcje przejazdowe/pojazdy @@ -2218,8 +2218,8 @@ STR_3197 :{WINDOW_COLOUR_2}Rzeczy wynalezione na początku gry: STR_3198 :{WINDOW_COLOUR_2}Rzeczy do wynalezienia podczas gry: STR_3199 :Losowe sortowanie STR_3200 :Losowe sortowanie rzeczy do wynalezienia w grze -STR_3201 :Wybór obiektu -STR_3202 :Edytor krajobrazu +STR_3201 :Wybór obiektów +STR_3202 :Edycja krajobrazu STR_3203 :Konfiguracja listy wynalazków STR_3204 :Wybór opcji STR_3205 :Wybór celu @@ -2252,7 +2252,7 @@ STR_3231 :Hamulce blokowe nie mogą znajdować się bezpośrednio za szczytem STR_3232 :Opcje - Finanse STR_3233 :Opcje - Goście STR_3234 :Opcje - Park -STR_3235 :Wyświetl opcje finansowe +STR_3235 :Pokaż opcje finansowe STR_3236 :Wyświetl opcje gości STR_3237 :Wyświetl opcje parku STR_3238 :Bez pieniędzy @@ -2296,8 +2296,8 @@ STR_3275 :Goście są trudniejsi do przyciągnięcia STR_3276 :Trudniej jest przyciągnąć gości do parku STR_3277 :{WINDOW_COLOUR_2}Koszt zakupu ziemi: STR_3278 :{WINDOW_COLOUR_2}Koszt zakupu planów budowy: -STR_3279 :Darmowe wejście do parku / atrakcje płatne -STR_3280 :Płatne wejście do parku / darmowe atrakcje +STR_3279 :Darmowe wejście i płatne atrakcje +STR_3280 :Płatne wejście i darmowe atrakcje STR_3281 :{WINDOW_COLOUR_2}Cena za wejście: STR_3282 :Wybierz cel i nazwę parku STR_3283 :Wybierz atrakcje, które mają zostać zachowane @@ -2398,7 +2398,7 @@ STR_3383 :Wybierz nową nazwę dla projektu trasy STR_3384 :Istnieje już trasa o takiej nazwie - Proszę wybrać nową nazwę: STR_3389 :Nie można wybrać dodatkowych przedmiotów scenerii… STR_3390 :Zaznaczono zbyt wiele rzeczy -STR_3437 :Usuwanie scenerii z terenu +STR_3437 :Usuń scenerię z dużego obszaru STR_3438 :Nie można stąd usunąć całej scenerii… STR_3439 :Usuń scenerię STR_3445 :Ustaw obszar do patrolowania @@ -2480,7 +2480,7 @@ STR_5206 :Lista gości STR_5207 :Personel STR_5208 :Lista pracowników STR_5209 :Baner -STR_5210 :Wybór obiektu +STR_5210 :Wybór obiektów STR_5211 :Lista wynalazków STR_5212 :Opcje scenariusza STR_5213 :Opcje celów @@ -2494,7 +2494,7 @@ STR_5220 :Skróty klawiszowe STR_5221 :Zmień skróty klawiszowe STR_5222 :Wczytaj/Zapisz STR_5223 :Ostrzeżenie o zapisie -STR_5224 :Ostrzeżenie o zniszczeniu atrakcji +STR_5224 :Ostrzeżenie o wyburzeniu atrakcji STR_5225 :Ostrzeżenie o straży pożarnej STR_5226 :Ostrzeżenie o usunięciu trasy STR_5227 :Ostrzeżenie o nadpisaniu gry @@ -2612,7 +2612,7 @@ STR_5365 :{BLACK}Szybkość personelu: STR_5366 :Normalnie STR_5367 :Szybko STR_5368 :Zresetuj wypadki -STR_5371 :Wybór obiektu +STR_5371 :Wybór obiektów STR_5372 :Odwrócone przesuwanie prawym przyciskiem myszy STR_5373 :Nazwa {STRINGID} STR_5374 :Data {STRINGID} @@ -2629,7 +2629,7 @@ STR_5451 :Otwórz okno kodów STR_5452 :Przełącz widoczność pasków narzędzi STR_5453 :Wybierz inną atrakcję STR_5454 :Odblokuj FPS -STR_5455 :Uruchom tryb piaskownicy +STR_5455 :Włącz tryb piaskownicy STR_5456 :Wyłącz sprawdzanie kolizji STR_5457 :Wyłącz limity wsporników STR_5458 :Obróć zgodnie ze wskazówką zegara @@ -2661,7 +2661,7 @@ STR_5483 :{BLACK}(pozostało {COMMA16} tygodni) STR_5484 :{BLACK}(pozostał {COMMA16} tydzień) STR_5485 :{STRING} STR_5486 :{BLACK}{COMMA16} -STR_5487 :Pokaż ostatnie wiadomości +STR_5487 :Ostatnie wiadomości STR_5489 :Pokaż tylko śledzonych gości STR_5490 :Wyłącz dźwięk gdy okno gry jest nieaktywne STR_5491 :Lista odkryć @@ -2895,20 +2895,20 @@ STR_5764 :Nieprawidłowy typ atrakcji STR_5765 :Nie można edytować atrakcji o nieprawidłowym typie STR_5766 :Węgierski Forint (Ft) STR_5767 :Przychód -STR_5768 :Wszystkich klientów +STR_5768 :Wszyscy klienci STR_5769 :Całkowity zysk -STR_5770 :Klientów na godzinę -STR_5771 :Koszty eksploatacji +STR_5770 :Klienci na godzinę +STR_5771 :Koszt eksploatacji STR_5772 :Wiek -STR_5773 :Wszystkich klientów: {COMMA32} +STR_5773 :Wszyscy klienci: {COMMA32} STR_5774 :Całkowity zysk: {CURRENCY2DP} STR_5775 :Klienci: {COMMA32} na godzinę -STR_5776 :Wybudowano: w tym roku -STR_5777 :Wybudowano: w zeszłym roku -STR_5778 :Wybudowano: {COMMA16} lat temu +STR_5776 :Zbudowano: w tym roku +STR_5777 :Zbudowano: w zeszłym roku +STR_5778 :Zbudowano: {COMMA16} lat temu STR_5779 :Przychód: {CURRENCY2DP} na godzinę -STR_5780 :Koszty eksploatacji: {CURRENCY2DP} na godzinę -STR_5781 :Koszty eksploatacji: nieznane +STR_5780 :Koszt: {CURRENCY2DP} na godzinę +STR_5781 :Koszt: nieznane STR_5782 :Połączono. Naciśnij „{STRING}” aby pisać na czacie. STR_5783 :{WINDOW_COLOUR_2}Scenariusz zablokowany STR_5784 :{BLACK}Aby odblokować ten scenariusz ukończ poprzedni. @@ -2996,7 +2996,7 @@ STR_5869 :{WINDOW_COLOUR_2}Strona hostującego: {BLACK}{STRING} STR_5870 :Pokaż informacje o serwerze STR_5871 :Wyłącz usychanie kwiatów STR_5872 :Kwiaty się nie starzeją, nie usychają, nie trzeba ich wymieniać -STR_5873 :Wyciągarka dozwolona na dowolnym torze +STR_5873 :Wyciągarka dozwolona na każdym torze STR_5874 :Umożliwia przekształcenie dowolnego typu toru w wyciągarkę. STR_5875 :Silnik graficzny: STR_5876 :Silnik używany do generowania grafiki. @@ -3129,7 +3129,7 @@ STR_6003 :Widok przekroju STR_6004 :Widok przekroju STR_6005 :Włącz widok przekroju STR_6006 :Widok przekroju wyświetla jedynie elementy mapy na lub poniżej wysokości przycięcia (przycięcie pionowe) oraz w wybranym obszarze (przycięcie poziome). -STR_6007 :Wysokość cięcia +STR_6007 :Wysokość STR_6008 :Kliknij aby przełączyć surowe wartości<->wartości jednostek pomiarowych STR_6009 :Wybierz wysokość cięcia STR_6010 :{COMMA2DP32}m @@ -3151,7 +3151,7 @@ STR_6025 :Konstrukcja - Nachylenie w prawo STR_6026 :Konstrukcja - Poprzedni element STR_6027 :Konstrukcja - Następny element STR_6028 :Konstrukcja - Wybuduj bieżący -STR_6029 :Konstrukcja - Zniszcz bieżący +STR_6029 :Konstrukcja - Usuń bieżący STR_6030 :Przechwytywacz scenerii. Wybierz dowolny element scenerii na mapie aby wybrać taki sam do konstrukcji. STR_6031 :Opis serwera: STR_6032 :Wiadomość powitalna: @@ -3200,7 +3200,7 @@ STR_6075 :{STRING} zmienił domyślna grupę graczy na „{STRING}”. STR_6076 :{STRING} pokaż/schowaj kody „{STRING}”. STR_6077 :Dodaj pieniądze STR_6078 :{STRING} stworzył atrakcję „{STRING}”. -STR_6079 :{STRING} zniszczył atrakcję „{STRING}”. +STR_6079 :{STRING} zburzył atrakcję „{STRING}”. STR_6080 :{STRING} zmienił wygląd atrakcji „{STRING}”. STR_6081 :{STRING} zmienił status atrakcji „{STRING}” na zamkniętą. STR_6082 :{STRING} zmienił status atrakcji „{STRING}” na otwartą. @@ -3225,14 +3225,14 @@ STR_6100 :Rozłączyłeś się z serwerem. STR_6101 :Wartość atrakcji nie spada STR_6102 :Wartość atrakcji nie będzie spadała z czasem, więc goście nie będą nagle twierdzić, że atrakcja jest za droga. STR_6103 :Opcja ta nie jest dostępna w grze wieloosobowej. -STR_6105 :Hiperjazda +STR_6105 :Hiper jazda STR_6107 :Potworne pikapy STR_6109 :Hiperzwijka -STR_6111 :Klasyczna mini kolejka górska -STR_6113 :Wysoka kolejka górska bez inwersji z wielkimi zjazdami, wysokimi prędkościami i wygodnymi wagonikami, które zabezpieczone są tylko pasem na biodrach -STR_6115 :Zasilane wielkie auta z napędem 4x4, które są w stanie wjechać na strome zbocza -STR_6116 :Szerokie wagony kolejki górskiej delikatnie ślizgają się na stalowym torze przez przeróżne inwersje -STR_6119 :Tania i łatwa do zbudowania kolejka górska, jednak z limitem wysokości +STR_6111 :Klasyczna kolejka dla dzieci +STR_6113 :Wysoka, nieobrotowa kolejka górska z wielkimi zjazdami, wysokimi prędkościami i wygodnymi wagonikami, wyposażonymi w zabezpieczenia obejmujące pasażerów jedynie w pasie +STR_6115 :Samochody na olbrzymich kołach z napędem 4x4, które mogą wjeżdzać na strome zbocza +STR_6116 :Szerokie wagoniki suną po gładkim stalowym torze, pokonując przeróżne inwersje +STR_6119 :Tania i łatwa do zbudowania kolejka, jednak z limitem wysokości STR_6120 :{BABYBLUE}Nowy pojazd dostępny dla {STRINGID}:{NEWLINE}{STRINGID} STR_6121 :Rozszerz prawa do terenu aż do krawędzi mapy STR_6122 :W tym scenariuszu jest za mało kolejek górskich! @@ -3266,7 +3266,7 @@ STR_6149 :Nieudane połączenie z serwerem głównym STR_6150 :Błędna odpowiedź z głównego serwera (brak numeru JSON) STR_6151 :Główny serwer nie zwrócił listy serwerów STR_6152 :Błędna odpowiedź z głównego serwera (brak tablicy JSON) -STR_6153 :Opłata za wejście do parku / Opłata za atrakcje +STR_6153 :Płatne wejście i płatne atrakcje STR_6154 :Z uwagi na bezpieczeństwo, nie zaleca się uruchamiania OpenRCT2 z podwyższonymi uprawnieniami. STR_6155 :Ani KDialog, ani Zenity nie jest zainstalowane. Zainstaluj jedno z nich, lub skonfiguruj z poziomu konsoli. STR_6156 :Nazwa jest zastrzeżona @@ -3274,7 +3274,7 @@ STR_6157 :Konsola STR_6160 :{WINDOW_COLOUR_2}Dostępne pojazdy: {BLACK}{STRING} STR_6161 :Przełącz widok siatki STR_6162 :Wirująca szalona mysz -STR_6163 :Pojazdy wyglądające jak myszki, szybko jeżdżą po ciasnych zakrętach i krótkich zjazdach, dodatkowo łagodnie się kręcą przez co dezorientują gości +STR_6163 :Wagoniki w kształcie myszy pokonujące ostre zakręty i krótkie zjazdy, wirujące łagodnie w celu zdezorientowania pasażerów STR_6164 :{WHITE}❌ STR_6165 :Synchronizacja pionowa STR_6166 :Synchronizuje każdą wyświetlaną klatkę z częstotliwością odświeżania monitora, zapobiegając rozrywaniu ekranu @@ -3588,7 +3588,7 @@ STR_6514 :Nieprawidłowa wysokość! STR_6515 :{BLACK}Rollercoaster Tycoon 1 niezaładowany - zostaną użyte grafiki zapasowe. STR_6516 :Jeden lub więcej obiektów wymaga załadowania Rollercoaster Tycoon 1, aby mogły być poprawnie wyświetlane. Zostaną użyte grafiki zapasowe. STR_6517 :Jeden lub więcej obiektów w tym parku wymaga załadowania Rollercoaster Tycoon 1, aby mogły być poprawnie wyświetlane. Zostaną użyte grafiki zapasowe. -STR_6518 :{BLACK}Najedź na scenariusz aby wyświetlić jego opis oraz cel. Kliknij go aby rozpocząc rozgrywkę. +STR_6518 :{BLACK}Najedź na scenariusz aby wyświetlić jego opis oraz cel. Kliknij scenariusz aby rozpocząc rozgrywkę. STR_6519 :Dodatkowe STR_6520 :Paczki zasobów STR_6521 :Niski priorytet @@ -3616,11 +3616,11 @@ STR_6542 :Współautorzy STR_6543 :Współautorzy… STR_6544 :Kwota pożyczki nie może być ujemna! STR_6545 :Użyj obliczania odsetek z RCT1 -STR_6546 :Użyj algorytmu obliczania odsetek z RollerCoaster Tycoon 1, który stosował oprocentowanie stałe wynoszące około 1,33%. +STR_6546 :Użyj algorytmu obliczania odsetek z RollerCoaster Tycoon 1, który stosował oprocentowanie stałe wynoszące około 1,33% STR_6547 :Wszystkie obiekty STR_6548 :Pokaż balustrady na skrzyżowaniu STR_6549 :Obiekty zapewniające kompatybilność wsteczną nie mogą być wybrane! -STR_6550 :Ten wpis jest dołączony dla zapewnienia wstecznej kompatybilności ze starymi lub uszkodzonymi obiektami. Nie może być wybrany, tylko odznaczony. +STR_6550 :Ten wpis jest dołączony dla zapewnienia wstecznej kompatybilności ze starymi lub uszkodzonymi obiektami. Nie może być wybrany, tylko odznaczony STR_6551 :Zielony wojskowy STR_6552 :Spadziowy STR_6553 :Jasnobrązowy @@ -3723,8 +3723,8 @@ STR_6649 :Ładowanie scenariusza… STR_6650 :Ładowanie zapisu gry… STR_6651 :{STRING} ({COMMA32}%) STR_6652 :Okno błędu -STR_6653 :Wszystkie źródła wyświetlone -STR_6654 :Wyświetlone źródła: {POP16}{UINT16} +STR_6653 :Wszystkie źródła +STR_6654 :Wyświetlane źródła: {POP16}{UINT16} STR_6655 :Tylko „{POP16}{STRINGID}” STR_6656 :Usuń wszystkie ogrodzenia parku STR_6657 :Nieposiadany teren From 850f35f4b808b87833960837282f755e717a7c11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Thu, 14 Nov 2024 19:10:38 +0100 Subject: [PATCH 028/139] Explicitly use tags for describing version in CI (#23190) While we use annotated tags for releases, apparently GitHub Actions Workers do some peculiar steps for fetching the repository, resulting in incomplete(?) tag being checked out. The lightweight version of tag is present, but annotation lives on a different git object, which is not currently checked out in the CI job. To resolve the issue where GitHub Actions would try creating a release for a previous tag instead of current, make sure lightweight tags are considered as well. You can validate the difference between the two with following commands: ``` $ git rev-parse v0.4.16 20fff63f05dd5508c24bcd2eaf9f34845c7dd472 $ git --no-pager log -1 --oneline v0.4.16 c1082a3d6c (tag: v0.4.16, origin/master) Release v0.4.16 ``` --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5daf8af0ae..ea846e173c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,8 +51,8 @@ jobs: - name: Git describe id: ghd run: | - TAG=$(git describe --abbrev=0) - DESCRIBE=$(git describe) + TAG=$(git describe --tags --abbrev=0) + DESCRIBE=$(git describe --tags) SHORT_SHA=$(git rev-parse --short HEAD) DISTANCE=$(git rev-list --count $TAG..HEAD) echo "tag=$TAG" From 09adb2bf81d8e50952cf563b28b10e0f68f5823f Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sat, 16 Nov 2024 04:02:15 +0000 Subject: [PATCH 029/139] Merge Localisation/master into OpenRCT2/develop --- data/language/da-DK.txt | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index 70876baf36..d973c7b94a 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -98,6 +98,7 @@ STR_0093 :Hybrid Rutschebane STR_0094 :Enkelt skinde rutchebane STR_0095 :Alpin rutchebane STR_0096 :Klassisk træ rutsjebane +STR_0097 :Klassisk Stå-op Rutschebane STR_0512 :En kompakt rutschebane med en spiral stigning og bløde, snoede fald. STR_0513 :En loopende rutschebane hvor passagerne er i en stående position STR_0514 :Vogne suspenderet under rutschebane sporet, svinger ud til siden i svingene @@ -181,6 +182,7 @@ STR_0603 :En rutsjebane i træ stil, med stål spor, Med stejle fald og hurti STR_0604 :Gæster sider i en enkelt række, på et smalt monorail spor, imens de suser igennem skarpe sving ,snoninger og hurtige vridninger. STR_0605 :Ryttere kælker ned ad en bugtende stålbane og bremser for at kontrollere deres hastighed STR_0606 :En ældre stils trærutsjebane med en hurtig og ujævn tur med masser af luft tid, laterale G'er, og designet til at føles som ‘ude-af-kontrol’ +STR_0607 :En intens, Klassisk stål-stil, loopende rutschebane hvor passagerne er i en stående position STR_0767 :Gæst {INT32} STR_0768 :Handymand {INT32} STR_0769 :Mekaniker {INT32} @@ -3247,7 +3249,7 @@ STR_6134 :Ryd sceneri STR_6135 :Klienten sendte en ugyldig anmodning STR_6136 :Serveren sendte en ugyldig anmodning STR_6137 :OpenRCT2, en gratis, open source genskabelse af Roller Coaster Tycoon 2. -STR_6138 :OpenRCT2 er et samarbejde imellem mange forfattere, en komplet liste kan findes under “bidragudere” knappen. Du kan finde flere oplysninger på http://github.com/OpenRCT2/OpenRCT2 +STR_6138 :OpenRCT2 er et samarbejde imellem mange forfattere, en komplet liste kan findes under “bidragydere” knappen. Du kan finde flere oplysninger på http://github.com/OpenRCT2/OpenRCT2 STR_6139 :Alle produkt- og firmanavne tilhører deres respektive indehavere. Brug af dem indebærer ikke nogen tilknytning til eller godkendelse af dem. STR_6140 :Ændringslog… STR_6141 :RCT1 bund værktøjslinje @@ -3690,3 +3692,28 @@ STR_6619 :Objekttype kan ikke begrænses! STR_6620 :Objektet blev ikke fundet! STR_6621 :Begræns STR_6622 :Begræns objekt til scenarieeditoren og sandkassetilstanden. +STR_6623 :Skriv 'help' for at få en liste over tilgængelige kommandoer. Skriv 'hide' for at skjule konsollen. +STR_6624 :Fliseinspektør: Sortér elementer +STR_6625 :Ugyldig farve +STR_6626 :Animation er baglæns +STR_6627 :Sporhastighed er for høj! +STR_6628 :Kan kun placeres på stikanter! +STR_6629 :Juster værktøjslinjeknapper vandret centreret +STR_6630 :Denne indstilling justerer værktøjslinjeknapperne vandret i midten af skærmen. Den traditionelle måde at justere dem på er i venstre og højre hjørne. +STR_6631 :Indlæser… +STR_6632 :Kontrollerer objekt filer… +STR_6633 :Kontrollerer scenarie filer… +STR_6634 :Kontrollerer banedesign filer… +STR_6635 :Kontrollerer aktivpakker… +STR_6636 :Kontrollerer titel sekvenser… +STR_6637 :Indlæser titel sekvens… +STR_6638 :Forstørret UI +STR_6639 :Ændrer grænsefladen, så den er mere velegnet til touchskærm +STR_6640 :Rediger aktivpakker… +STR_6641 :Indlæsning/Fremskridt vindue +STR_6642 :{STRING} ({COMMA32} / {COMMA32}) +STR_6643 :{STRING} ({COMMA32} / {COMMA32} KiB) +STR_6644 :Touch-forbedringer +STR_6645 :Gør nogle UI-elementer større, så de er nemmere at klikke eller trykke på. +STR_6646 :Forfatter: {STRING} +STR_6647 :Forfattere: {STRING} From 4a78062f5438ff55d14f9607dc40e32c6e776cc3 Mon Sep 17 00:00:00 2001 From: Matt <5415177+ZehMatt@users.noreply.github.com> Date: Sun, 17 Nov 2024 19:49:47 +0200 Subject: [PATCH 030/139] Fix #23206: Desyncs when using uncapped FPS Because the position is one tick behind the spatial mapping was incorrect, it's not allowed to modify that during interpolation. --- distribution/changelog.txt | 1 + src/openrct2/entity/EntityRegistry.cpp | 20 ++++++++++---------- src/openrct2/entity/EntityRegistry.h | 1 - src/openrct2/entity/EntityTweener.cpp | 6 +----- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 758103600b..7411f41770 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -3,6 +3,7 @@ - Feature: [#23166] Add Galician translation. - Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. +- Fix: [#23206] Multiplayer desyncs when FPS is uncapped. 0.4.16 (2024-11-03) ------------------------------------------------------------------------ diff --git a/src/openrct2/entity/EntityRegistry.cpp b/src/openrct2/entity/EntityRegistry.cpp index b3a5f76991..4d7e883689 100644 --- a/src/openrct2/entity/EntityRegistry.cpp +++ b/src/openrct2/entity/EntityRegistry.cpp @@ -481,6 +481,16 @@ void EntityBase::SetLocation(const CoordsXYZ& newLocation) SpatialIndex |= kSpatialIndexDirtyMask; } +static void EntitySetCoordinates(const CoordsXYZ& entityPos, EntityBase* entity) +{ + auto screenCoords = Translate3DTo2DWithZ(GetCurrentRotation(), entityPos); + + entity->SpriteData.SpriteRect = ScreenRect( + screenCoords - ScreenCoordsXY{ entity->SpriteData.Width, entity->SpriteData.HeightMin }, + screenCoords + ScreenCoordsXY{ entity->SpriteData.Width, entity->SpriteData.HeightMax }); + entity->SetLocation(entityPos); +} + void EntityBase::MoveTo(const CoordsXYZ& newLocation) { if (x != kLocationNull) @@ -506,16 +516,6 @@ void EntityBase::MoveTo(const CoordsXYZ& newLocation) } } -void EntitySetCoordinates(const CoordsXYZ& entityPos, EntityBase* entity) -{ - auto screenCoords = Translate3DTo2DWithZ(GetCurrentRotation(), entityPos); - - entity->SpriteData.SpriteRect = ScreenRect( - screenCoords - ScreenCoordsXY{ entity->SpriteData.Width, entity->SpriteData.HeightMin }, - screenCoords + ScreenCoordsXY{ entity->SpriteData.Width, entity->SpriteData.HeightMax }); - entity->SetLocation(entityPos); -} - /** * Frees any dynamically attached memory to the entity, such as peep name. */ diff --git a/src/openrct2/entity/EntityRegistry.h b/src/openrct2/entity/EntityRegistry.h index b33230e710..a370f38f44 100644 --- a/src/openrct2/entity/EntityRegistry.h +++ b/src/openrct2/entity/EntityRegistry.h @@ -67,7 +67,6 @@ void ResetAllEntities(); void ResetEntitySpatialIndices(); void UpdateAllMiscEntities(); void UpdateMoneyEffect(); -void EntitySetCoordinates(const CoordsXYZ& entityPos, EntityBase* entity); void EntityRemove(EntityBase* entity); uint16_t RemoveFloatingEntities(); void UpdateEntitiesSpatialIndex(); diff --git a/src/openrct2/entity/EntityTweener.cpp b/src/openrct2/entity/EntityTweener.cpp index 52bc453237..acd5e38ccf 100644 --- a/src/openrct2/entity/EntityTweener.cpp +++ b/src/openrct2/entity/EntityTweener.cpp @@ -101,8 +101,6 @@ void EntityTweener::Tween(float alpha) static_cast(std::round(posB.y * alpha + posA.y * inv)), static_cast(std::round(posB.z * alpha + posA.z * inv)) }); } - - UpdateEntitiesSpatialIndex(); } void EntityTweener::Restore() @@ -113,9 +111,7 @@ void EntityTweener::Restore() if (ent == nullptr) continue; - ent->Invalidate(); - EntitySetCoordinates(PostPos[i], ent); - ent->Invalidate(); + ent->MoveTo(PostPos[i]); } } From 1a93c9855a779af63b85c83ec54db713de4002aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 21:39:03 +0100 Subject: [PATCH 031/139] Enable _itScanForward64 for ARM64 MSVC target (#23220) --- src/openrct2/core/Numerics.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2/core/Numerics.hpp b/src/openrct2/core/Numerics.hpp index 2a770a56d1..23ac49ef68 100644 --- a/src/openrct2/core/Numerics.hpp +++ b/src/openrct2/core/Numerics.hpp @@ -30,7 +30,7 @@ namespace OpenRCT2::Numerics int32_t success = __builtin_ffs(source); return success - 1; #else -# pragma message("Falling back to iterative bitscan forward, consider using intrinsics") +# pragma message("Falling back to iterative bitscan32 forward, consider using intrinsics") // This is a low-hanging optimisation boost, check if your compiler offers // any intrinsic. // cf. https://github.com/OpenRCT2/OpenRCT2/pull/2093 @@ -44,7 +44,7 @@ namespace OpenRCT2::Numerics inline int64_t bitScanForward(uint64_t source) { -#if defined(_MSC_VER) && (_MSC_VER >= 1400) && defined(_M_X64) // Visual Studio 2005 +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (defined(_M_X64) || defined(_M_ARM64)) // Visual Studio 2005 unsigned long i; uint8_t success = _BitScanForward64(&i, source); return success != 0 ? i : -1; @@ -52,7 +52,7 @@ namespace OpenRCT2::Numerics int32_t success = __builtin_ffsll(source); return success - 1; #else -# pragma message("Falling back to iterative bitscan forward, consider using intrinsics") +# pragma message("Falling back to iterative bitscan64 forward, consider using intrinsics") // This is a low-hanging optimisation boost, check if your compiler offers // any intrinsic. // cf. https://github.com/OpenRCT2/OpenRCT2/pull/2093 From 0e7bcf6e5358b905a1593319062faa3b9df08580 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Mon, 18 Nov 2024 04:02:10 +0000 Subject: [PATCH 032/139] Merge Localisation/master into OpenRCT2/develop --- data/language/ca-ES.txt | 84 ++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 17 deletions(-) diff --git a/data/language/ca-ES.txt b/data/language/ca-ES.txt index a8bbdb9dfd..5e20a13b7c 100644 --- a/data/language/ca-ES.txt +++ b/data/language/ca-ES.txt @@ -99,7 +99,9 @@ STR_0094 :Muntanya russa d’un sol rail STR_0095 :Muntanya russa alpina STR_0096 :Muntanya russa clàssica de fusta STR_0097 :Muntanya russa a peu dret clàssica +STR_0098 :Muntanya russa d’impuls LSM STR_0607 :Una muntanya russa d’estil antic i d’acer molt intensa on els passatgers van com si estiguessin de peu. +STR_0608 :Els cotxes acceleren amb motors síncrons lineals i circulen a gran velocitat per girs i corbes tancades. STR_0512 :Muntanya russa compacta amb una pujada en espiral i caigudes sinuoses suaus. STR_0513 :Muntanya russa amb inversions en la qual els passatgers es mantenen drets. STR_0514 :Els cotxes que pengen per sota dels rails es balancegen cap a fora en les corbes. @@ -1045,10 +1047,10 @@ STR_1653 :«…i aquí estem en {STRINGID}!» STR_1654 :{WINDOW_COLOUR_2}Pensaments recents: STR_1655 :Construeix camí al terra STR_1656 :Construeix camí al pont o al túnel -STR_1657 :{WINDOW_COLOUR_2}Atracció preferida -STR_1658 :{WINDOW_COLOUR_2}intensitat: {BLACK}menys de {COMMA16} -STR_1659 :{WINDOW_COLOUR_2}intensitat: {BLACK}entre {COMMA16} i {COMMA16} -STR_1660 :{WINDOW_COLOUR_2}intensitat: {BLACK}més de {COMMA16} +STR_1657 :{WINDOW_COLOUR_2}Atraccions preferides: +STR_1658 :{WINDOW_COLOUR_2}De {BLACK}menys de {COMMA16} {WINDOW_COLOUR_2}d’intensitat +STR_1659 :{WINDOW_COLOUR_2}D’{BLACK}entre {COMMA16} i {COMMA16} {WINDOW_COLOUR_2}d’intensitat +STR_1660 :{WINDOW_COLOUR_2}De {BLACK}més de {COMMA16} {WINDOW_COLOUR_2}d’intensitat STR_1661 :{WINDOW_COLOUR_2}Tolerància a la nàusea: {BLACK}{STRINGID} STR_1662 :{WINDOW_COLOUR_2}Felicitat: STR_1663 :{WINDOW_COLOUR_2}Nàusea: @@ -1742,7 +1744,7 @@ STR_2382 :Terra STR_2383 :Aigua STR_2384 :{WINDOW_COLOUR_2}El vostre objectiu: STR_2385 :{BLACK}Cap -STR_2386 :{BLACK}Tenir almenys {COMMA32} visitants al parc al final de {MONTHYEAR}, amb una valoració del parc d’almenys 600. +STR_2386 :{BLACK}Tenir almenys {COMMA32} visitants al parc al final de {MONTHYEAR}, amb una valoració del parc almenys de 600. STR_2387 :{BLACK}Aconseguir una valoració del parc d’almenys {POP16}{POP16}{CURRENCY} al final de {PUSH16}{PUSH16}{PUSH16}{PUSH16}{PUSH16}{MONTHYEAR}. STR_2388 :{BLACK}Divertiu-vos! STR_2389 :{BLACK}Construïu el millor {STRINGID} que pugueu! @@ -1913,8 +1915,8 @@ STR_2670 :Bloq Despl STR_2680 :S’han completat totes les recerques. STR_2684 :Arriba un grup gran de visitants. STR_2685 :Paràmetres de soroll del símplex -STR_2686 :Baix: -STR_2687 :Alt: +STR_2686 :Altura del terreny mín.: +STR_2687 :Altura del terreny màx.: STR_2688 :Freqüència base: STR_2689 :Octaves: STR_2690 :Generació del mapa @@ -2150,8 +2152,8 @@ STR_3107 :Tanca STR_3108 :Prova STR_3109 :Obre STR_3110 :{WINDOW_COLOUR_2}Seccions de bloc: {BLACK}{COMMA16} -STR_3111 :Cliqueu el disseny per a construir-lo. -STR_3112 :Cliqueu el disseny per a canviar-ne el nom o per a esborrar-lo. +STR_3111 :Feu clic al disseny per a construir-lo. +STR_3112 :Feu clic al disseny per a canviar-ne el nom o per a esborrar-lo. STR_3113 :Selecciona un altre disseny STR_3114 :Torna a la finestra de selecció de dissenys. STR_3115 :Desa el disseny de via @@ -2171,7 +2173,7 @@ STR_3128 :Desa el disseny de via STR_3129 :Desa el disseny de via i el decorat STR_3130 :Desa STR_3131 :Cancel·la -STR_3132 :{BLACK}Cliqueu elements del decorat per a seleccionar-los i desar-los amb el disseny de via. +STR_3132 :{BLACK}Feu clic als elements del decorat per a seleccionar-los i desar-los amb el disseny de via. STR_3133 :No es pot construir a sobre d’un pendent. STR_3134 :{RED}(El disseny inclou algun decorat no disponible) STR_3135 :{RED}(Disseny de vehicle no disponible - Això pot afectar al rendiment de l’atracció) @@ -2440,7 +2442,7 @@ STR_5149 :Mostra les trampes que es poden fer a la partida. STR_5150 :Activa les eines de depuració STR_5151 :. STR_5152 :, -STR_5153 :Edita temes… +STR_5153 :Edita els temes… STR_5154 :Renderitzat per maquinari STR_5155 :Permet provar atraccions sense acabar STR_5156 :Permet provar la majoria d’atraccions fins i tot si la via no està acabada. No s’aplica als modes de bloc de seccions. @@ -2607,8 +2609,8 @@ STR_5357 :{BLACK}Tolerància a la nàusea: STR_5358 :{BLACK}Orina: STR_5359 :Treu visitants STR_5360 :Elimina tots els visitants del mapa. -STR_5361 :Dóna a tots els visitants: -STR_5362 :{BLACK}Estableix la intensitat preferida dels visitants a: +STR_5361 :Afegeix a l’inventari dels visitants +STR_5362 :{BLACK}Intensitat preferida dels visitants: STR_5363 :Més d’1 STR_5364 :Menys de 15 STR_5365 :{BLACK}Velocitat dels empleats: @@ -2638,7 +2640,7 @@ STR_5457 :Desactiva els límits dels suports STR_5458 :Gira en sentit horari STR_5459 :Gira en sentit antihorari STR_5460 :Gira la vista en sentit antihorari -STR_5461 :Estableix els paràmetres dels visitants +STR_5461 :Estableix els paràmetres de tots els visitants STR_5462 :{CURRENCY} STR_5463 :Objectiu: Divertiu-vos! STR_5464 :General @@ -3170,9 +3172,9 @@ STR_6041 :{BLACK}No s’han contractat mecànics! STR_6042 :Carrega el mapa d’alçades STR_6043 :Selecciona el mapa d’alçades STR_6044 :Suavitza el mapa d’alçades -STR_6045 :Força +STR_6045 :Força: STR_6046 :Normalitza el mapa d’alçades -STR_6047 :Suavitza les caselles +STR_6047 :Suavitza les vores de les caselles STR_6048 :Error del mapa d’alçades STR_6049 :S’ha produït un error mentre es llegia el fitxer PNG. STR_6050 :S’ha produït un error mentre es llegia el bitmap. @@ -3614,7 +3616,7 @@ STR_6537 :Permet fer servir els camins normals per a fer cues STR_6538 :Mostra els camins normals al menú desplegable de les cues de la finestra de construcció corresponent. STR_6539 :Fre tancat STR_6540 :{WINDOW_COLOUR_2}Donem les gràcies a les companyies següents per permetre fer servir les seves imatges: -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 :Col·laboradors STR_6543 :Col·laboradors… STR_6544 :El préstec no pot ser negatiu! @@ -3736,3 +3738,51 @@ STR_6659 :Els visitants ignoren els preus STR_6660 :Els visitants ignoraran els preus de les atraccions i paradetes. STR_6661 :Aleatoritza’ls tots STR_6662 :Aleatoritza els colors de cada cotxe o vehicle. +STR_6663 :Trampes de dates +STR_6664 :Mostra les trampes de dates +STR_6665 :Trampes de clima/natura +STR_6666 :Mostra les trampes de clima/natura +STR_6667 :Fauna +STR_6668 :Trampes dels encarregats +STR_6669 :Mostra les trampes sobre encarregats +STR_6670 :Comportament dels visitants +STR_6671 :Mostra noms «reals» dels encarregats +STR_6672 :Commuta entre mostra noms «reals» dels encarregats o el seu número. +STR_6673 :Transparència +STR_6674 :{MONTH} de l’any {COMMA16} +STR_6675 :Noms de persones +STR_6676 :Cal escollir com a mínim un objecte de noms de persona. +STR_6677 :Afegeix platges al voltant de les masses d’aigua +STR_6678 :Origen del mapa d’alçades: +STR_6679 :Terreny pla +STR_6680 :Soroll símplex +STR_6681 :Fitxer del mapa d’alçades +STR_6682 :Generador de mapes - Generador +STR_6683 :Generador de mapes - Terreny +STR_6684 :Generador de mapes - Aigua +STR_6685 :Generador de mapes - Boscos +STR_6686 :Proporció arbres/terreny: +STR_6687 :Altura mín. per als arbres: +STR_6688 :Altura màx. per als arbres: +STR_6689 :{UINT16} % +STR_6690 :Altura mínima del terreny +STR_6691 :Escriviu una altura mínima del terreny entre {COMMA16} i {COMMA16} +STR_6692 :Altura màxima del terreny +STR_6693 :Escriviu una altura màxima del terreny entre {COMMA16} i {COMMA16} +STR_6694 :Altura mínima per als arbres +STR_6695 :Escriviu una altura mínima per als arbres entre {COMMA16} i {COMMA16} +STR_6696 :Altura màxima per als arbres +STR_6697 :Escriviu una altura màxima per als arbres entre {COMMA16} i {COMMA16} +STR_6698 :Proporció arbres/terreny +STR_6699 :Escriviu una proporció arbres/terreny entre {COMMA16} i {COMMA16} +STR_6700 :Freqüència base del símplex +STR_6701 :Escriviu una freqüència base del símplex entre {COMMA2DP32} i {COMMA2DP32} +STR_6702 :Octaves del símplex +STR_6703 :Escriviu octaves entre {COMMA16} i {COMMA16} +STR_6704 :{COMMA2DP32} +STR_6705 :Navega… +STR_6706 :{WINDOW_COLOUR_2}Fitxer d’imatge actual: {BLACK}{STRING} +STR_6707 :(cap de seleccionat) +STR_6708 :Força suau +STR_6709 :Escriviu una força suau entre {COMMA16} i {COMMA16} + From 4f93448606e3240911fbc77285cedb1ebd64108b Mon Sep 17 00:00:00 2001 From: ZeeMaji <42477864+ZeeMaji@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:49:27 -0500 Subject: [PATCH 033/139] Close #23210: Add boosters to classic wooden coaster (cheats only) The classic wooden roller coaster can draw boosters from the RCT2 wooden coaster and it also has booster settings set, so the pieces are fully functional and they can be built with ride type changing. This just simply adds them to the extra track pieces so you can use them without ride type switching. --- distribution/changelog.txt | 1 + src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 7411f41770..cf74b70b6c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -3,6 +3,7 @@ - Feature: [#23166] Add Galician translation. - Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. +- Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). - Fix: [#23206] Multiplayer desyncs when FPS is uncapped. 0.4.16 (2024-11-03) diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h index fab16a757a..c6b65f1486 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor ClassicWoodenRollerCoasterRTD = .Drawer = GetTrackPaintFunctionClassicWoodenRC, .supportType = WoodenSupportType::Truss, .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::waterSplash, TrackGroup::blockBrakes, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeSteepLong, TrackGroup::halfLoopMedium, TrackGroup::halfLoopLarge}, - .extraTrackGroups = {}, + .extraTrackGroups = {TrackGroup::booster}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | From 290b39ade2d70835b001621ac616311b5889abb0 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 20 Nov 2024 16:25:59 +0900 Subject: [PATCH 034/139] Refactor CarEntrySetImageMaxSizes to use constants (#23234) * Use designated initialisers in CarEntrySetImageMaxSizes * Add named constants to CarEntrySetImageMaxSizes --- src/openrct2/ride/CarEntry.cpp | 48 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/src/openrct2/ride/CarEntry.cpp b/src/openrct2/ride/CarEntry.cpp index 460c385491..0a23c5ce10 100644 --- a/src/openrct2/ride/CarEntry.cpp +++ b/src/openrct2/ride/CarEntry.cpp @@ -46,28 +46,34 @@ uint32_t CarEntry::SpriteOffset(SpriteGroupType spriteGroup, int32_t imageDirect */ void CarEntrySetImageMaxSizes(CarEntry& carEntry, int32_t numImages) { - uint8_t bitmap[200][200] = { 0 }; + constexpr uint8_t kWidth = 200; + constexpr uint8_t kHeight = 200; + constexpr uint8_t kCentreX = kWidth / 2; + constexpr uint8_t kCentreY = kHeight / 2; + + uint8_t bitmap[kHeight][kWidth] = { 0 }; DrawPixelInfo dpi = { - /*.bits = */ reinterpret_cast(bitmap), - /*.x = */ -100, - /*.y = */ -100, - /*.width = */ 200, - /*.height = */ 200, - /*.pitch = */ 0, - /*.zoom_level = */ ZoomLevel{ 0 }, + .bits = reinterpret_cast(bitmap), + .x = -(kWidth / 2), + .y = -(kHeight / 2), + .width = kWidth, + .height = kHeight, + .pitch = 0, + .zoom_level = ZoomLevel{ 0 }, }; for (int32_t i = 0; i < numImages; ++i) { GfxDrawSpriteSoftware(dpi, ImageId(carEntry.base_image_id + i), { 0, 0 }); } + int32_t spriteWidth = -1; - for (int32_t i = 99; i != 0; --i) + for (int32_t i = kCentreX - 1; i != 0; --i) { - for (int32_t j = 0; j < 200; j++) + for (int32_t j = 0; j < kWidth; j++) { - if (bitmap[j][100 - i] != 0) + if (bitmap[j][kCentreX - i] != 0) { spriteWidth = i; break; @@ -77,9 +83,9 @@ void CarEntrySetImageMaxSizes(CarEntry& carEntry, int32_t numImages) if (spriteWidth != -1) break; - for (int32_t j = 0; j < 200; j++) + for (int32_t j = 0; j < kWidth; j++) { - if (bitmap[j][100 + i] != 0) + if (bitmap[j][kCentreX + i] != 0) { spriteWidth = i; break; @@ -89,15 +95,14 @@ void CarEntrySetImageMaxSizes(CarEntry& carEntry, int32_t numImages) if (spriteWidth != -1) break; } - spriteWidth++; - int32_t spriteHeightNegative = -1; - for (int32_t i = 99; i != 0; --i) + int32_t spriteHeightNegative = -1; + for (int32_t i = kCentreY - 1; i != 0; --i) { - for (int32_t j = 0; j < 200; j++) + for (int32_t j = 0; j < kWidth; j++) { - if (bitmap[100 - i][j] != 0) + if (bitmap[kCentreY - i][j] != 0) { spriteHeightNegative = i; break; @@ -110,12 +115,11 @@ void CarEntrySetImageMaxSizes(CarEntry& carEntry, int32_t numImages) spriteHeightNegative++; int32_t spriteHeightPositive = -1; - - for (int32_t i = 99; i != 0; --i) + for (int32_t i = kCentreY - 1; i != 0; --i) { - for (int32_t j = 0; j < 200; j++) + for (int32_t j = 0; j < kWidth; j++) { - if (bitmap[100 + i][j] != 0) + if (bitmap[kCentreY + i][j] != 0) { spriteHeightPositive = i; break; From a88ea7a399f3f19e56d844437c483e20a64a83f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Thu, 14 Nov 2024 19:49:48 +0100 Subject: [PATCH 035/139] Sign Windows executables and installers with SignPath --- .github/workflows/ci.yml | 46 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea846e173c..9376a52b76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,9 +161,31 @@ jobs: uses: ammaraskar/msvc-problem-matcher@master - name: Build OpenRCT2 run: . scripts/setenv && build + - name: Upload unsigned binaries + id: upload-windows-binaries-unsigned + uses: actions/upload-artifact@v4 + with: + name: OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-unsigned-${{ matrix.platform }} + path: | + bin/openrct2.exe + bin/openrct2.com + - name: Sign binaries + id: sign-binaries + uses: signpath/github-action-submit-signing-request@v1 + with: + api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' + organization-id: 645b821f-6283-45e1-8198-264997072801 + project-slug: OpenRCT2 + signing-policy-slug: 'test-signing' + artifact-configuration-slug: 'binaries' + github-artifact-id: ${{ steps.upload-windows-binaries-unsigned.outputs.artifact-id }} + wait-for-completion: true + output-artifact-directory: files-signed - name: Build artifacts run: | . scripts/setenv -q + mv files-signed/openrct2.com bin/openrct2.com + mv files-signed/openrct2.exe bin/openrct2.exe build-portable build-symbols build-installer -i @@ -178,11 +200,31 @@ jobs: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-portable-${{ matrix.platform }} path: artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-portable-${{ matrix.platform }}.zip if-no-files-found: error - - name: Upload installer artifact (CI) + - name: Upload unsigned installer artifact (CI) + id: upload-windows-installer-unsigned + uses: actions/upload-artifact@v4 + with: + name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-installer-${{ matrix.platform }}-unsigned + path: artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-installer-${{ matrix.platform }}.exe + if-no-files-found: error + - name: Sign installer + id: sign-installer + uses: signpath/github-action-submit-signing-request@v1 + with: + api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' + organization-id: 645b821f-6283-45e1-8198-264997072801 + project-slug: OpenRCT2 + signing-policy-slug: 'test-signing' + artifact-configuration-slug: 'installer' + github-artifact-id: ${{ steps.upload-windows-installer-unsigned.outputs.artifact-id }} + wait-for-completion: true + output-artifact-directory: files-signed + - name: Upload signed installer artifact (CI) + id: upload-windows-installer-signed uses: actions/upload-artifact@v4 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-installer-${{ matrix.platform }} - path: artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-installer-${{ matrix.platform }}.exe + path: files-signed/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-installer-${{ matrix.platform }}.exe if-no-files-found: error - name: Upload symbols artifact (CI) uses: actions/upload-artifact@v4 From 38a59d9831931ed9f5db9f5d2b41779848d49bf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sat, 16 Nov 2024 17:55:47 +0100 Subject: [PATCH 036/139] Make MSVC ARM64 build download g2.dat --- .github/workflows/ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9376a52b76..81b6a4b880 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,7 +139,7 @@ jobs: windows: name: Windows runs-on: windows-latest - needs: [check-code-formatting, build_variables] + needs: [check-code-formatting, build_variables, g2dat] strategy: fail-fast: false matrix: @@ -181,6 +181,12 @@ jobs: github-artifact-id: ${{ steps.upload-windows-binaries-unsigned.outputs.artifact-id }} wait-for-completion: true output-artifact-directory: files-signed + - name: Download g2.dat on ARM64 + if: matrix.platform == 'arm64' + uses: actions/download-artifact@v4 + with: + name: g2-${{ needs.build_variables.outputs.name }}.dat + path: bin/data/g2.dat - name: Build artifacts run: | . scripts/setenv -q From edd82f968cf76ac31c0c5be5a04782a7a8c31a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sat, 16 Nov 2024 18:30:23 +0100 Subject: [PATCH 037/139] Filter which artifacts get uploaded in the release job --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 81b6a4b880..a0cfdd0288 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -587,6 +587,10 @@ jobs: uses: actions/download-artifact@v4 with: merge-multiple: true + # Having multiple artifacts named the same might be onfusing to the users. Drop the unsigned versions + - name: Remove unsigned artifacts + run: | + rm -rf *unsigned* - name: Concatenate sha1 files run: | ls -lR From ef1d59e3b605423bba07a7ea575391423ae15fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sat, 16 Nov 2024 19:43:17 +0100 Subject: [PATCH 038/139] Only sign conditionally when token is present --- .github/workflows/ci.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a0cfdd0288..3d3bca3cdd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,7 @@ jobs: distance: ${{ steps.ghd.outputs.distance }} tag: ${{ steps.ghd.outputs.tag }} push: ${{ steps.setenv.outputs.push }} + sign: ${{ steps.sign.outputs.sign }} steps: # We need to fetch entire repo to get the tags and correctly run `describe` - name: Check out code @@ -75,6 +76,11 @@ jobs: run: | echo "name=${{ steps.ghd.outputs.describe }}" echo "name=${{ steps.ghd.outputs.describe }}" >> $GITHUB_OUTPUT + - name: Sign + id: sign + run: | + echo "sign=${{ env.SIGNPATH_API_TOKEN != '' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }}" + echo "sign=${{ env.SIGNPATH_API_TOKEN != '' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }}" >> $GITHUB_OUTPUT lint-commit: name: Lint Commit Message if: github.event_name == 'pull_request' @@ -169,8 +175,12 @@ jobs: path: | bin/openrct2.exe bin/openrct2.com + # Sign the binaries first, so that all other artifacts (portable, installer, symbols) use signed binaries - name: Sign binaries id: sign-binaries + env: + SIGNPATH_API_TOKEN: ${{ secrets.SIGNPATH_API_TOKEN }} + if: ${{ needs.build_variables.outputs.sign == 'true' }} uses: signpath/github-action-submit-signing-request@v1 with: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' @@ -181,6 +191,11 @@ jobs: github-artifact-id: ${{ steps.upload-windows-binaries-unsigned.outputs.artifact-id }} wait-for-completion: true output-artifact-directory: files-signed + - name: Use signed binaries + if: ${{ needs.build_variables.outputs.sign == 'true' }} + run: | + mv files-signed/openrct2.com bin/openrct2.com + mv files-signed/openrct2.exe bin/openrct2.exe - name: Download g2.dat on ARM64 if: matrix.platform == 'arm64' uses: actions/download-artifact@v4 @@ -190,8 +205,6 @@ jobs: - name: Build artifacts run: | . scripts/setenv -q - mv files-signed/openrct2.com bin/openrct2.com - mv files-signed/openrct2.exe bin/openrct2.exe build-portable build-symbols build-installer -i @@ -215,6 +228,7 @@ jobs: if-no-files-found: error - name: Sign installer id: sign-installer + if: ${{ needs.build_variables.outputs.sign == 'true' }} uses: signpath/github-action-submit-signing-request@v1 with: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' @@ -227,6 +241,7 @@ jobs: output-artifact-directory: files-signed - name: Upload signed installer artifact (CI) id: upload-windows-installer-signed + if: ${{ needs.build_variables.outputs.sign == 'true' }} uses: actions/upload-artifact@v4 with: name: OpenRCT2-${{ needs.build_variables.outputs.name }}-${{ runner.os }}-installer-${{ matrix.platform }} From d784587374b21572c32441c14281f0618c4b04d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sat, 16 Nov 2024 20:51:22 +0100 Subject: [PATCH 039/139] Validate certificates used for signing --- .github/workflows/ci.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d3bca3cdd..caec1c4e51 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,16 @@ on: - '.github/workflows/localisation.yml' - '.gitignore' - '.vscode/**' + workflow_dispatch: + inputs: + sign: + description: Sign binaries + type: choice + options: + - test-signing + - release-signing + default: test-signing + defaults: run: shell: bash @@ -34,6 +44,11 @@ jobs: build_variables: name: Get version info runs-on: ubuntu-latest + # We want to sign tagged releases with release certificates, but it is only allowed to be ran manually. + # Disable automatic runs for tags and force release signing for tags. + if: | + (startsWith(github.ref, 'refs/tags/v') && github.event_name == 'workflow_dispatch' && github.event.inputs.sign == 'release-signing') || + (!startsWith(github.ref, 'refs/tags/v') && github.event.inputs.sign != 'release-signing') outputs: name: ${{ steps.artifact-name.outputs.name }} describe: ${{ steps.ghd.outputs.describe }} @@ -42,6 +57,7 @@ jobs: tag: ${{ steps.ghd.outputs.tag }} push: ${{ steps.setenv.outputs.push }} sign: ${{ steps.sign.outputs.sign }} + certificate: ${{ steps.sign.outputs.certificate }} steps: # We need to fetch entire repo to get the tags and correctly run `describe` - name: Check out code @@ -80,7 +96,16 @@ jobs: id: sign run: | echo "sign=${{ env.SIGNPATH_API_TOKEN != '' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }}" + # if using workflow_dispatch, use the provided certificate + if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then + certificate=${{ github.event.inputs.sign }} + else + # Default to test-signing + certificate=test-signing + fi + echo "certificate=$certificate" echo "sign=${{ env.SIGNPATH_API_TOKEN != '' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }}" >> $GITHUB_OUTPUT + echo "certificate=$certificate" >> $GITHUB_OUTPUT lint-commit: name: Lint Commit Message if: github.event_name == 'pull_request' @@ -186,7 +211,7 @@ jobs: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' organization-id: 645b821f-6283-45e1-8198-264997072801 project-slug: OpenRCT2 - signing-policy-slug: 'test-signing' + signing-policy-slug: ${{ needs.build_variables.outputs.certificate }} artifact-configuration-slug: 'binaries' github-artifact-id: ${{ steps.upload-windows-binaries-unsigned.outputs.artifact-id }} wait-for-completion: true @@ -234,7 +259,7 @@ jobs: api-token: '${{ secrets.SIGNPATH_API_TOKEN }}' organization-id: 645b821f-6283-45e1-8198-264997072801 project-slug: OpenRCT2 - signing-policy-slug: 'test-signing' + signing-policy-slug: ${{ needs.build_variables.outputs.certificate }} artifact-configuration-slug: 'installer' github-artifact-id: ${{ steps.upload-windows-installer-unsigned.outputs.artifact-id }} wait-for-completion: true From 91d33c6152300863ccf5a7a6d22df25bff50aad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 18:38:14 +0100 Subject: [PATCH 040/139] Make more jobs require build_variable, so that we exit early --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index caec1c4e51..a369260d88 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -333,7 +333,7 @@ jobs: macos-cmake: name: macOS (${{ matrix.arch }}) using CMake runs-on: macos-14 - needs: check-code-formatting + needs: [check-code-formatting, build_variables] strategy: fail-fast: false matrix: @@ -505,7 +505,7 @@ jobs: if-no-files-found: error linux-docker: name: Ubuntu Linux (Docker) - needs: check-code-formatting + needs: [check-code-formatting, build_variables] if: github.repository == 'OpenRCT2/OpenRCT2' && github.ref == 'refs/heads/develop' runs-on: ubuntu-latest steps: @@ -531,7 +531,7 @@ jobs: linux-clang: name: Ubuntu Linux (noble, debug, [http, network, flac, vorbis OpenGL] disabled) using clang runs-on: ubuntu-latest - needs: check-code-formatting + needs: [check-code-formatting, build_variables] container: openrct2/openrct2-build:16-noble steps: - name: Checkout From b9b294e84a81f828b9d599c6330db6d7f8737e25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 19:55:58 +0100 Subject: [PATCH 041/139] Print job info to release notes --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a369260d88..2a024c6bf0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -643,11 +643,16 @@ jobs: sed -n '1,/^$/p' distribution/changelog.txt >> release_notes.txt echo "" >> release_notes.txt + echo "Release created in ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> release_notes.txt + echo "" >> release_notes.txt + echo "SHA1 checksums:" >> release_notes.txt echo "\`\`\`" >> release_notes.txt cat OpenRCT2-${{ needs.build_variables.outputs.name }}-sha1sums.txt >> release_notes.txt echo "\`\`\`" >> release_notes.txt echo "" >> release_notes.txt + + cat release_notes.txt # Only upload tagged releases, mark them as draft for manual verification - name: Create tagged release uses: softprops/action-gh-release@v2 From e8742c16e4582b887dd62e136ae749e82ab799dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 20:49:13 +0100 Subject: [PATCH 042/139] Drop duplicate release asset --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a024c6bf0..cd85cf2104 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -660,7 +660,6 @@ jobs: with: draft: true files: | - OpenRCT2-${{ needs.build_variables.outputs.name }}-sha1sums.txt OpenRCT2-${{ needs.build_variables.outputs.name }}-* body_path: release_notes.txt tag_name: ${{ needs.build_variables.outputs.tag }} From 52f95f5d31cda80760bcdc7b38a78ffc9d35f1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 20:53:34 +0100 Subject: [PATCH 043/139] Don't sign if not set manually --- .github/workflows/ci.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd85cf2104..6f0e8df563 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,7 @@ on: description: Sign binaries type: choice options: + - 'no' - test-signing - release-signing default: test-signing @@ -95,16 +96,18 @@ jobs: - name: Sign id: sign run: | - echo "sign=${{ env.SIGNPATH_API_TOKEN != '' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }}" + sign=${{ env.SIGNPATH_API_TOKEN != '' && github.event.inputs.sign != 'no' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }} # if using workflow_dispatch, use the provided certificate if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then certificate=${{ github.event.inputs.sign }} else - # Default to test-signing - certificate=test-signing + # Default to no signing + certificate=no + sign=false fi + echo "sign=$sign" echo "certificate=$certificate" - echo "sign=${{ env.SIGNPATH_API_TOKEN != '' && (needs.build_variables.outputs.push || startsWith(github.ref, 'refs/tags/v')) }}" >> $GITHUB_OUTPUT + echo "sign=$sign" >> $GITHUB_OUTPUT echo "certificate=$certificate" >> $GITHUB_OUTPUT lint-commit: name: Lint Commit Message From 34b9f369890be7971a8622d63797148fc6f50f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 22:37:48 +0100 Subject: [PATCH 044/139] Fix setting of env variables --- .github/workflows/ci.yml | 1 + scripts/build | 20 +++++++++----------- scripts/setenv | 4 +--- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f0e8df563..73221b677b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,6 +180,7 @@ jobs: platform: [win32, x64, arm64] env: PLATFORM: ${{ matrix.platform }} + DISTANCE_FROM_TAG: ${{ needs.build_variables.outputs.distance }} steps: - name: Setup environment run: | diff --git a/scripts/build b/scripts/build index c1dbe3a00a..5e6164d204 100755 --- a/scripts/build +++ b/scripts/build @@ -12,17 +12,15 @@ cd $basedir if [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]]; then # Patch version.h - if [[ -n "$OPENRCT2_BUILD" ]]; then - echo -e "\033[0;36mPatching version.h...\033[0m" - fileversion=$OPENRCT2_VERSION.$OPENRCT2_BUILD - productversion="$fileversion-${OPENRCT2_SHA1_SHORT}" - fileversion=${fileversion//./,} - # FILEVERSION in the resource file can only take up to 4 digits in the version string, so we remove the surplus of version numbers - fileversion=$(echo $fileversion | cut -f1-4 -d",") - echo "#define OPENRCT2_FILE_VERSION $fileversion" > "resources/version.h" - echo "#define OPENRCT2_PRODUCT_VERSION \"$productversion\"" >> "resources/version.h" - cat "resources/version.h" - fi + echo -e "\033[0;36mPatching version.h...\033[0m" + fileversion=$OPENRCT2_VERSION.$OPENRCT2_BUILD + productversion="$fileversion-${OPENRCT2_SHA1_SHORT}" + fileversion=${fileversion//./,} + # FILEVERSION in the resource file can only take up to 4 digits in the version string, so we remove the surplus of version numbers + fileversion=$(echo $fileversion | cut -f1-4 -d",") + echo "#define OPENRCT2_FILE_VERSION $fileversion" > "resources/version.h" + echo "#define OPENRCT2_PRODUCT_VERSION \"$productversion\"" >> "resources/version.h" + cat "resources/version.h" # Build everything echo -e "\033[0;36mBuilding OpenRCT2 for Windows $CONFIGURATION|$PLATFORM...\033[0m" diff --git a/scripts/setenv b/scripts/setenv index 9ad51e1643..ef2593f60e 100755 --- a/scripts/setenv +++ b/scripts/setenv @@ -16,9 +16,7 @@ echo -e "\033[0;36mSetting up environment for OpenRCT2...\033[0m" # Get the build number (number of commits since last tag) get_build_number() { - local pattern='.+-([0-9]+)-.+' - [[ $OPENRCT2_DESCRIBE =~ $pattern ]] - echo "${BASH_REMATCH[1]}" + echo "${DISTANCE_FROM_TAG}" } export OPENRCT2_BUILD=$(get_build_number) From 6071dbb6d26e54d4dd9e49b1bea59ba484804403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 22:58:09 +0100 Subject: [PATCH 045/139] Specify version for signing --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73221b677b..254dc47a10 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -220,6 +220,8 @@ jobs: github-artifact-id: ${{ steps.upload-windows-binaries-unsigned.outputs.artifact-id }} wait-for-completion: true output-artifact-directory: files-signed + parameters: | + version: "${{ env.OPENRCT2_VERSION }}.${{ needs.build_variables.outputs.distance }}-${{ needs.build_variables.outputs.short-sha }}" - name: Use signed binaries if: ${{ needs.build_variables.outputs.sign == 'true' }} run: | From b2093f412b9ad215007597b5233d9c9847a89040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sun, 17 Nov 2024 23:22:55 +0100 Subject: [PATCH 046/139] Rename installers and use their version info for signing --- .github/workflows/ci.yml | 4 ++++ distribution/windows/install.nsi | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 254dc47a10..c5c17abf11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -239,6 +239,7 @@ jobs: build-portable build-symbols build-installer -i + echo "OPENRCT2_VERSION_EXTRA=$OPENRCT2_VERSION_EXTRA" >> "$GITHUB_ENV" - name: Rename artifacts run: | mv artifacts/openrct2-portable-*.zip artifacts/OpenRCT2-${{ needs.build_variables.outputs.name }}-windows-portable-$PLATFORM.zip @@ -270,6 +271,9 @@ jobs: github-artifact-id: ${{ steps.upload-windows-installer-unsigned.outputs.artifact-id }} wait-for-completion: true output-artifact-directory: files-signed + parameters: | + version: "${{ env.OPENRCT2_VERSION }}${{ env.OPENRCT2_VERSION_EXTRA }}" + product: "OpenRCT2 ${{ matrix.platform }} Installer for Windows 7 and later" - name: Upload signed installer artifact (CI) id: upload-windows-installer-signed if: ${{ needs.build_variables.outputs.sign == 'true' }} diff --git a/distribution/windows/install.nsi b/distribution/windows/install.nsi index 7f79863ffa..1dc320c392 100644 --- a/distribution/windows/install.nsi +++ b/distribution/windows/install.nsi @@ -35,7 +35,7 @@ SetCompressor LZMA ; Version Info VIProductVersion "${APPVERSIONINTERNAL}" -VIAddVersionKey "ProductName" "OpenRCT2 ${APPBITS}-bit Installer for ${SUPPORTED_OS}" +VIAddVersionKey "ProductName" "OpenRCT2 ${PLATFORM} Installer for ${SUPPORTED_OS}" VIAddVersionKey "Comments" "Installs ${APPNAMEANDVERSION}" VIAddVersionKey "CompanyName" "OpenRCT2 Developers" VIAddVersionKey "FileDescription" "Installs ${APPNAMEANDVERSION}" @@ -44,7 +44,7 @@ VIAddVersionKey "InternalName" "InstOpenRCT2-${APPARCH}" VIAddVersionKey "FileVersion" "${APPVERSION}-${APPARCH}" VIAddVersionKey "LegalCopyright" " " ; Main Install settings -Name "${APPNAMEANDVERSION} ${APPBITS}-bit for ${SUPPORTED_OS}" +Name "${APPNAMEANDVERSION} ${PLATFORM} for ${SUPPORTED_OS}" ; NOTE: Keep trailing backslash! InstallDirRegKey HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\OpenRCT2" "Install Folder" From 63c7c05d431210463d4c0e3cad82c4e41ec97205 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Mon, 18 Nov 2024 19:40:42 +0100 Subject: [PATCH 047/139] Add SignPath information to sponsors --- readme.md | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/readme.md b/readme.md index 83b455715f..2f5f41c04f 100644 --- a/readme.md +++ b/readme.md @@ -52,9 +52,10 @@ If you want to help translate the game to your language, please stop by the Loca - 4.4 - [Graphics](#44-graphics) - 4.5 - [Audio](#45-audio) - 4.6 - [Scenarios](#46-scenarios) -- 5 - [Licence](#5-licence) -- 6 - [More information](#6-more-information) -- 7 - [Sponsors](#7-sponsors) +- 5 - [Code signing policy](#5-code-signing-policy) +- 5 - [Licence](#6-licence) +- 6 - [More information](#7-more-information) +- 7 - [Sponsors](#8-sponsors) --- @@ -246,12 +247,22 @@ We would also like to distribute additional scenarios with the game, when the ti --- -# 5. Licence +# 5. Code signing policy + +We sign our releases digital certificate provided by SignPath Foundation. + +Free code signing provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/). + +Signed releases can only be done by member of the [development team](https://github.com/OpenRCT2/OpenRCT2/blob/develop/contributors.md#development-team). + +--- + +# 6. Licence **OpenRCT2** is licensed under the GNU General Public License version 3 or (at your option) any later version. See the [`licence.txt`](licence.txt) file for more details. --- -# 6. More information +# 7. More information - [GitHub](https://github.com/OpenRCT2/OpenRCT2) - [OpenRCT2.org](https://openrct2.org) - [Forums](https://openrct2.org/forums/) @@ -266,11 +277,11 @@ We would also like to distribute additional scenarios with the game, when the ti | [![icon_x128](https://user-images.githubusercontent.com/604665/53047651-2c533c00-3493-11e9-911a-1a3540fc1156.png)](https://github.com/OpenLoco/OpenLoco) | [![](https://github.com/OpenTTD/OpenTTD/raw/850d05d24d4768c81d97765204ef2a487dd4972c/media/openttd.128.png)](https://github.com/OpenTTD/OpenTTD) | [![](https://user-images.githubusercontent.com/550290/36507534-4693f354-175a-11e8-93a7-faa0481474fb.png)](https://github.com/SFTtech/openage) | [![](https://raw.githubusercontent.com/OpenRA/OpenRA/bleed/packaging/artwork/ra_128x128.png)](https://github.com/OpenRA/OpenRA) | | Chris Sawyer's Locomotion | Transport Tycoon Deluxe | Age of Empires 2 | Red Alert | -# 7. Sponsors +# 8. Sponsors Companies that kindly allow us to use their stuff: -| [DigitalOcean](https://www.digitalocean.com/) | [JetBrains](https://www.jetbrains.com/) | [Backtrace](https://backtrace.io/) | -|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| -| [![do_logo_vertical_blue svg](https://user-images.githubusercontent.com/550290/36508276-8b572f0e-175c-11e8-8622-9febbce756b2.png)](https://www.digitalocean.com/) | [![jetbrains](https://user-images.githubusercontent.com/550290/36413299-0e0985ea-161e-11e8-8a01-3ef523b5905b.png)](https://www.jetbrains.com/) | [![backtrace](https://user-images.githubusercontent.com/550290/47113259-d0647680-d258-11e8-97c3-1a2c6bde6d11.png)](https://backtrace.io/) | -| Hosting of various services | CLion and other products | Minidump uploads and inspection | +| [DigitalOcean](https://www.digitalocean.com/) | [JetBrains](https://www.jetbrains.com/) | [Backtrace](https://backtrace.io/) | [SignPath](https://signpath.org/) | +|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------| +| [![do_logo_vertical_blue svg](https://user-images.githubusercontent.com/550290/36508276-8b572f0e-175c-11e8-8622-9febbce756b2.png)](https://www.digitalocean.com/) | [![jetbrains](https://user-images.githubusercontent.com/550290/36413299-0e0985ea-161e-11e8-8a01-3ef523b5905b.png)](https://www.jetbrains.com/) | [![backtrace](https://user-images.githubusercontent.com/550290/47113259-d0647680-d258-11e8-97c3-1a2c6bde6d11.png)](https://backtrace.io/) | [![Image](https://github.com/user-attachments/assets/2b5679e0-76a4-4ae7-bb37-a6a507a53466)](https://signpath.org/) | +| Hosting of various services | CLion and other products | Minidump uploads and inspection | Code signing | From e77b284f448b7c24d4ccb2bd45ec9ed866c80791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Mon, 18 Nov 2024 19:54:32 +0100 Subject: [PATCH 048/139] Add privacy policy --- PRIVACY.md | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ readme.md | 19 ++++++++++++++++--- 2 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 PRIVACY.md diff --git a/PRIVACY.md b/PRIVACY.md new file mode 100644 index 0000000000..219dd55df1 --- /dev/null +++ b/PRIVACY.md @@ -0,0 +1,55 @@ +# Privacy Policy + +## Overview +This document describes how this project collects, handles, and processes data. + +## Data Collection +- No personal information is collected without explicit user consent +- For multiplayer functionality, we only collect necessary data: + - Username + - Game session data + - Network connection details + +## Data Storage +- User preferences and settings are stored locally on your device +- No sensitive data is transmitted to external servers +- Game saves and configurations remain on your local system + +## Network Communications +- Multiplayer sessions only transmit game-relevant data +- Server connections are used solely for gameplay functionality +- No tracking or analytics services are implemented + +## Crash Reporting +- Crash dumps may be sent to Backtrace.io for diagnostic purposes +- Each crash report transfer requires explicit user consent +- Crash dumps contain: + - System information + - Machine hostname + - System username + - Technical data about the crash + - In-game screenshot +- This data helps improve software stability +- Users can decline sending crash reports without limiting gameplay functionality +- Only team members have access to crash reports + +## Third-Party Services +If you use optional features: +- Server hosting services may collect connection data +- Plugin systems operate under their own privacy terms + +## User Rights +You have the right to: +- Access your data +- Delete your data +- Opt out of any data collection +- Request information about stored data + +## Changes to Privacy Policy +- Users will be notified of any privacy policy updates +- Changes will be documented in the project's changelog + +## Contact +For privacy concerns or questions, please open an issue in the project repository or contact the team via [Discord](https://discord.gg/ZXZd8D8) + +Last updated: 2024-11-18 diff --git a/readme.md b/readme.md index 2f5f41c04f..b1435910cf 100644 --- a/readme.md +++ b/readme.md @@ -52,7 +52,10 @@ If you want to help translate the game to your language, please stop by the Loca - 4.4 - [Graphics](#44-graphics) - 4.5 - [Audio](#45-audio) - 4.6 - [Scenarios](#46-scenarios) -- 5 - [Code signing policy](#5-code-signing-policy) +- 5 - [Policies](#5-policies) + - 5.1 - [Code of conduct](#51-code-of-conduct) + - 5.2 - [Code signing policy](#52-code-signing-policy) + - 5.3 - [Privacy policy](#53-privacy-policy) - 5 - [Licence](#6-licence) - 6 - [More information](#7-more-information) - 7 - [Sponsors](#8-sponsors) @@ -247,14 +250,24 @@ We would also like to distribute additional scenarios with the game, when the ti --- -# 5. Code signing policy +# 5. Policies -We sign our releases digital certificate provided by SignPath Foundation. +## 5.1 Code of Conduct + +We have a [Code of Conduct](CODE_OF_CONDUCT.md) that applies to all OpenRCT2 projects. Please read it. + +## 5.2 Code signing policy + +We sign our releases with a digital certificate provided by SignPath Foundation. Free code signing provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/). Signed releases can only be done by member of the [development team](https://github.com/OpenRCT2/OpenRCT2/blob/develop/contributors.md#development-team). +## 5.3 Privacy policy + +See [PRIVACY.md](PRIVACY.md) for more information. + --- # 6. Licence From 41b13197d1d3b1ad94d1551e57d079895ebdb60c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Tue, 19 Nov 2024 23:56:49 +0100 Subject: [PATCH 049/139] Distribute Privacy policy in all the artifacts --- CMakeLists.txt | 1 + distribution/readme.txt | 11 ++++++++--- distribution/windows/install.nsi | 6 ++++++ scripts/build-portable | 1 + src/openrct2-ui/CMakeLists.txt | 2 ++ src/openrct2/command_line/RootCommands.cpp | 7 ++++--- 6 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d1396c5c..e6ad88c07e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -436,6 +436,7 @@ if (NOT MACOS_BUNDLE OR (MACOS_BUNDLE AND WITH_TESTS)) add_definitions(-DDOCDIR="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DOCDIR}") file(GLOB DOC_FILES "${ROOT_DIR}/distribution/*.txt") list(APPEND DOC_FILES "${ROOT_DIR}/contributors.md" + "${ROOT_DIR}/PRIVACY.md" "${ROOT_DIR}/licence.txt" "${ROOT_DIR}/distribution/scripting.md" "${ROOT_DIR}/distribution/openrct2.d.ts") diff --git a/distribution/readme.txt b/distribution/readme.txt index e2865eb25b..e71efd79e2 100644 --- a/distribution/readme.txt +++ b/distribution/readme.txt @@ -1,4 +1,4 @@ -Last updated: 2024-08-04 +Last updated: 2024-11-19 ------------------------------------------------------------------------ @@ -13,7 +13,8 @@ Table of contents 6.0) Translation 7.0) Troubleshooting 8.0) Licensing -9.0) Credits +9.0) Privacy policy +10.0) Credits 1.0) About ---- ----- @@ -156,6 +157,10 @@ Google Benchmark | Apache 2.0 licence. Licences for sub-libraries used by the above may vary. For more information, visit the libraries' respective official websites. -9.0) Credits +9.0) Privacy policy + +For privacy policy, see the file 'PRIVACY.md'. + +10.0) Credits ---- ------- For the full list of contributors to OpenRCT2, see the file 'contributors.md'. diff --git a/distribution/windows/install.nsi b/distribution/windows/install.nsi index 1dc320c392..67fb7f5d82 100644 --- a/distribution/windows/install.nsi +++ b/distribution/windows/install.nsi @@ -170,6 +170,9 @@ Section "!OpenRCT2" Section1 File ..\..\contributors.md Push "$INSTDIR\contributors.md" Call unix2dos + File ..\..\PRIVACY.md + Push "$INSTDIR\PRIVACY.md" + Call unix2dos File ..\scripting.md Push "$INSTDIR\scripting.md" Call unix2dos @@ -204,6 +207,7 @@ Section "!OpenRCT2" Section1 CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Readme.lnk" "$INSTDIR\Readme.txt" CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Changelog.lnk" "$INSTDIR\Changelog.txt" CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Contributors.lnk" "$INSTDIR\contributors.md" + CreateShortCut "$SMPROGRAMS\$SHORTCUTS\PrivacyPolicy.lnk" "$INSTDIR\PRIVACY.md" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd @@ -240,12 +244,14 @@ Section "Uninstall" Delete "$SMPROGRAMS\$SHORTCUTS\Readme.lnk" Delete "$SMPROGRAMS\$SHORTCUTS\Changelog.lnk" Delete "$SMPROGRAMS\$SHORTCUTS\Contributors.lnk" + Delete "$SMPROGRAMS\$SHORTCUTS\PrivacyPolicy.lnk" ; Clean up OpenRCT2 dir Delete "$INSTDIR\changelog.txt" Delete "$INSTDIR\licence.txt" Delete "$INSTDIR\readme.txt" Delete "$INSTDIR\contributors.md" + Delete "$INSTDIR\PRIVACY.md" Delete "$INSTDIR\scripting.md" Delete "$INSTDIR\openrct2.d.ts" Delete "$INSTDIR\${OPENRCT2_EXE}" diff --git a/scripts/build-portable b/scripts/build-portable index 50b85d251e..61cda98659 100755 --- a/scripts/build-portable +++ b/scripts/build-portable @@ -22,6 +22,7 @@ if [[ "$OSTYPE" == "cygwin" || "$OSTYPE" == "msys" ]]; then 7z a -r $destination \ openrct2.exe openrct2.com data \ ../contributors.md \ + ../PRIVACY.md \ ../licence.txt \ ../distribution/changelog.txt \ ../distribution/readme.txt \ diff --git a/src/openrct2-ui/CMakeLists.txt b/src/openrct2-ui/CMakeLists.txt index b321a5dedb..d98a5a159f 100644 --- a/src/openrct2-ui/CMakeLists.txt +++ b/src/openrct2-ui/CMakeLists.txt @@ -184,6 +184,7 @@ if(MACOS_BUNDLE) PUBLIC ${ROOT_DIR}/distribution/readme.txt PUBLIC ${ROOT_DIR}/distribution/changelog.txt PUBLIC ${ROOT_DIR}/contributors.md + PUBLIC ${ROOT_DIR}/PRIVACY.md PUBLIC ${ROOT_DIR}/resources/mac/openrct2.icns ) @@ -192,6 +193,7 @@ if(MACOS_BUNDLE) ${ROOT_DIR}/distribution/readme.txt ${ROOT_DIR}/distribution/changelog.txt ${ROOT_DIR}/contributors.md + ${ROOT_DIR}/PRIVACY.md ${ROOT_DIR}/resources/mac/openrct2.icns ) diff --git a/src/openrct2/command_line/RootCommands.cpp b/src/openrct2/command_line/RootCommands.cpp index 2fe5c348e0..3fe044d43d 100644 --- a/src/openrct2/command_line/RootCommands.cpp +++ b/src/openrct2/command_line/RootCommands.cpp @@ -439,9 +439,10 @@ static void PrintAbout() Console::WriteLine("includes some 3rd party software under different licenses. See the file"); Console::WriteLine("\"licence.txt\" shipped with the game for details."); Console::WriteLine(); - Console::WriteLine("Website: https://openrct2.io"); - Console::WriteLine("GitHub: https://github.com/OpenRCT2/OpenRCT2"); - Console::WriteLine("Contributors: https://github.com/OpenRCT2/OpenRCT2/blob/develop/contributors.md"); + Console::WriteLine("Website: https://openrct2.io"); + Console::WriteLine("GitHub: https://github.com/OpenRCT2/OpenRCT2"); + Console::WriteLine("Contributors: https://github.com/OpenRCT2/OpenRCT2/blob/develop/contributors.md"); + Console::WriteLine("Privacy Policy: https://github.com/OpenRCT2/OpenRCT2/blob/develop/PRIVACY.md"); Console::WriteLine(); } From 759d850e56ee70d96a50a98cec1be7a8eaaf2808 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sat, 23 Nov 2024 10:39:17 +0000 Subject: [PATCH 050/139] Fix #23238: Guest ride favourite mistake Mistake made during implementation. --- CMakeLists.txt | 4 ++-- distribution/changelog.txt | 1 + openrct2.proj | 4 ++-- src/openrct2/entity/Guest.cpp | 22 +++++++++++----------- src/openrct2/network/NetworkBase.cpp | 2 +- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d1396c5c..0e76f1d9c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,9 +81,9 @@ set(OPENMSX_VERSION "1.6") set(OPENMSX_URL "https://github.com/OpenRCT2/OpenMusic/releases/download/v${OPENMSX_VERSION}/openmusic.zip") set(OPENMSX_SHA1 "ba170fa6d777b309c15420f4b6eb3fa25082a9d1") -set(REPLAYS_VERSION "0.0.83") +set(REPLAYS_VERSION "0.0.84") set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip") -set(REPLAYS_SHA1 "FFC98C36AFEC68DC6A48E863413D4E2364A202B3") +set(REPLAYS_SHA1 "90B848AB344E29A2CF1E3E48539F06F5845772C3") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/distribution/changelog.txt b/distribution/changelog.txt index cf74b70b6c..2b502777bf 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -5,6 +5,7 @@ - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). - Fix: [#23206] Multiplayer desyncs when FPS is uncapped. +- Fix: [#23238] Updating a guest’s favourite ride works differently from vanilla RCT2. 0.4.16 (2024-11-03) ------------------------------------------------------------------------ diff --git a/openrct2.proj b/openrct2.proj index 1d96adb75c..f48b09c334 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -51,8 +51,8 @@ b1b1f1b241d2cbff63a1889c4dc5a09bdf769bfb https://github.com/OpenRCT2/OpenMusic/releases/download/v1.6/openmusic.zip ba170fa6d777b309c15420f4b6eb3fa25082a9d1 - https://github.com/OpenRCT2/replays/releases/download/v0.0.83/replays.zip - FFC98C36AFEC68DC6A48E863413D4E2364A202B3 + https://github.com/OpenRCT2/replays/releases/download/v0.0.84/replays.zip + 90B848AB344E29A2CF1E3E48539F06F5845772C3 diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index 8950d68c9c..13a160e37f 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -440,7 +440,7 @@ static void PeepRideIsTooIntense(Guest* peep, Ride& ride, bool peepAtRide); static void PeepResetRideHeading(Guest* peep); static void PeepTriedToEnterFullQueue(Guest* peep, Ride& ride); static int16_t PeepCalculateRideSatisfaction(Guest* peep, const Ride& ride); -static void PeepUpdateFavouriteRide(Guest* peep, const Ride& ride); +static void GuestUpdateFavouriteRide(Guest& peep, const Ride& ride, const uint8_t satisfaction); static int16_t PeepCalculateRideValueSatisfaction(Guest* peep, const Ride& ride); static int16_t PeepCalculateRideIntensityNauseaSatisfaction(Guest* peep, const Ride& ride); static void PeepUpdateRideNauseaGrowth(Guest* peep, const Ride& ride); @@ -1761,7 +1761,7 @@ void Guest::OnEnterRide(Ride& ride) GuestNumRides++; SetHasRidden(ride); - PeepUpdateFavouriteRide(this, ride); + GuestUpdateFavouriteRide(*this, ride, satisfaction); HappinessTarget = std::clamp(HappinessTarget + satisfaction, 0, kPeepMaxHappiness); PeepUpdateRideNauseaGrowth(this, ride); } @@ -2703,24 +2703,24 @@ static int16_t PeepCalculateRideSatisfaction(Guest* peep, const Ride& ride) /** * Check to see if the specified ride should become the peep's favourite. - * For this, a "ride rating" is calculated based on the excitement of the ride and the peep's current happiness. - * As this value cannot exceed 255, the happier the peep is, the more irrelevant the ride's excitement becomes. + * For this, a "ride rating" is calculated based on the excitement of the ride and the satisfaction of the ride. + * As this value cannot exceed 255, the more satisfied the peep is, the more irrelevant the ride's excitement becomes. * Due to the minimum happiness requirement, an excitement rating of more than 3.8 has no further effect. * * If the ride rating is higher than any ride the peep has already been on and the happiness criteria is met, * the ride becomes the peep's favourite. (This doesn't happen right away, but will be updated once the peep * exits the ride.) */ -static void PeepUpdateFavouriteRide(Guest* peep, const Ride& ride) +static void GuestUpdateFavouriteRide(Guest& peep, const Ride& ride, uint8_t satisfaction) { - peep->PeepFlags &= ~PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE; - uint8_t peepRideRating = std::clamp((ride.ratings.excitement / 4) + peep->Happiness, 0, kPeepMaxHappiness); - if (peepRideRating >= peep->FavouriteRideRating) + peep.PeepFlags &= ~PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE; + uint8_t peepRideRating = std::clamp((ride.ratings.excitement / 4) + satisfaction, 0, kPeepMaxHappiness); + if (peepRideRating >= peep.FavouriteRideRating) { - if (peep->Happiness >= 160 && peep->HappinessTarget >= 160) + if (peep.Happiness >= 160 && peep.HappinessTarget >= 160) { - peep->FavouriteRideRating = peepRideRating; - peep->PeepFlags |= PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE; + peep.FavouriteRideRating = peepRideRating; + peep.PeepFlags |= PEEP_FLAGS_RIDE_SHOULD_BE_MARKED_AS_FAVOURITE; } } } diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index d8095e0b6e..b739f31ecd 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -49,7 +49,7 @@ using namespace OpenRCT2; // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -constexpr uint8_t kNetworkStreamVersion = 1; +constexpr uint8_t kNetworkStreamVersion = 2; const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion); From 21ce7d87922e94be753faa0a6713b9f0c045a3e3 Mon Sep 17 00:00:00 2001 From: Joan Josep Date: Sat, 23 Nov 2024 11:58:59 +0100 Subject: [PATCH 051/139] Add ca-ES translation to Flathub package, add missing releases Co-authored-by: Michael Steenbeek <1478678+Gymnasiast@users.noreply.github.com> --- distribution/linux/openrct2.appdata.xml | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/distribution/linux/openrct2.appdata.xml b/distribution/linux/openrct2.appdata.xml index f7a9a962de..693010aefb 100644 --- a/distribution/linux/openrct2.appdata.xml +++ b/distribution/linux/openrct2.appdata.xml @@ -5,7 +5,9 @@ GPL-3.0 OpenRCT2 Amusement park simulation + Simulador de parcs d’atraccions The OpenRCT2 Team + Equip de l’OpenRCT2 openrct2.desktop

@@ -17,23 +19,58 @@ objective in a set time limit whilst sandbox allows the player to build a more flexible park with optionally no restrictions or finance.

+

+ L’OpenRCT2 és una reimplementació de codi obert del RollerCoaster Tycoon 2 (RCT2). + El joc consisteix en construir i mantenir un parc d’atraccions i gestionar-ne també + les paradetes i instal·lacions. El jugador ha d’obtenir beneficis i mantenir una bona + reputació del seu parc i alhora fer que els seus visitants siguin feliços. L’OpenRCT2 + permet jugar en escenaris o en mode lliure. Als escenaris, el jugador ha de completar + alguns objectius en un determinat període de temps, mentre que al mode lliure pot + construir amb més flexibilitat, fins i tot sense restriccions. +

+

OpenRCT2 features many changes compared to the original RollerCoaster Tycoon 2 game. A few of them are listed here.

+

+ L’OpenRCT2 té molts canvis respecte al joc RollerCoaster Tycoon 2 original, com ara: +

+
  • User Interface theming.
  • +
  • Temes per a la interfície gràfica
  • +
  • Fast-forwarding gameplay.
  • +
  • Diferents velocitats de joc disponibles durant la partida
  • +
  • Multiplayer support.
  • +
  • Suport multijugador
  • +
  • Multilingual. Improved translations.
  • +
  • Traduït a diversos idiomes i amb traduccions millorades
  • +
  • OpenGL hardware rendering.
  • +
  • Renderització OpenGL per maquinari
  • +
  • Various fixes and improvements for bugs in the original game.
  • +
  • Correccions i millores dels errors del joc original
  • +
  • Native support for Linux and macOS.
  • +
  • Suport natiu per a Linux i macOS
  • +
  • Added hacks and cheats.
  • +
  • Es poden fer trucs i trampes
  • +
  • Auto-saving and giant screenshots.
  • +
  • Desades automàtiques i captures de pantalla gegants
+

Original RollerCoaster Tycoon 2 or RollerCoaster Tycoon Classic game files are required in order to play OpenRCT2.

+

+ Per a jugar a l’OpenRCT2, fan falta els fitxers originals del RollerCoaster Tycoon 2 o del RollerCoaster Tycoon clàssic. +

From 4b259807af372035c38630e84b579823ea656139 Mon Sep 17 00:00:00 2001 From: TELK Date: Sun, 24 Nov 2024 05:16:18 +0900 Subject: [PATCH 052/139] ko-KR: Add translation to Flathub package Apply OpenRCT2/Localisation#2973 --- distribution/linux/openrct2.appdata.xml | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/distribution/linux/openrct2.appdata.xml b/distribution/linux/openrct2.appdata.xml index 693010aefb..43e3340151 100644 --- a/distribution/linux/openrct2.appdata.xml +++ b/distribution/linux/openrct2.appdata.xml @@ -6,7 +6,9 @@ OpenRCT2 Amusement park simulation Simulador de parcs d’atraccions + 놀이공원 시뮬레이션 The OpenRCT2 Team + OpenRCT2 팀 Equip de l’OpenRCT2 openrct2.desktop @@ -28,6 +30,15 @@ alguns objectius en un determinat període de temps, mentre que al mode lliure pot construir amb més flexibilitat, fins i tot sense restriccions.

+

+ OpenRCT는 RollerCoaster Tycoon 2 (RCT2)의 오픈 소스 재구현판입니다. + 놀이기구, 상점, 매점 등을 건설하고 유지하는 것이 게임 플레이의 중심이 됩니다. + 플레이어는 수익을 내고 손님을 만족시키는 동시에 좋은 공원 평판을 유지해야 합니다. + OpenRCT2에서는 시나리오나 모래상자 플레이를 모두 플레이할 수 있습니다. + 시나리오에서는 플레이어가 정해진 시간 이내에 특정 목표를 완수해야 하는 반면, + 모래상자에서는 플레이어가 자금이타 금지 행위에 대한 제한 없이 더 유연한 공원을 + 만들 수 있습니다. +

OpenRCT2 features many changes compared to the original RollerCoaster Tycoon 2 game. A few of them are listed here. @@ -35,34 +46,46 @@

L’OpenRCT2 té molts canvis respecte al joc RollerCoaster Tycoon 2 original, com ara:

+

+ OpenRCT2는 오리지널 RollerCoaster Tycoon 2 게임에 비해 많은 기능적 변화가 있습니다. 여기에 일부 기능이 나열되어 있습니다. +

  • User Interface theming.
  • Temes per a la interfície gràfica
  • +
  • 유저 인터페이스 커스터마이징
  • Fast-forwarding gameplay.
  • Diferents velocitats de joc disponibles durant la partida
  • +
  • 게임 속도 조절
  • Multiplayer support.
  • Suport multijugador
  • +
  • 멀티플레이 지원
  • Multilingual. Improved translations.
  • Traduït a diversos idiomes i amb traduccions millorades
  • +
  • 다국어 지원 및 번역 개선
  • OpenGL hardware rendering.
  • Renderització OpenGL per maquinari
  • +
  • OpenGL 하드웨어 렌더링
  • Various fixes and improvements for bugs in the original game.
  • Correccions i millores dels errors del joc original
  • +
  • 오리지널 게임에 있던 다양한 버그 수정 및 개선
  • Native support for Linux and macOS.
  • Suport natiu per a Linux i macOS
  • +
  • Linux 및 macOS 자체 지원
  • Added hacks and cheats.
  • Es poden fer trucs i trampes
  • +
  • 치트 기능 지원
  • Auto-saving and giant screenshots.
  • Desades automàtiques i captures de pantalla gegants
  • +
  • 자동 저장 및 대형 스크린 샷

@@ -71,11 +94,15 @@

Per a jugar a l’OpenRCT2, fan falta els fitxers originals del RollerCoaster Tycoon 2 o del RollerCoaster Tycoon clàssic.

+

+ OpenRCT2를 플레이하기 위해서는 오리지널 RollerCoaster Tycoon 2 또는 RollerCoaster Tycoon Classic 게임 파일이 필요합니다. +

https://camo.githubusercontent.com/f513bc551e2c9e04e292724113ea4789726d23921d286f21dad39a6e955b5a56/68747470733a2f2f692e696d6775722e636f6d2f6537434b3553632e706e67 Amusement park featuring an inverted roller coaster, a river rapids ride and custom scenery + 인버티드 롤러코스터를 구현한 놀이공원과 리버 래피드 기구 및 커스텀 풍경 오브젝트 https://openrct2.io/ From 01d23d81f0ff3c93c3a3944b2936a7820d3643ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Sat, 23 Nov 2024 21:38:53 +0100 Subject: [PATCH 053/139] Apply suggestions from code review Co-authored-by: Michael Steenbeek <1478678+Gymnasiast@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- distribution/windows/install.nsi | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5c17abf11..2036f5b300 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -637,7 +637,7 @@ jobs: uses: actions/download-artifact@v4 with: merge-multiple: true - # Having multiple artifacts named the same might be onfusing to the users. Drop the unsigned versions + # Having multiple artifacts named the same might be confusing to the users. Drop the unsigned versions. - name: Remove unsigned artifacts run: | rm -rf *unsigned* diff --git a/distribution/windows/install.nsi b/distribution/windows/install.nsi index 67fb7f5d82..a9a4bac6c0 100644 --- a/distribution/windows/install.nsi +++ b/distribution/windows/install.nsi @@ -207,7 +207,7 @@ Section "!OpenRCT2" Section1 CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Readme.lnk" "$INSTDIR\Readme.txt" CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Changelog.lnk" "$INSTDIR\Changelog.txt" CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Contributors.lnk" "$INSTDIR\contributors.md" - CreateShortCut "$SMPROGRAMS\$SHORTCUTS\PrivacyPolicy.lnk" "$INSTDIR\PRIVACY.md" + CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Privacy Policy.lnk" "$INSTDIR\PRIVACY.md" !insertmacro MUI_STARTMENU_WRITE_END SectionEnd @@ -244,7 +244,7 @@ Section "Uninstall" Delete "$SMPROGRAMS\$SHORTCUTS\Readme.lnk" Delete "$SMPROGRAMS\$SHORTCUTS\Changelog.lnk" Delete "$SMPROGRAMS\$SHORTCUTS\Contributors.lnk" - Delete "$SMPROGRAMS\$SHORTCUTS\PrivacyPolicy.lnk" + Delete "$SMPROGRAMS\$SHORTCUTS\Privacy Policy.lnk" ; Clean up OpenRCT2 dir Delete "$INSTDIR\changelog.txt" From 36f0ce04e70baa04ee94cc041c89ed4173ce16bd Mon Sep 17 00:00:00 2001 From: RedMarcher Date: Sat, 23 Nov 2024 13:03:18 -0800 Subject: [PATCH 054/139] Fix #22726: Force park rating cheat does not save --- distribution/changelog.txt | 1 + src/openrct2/Cheats.cpp | 4 ++++ src/openrct2/Cheats.h | 2 ++ src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/world/Park.cpp | 18 +++++++++--------- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 2b502777bf..b0ab155f4c 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -4,6 +4,7 @@ - Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). +- Fix: [#22726] ‘Force park rating’ cheat is not saved with the park. - Fix: [#23206] Multiplayer desyncs when FPS is uncapped. - Fix: [#23238] Updating a guest’s favourite ride works differently from vanilla RCT2. diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index 5a3d0a237d..d84407f232 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -57,6 +57,7 @@ void CheatsReset() gameState.Cheats.AllowSpecialColourSchemes = false; gameState.Cheats.MakeAllDestructible = false; gameState.Cheats.SelectedStaffSpeed = StaffSpeedCheat::None; + gameState.Cheats.forcedParkRating = kForcedParkRatingDisabled; } void CheatsSet(CheatType cheatType, int64_t param1 /* = 0*/, int64_t param2 /* = 0*/) @@ -115,6 +116,7 @@ void CheatsSerialise(DataSerialiser& ds) CheatEntrySerialise(ds, CheatType::MakeDestructible, gameState.Cheats.MakeAllDestructible, count); CheatEntrySerialise(ds, CheatType::SetStaffSpeed, gameState.Cheats.SelectedStaffSpeed, count); CheatEntrySerialise(ds, CheatType::IgnorePrice, gameState.Cheats.IgnorePrice, count); + CheatEntrySerialise(ds, CheatType::SetForcedParkRating, gameState.Cheats.forcedParkRating, count); // Remember current position and update count. uint64_t endOffset = stream.GetPosition(); @@ -222,6 +224,8 @@ void CheatsSerialise(DataSerialiser& ds) case CheatType::SetStaffSpeed: ds << gameState.Cheats.SelectedStaffSpeed; break; + case CheatType::SetForcedParkRating: + ds << gameState.Cheats.forcedParkRating; default: break; } diff --git a/src/openrct2/Cheats.h b/src/openrct2/Cheats.h index a244f9d0f3..15a133cdb9 100644 --- a/src/openrct2/Cheats.h +++ b/src/openrct2/Cheats.h @@ -47,6 +47,7 @@ struct CheatsState bool AllowSpecialColourSchemes; bool MakeAllDestructible; StaffSpeedCheat SelectedStaffSpeed; + int32_t forcedParkRating; }; enum class CheatType : int32_t @@ -134,6 +135,7 @@ constexpr int kCheatsDuckIncrement = 20; constexpr int kCheatsStaffFastSpeed = 0xFF; constexpr int kCheatsStaffNormalSpeed = 0x60; constexpr int kCheatsStaffFreezeSpeed = 0; +constexpr int32_t kForcedParkRatingDisabled = -1; void CheatsReset(); const char* CheatsGetName(CheatType cheatType); diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index b739f31ecd..0ffe91152a 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -49,7 +49,7 @@ using namespace OpenRCT2; // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -constexpr uint8_t kNetworkStreamVersion = 2; +constexpr uint8_t kNetworkStreamVersion = 3; const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion); diff --git a/src/openrct2/world/Park.cpp b/src/openrct2/world/Park.cpp index 24a3521dc3..e4955e4078 100644 --- a/src/openrct2/world/Park.cpp +++ b/src/openrct2/world/Park.cpp @@ -49,9 +49,6 @@ using namespace OpenRCT2::Scripting; namespace OpenRCT2::Park { - // If this value is more than or equal to 0, the park rating is forced to this value. Used for cheat - static int32_t _forcedParkRating = -1; - static money64 calculateRideValue(const Ride& ride); static money64 calculateTotalRideValueForMoney(); static uint32_t calculateSuggestedMaxGuests(); @@ -395,12 +392,13 @@ namespace OpenRCT2::Park int32_t CalculateParkRating() { - if (_forcedParkRating >= 0) + auto& gameState = GetGameState(); + + if (gameState.Cheats.forcedParkRating != kForcedParkRatingDisabled) { - return _forcedParkRating; + return gameState.Cheats.forcedParkRating; } - auto& gameState = GetGameState(); int32_t result = 1150; if (gameState.Park.Flags & PARK_FLAGS_DIFFICULT_PARK_RATING) { @@ -734,15 +732,17 @@ namespace OpenRCT2::Park void SetForcedRating(int32_t rating) { - _forcedParkRating = rating; - GetGameState().Park.Rating = CalculateParkRating(); + auto& gameState = GetGameState(); + gameState.Cheats.forcedParkRating = rating; + gameState.Park.Rating = CalculateParkRating(); + auto intent = Intent(INTENT_ACTION_UPDATE_PARK_RATING); ContextBroadcastIntent(&intent); } int32_t GetForcedRating() { - return _forcedParkRating; + return GetGameState().Cheats.forcedParkRating; } money64 GetEntranceFee() From 55f0892106fdd06c2514a5208374be579a0a34e2 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 9 Oct 2024 10:44:40 +0200 Subject: [PATCH 055/139] Wooden Twister: Add type and implement flat-to-steep transitions --- data/language/en-GB.txt | 2 + src/openrct2-ui/windows/NewRide.cpp | 1 + src/openrct2/libopenrct2.vcxproj | 4 +- .../coaster/ClassicWoodenRollerCoaster.cpp | 4 +- .../ClassicWoodenTwisterRollerCoaster.cpp | 248 ++++++++++++ .../track/coaster/WoodenRollerCoaster.cpp | 359 ++++++------------ ...ollerCoaster.h => WoodenRollerCoaster.hpp} | 60 +++ src/openrct2/rct1/Tables.cpp | 174 ++++----- src/openrct2/ride/Ride.h | 1 + src/openrct2/ride/RideData.cpp | 2 + src/openrct2/ride/RideStringIds.h | 2 + src/openrct2/ride/TrackPaint.h | 1 + .../rtd/coaster/ClassicWoodenRollerCoaster.h | 2 +- .../ClassicWoodenTwisterRollerCoaster.h | 91 +++++ 14 files changed, 614 insertions(+), 337 deletions(-) create mode 100644 src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp rename src/openrct2/paint/track/coaster/{WoodenRollerCoaster.h => WoodenRollerCoaster.hpp} (54%) create mode 100644 src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 0e69146f78..b0a4e3afaf 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -100,6 +100,7 @@ STR_0095 :Alpine Coaster STR_0096 :Classic Wooden Roller Coaster STR_0097 :Classic Stand-up Roller Coaster STR_0098 :LSM Launched Roller Coaster +STR_0099 :Classic Wooden Twister 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 @@ -185,6 +186,7 @@ STR_0605 :Riders toboggan down a meandering steel track, braking to control t 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_0609 :An older-style wooden roller coaster with a fast and rough ride featuring articulated trains, plenty of air-time and twisting track STR_0767 :Guest {INT32} STR_0768 :Handyman {INT32} STR_0769 :Mechanic {INT32} diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index 2b76554c6a..4d02634b6c 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -68,6 +68,7 @@ namespace OpenRCT2::Ui::Windows RIDE_TYPE_VIRGINIA_REEL, RIDE_TYPE_REVERSER_ROLLER_COASTER, RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER, + RIDE_TYPE_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER, RIDE_TYPE_WOODEN_ROLLER_COASTER, RIDE_TYPE_WOODEN_WILD_MOUSE, RIDE_TYPE_STEEL_WILD_MOUSE, diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 7323e94289..81084c84d8 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -380,7 +380,7 @@ - + @@ -435,6 +435,7 @@ + @@ -916,6 +917,7 @@ + diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp index 1f851fb61e..98dd180af4 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp @@ -22,11 +22,11 @@ #include "../../tile_element/Segment.h" #include "../../track/Segment.h" #include "../../track/Support.h" -#include "WoodenRollerCoaster.h" +#include "WoodenRollerCoaster.hpp" using namespace OpenRCT2; -static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; +// static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; enum { diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp new file mode 100644 index 0000000000..8485e4390f --- /dev/null +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -0,0 +1,248 @@ +/***************************************************************************** + * 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 "../../../ride/Track.h" +#include "../../../ride/TrackPaint.h" +#include "../../../sprites.h" +#include "../../tile_element/Paint.Tunnel.h" +#include "../../tile_element/Segment.h" +#include "WoodenRollerCoaster.hpp" + +using namespace OpenRCT2; + +// static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; + +enum +{ + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65447, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65448, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 65449, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 65450, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 65451, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 65452, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65453, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65454, + + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_0 = SPR_CSG_BEGIN + 65455, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_1 = SPR_CSG_BEGIN + 65456, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_2 = SPR_CSG_BEGIN + 65457, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_3 = SPR_CSG_BEGIN + 65458, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65459, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65460, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 65461, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 65462, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 65463, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 65464, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65465, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65466, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65475, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_3 = SPR_CSG_BEGIN + 65476, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65477, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65478, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66206, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66207, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66208, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66209, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66210, + + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66211, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66212, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66213, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66214, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66215, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66216, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66217, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66218, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66219, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66220, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66221, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66222, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66231, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3 = SPR_CSG_BEGIN + 66232, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66233, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66234, +}; + +static constexpr std::array kFlatToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_1, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_3, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3, + }, +} }; + +static constexpr std::array kFlatToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_0, SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_2, SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2, + // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_3, + }, +} }; + +static constexpr std::array kLeftBankImages = { { + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_0, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_0 }, + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_1, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_1 }, + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_2, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_2 }, + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_3, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_3 }, +} }; + +static constexpr std::array kUp25ToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_3, + }, +} }; + +static constexpr std::array kUp25ToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_3, + }, +} }; + +static void ClassicWoodenTwisterRCTrackLeftBankToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrackRightBankToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrackRightBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrackLeftBankTo25DegDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrack25DegUpToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrackRightBankTo25DegDown( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrack25DegUpToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +// Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. +// The only difference is the degree of the banking. +// As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. +TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::TrackElemType trackType) +{ + if (!IsCsgLoaded()) + { + return GetTrackPaintFunctionWoodenRC(trackType); + } + + switch (trackType) + { + case TrackElemType::FlatToLeftBank: + return WoodenRCTrackFlatToBank; + case TrackElemType::FlatToRightBank: + return WoodenRCTrackFlatToBank; + case TrackElemType::LeftBankToFlat: + return ClassicWoodenTwisterRCTrackLeftBankToFlat; + case TrackElemType::RightBankToFlat: + return ClassicWoodenTwisterRCTrackRightBankToFlat; + case TrackElemType::LeftBank: + return WoodenRCTrackFlatToBank; + case TrackElemType::RightBank: + return ClassicWoodenTwisterRCTrackRightBank; + case TrackElemType::Up25ToLeftBank: + return WoodenRCTrack25DegUpToBank; + case TrackElemType::Up25ToRightBank: + return WoodenRCTrack25DegUpToBank; + case TrackElemType::LeftBankToDown25: + return ClassicWoodenTwisterRCTrackLeftBankTo25DegDown; + case TrackElemType::RightBankToDown25: + return ClassicWoodenTwisterRCTrackRightBankTo25DegDown; + default: + return GetTrackPaintFunctionWoodenRC(trackType); + } +} diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index af2f92fb46..8f472d13ff 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -7,7 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "WoodenRollerCoaster.h" +#include "WoodenRollerCoaster.hpp" #include "../../../config/Config.h" #include "../../../drawing/Drawing.h" @@ -29,7 +29,7 @@ using namespace OpenRCT2; -static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; +// static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; enum { @@ -479,6 +479,105 @@ static constexpr const uint32_t WoodenRCDiagBlockBrakeImages[2][kNumOrthogonalDi }, }; +static constexpr std::array kFlatToLeftBankImages = { { + { + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_SW_NE, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SW_NE, + }, + { + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_NW_SE, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NW_SE, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_NW_SE, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_FRONT_NW_SE, + }, + { + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_NE_SW, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NE_SW, + }, + { + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_SE_NW, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SE_NW, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_SE_NW, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_FRONT_SE_NW, + }, +} }; + +static constexpr std::array kFlatToRightBankImages = { { + { + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_SW_NE, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_SW_NE, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_SW_NE, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_FRONT_SW_NE, + }, + { + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_NW_SE, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_NW_SE, + }, + { + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_NE_SW, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_NE_SW, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_NE_SW, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_FRONT_NE_SW, + }, + { + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_SE_NW, + SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_SE_NW, + }, +} }; + +static constexpr std::array kLeftBankImages = { { + { SPR_WOODEN_RC_LEFT_BANK_SW_NE, SPR_WOODEN_RC_LEFT_BANK_RAILS_SW_NE }, + { SPR_WOODEN_RC_LEFT_BANK_NW_SE, SPR_WOODEN_RC_LEFT_BANK_RAILS_NW_SE }, + { SPR_WOODEN_RC_LEFT_BANK_NE_SW, SPR_WOODEN_RC_LEFT_BANK_RAILS_NE_SW }, + { SPR_WOODEN_RC_LEFT_BANK_SE_NW, SPR_WOODEN_RC_LEFT_BANK_RAILS_SE_NW }, +} }; + +static constexpr std::array kUp25ToLeftBankImages = { { + { + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_SW_NE, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_SW_NE, + }, + { + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_NW_SE, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_NW_SE, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_FRONT_NW_SE, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_FRONT_NW_SE, + }, + { + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_NE_SW, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_NE_SW, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_FRONT_NE_SW, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_FRONT_NE_SW, + }, + { + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_SE_NW, + SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_SE_NW, + }, +} }; + +static constexpr std::array kUp25ToRightBankImages = { { + { + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_SW_NE, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_SW_NE, + }, + { + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_NW_SE, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_NW_SE, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_FRONT_NW_SE, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_FRONT_NW_SE, + }, + { + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_NE_SW, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_NE_SW, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_FRONT_NE_SW, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_FRONT_NE_SW, + }, + { + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_SE_NW, + SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_SE_NW, + }, +} }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -1523,111 +1622,13 @@ static void WoodenRCTrackLeftQuarterTurn5( session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); } -/** rct2: 0x008AC658 */ -template -static void WoodenRCTrackFlatToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr uint32_t imageIds[4][4] = { - { - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_SW_NE, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SW_NE, - 0, - 0, - }, - { - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_NW_SE, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NW_SE, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_NW_SE, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_FRONT_NW_SE, - }, - { - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_NE_SW, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NE_SW, - 0, - 0, - }, - { - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_SE_NW, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SE_NW, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_SE_NW, - SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_FRONT_SE_NW, - }, - }; - - WoodenRCTrackPaint( - session, direction, imageIds[direction][0], imageIds[direction][1], { 0, 0, height }, - { { 0, 3, height }, { 32, 25, 2 } }); - if (direction == 1 || direction == 3) - { - WoodenRCTrackPaint( - session, direction, imageIds[direction][2], imageIds[direction][3], { 0, 0, height }, - { { 0, 26, height + 5 }, { 32, 1, 9 } }); - } - WoodenASupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours); - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} - -/** rct2: 0x008AC668 */ -template -static void WoodenRCTrackFlatToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr uint32_t imageIds[4][4] = { - { - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_SW_NE, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_SW_NE, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_SW_NE, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_FRONT_SW_NE, - }, - { - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_NW_SE, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_NW_SE, - 0, - 0, - }, - { - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_NE_SW, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_NE_SW, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_NE_SW, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_FRONT_NE_SW, - }, - { - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_SE_NW, - SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_SE_NW, - 0, - 0, - }, - }; - - WoodenRCTrackPaint( - session, direction, imageIds[direction][0], imageIds[direction][1], { 0, 0, height }, - { { 0, 3, height }, { 32, 25, 2 } }); - if (direction == 0 || direction == 2) - { - WoodenRCTrackPaint( - session, direction, imageIds[direction][2], imageIds[direction][3], { 0, 0, height }, - { { 0, 26, height + 5 }, { 32, 1, 9 } }); - } - WoodenASupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours); - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} - /** rct2: 0x008AC678 */ template static void WoodenRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - WoodenRCTrackFlatToRightBank( + WoodenRCTrackFlatToBank( session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); } @@ -1637,7 +1638,7 @@ static void WoodenRCTrackRightBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - WoodenRCTrackFlatToLeftBank( + WoodenRCTrackFlatToBank( session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); } @@ -2115,119 +2116,7 @@ static void WoodenRCTrackRightBankTo25DegUp( PaintUtilSetGeneralSupportHeight(session, height + 48); } -/** rct2: 0x008AC6D8 */ -template -static void WoodenRCTrack25DegUpToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr uint32_t imageIds[4][4] = { - { - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_SW_NE, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_SW_NE, - 0, - 0, - }, - { - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_NW_SE, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_NW_SE, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_FRONT_NW_SE, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_FRONT_NW_SE, - }, - { - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_NE_SW, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_NE_SW, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_FRONT_NE_SW, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_FRONT_NE_SW, - }, - { - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_SE_NW, - SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_SE_NW, - 0, - 0, - }, - }; - - WoodenRCTrackPaint( - session, direction, imageIds[direction][0], imageIds[direction][1], { 0, 0, height }, - { { 0, 3, height }, { 32, 25, 2 } }); - if (direction == 1 || direction == 2) - { - WoodenRCTrackPaint( - session, direction, imageIds[direction][2], imageIds[direction][3], { 0, 0, height }, - { { 0, 26, height + 5 }, { 32, 1, 9 } }); - } - WoodenASupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours, - WoodenSupportTransitionType::Up25DegToFlat); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::FlatTo25Deg); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 40); -} - -/** rct2: 0x008AC6E8 */ -template -static void WoodenRCTrack25DegUpToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr uint32_t imageIds[4][4] = { - { - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_SW_NE, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_SW_NE, - 0, - 0, - }, - { - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_NW_SE, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_NW_SE, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_FRONT_NW_SE, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_FRONT_NW_SE, - }, - { - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_NE_SW, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_NE_SW, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_FRONT_NE_SW, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_FRONT_NE_SW, - }, - { - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_SE_NW, - SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_SE_NW, - 0, - 0, - }, - }; - - WoodenRCTrackPaint( - session, direction, imageIds[direction][0], imageIds[direction][1], { 0, 0, height }, - { { 0, 3, height }, { 32, 25, 2 } }); - if (direction == 1 || direction == 2) - { - WoodenRCTrackPaint( - session, direction, imageIds[direction][2], imageIds[direction][3], { 0, 0, height }, - { { 0, 26, height + 5 }, { 32, 1, 9 } }); - } - WoodenASupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours, - WoodenSupportTransitionType::Up25DegToFlat); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::FlatTo25Deg); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 40); -} +/** rct2: */ /** rct2: 0x008AC6F8 */ template @@ -2235,7 +2124,7 @@ static void WoodenRCTrackLeftBankTo25DegDown( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - WoodenRCTrack25DegUpToRightBank( + WoodenRCTrack25DegUpToBank( session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); } @@ -2245,7 +2134,7 @@ static void WoodenRCTrackRightBankTo25DegDown( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - WoodenRCTrack25DegUpToLeftBank( + WoodenRCTrack25DegUpToBank( session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); } @@ -2269,36 +2158,14 @@ static void WoodenRCTrack25DegDownToRightBank( session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); } -/** rct2: 0x008AC738 */ -template -static void WoodenRCTrackLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr uint32_t imageIds[4][2] = { - { SPR_WOODEN_RC_LEFT_BANK_SW_NE, SPR_WOODEN_RC_LEFT_BANK_RAILS_SW_NE }, - { SPR_WOODEN_RC_LEFT_BANK_NW_SE, SPR_WOODEN_RC_LEFT_BANK_RAILS_NW_SE }, - { SPR_WOODEN_RC_LEFT_BANK_NE_SW, SPR_WOODEN_RC_LEFT_BANK_RAILS_NE_SW }, - { SPR_WOODEN_RC_LEFT_BANK_SE_NW, SPR_WOODEN_RC_LEFT_BANK_RAILS_SE_NW }, - }; - - WoodenRCTrackPaint( - session, direction, imageIds[direction][0], imageIds[direction][1], { 0, 0, height }, - { { 0, 3, height }, { 32, 25, 2 } }); - WoodenASupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours); - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} - /** rct2: 0x008AC748 */ template static void WoodenRCTrackRightBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - WoodenRCTrackLeftBank(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackFlatToBank( + session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); } /** rct2: 0x008AC758 */ @@ -17668,9 +17535,9 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::RightQuarterTurn5Tiles: return WoodenRCTrackRightQuarterTurn5; case TrackElemType::FlatToLeftBank: - return WoodenRCTrackFlatToLeftBank; + return WoodenRCTrackFlatToBank; case TrackElemType::FlatToRightBank: - return WoodenRCTrackFlatToRightBank; + return WoodenRCTrackFlatToBank; case TrackElemType::LeftBankToFlat: return WoodenRCTrackLeftBankToFlat; case TrackElemType::RightBankToFlat: @@ -17684,9 +17551,9 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::RightBankToUp25: return WoodenRCTrackRightBankTo25DegUp; case TrackElemType::Up25ToLeftBank: - return WoodenRCTrack25DegUpToLeftBank; + return WoodenRCTrack25DegUpToBank; case TrackElemType::Up25ToRightBank: - return WoodenRCTrack25DegUpToRightBank; + return WoodenRCTrack25DegUpToBank; case TrackElemType::LeftBankToDown25: return WoodenRCTrackLeftBankTo25DegDown; case TrackElemType::RightBankToDown25: @@ -17696,7 +17563,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::Down25ToRightBank: return WoodenRCTrack25DegDownToRightBank; case TrackElemType::LeftBank: - return WoodenRCTrackLeftBank; + return WoodenRCTrackFlatToBank; case TrackElemType::RightBank: return WoodenRCTrackRightBank; case TrackElemType::LeftQuarterTurn5TilesUp25: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.h b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp similarity index 54% rename from src/openrct2/paint/track/coaster/WoodenRollerCoaster.h rename to src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 0347a3d74e..cd3051c691 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.h +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -20,6 +20,16 @@ #include +static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; + +struct StraightWoodenTrack +{ + ImageIndex track; + ImageIndex handrail; + ImageIndex frontTrack = ImageIndexUndefined; + ImageIndex frontHandrail = ImageIndexUndefined; +}; + struct SpriteBoundBox2 { ImageIndex ImageIdA; @@ -82,4 +92,54 @@ void WoodenRCTrackPaintBb(PaintSession& session, const SpriteBoundBox2* bb, int1 } } +template imageIds> +static void WoodenRCTrackStraightBankTrack(PaintSession& session, uint8_t direction, int32_t height) +{ + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { 0, 0, height }, + { { 0, 3, height }, { 32, 25, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, { 0, 0, height }, + { { 0, 26, height + 5 }, { 32, 1, 9 } }); + } +} + +/** rct2: 0x008AC658, 0x008AC668, 0x008AC738 */ +template imageIds> +void WoodenRCTrackFlatToBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackStraightBankTrack(session, direction, height); + WoodenASupportsPaintSetupRotated( + session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours); + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + +/** rct2: 0x008AC6D8, 0x008AC6E8 */ +template imageIds> +static void WoodenRCTrack25DegUpToBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackStraightBankTrack(session, direction, height); + WoodenASupportsPaintSetupRotated( + session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours, + WoodenSupportTransitionType::Up25DegToFlat); + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::Flat); + } + else + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::FlatTo25Deg); + } + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 40); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); diff --git a/src/openrct2/rct1/Tables.cpp b/src/openrct2/rct1/Tables.cpp index 23211ae6e4..1323448093 100644 --- a/src/openrct2/rct1/Tables.cpp +++ b/src/openrct2/rct1/Tables.cpp @@ -171,91 +171,91 @@ namespace OpenRCT2::RCT1 static uint8_t map[] = { - RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER,// RCT1_RIDE_TYPE_WOODEN_ROLLER_COASTER - RIDE_TYPE_CLASSIC_STAND_UP_ROLLER_COASTER, // RCT1_RIDE_TYPE_STAND_UP_STEEL_ROLLER_COASTER - RIDE_TYPE_SUSPENDED_SWINGING_COASTER, // RCT1_RIDE_TYPE_SUSPENDED_ROLLER_COASTER - RIDE_TYPE_INVERTED_ROLLER_COASTER, // RCT1_RIDE_TYPE_INVERTED_ROLLER_COASTER - RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_MINI_ROLLER_COASTER - RIDE_TYPE_MINIATURE_RAILWAY, // RCT1_RIDE_TYPE_MINIATURE_RAILWAY - RIDE_TYPE_MONORAIL, // RCT1_RIDE_TYPE_MONORAIL - RIDE_TYPE_MINI_SUSPENDED_COASTER, // RCT1_RIDE_TYPE_SUSPENDED_SINGLE_RAIL_ROLLER_COASTER - RIDE_TYPE_BOAT_HIRE, // RCT1_RIDE_TYPE_BOAT_HIRE - RIDE_TYPE_WOODEN_WILD_MOUSE, // RCT1_RIDE_TYPE_WOODEN_CRAZY_RODENT_ROLLER_COASTER - RIDE_TYPE_STEEPLECHASE, // RCT1_RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER - RIDE_TYPE_CAR_RIDE, // RCT1_RIDE_TYPE_CAR_RIDE - RIDE_TYPE_LAUNCHED_FREEFALL, // RCT1_RIDE_TYPE_LAUNCHED_FREEFALL - RIDE_TYPE_BOBSLEIGH_COASTER, // RCT1_RIDE_TYPE_BOBSLED_ROLLER_COASTER - RIDE_TYPE_OBSERVATION_TOWER, // RCT1_RIDE_TYPE_OBSERVATION_TOWER - RIDE_TYPE_LOOPING_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_ROLLER_COASTER - RIDE_TYPE_DINGHY_SLIDE, // RCT1_RIDE_TYPE_WATER_SLIDE - RIDE_TYPE_MINE_TRAIN_COASTER, // RCT1_RIDE_TYPE_MINE_TRAIN_ROLLER_COASTER - RIDE_TYPE_CHAIRLIFT, // RCT1_RIDE_TYPE_CHAIRLIFT - RIDE_TYPE_CORKSCREW_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_CORKSCREW_ROLLER_COASTER - RIDE_TYPE_MAZE, // RCT1_RIDE_TYPE_HEDGE_MAZE - RIDE_TYPE_SPIRAL_SLIDE, // RCT1_RIDE_TYPE_SPIRAL_SLIDE - RIDE_TYPE_GO_KARTS, // RCT1_RIDE_TYPE_GO_KARTS - RIDE_TYPE_LOG_FLUME, // RCT1_RIDE_TYPE_LOG_FLUME - RIDE_TYPE_RIVER_RAPIDS, // RCT1_RIDE_TYPE_RIVER_RAPIDS - RIDE_TYPE_DODGEMS, // RCT1_RIDE_TYPE_DODGEMS - RIDE_TYPE_SWINGING_SHIP, // RCT1_RIDE_TYPE_SWINGING_SHIP - RIDE_TYPE_SWINGING_INVERTER_SHIP, // RCT1_RIDE_TYPE_SWINGING_INVERTER_SHIP - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_ICE_CREAM_STALL - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_CHIPS_STALL - RIDE_TYPE_DRINK_STALL, // RCT1_RIDE_TYPE_DRINK_STALL - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_CANDYFLOSS_STALL - RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_BURGER_BAR - RIDE_TYPE_MERRY_GO_ROUND, // RCT1_RIDE_TYPE_MERRY_GO_ROUND - RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_BALLOON_STALL - RIDE_TYPE_INFORMATION_KIOSK, // RCT1_RIDE_TYPE_INFORMATION_KIOSK - RIDE_TYPE_TOILETS, // RCT1_RIDE_TYPE_TOILETS - RIDE_TYPE_FERRIS_WHEEL, // RCT1_RIDE_TYPE_FERRIS_WHEEL - RIDE_TYPE_MOTION_SIMULATOR, // RCT1_RIDE_TYPE_MOTION_SIMULATOR - RIDE_TYPE_3D_CINEMA, // RCT1_RIDE_TYPE_3D_CINEMA - RIDE_TYPE_TOP_SPIN, // RCT1_RIDE_TYPE_TOP_SPIN - RIDE_TYPE_SPACE_RINGS, // RCT1_RIDE_TYPE_SPACE_RINGS - RIDE_TYPE_REVERSE_FREEFALL_COASTER, // RCT1_RIDE_TYPE_REVERSE_FREEFALL_ROLLER_COASTER - RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_SOUVENIR_STALL - RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER, // RCT1_RIDE_TYPE_VERTICAL_ROLLER_COASTER - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_PIZZA_STALL - RIDE_TYPE_TWIST, // RCT1_RIDE_TYPE_TWIST - RIDE_TYPE_HAUNTED_HOUSE, // RCT1_RIDE_TYPE_HAUNTED_HOUSE - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_POPCORN_STALL - RIDE_TYPE_CIRCUS, // RCT1_RIDE_TYPE_CIRCUS - RIDE_TYPE_GHOST_TRAIN, // RCT1_RIDE_TYPE_GHOST_TRAIN - RIDE_TYPE_TWISTER_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_TWISTER_ROLLER_COASTER - RIDE_TYPE_WOODEN_ROLLER_COASTER, // RCT1_RIDE_TYPE_WOODEN_TWISTER_ROLLER_COASTER - RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER, // RCT1_RIDE_TYPE_WOODEN_SIDE_FRICTION_ROLLER_COASTER - RIDE_TYPE_STEEL_WILD_MOUSE, // RCT1_RIDE_TYPE_STEEL_WILD_MOUSE_ROLLER_COASTER - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_HOT_DOG_STALL - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_EXOTIC_SEA_FOOD_STALL - RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_HAT_STALL - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_TOFFEE_APPLE_STALL - RIDE_TYPE_VIRGINIA_REEL, // RCT1_RIDE_TYPE_VIRGINIA_REEL - RIDE_TYPE_SPLASH_BOATS, // RCT1_RIDE_TYPE_RIVER_RIDE - RIDE_TYPE_MINI_HELICOPTERS, // RCT1_RIDE_TYPE_CYCLE_MONORAIL - RIDE_TYPE_LAY_DOWN_ROLLER_COASTER, // RCT1_RIDE_TYPE_FLYING_ROLLER_COASTER - RIDE_TYPE_SUSPENDED_MONORAIL, // RCT1_RIDE_TYPE_SUSPENDED_MONORAIL - RIDE_TYPE_NULL, // RCT1_RIDE_TYPE_40 - RIDE_TYPE_REVERSER_ROLLER_COASTER, // RCT1_RIDE_TYPE_WOODEN_REVERSER_ROLLER_COASTER - RIDE_TYPE_HEARTLINE_TWISTER_COASTER, // RCT1_RIDE_TYPE_HEARTLINE_TWISTER_ROLLER_COASTER - RIDE_TYPE_MINI_GOLF, // RCT1_RIDE_TYPE_MINIATURE_GOLF - RIDE_TYPE_NULL, // RCT1_RIDE_TYPE_44 - RIDE_TYPE_ROTO_DROP, // RCT1_RIDE_TYPE_ROTO_DROP - RIDE_TYPE_FLYING_SAUCERS, // RCT1_RIDE_TYPE_FLYING_SAUCERS - RIDE_TYPE_CROOKED_HOUSE, // RCT1_RIDE_TYPE_CROOKED_HOUSE - RIDE_TYPE_MONORAIL_CYCLES, // RCT1_RIDE_TYPE_CYCLE_RAILWAY - RIDE_TYPE_COMPACT_INVERTED_COASTER, // RCT1_RIDE_TYPE_SUSPENDED_LOOPING_ROLLER_COASTER - RIDE_TYPE_WATER_COASTER, // RCT1_RIDE_TYPE_WATER_COASTER - RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER, // RCT1_RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER - RIDE_TYPE_INVERTED_HAIRPIN_COASTER, // RCT1_RIDE_TYPE_INVERTED_WILD_MOUSE_COASTER - RIDE_TYPE_BOAT_HIRE, // RCT1_RIDE_TYPE_JET_SKIS - RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_T_SHIRT_STALL - RIDE_TYPE_RIVER_RAFTS, // RCT1_RIDE_TYPE_RAFT_RIDE - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_DOUGHNUT_SHOP - RIDE_TYPE_ENTERPRISE, // RCT1_RIDE_TYPE_ENTERPRISE - RIDE_TYPE_DRINK_STALL, // RCT1_RIDE_TYPE_COFFEE_SHOP - RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_FRIED_CHICKEN_STALL - RIDE_TYPE_DRINK_STALL, // RCT1_RIDE_TYPE_LEMONADE_STALL + RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER, // RCT1_RIDE_TYPE_WOODEN_ROLLER_COASTER + RIDE_TYPE_CLASSIC_STAND_UP_ROLLER_COASTER, // RCT1_RIDE_TYPE_STAND_UP_STEEL_ROLLER_COASTER + RIDE_TYPE_SUSPENDED_SWINGING_COASTER, // RCT1_RIDE_TYPE_SUSPENDED_ROLLER_COASTER + RIDE_TYPE_INVERTED_ROLLER_COASTER, // RCT1_RIDE_TYPE_INVERTED_ROLLER_COASTER + RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_MINI_ROLLER_COASTER + RIDE_TYPE_MINIATURE_RAILWAY, // RCT1_RIDE_TYPE_MINIATURE_RAILWAY + RIDE_TYPE_MONORAIL, // RCT1_RIDE_TYPE_MONORAIL + RIDE_TYPE_MINI_SUSPENDED_COASTER, // RCT1_RIDE_TYPE_SUSPENDED_SINGLE_RAIL_ROLLER_COASTER + RIDE_TYPE_BOAT_HIRE, // RCT1_RIDE_TYPE_BOAT_HIRE + RIDE_TYPE_WOODEN_WILD_MOUSE, // RCT1_RIDE_TYPE_WOODEN_CRAZY_RODENT_ROLLER_COASTER + RIDE_TYPE_STEEPLECHASE, // RCT1_RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER + RIDE_TYPE_CAR_RIDE, // RCT1_RIDE_TYPE_CAR_RIDE + RIDE_TYPE_LAUNCHED_FREEFALL, // RCT1_RIDE_TYPE_LAUNCHED_FREEFALL + RIDE_TYPE_BOBSLEIGH_COASTER, // RCT1_RIDE_TYPE_BOBSLED_ROLLER_COASTER + RIDE_TYPE_OBSERVATION_TOWER, // RCT1_RIDE_TYPE_OBSERVATION_TOWER + RIDE_TYPE_LOOPING_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_ROLLER_COASTER + RIDE_TYPE_DINGHY_SLIDE, // RCT1_RIDE_TYPE_WATER_SLIDE + RIDE_TYPE_MINE_TRAIN_COASTER, // RCT1_RIDE_TYPE_MINE_TRAIN_ROLLER_COASTER + RIDE_TYPE_CHAIRLIFT, // RCT1_RIDE_TYPE_CHAIRLIFT + RIDE_TYPE_CORKSCREW_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_CORKSCREW_ROLLER_COASTER + RIDE_TYPE_MAZE, // RCT1_RIDE_TYPE_HEDGE_MAZE + RIDE_TYPE_SPIRAL_SLIDE, // RCT1_RIDE_TYPE_SPIRAL_SLIDE + RIDE_TYPE_GO_KARTS, // RCT1_RIDE_TYPE_GO_KARTS + RIDE_TYPE_LOG_FLUME, // RCT1_RIDE_TYPE_LOG_FLUME + RIDE_TYPE_RIVER_RAPIDS, // RCT1_RIDE_TYPE_RIVER_RAPIDS + RIDE_TYPE_DODGEMS, // RCT1_RIDE_TYPE_DODGEMS + RIDE_TYPE_SWINGING_SHIP, // RCT1_RIDE_TYPE_SWINGING_SHIP + RIDE_TYPE_SWINGING_INVERTER_SHIP, // RCT1_RIDE_TYPE_SWINGING_INVERTER_SHIP + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_ICE_CREAM_STALL + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_CHIPS_STALL + RIDE_TYPE_DRINK_STALL, // RCT1_RIDE_TYPE_DRINK_STALL + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_CANDYFLOSS_STALL + RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_BURGER_BAR + RIDE_TYPE_MERRY_GO_ROUND, // RCT1_RIDE_TYPE_MERRY_GO_ROUND + RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_BALLOON_STALL + RIDE_TYPE_INFORMATION_KIOSK, // RCT1_RIDE_TYPE_INFORMATION_KIOSK + RIDE_TYPE_TOILETS, // RCT1_RIDE_TYPE_TOILETS + RIDE_TYPE_FERRIS_WHEEL, // RCT1_RIDE_TYPE_FERRIS_WHEEL + RIDE_TYPE_MOTION_SIMULATOR, // RCT1_RIDE_TYPE_MOTION_SIMULATOR + RIDE_TYPE_3D_CINEMA, // RCT1_RIDE_TYPE_3D_CINEMA + RIDE_TYPE_TOP_SPIN, // RCT1_RIDE_TYPE_TOP_SPIN + RIDE_TYPE_SPACE_RINGS, // RCT1_RIDE_TYPE_SPACE_RINGS + RIDE_TYPE_REVERSE_FREEFALL_COASTER, // RCT1_RIDE_TYPE_REVERSE_FREEFALL_ROLLER_COASTER + RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_SOUVENIR_STALL + RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER, // RCT1_RIDE_TYPE_VERTICAL_ROLLER_COASTER + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_PIZZA_STALL + RIDE_TYPE_TWIST, // RCT1_RIDE_TYPE_TWIST + RIDE_TYPE_HAUNTED_HOUSE, // RCT1_RIDE_TYPE_HAUNTED_HOUSE + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_POPCORN_STALL + RIDE_TYPE_CIRCUS, // RCT1_RIDE_TYPE_CIRCUS + RIDE_TYPE_GHOST_TRAIN, // RCT1_RIDE_TYPE_GHOST_TRAIN + RIDE_TYPE_TWISTER_ROLLER_COASTER, // RCT1_RIDE_TYPE_STEEL_TWISTER_ROLLER_COASTER + RIDE_TYPE_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER, // RCT1_RIDE_TYPE_WOODEN_TWISTER_ROLLER_COASTER + RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER, // RCT1_RIDE_TYPE_WOODEN_SIDE_FRICTION_ROLLER_COASTER + RIDE_TYPE_STEEL_WILD_MOUSE, // RCT1_RIDE_TYPE_STEEL_WILD_MOUSE_ROLLER_COASTER + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_HOT_DOG_STALL + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_EXOTIC_SEA_FOOD_STALL + RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_HAT_STALL + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_TOFFEE_APPLE_STALL + RIDE_TYPE_VIRGINIA_REEL, // RCT1_RIDE_TYPE_VIRGINIA_REEL + RIDE_TYPE_SPLASH_BOATS, // RCT1_RIDE_TYPE_RIVER_RIDE + RIDE_TYPE_MINI_HELICOPTERS, // RCT1_RIDE_TYPE_CYCLE_MONORAIL + RIDE_TYPE_LAY_DOWN_ROLLER_COASTER, // RCT1_RIDE_TYPE_FLYING_ROLLER_COASTER + RIDE_TYPE_SUSPENDED_MONORAIL, // RCT1_RIDE_TYPE_SUSPENDED_MONORAIL + RIDE_TYPE_NULL, // RCT1_RIDE_TYPE_40 + RIDE_TYPE_REVERSER_ROLLER_COASTER, // RCT1_RIDE_TYPE_WOODEN_REVERSER_ROLLER_COASTER + RIDE_TYPE_HEARTLINE_TWISTER_COASTER, // RCT1_RIDE_TYPE_HEARTLINE_TWISTER_ROLLER_COASTER + RIDE_TYPE_MINI_GOLF, // RCT1_RIDE_TYPE_MINIATURE_GOLF + RIDE_TYPE_NULL, // RCT1_RIDE_TYPE_44 + RIDE_TYPE_ROTO_DROP, // RCT1_RIDE_TYPE_ROTO_DROP + RIDE_TYPE_FLYING_SAUCERS, // RCT1_RIDE_TYPE_FLYING_SAUCERS + RIDE_TYPE_CROOKED_HOUSE, // RCT1_RIDE_TYPE_CROOKED_HOUSE + RIDE_TYPE_MONORAIL_CYCLES, // RCT1_RIDE_TYPE_CYCLE_RAILWAY + RIDE_TYPE_COMPACT_INVERTED_COASTER, // RCT1_RIDE_TYPE_SUSPENDED_LOOPING_ROLLER_COASTER + RIDE_TYPE_WATER_COASTER, // RCT1_RIDE_TYPE_WATER_COASTER + RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER, // RCT1_RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER + RIDE_TYPE_INVERTED_HAIRPIN_COASTER, // RCT1_RIDE_TYPE_INVERTED_WILD_MOUSE_COASTER + RIDE_TYPE_BOAT_HIRE, // RCT1_RIDE_TYPE_JET_SKIS + RIDE_TYPE_SHOP, // RCT1_RIDE_TYPE_T_SHIRT_STALL + RIDE_TYPE_RIVER_RAFTS, // RCT1_RIDE_TYPE_RAFT_RIDE + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_DOUGHNUT_SHOP + RIDE_TYPE_ENTERPRISE, // RCT1_RIDE_TYPE_ENTERPRISE + RIDE_TYPE_DRINK_STALL, // RCT1_RIDE_TYPE_COFFEE_SHOP + RIDE_TYPE_FOOD_STALL, // RCT1_RIDE_TYPE_FRIED_CHICKEN_STALL + RIDE_TYPE_DRINK_STALL, // RCT1_RIDE_TYPE_LEMONADE_STALL }; const auto index = EnumValue(rideType); @@ -755,7 +755,7 @@ namespace OpenRCT2::RCT1 "rct2.ride.circus1", // RCT1_RIDE_TYPE_CIRCUS "rct1aa.ride.ghost_train_cars", // RCT1_RIDE_TYPE_GHOST_TRAIN "rct1aa.ride.twister_trains", // RCT1_RIDE_TYPE_STEEL_TWISTER_ROLLER_COASTER - "rct2.ride.mft", // RCT1_RIDE_TYPE_WOODEN_TWISTER_ROLLER_COASTER + "rct1aa.ride.woodtrc", // RCT1_RIDE_TYPE_WOODEN_TWISTER_ROLLER_COASTER "rct1aa.ride.side_friction_cars", // RCT1_RIDE_TYPE_WOODEN_SIDE_FRICTION_ROLLER_COASTER "rct1aa.ride.steel_wild_mouse_cars", // RCT1_RIDE_TYPE_STEEL_WILD_MOUSE_ROLLER_COASTER "rct2.ride.hotds", // RCT1_RIDE_TYPE_HOT_DOG_STALL @@ -856,7 +856,7 @@ namespace OpenRCT2::RCT1 "rct2.ride.circus1", // VehicleType::CircusTent "rct1aa.ride.ghost_train_cars", // VehicleType::GhostTrainCars "rct1aa.ride.twister_trains", // VehicleType::SteelTwisterRollerCoasterTrain - "rct2.ride.mft", // VehicleType::WoodenTwisterRollerCoasterTrain + "rct1aa.ride.woodtrc", // VehicleType::WoodenTwisterRollerCoasterTrain "rct1aa.ride.side_friction_cars", // VehicleType::WoodenSideFrictionCars "rct1aa.ride.vintage_cars", // VehicleType::VintageCars "rct1aa.ride.steam_trains_covered", // VehicleType::SteamTrainCoveredCars diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 882807edbb..3ed9704c67 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -620,6 +620,7 @@ enum RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER, RIDE_TYPE_CLASSIC_STAND_UP_ROLLER_COASTER, RIDE_TYPE_LSM_LAUNCHED_ROLLER_COASTER, + RIDE_TYPE_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER, RIDE_TYPE_COUNT }; diff --git a/src/openrct2/ride/RideData.cpp b/src/openrct2/ride/RideData.cpp index e503a233b4..0412f2624e 100644 --- a/src/openrct2/ride/RideData.cpp +++ b/src/openrct2/ride/RideData.cpp @@ -36,6 +36,7 @@ #include "rtd/coaster/ClassicMiniRollerCoaster.h" #include "rtd/coaster/ClassicStandUpRollerCoaster.h" #include "rtd/coaster/ClassicWoodenRollerCoaster.h" +#include "rtd/coaster/ClassicWoodenTwisterRollerCoaster.h" #include "rtd/coaster/CompactInvertedCoaster.h" #include "rtd/coaster/CorkscrewRollerCoaster.h" #include "rtd/coaster/FlyingRollerCoaster.h" @@ -354,6 +355,7 @@ constexpr RideTypeDescriptor RideTypeDescriptors[RIDE_TYPE_COUNT] = { /* RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER */ ClassicWoodenRollerCoasterRTD, /* RIDE_TYPE_CLASSIC_STAND_UP_ROLLER_COASTER */ ClassicStandUpRollerCoasterRTD, /* RIDE_TYPE_LSM_LAUNCHED_ROLLER_COASTER */ LSMLaunchedRollerCoasterRTD, + /* RIDE_TYPE_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER */ ClassicWoodenTwisterRollerCoasterRTD, }; bool RideTypeDescriptor::HasFlag(RtdFlag flag) const diff --git a/src/openrct2/ride/RideStringIds.h b/src/openrct2/ride/RideStringIds.h index 928ab36163..ab02567a71 100644 --- a/src/openrct2/ride/RideStringIds.h +++ b/src/openrct2/ride/RideStringIds.h @@ -23,6 +23,7 @@ enum : StringId STR_RIDE_NAME_CLASSIC_MINI_ROLLER_COASTER = 6111, STR_RIDE_NAME_CLASSIC_STAND_UP_ROLLER_COASTER = 97, STR_RIDE_NAME_CLASSIC_WOODEN_ROLLER_COASTER = 96, + STR_RIDE_NAME_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER = 99, STR_RIDE_NAME_COMPACT_INVERTED_COASTER = 75, STR_RIDE_NAME_CORKSCREW_ROLLER_COASTER = 21, STR_RIDE_NAME_FLYING_ROLLER_COASTER = 59, @@ -66,6 +67,7 @@ enum : StringId STR_RIDE_DESCRIPTION_CLASSIC_MINI_COASTER = 6119, STR_RIDE_DESCRIPTION_CLASSIC_STAND_UP_ROLLER_COASTER = 607, STR_RIDE_DESCRIPTION_CLASSIC_WOODEN_ROLLER_COASTER = 606, + STR_RIDE_DESCRIPTION_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER = 609, STR_RIDE_DESCRIPTION_COMPACT_INVERTED_COASTER = 585, STR_RIDE_DESCRIPTION_CORKSCREW_ROLLER_COASTER = 531, STR_RIDE_DESCRIPTION_FLYING_ROLLER_COASTER = 569, diff --git a/src/openrct2/ride/TrackPaint.h b/src/openrct2/ride/TrackPaint.h index 9fdfbb9f85..ebc5fe4fe3 100644 --- a/src/openrct2/ride/TrackPaint.h +++ b/src/openrct2/ride/TrackPaint.h @@ -639,3 +639,4 @@ namespace OpenRCT2::AlpineRC } TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRC(OpenRCT2::TrackElemType trackType); TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicStandUpRC(OpenRCT2::TrackElemType trackType); +TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::TrackElemType trackType); diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h index c6b65f1486..b7565f38eb 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor ClassicWoodenRollerCoasterRTD = .Drawer = GetTrackPaintFunctionClassicWoodenRC, .supportType = WoodenSupportType::Truss, .enabledTrackGroups = {TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::verticalLoop, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::waterSplash, TrackGroup::blockBrakes, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeSteepLong, TrackGroup::halfLoopMedium, TrackGroup::halfLoopLarge}, - .extraTrackGroups = {TrackGroup::booster}, + .extraTrackGroups = {TrackGroup::booster, TrackGroup::slopeCurveSteep}, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h new file mode 100644 index 0000000000..c621802826 --- /dev/null +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h @@ -0,0 +1,91 @@ +/***************************************************************************** + * 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 ClassicWoodenTwisterRollerCoasterRTD = +{ + .Category = RIDE_CATEGORY_ROLLERCOASTER, + .StartTrackPiece = OpenRCT2::TrackElemType::EndStation, + .TrackPaintFunctions = TrackDrawerDescriptor({ + .Drawer = GetTrackPaintFunctionClassicWoodenTwisterRC, + .supportType = WoodenSupportType::Truss, + .enabledTrackGroups = { TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::blockBrakes, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeSteepLong, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::slopeCurveSteep }, + .extraTrackGroups = { TrackGroup::verticalLoop, TrackGroup::waterSplash }, + }), + .InvertedTrackPaintFunctions = {}, + .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | + EnumsToFlags(RtdFlag::hasLeaveWhenAnotherVehicleArrivesAtStation, RtdFlag::checkGForces, + RtdFlag::allowMultipleCircuits, RtdFlag::allowReversedTrains), + .RideModes = EnumsToFlags(RideMode::ContinuousCircuit, RideMode::ContinuousCircuitBlockSectioned), + .DefaultMode = RideMode::ContinuousCircuit, + .BoosterSettings = { 0, 68 }, + .LegacyBoosterSettings = { 0, 68 }, + .Naming = { STR_RIDE_NAME_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER, STR_RIDE_DESCRIPTION_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER }, + .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, + .EnumName = "RIDE_TYPE_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER", + .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), + .Heights = { 24, 24, 8, 11, }, + .MaxMass = 19, + .LiftData = { OpenRCT2::Audio::SoundId::LiftWood, 3, 5 }, + .RatingsMultipliers = { 52, 33, 4 }, + .UpkeepCosts = { 40, 20, 80, 10, 3, 10 }, + .BuildCosts = {37.50_GBP, 3.50_GBP, 50, }, + .DefaultPrices = { 20, 20 }, + .DefaultMusic = MUSIC_OBJECT_WILD_WEST, + .PhotoItem = ShopItem::Photo3, + .BonusValue = 105, + .ColourPresets = TRACK_COLOUR_PRESETS( + { COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_WHITE }, + { COLOUR_BRIGHT_RED, COLOUR_BLACK, COLOUR_GREY }, + { COLOUR_YELLOW, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN }, + { COLOUR_TEAL, COLOUR_BORDEAUX_RED, COLOUR_WHITE }, + { COLOUR_LIGHT_BLUE, COLOUR_BLACK, COLOUR_BLACK }, + { COLOUR_LIGHT_BLUE, COLOUR_BLACK, COLOUR_DARK_BROWN }, + ), + .ColourPreview = { SPR_RIDE_DESIGN_PREVIEW_CLASSIC_WOODEN_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_CLASSIC_WOODEN_ROLLER_COASTER_SUPPORTS }, + .ColourKey = RideColourKey::Ride, + .Name = "classic_wooden_twister_rc", + .RatingsData = + { + RatingsCalculationType::Normal, + { RIDE_RATING(2, 80), RIDE_RATING(2, 60), RIDE_RATING(2, 00) }, + 19, + -1, + false, + { + { RatingsModifierType::BonusLength, 6000, 873, 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, 364088, 655360, 0 }, + { RatingsModifierType::BonusDuration, 150, 26214, 0, 0 }, + { RatingsModifierType::BonusGForces, 0, 40960, 34555, 49648 }, + { RatingsModifierType::BonusTurns, 0, 26749, 43458, 45749 }, + { RatingsModifierType::BonusDrops, 0, 40777, 46811, 49152 }, + { RatingsModifierType::BonusSheltered, 0, 16705, 30583, 35108 }, + { RatingsModifierType::BonusReversedTrains, 0, 2, 12, 22 }, + { RatingsModifierType::BonusProximity, 0, 22367, 0, 0 }, + { RatingsModifierType::BonusScenery, 0, 11155, 0, 0 }, + { RatingsModifierType::RequirementDropHeight, 12, 2, 1, 2 }, + { RatingsModifierType::RequirementMaxSpeed, 0xA0000, 2, 1, 2 }, + { RatingsModifierType::RequirementNegativeGs, FIXED_2DP(0, 10), 2, 1, 2 }, + { RatingsModifierType::RequirementLength, 0x1720000, 2, 1, 2 }, + { RatingsModifierType::RequirementNumDrops, 2, 2, 1, 2 }, + { RatingsModifierType::PenaltyLateralGs, 0, 40960, 34555, 49648 }, + }, + }, +}; +// clang-format on From f5818794d8ea3f0b339946abd76fe2644f4ec7bb Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 13 Nov 2024 08:34:02 +0000 Subject: [PATCH 056/139] Implement Classic Wooden Twister bank to gentle up track --- .../ClassicWoodenTwisterRollerCoaster.cpp | 99 ++++++++++ .../track/coaster/WoodenRollerCoaster.cpp | 171 ++++++------------ .../track/coaster/WoodenRollerCoaster.hpp | 22 +++ 3 files changed, 172 insertions(+), 120 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 8485e4390f..e31a566c9e 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -45,11 +45,27 @@ enum SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65465, SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65466, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_0 = SPR_CSG_BEGIN + 65467, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_1 = SPR_CSG_BEGIN + 65468, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_2 = SPR_CSG_BEGIN + 65469, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_3 = SPR_CSG_BEGIN + 65470, + + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_0 = SPR_CSG_BEGIN + 65471, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_1 = SPR_CSG_BEGIN + 65472, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_2 = SPR_CSG_BEGIN + 65473, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_3 = SPR_CSG_BEGIN + 65474, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65475, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_3 = SPR_CSG_BEGIN + 65476, // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65477, // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65478, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65482, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65483, + + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65484, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65485, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -75,10 +91,26 @@ enum SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66221, SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66222, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_0 = SPR_CSG_BEGIN + 66223, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_1 = SPR_CSG_BEGIN + 66224, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_2 = SPR_CSG_BEGIN + 66225, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_3 = SPR_CSG_BEGIN + 66226, + + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_0 = SPR_CSG_BEGIN + 66227, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_1 = SPR_CSG_BEGIN + 66228, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_2 = SPR_CSG_BEGIN + 66229, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_3 = SPR_CSG_BEGIN + 66230, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66231, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3 = SPR_CSG_BEGIN + 66232, // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66233, // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66234, + + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66238, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66239, + + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66240, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66241, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -170,6 +202,47 @@ static constexpr std::array kUp25 }, } }; +static constexpr std::array kLeftBankToUp25Images = { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_0, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_2, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_2, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_3, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_3, + }, +} }; +static constexpr std::array kRightBankToUp25Images = { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_3, + }, +} }; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -210,6 +283,22 @@ static void ClassicWoodenTwisterRCTrackRightBankTo25DegDown( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrack25DegDownToLeftBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrack25DegDownToRightBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -242,6 +331,16 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track return ClassicWoodenTwisterRCTrackLeftBankTo25DegDown; case TrackElemType::RightBankToDown25: return ClassicWoodenTwisterRCTrackRightBankTo25DegDown; + + case TrackElemType::LeftBankToUp25: + return WoodenRCTrackBankTo25DegUp; + case TrackElemType::RightBankToUp25: + return WoodenRCTrackBankTo25DegUp; + case TrackElemType::Down25ToLeftBank: + return ClassicWoodenTwisterRCTrack25DegDownToLeftBank; + case TrackElemType::Down25ToRightBank: + return ClassicWoodenTwisterRCTrack25DegDownToRightBank; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 8f472d13ff..466baa4259 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -578,6 +578,51 @@ static constexpr std::array kUp25 }, } }; +static constexpr std::array kLeftBankToUp25Images = { { + { + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_SW_NE, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_SW_NE, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_NW_SE, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_NW_SE, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_FRONT_NW_SE, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_FRONT_NW_SE, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_NE_SW, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_NE_SW, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_FRONT_NE_SW, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_FRONT_NE_SW, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_SE_NW, + SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_SE_NW, + }, +} }; +static constexpr std::array kRightBankToUp25Images = { { + { + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_SW_NE, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_SW_NE, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_NW_SE, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_NW_SE, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_FRONT_NW_SE, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_FRONT_NW_SE, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_NE_SW, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_NE_SW, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_FRONT_NE_SW, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_FRONT_NE_SW, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_SE_NW, + SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_SE_NW, + }, +} }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -2002,120 +2047,6 @@ static void WoodenRCTrackBankedLeftQuarterTurn5( session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); } -/** rct2: 0x008AC6B8 */ -template -static void WoodenRCTrackLeftBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr uint32_t imageIds[4][4] = { - { - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_SW_NE, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_SW_NE, - 0, - 0, - }, - { - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_NW_SE, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_NW_SE, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_FRONT_NW_SE, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_FRONT_NW_SE, - }, - { - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_NE_SW, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_NE_SW, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_FRONT_NE_SW, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_FRONT_NE_SW, - }, - { - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_SE_NW, - SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_SE_NW, - 0, - 0, - }, - }; - - WoodenRCTrackPaint( - session, direction, imageIds[direction][0], imageIds[direction][1], { 0, 0, height }, - { { 0, 3, height }, { 32, 25, 2 } }); - if (direction == 1 || direction == 2) - { - WoodenRCTrackPaint( - session, direction, imageIds[direction][2], imageIds[direction][3], { 0, 0, height }, - { { 0, 26, height + 5 }, { 32, 1, 9 } }); - } - WoodenASupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours, - WoodenSupportTransitionType::FlatToUp25Deg); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::SlopeEnd); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); -} - -/** rct2: 0x008AC6C8 */ -template -static void WoodenRCTrackRightBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr uint32_t imageIds[4][4] = { - { - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_SW_NE, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_SW_NE, - 0, - 0, - }, - { - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_NW_SE, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_NW_SE, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_FRONT_NW_SE, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_FRONT_NW_SE, - }, - { - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_NE_SW, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_NE_SW, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_FRONT_NE_SW, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_FRONT_NE_SW, - }, - { - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_SE_NW, - SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_SE_NW, - 0, - 0, - }, - }; - - WoodenRCTrackPaint( - session, direction, imageIds[direction][0], imageIds[direction][1], { 0, 0, height }, - { { 0, 3, height }, { 32, 25, 2 } }); - if (direction == 1 || direction == 2) - { - WoodenRCTrackPaint( - session, direction, imageIds[direction][2], imageIds[direction][3], { 0, 0, height }, - { { 0, 26, height + 5 }, { 32, 1, 9 } }); - } - WoodenASupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours, - WoodenSupportTransitionType::FlatToUp25Deg); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::SlopeEnd); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); -} - /** rct2: */ /** rct2: 0x008AC6F8 */ @@ -2144,8 +2075,8 @@ static void WoodenRCTrack25DegDownToLeftBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - WoodenRCTrackRightBankTo25DegUp( - session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } /** rct2: 0x008AC728 */ @@ -2154,8 +2085,8 @@ static void WoodenRCTrack25DegDownToRightBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - WoodenRCTrackLeftBankTo25DegUp( - session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } /** rct2: 0x008AC748 */ @@ -17547,9 +17478,9 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::BankedRightQuarterTurn5Tiles: return WoodenRCTrackBankedRightQuarterTurn5; case TrackElemType::LeftBankToUp25: - return WoodenRCTrackLeftBankTo25DegUp; + return WoodenRCTrackBankTo25DegUp; case TrackElemType::RightBankToUp25: - return WoodenRCTrackRightBankTo25DegUp; + return WoodenRCTrackBankTo25DegUp; case TrackElemType::Up25ToLeftBank: return WoodenRCTrack25DegUpToBank; case TrackElemType::Up25ToRightBank: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index cd3051c691..796439ee94 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -142,4 +142,26 @@ static void WoodenRCTrack25DegUpToBank( PaintUtilSetGeneralSupportHeight(session, height + 40); } +/** rct2: 0x008AC6B8, 0x008AC6C8 */ +template imageIds> +static void WoodenRCTrackBankTo25DegUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + WoodenRCTrackStraightBankTrack(session, direction, height); + WoodenASupportsPaintSetupRotated( + session, supportType.wooden, WoodenSupportSubType::NeSw, direction, height, session.SupportColours, + WoodenSupportTransitionType::FlatToUp25Deg); + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + else + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::SlopeEnd); + } + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From d5ef048448a588f2d17083b850e2cf27d3e378fc Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 13 Nov 2024 08:44:49 +0000 Subject: [PATCH 057/139] Implement Classic Wooden Twister flat banked front sprites --- .../ClassicWoodenTwisterRollerCoaster.cpp | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index e31a566c9e..daaeb6ad61 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -57,8 +57,10 @@ enum SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65475, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_3 = SPR_CSG_BEGIN + 65476, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65477, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65478, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65477, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65478, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65482, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65483, @@ -66,6 +68,8 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65484, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65485, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65486, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -103,14 +107,18 @@ enum SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66231, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3 = SPR_CSG_BEGIN + 66232, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66233, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66234, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66233, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66234, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66238, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66239, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66240, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66241, + + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66242, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -138,18 +146,20 @@ static constexpr std::array kFlat static constexpr std::array kFlatToRightBankImages = { { { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_0, SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, }, { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_1, SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_2, SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2, - // SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, }, { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_3, @@ -172,6 +182,8 @@ static constexpr std::array kUp25 { SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_1, SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_1, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_1, }, { SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_2, From a5b5460bdb689396042b12c103c6d54a741fd0e2 Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 13 Nov 2024 08:54:44 +0000 Subject: [PATCH 058/139] Implement more Classic Wooden Twister gentle banked front sprites --- .../ClassicWoodenTwisterRollerCoaster.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index daaeb6ad61..143ec41f68 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -61,6 +61,10 @@ enum SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65477, SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65478, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65479, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65480, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65481, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65482, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65483, @@ -111,6 +115,10 @@ enum SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66233, SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66234, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66235, + + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66236, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66237, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66238, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66239, @@ -188,6 +196,8 @@ static constexpr std::array kUp25 { SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_2, SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_2, }, { SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_3, @@ -203,10 +213,14 @@ static constexpr std::array kUp25 { SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_1, SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_1, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_1, }, { SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_2, SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_2, }, { SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_3, @@ -244,10 +258,14 @@ static constexpr std::array kRigh { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_1, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_1, }, { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_2, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2, }, { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_3, From a2cea6a860e9bdfbc47080c45607eacf3bf50e7c Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 13 Nov 2024 19:36:52 +0000 Subject: [PATCH 059/139] Implement Classic Wooden Twister medium banked turns --- .../ClassicWoodenTwisterRollerCoaster.cpp | 192 +++++++ .../track/coaster/WoodenRollerCoaster.cpp | 469 +++++------------- .../track/coaster/WoodenRollerCoaster.hpp | 219 ++++++++ 3 files changed, 527 insertions(+), 353 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 143ec41f68..99ba425856 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -74,6 +74,38 @@ enum SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65486, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_0 = SPR_CSG_BEGIN + 65585, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_0 = SPR_CSG_BEGIN + 65586, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_0 = SPR_CSG_BEGIN + 65587, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_0 = SPR_CSG_BEGIN + 65588, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_0 = SPR_CSG_BEGIN + 65589, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_1 = SPR_CSG_BEGIN + 65590, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_1 = SPR_CSG_BEGIN + 65591, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_1 = SPR_CSG_BEGIN + 65592, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_1 = SPR_CSG_BEGIN + 65593, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_1 = SPR_CSG_BEGIN + 65594, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_2 = SPR_CSG_BEGIN + 65595, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_2 = SPR_CSG_BEGIN + 65596, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_2 = SPR_CSG_BEGIN + 65597, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_2 = SPR_CSG_BEGIN + 65598, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_2 = SPR_CSG_BEGIN + 65599, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_3 = SPR_CSG_BEGIN + 65600, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_3 = SPR_CSG_BEGIN + 65601, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_3 = SPR_CSG_BEGIN + 65602, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_3 = SPR_CSG_BEGIN + 65603, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_3 = SPR_CSG_BEGIN + 65604, + + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_0 = SPR_CSG_BEGIN + 65605, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_0 = SPR_CSG_BEGIN + 65606, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_0 = SPR_CSG_BEGIN + 65607, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_0 = SPR_CSG_BEGIN + 65608, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_0 = SPR_CSG_BEGIN + 65609, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_2 = SPR_CSG_BEGIN + 65610, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_2 = SPR_CSG_BEGIN + 65611, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_2 = SPR_CSG_BEGIN + 65612, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_2 = SPR_CSG_BEGIN + 65613, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_2 = SPR_CSG_BEGIN + 65614, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -127,6 +159,38 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66241, SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66242, + + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66341, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66342, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66343, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66344, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66345, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66346, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66347, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66348, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66349, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66350, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66351, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66352, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66353, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66354, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66355, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66356, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66357, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66358, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66359, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66360, + + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66361, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66362, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66363, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66364, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66365, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66366, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66367, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66368, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66369, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66370, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -250,6 +314,7 @@ static constexpr std::array kLeft SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_3, }, } }; + static constexpr std::array kRightBankToUp25Images = { { { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_0, @@ -273,6 +338,119 @@ static constexpr std::array kRigh }, } }; +static constexpr std::array, 5> kBankedQuarterTurn5Images = { { + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_3, + }, + } }, +} }; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -329,6 +507,15 @@ static void ClassicWoodenTwisterRCTrack25DegDownToRightBank( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackBankedLeftQuarterTurn5( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapLeftQuarterTurn5TilesToRightQuarterTurn5Tiles[trackSequence]; + WoodenRCTrackBankedRightQuarterTurn5( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -371,6 +558,11 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::Down25ToRightBank: return ClassicWoodenTwisterRCTrack25DegDownToRightBank; + case TrackElemType::BankedLeftQuarterTurn5Tiles: + return ClassicWoodenTwisterRCTrackBankedLeftQuarterTurn5; + case TrackElemType::BankedRightQuarterTurn5Tiles: + return WoodenRCTrackBankedRightQuarterTurn5; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 466baa4259..fb99ec93c8 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -623,6 +623,119 @@ static constexpr std::array kRigh }, } }; +static constexpr std::array, 5> kBankedQuarterTurn5Images = { { + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_0, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_0, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_0, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_0, + }, + } }, + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_2, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_2, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_2, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_2, + }, + } }, + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_3, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_3, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_3, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_3, + }, + } }, + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_5, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_5, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_5, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_5, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_5, + }, + } }, + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_6, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_6, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_6, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_6, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_6, + }, + } }, +} }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -1687,364 +1800,14 @@ static void WoodenRCTrackRightBankToFlat( session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); } -template -static void WoodenRCTrackBankedRightQuarterTurn5( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[2][4][7] = { - { - { - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_0, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 2, 0 }, { 32, 32, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_2, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_2, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 32, 16, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_3, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_3, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 16, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_5, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_5, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 32, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_6, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SW_SE_SEQ_6, - { 0, 0, 0 }, - BoundBoxXYZ({ 2, 0, 0 }, { 32, 32, 2 }), - }, - }, - { - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_0, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_0, - { 0, 0, 0 }, - BoundBoxXYZ({ 2, 0, 0 }, { 32, 32, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_2, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_2, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 32, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_3, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_3, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 16, 16, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_5, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_5, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 16, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NW_SW_SEQ_6, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NW_SW_SEQ_6, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 2, 0 }, { 32, 27, 2 }), - }, - }, - { - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_0, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 2, 0 }, { 32, 27, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_2, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_2, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 16, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_3, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_3, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 16, 0 }, { 16, 16, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_5, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_5, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 32, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_NE_NW_SEQ_6, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_NE_NW_SEQ_6, - { 0, 0, 0 }, - BoundBoxXYZ({ 2, 0, 0 }, { 27, 32, 2 }), - }, - }, - { - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_0, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_0, - { 0, 0, 0 }, - BoundBoxXYZ({ 2, 0, 0 }, { 27, 32, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_2, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_2, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 32, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_3, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_3, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 16, 2 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_5, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_5, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 32, 16, 2 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SE_NE_SEQ_6, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_SE_NE_SEQ_6, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 2, 0 }, { 32, 32, 2 }), - }, - }, - }, - { - { - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_0, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 2, 27 }, { 32, 32, 0 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_2, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_2, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 27 }, { 32, 16, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_3, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_3, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 16, 16, 0 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_5, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_5, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 27 }, { 16, 32, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_SW_SE_SEQ_6, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_SW_SE_SEQ_6, - { 0, 0, 0 }, - BoundBoxXYZ({ 2, 0, 27 }, { 32, 32, 0 }), - }, - }, - { - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - }, - { - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_0, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 2, 27 }, { 32, 27, 0 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_2, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_2, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 32, 16, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_3, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_3, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 16, 27 }, { 16, 16, 0 }), - }, - { - 0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_5, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_5, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 16, 32, 0 }), - }, - { - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_6, - SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_6, - { 0, 0, 0 }, - BoundBoxXYZ({ 2, 0, 27 }, { 27, 32, 0 }), - }, - }, - { - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - { 0, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 0, 0 }, { 0, 0, 0 }) }, - }, - }, - }; - static WoodenSupportSubType supportSubType[kNumOrthogonalDirections][7] = { - { WoodenSupportSubType::NeSw, WoodenSupportSubType::Null, WoodenSupportSubType::Corner2, WoodenSupportSubType::Corner0, - WoodenSupportSubType::Null, WoodenSupportSubType::Corner2, WoodenSupportSubType::NwSe }, - { WoodenSupportSubType::NwSe, WoodenSupportSubType::Null, WoodenSupportSubType::Corner3, WoodenSupportSubType::Corner1, - WoodenSupportSubType::Null, WoodenSupportSubType::Corner3, WoodenSupportSubType::NeSw }, - { WoodenSupportSubType::NeSw, WoodenSupportSubType::Null, WoodenSupportSubType::Corner0, WoodenSupportSubType::Corner2, - WoodenSupportSubType::Null, WoodenSupportSubType::Corner0, WoodenSupportSubType::NwSe }, - { WoodenSupportSubType::NwSe, WoodenSupportSubType::Null, WoodenSupportSubType::Corner1, WoodenSupportSubType::Corner3, - WoodenSupportSubType::Null, WoodenSupportSubType::Corner1, WoodenSupportSubType::NeSw }, - }; - - WoodenRCTrackPaintBb(session, &imageIds[0][direction][trackSequence], height); - WoodenRCTrackPaintBb(session, &imageIds[1][direction][trackSequence], height); - TrackPaintUtilRightQuarterTurn5TilesTunnel(session, kTunnelGroup, TunnelSubType::Flat, height, direction, trackSequence); - - if (supportSubType[direction][trackSequence] != WoodenSupportSubType::Null) - { - WoodenASupportsPaintSetup( - session, supportType.wooden, supportSubType[direction][trackSequence], height, session.SupportColours); - } - - int32_t blockedSegments = 0; - switch (trackSequence) - { - case 0: - blockedSegments = kSegmentsAll; - break; - case 1: - blockedSegments = EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide); - break; - case 2: - blockedSegments = EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide); - break; - case 3: - blockedSegments = EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::centre, - PaintSegment::topLeftSide, PaintSegment::topRightSide, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide); - break; - case 4: - blockedSegments = EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide); - break; - case 5: - blockedSegments = EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide); - break; - case 6: - blockedSegments = kSegmentsAll; - break; - } - PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} - template static void WoodenRCTrackBankedLeftQuarterTurn5( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { trackSequence = kMapLeftQuarterTurn5TilesToRightQuarterTurn5Tiles[trackSequence]; - WoodenRCTrackBankedRightQuarterTurn5( - session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); + WoodenRCTrackBankedRightQuarterTurn5( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } /** rct2: */ @@ -17476,7 +17239,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::BankedLeftQuarterTurn5Tiles: return WoodenRCTrackBankedLeftQuarterTurn5; case TrackElemType::BankedRightQuarterTurn5Tiles: - return WoodenRCTrackBankedRightQuarterTurn5; + return WoodenRCTrackBankedRightQuarterTurn5; case TrackElemType::LeftBankToUp25: return WoodenRCTrackBankTo25DegUp; case TrackElemType::RightBankToUp25: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 796439ee94..0866addfa1 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -15,6 +15,7 @@ #include "../../Boundbox.h" #include "../../Paint.h" #include "../../support/WoodenSupports.h" +#include "../../support/WoodenSupports.hpp" #include "../../tile_element/Segment.h" #include "../../track/Segment.h" @@ -164,4 +165,222 @@ static void WoodenRCTrackBankTo25DegUp( PaintUtilSetGeneralSupportHeight(session, height + 48); } +template, 5> imageIds> +static void WoodenRCTrackBankedRightQuarterTurn5( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 32, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 2, height + 27 }, { 32, 32, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 32, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 27, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 2, height + 27 }, { 32, 27, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 27, 2 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 16, height + 27 }, { 32, 16, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + break; + } + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + } + break; + case 5: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 16, 0, height + 27 }, { 16, 32, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 32, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + break; + } + break; + case 6: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 2, 0, height }, { 32, 32, 2 } }); + if (imageIds[4][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].frontTrack, imageIds[4][direction].frontHandrail, + { 0, 0, height }, { { 2, 0, height + 27 }, { 32, 32, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 2, 0, height }, { 27, 32, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 2, 0, height }, { 27, 32, 2 } }); + if (imageIds[4][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].frontTrack, imageIds[4][direction].frontHandrail, + { 0, 0, height }, { { 2, 0, height + 27 }, { 27, 32, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 2, 0, height }, { 32, 32, 2 } }); + break; + } + break; + } + + TrackPaintUtilRightQuarterTurn5TilesTunnel(session, kTunnelGroup, TunnelSubType::Flat, height, direction, trackSequence); + + static constexpr int blockedSegments[7] = { + kSegmentsAll, + EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::centre, + PaintSegment::topLeftSide, PaintSegment::topRightSide, PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + kSegmentsAll, + }; + + DrawSupportForSequenceA( + session, supportType.wooden, trackSequence, direction, height, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments[trackSequence], direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From 6bd6db6342de6e97634a106da0b51749dbe4c3b6 Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 13 Nov 2024 22:57:55 +0000 Subject: [PATCH 060/139] Implement Classic Wooden Twister large right helix --- .../ClassicWoodenTwisterRollerCoaster.cpp | 198 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 961 ++++-------------- .../track/coaster/WoodenRollerCoaster.hpp | 658 ++++++++++++ 3 files changed, 1035 insertions(+), 782 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 99ba425856..ec3bb01dba 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -106,6 +106,38 @@ enum SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_2 = SPR_CSG_BEGIN + 65613, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_2 = SPR_CSG_BEGIN + 65614, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_0 = SPR_CSG_BEGIN + 65615, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_0 = SPR_CSG_BEGIN + 65616, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_0 = SPR_CSG_BEGIN + 65617, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_0 = SPR_CSG_BEGIN + 65618, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_0 = SPR_CSG_BEGIN + 65619, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_1 = SPR_CSG_BEGIN + 65620, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_1 = SPR_CSG_BEGIN + 65621, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_1 = SPR_CSG_BEGIN + 65622, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_1 = SPR_CSG_BEGIN + 65623, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_1 = SPR_CSG_BEGIN + 65624, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_2 = SPR_CSG_BEGIN + 65625, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_2 = SPR_CSG_BEGIN + 65626, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_2 = SPR_CSG_BEGIN + 65627, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_2 = SPR_CSG_BEGIN + 65628, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_2 = SPR_CSG_BEGIN + 65629, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_3 = SPR_CSG_BEGIN + 65630, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_3 = SPR_CSG_BEGIN + 65631, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_3 = SPR_CSG_BEGIN + 65632, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_3 = SPR_CSG_BEGIN + 65633, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_3 = SPR_CSG_BEGIN + 65634, + + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_0 = SPR_CSG_BEGIN + 65635, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_0 = SPR_CSG_BEGIN + 65636, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_0 = SPR_CSG_BEGIN + 65637, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_0 = SPR_CSG_BEGIN + 65638, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_0 = SPR_CSG_BEGIN + 65639, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_2 = SPR_CSG_BEGIN + 65640, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65641, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_2 = SPR_CSG_BEGIN + 65642, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2 = SPR_CSG_BEGIN + 65643, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2 = SPR_CSG_BEGIN + 65644, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -191,6 +223,38 @@ enum SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66368, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66369, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66370, + + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66371, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66372, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66373, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66374, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66375, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66376, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66377, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66378, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66379, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66380, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66381, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66382, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66383, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66384, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66385, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66386, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66387, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66388, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66389, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66390, + + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66391, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66392, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66393, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66394, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66395, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66396, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66397, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66398, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66399, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66400, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -451,6 +515,121 @@ static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { + { + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, + }, + } }, + } +}; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -516,6 +695,20 @@ static void ClassicWoodenTwisterRCTrackBankedLeftQuarterTurn5( session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackLeftHalfBankedHelixDownLarge( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + if (trackSequence >= 7) + { + trackSequence -= 7; + direction = DirectionPrev(direction); + } + trackSequence = kMapLeftQuarterTurn5TilesToRightQuarterTurn5Tiles[trackSequence]; + WoodenRCTrackRightHalfBankedHelixUpLarge( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -563,6 +756,11 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::BankedRightQuarterTurn5Tiles: return WoodenRCTrackBankedRightQuarterTurn5; + case TrackElemType::RightHalfBankedHelixUpLarge: + return WoodenRCTrackRightHalfBankedHelixUpLarge; + case TrackElemType::LeftHalfBankedHelixDownLarge: + return ClassicWoodenTwisterRCTrackLeftHalfBankedHelixDownLarge; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index fb99ec93c8..17498de1c6 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -194,6 +194,36 @@ enum SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_3 = 23662, SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_5 = 23663, SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_NE_NW_SEQ_6 = 23664, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_0 = 23665, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_0 = 23666, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_0 = 23667, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_0 = 23668, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_0 = 23669, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_1 = 23670, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_1 = 23671, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_1 = 23672, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_1 = 23673, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_1 = 23674, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_2 = 23675, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_2 = 23676, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_2 = 23677, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_2 = 23678, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_2 = 23679, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_3 = 23680, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_3 = 23681, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_3 = 23682, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_3 = 23683, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_3 = 23684, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_0 = 23685, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_0 = 23686, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_0 = 23687, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_0 = 23688, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_0 = 23689, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_2 = 23690, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_2 = 23691, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_2 = 23692, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2 = 23693, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2 = 23694, SPR_WOODEN_RC_FLAT_CHAIN_SW_NE = 23749, SPR_WOODEN_RC_FLAT_CHAIN_NW_SE = 23750, @@ -427,6 +457,36 @@ enum SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_3 = 24528, SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_5 = 24529, SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_RAILS_FRONT_NE_NW_SEQ_6 = 24530, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = 24531, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = 24532, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = 24533, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = 24534, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = 24535, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = 24536, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = 24537, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = 24538, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = 24539, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = 24540, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = 24541, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = 24542, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = 24543, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = 24544, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = 24545, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = 24546, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = 24547, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = 24548, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = 24549, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = 24550, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_0 = 24551, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_0 = 24552, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_0 = 24553, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_0 = 24554, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_0 = 24555, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_2 = 24556, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_2 = 24557, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2 = 24558, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2 = 24559, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2 = 24560, SPR_WOODEN_RC_FLAT_CHAIN_RAILS_SW_NE = 24615, SPR_WOODEN_RC_FLAT_CHAIN_RAILS_NW_SE = 24616, @@ -736,6 +796,121 @@ static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { + { + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, + }, + } }, + } +}; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -6366,784 +6541,6 @@ static void WoodenRCTrackLeftHalfBankedHelixUpLarge( } } -/** rct2: 0x008ACB08 */ -template -static void WoodenRCTrackRightHalfBankedHelixUpLarge( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23665), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24531), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23685), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24551), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23670), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24536), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23675), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24541), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23690), { 0, 0, height }, - { { 0, 2, height + 27 }, { 32, 27, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24556), { 0, 0, height }, - { { 0, 2, height + 27 }, { 32, 27, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23680), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24546), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, - PaintSegment::topLeftSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23666), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24532), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23686), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24552), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23671), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24537), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23676), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24542), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23691), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24557), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23681), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24547), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23667), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24533), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23687), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24553), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23672), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24538), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23677), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24543), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23692), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24558), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23682), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24548), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 4: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 5: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23668), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24534), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23688), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24554), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23673), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24539), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23678), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24544), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23693), { 0, 0, height }, - { { 0, 0, height + 33 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24559), { 0, 0, height }, - { { 0, 0, height + 33 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23683), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24549), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 6: - switch (direction) - { - case 0: - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23669), { 0, 0, height }, - { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24535), { 0, 0, height }, - { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23689), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24555), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23674), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24540), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23679), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24545), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23694), { 0, 0, height }, - { { 2, 0, height + 33 }, { 27, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24560), { 0, 0, height }, - { { 2, 0, height + 33 }, { 27, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23684), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24550), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - } - switch (direction) - { - case 0: - PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - case 1: - PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 7: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23670), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24536), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23675), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24541), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23690), { 0, 0, height }, - { { 2, 0, height + 27 }, { 27, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24556), { 0, 0, height }, - { { 2, 0, height + 27 }, { 27, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23680), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24546), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23665), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24531), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23685), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24551), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - } - switch (direction) - { - case 2: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - case 3: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 8: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 9: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23671), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24537), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23676), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24542), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23691), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24557), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23681), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24547), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23666), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24532), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23686), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24552), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 10: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23672), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24538), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23677), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24543), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23692), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24558), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23682), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24548), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23667), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24533), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23687), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24553), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 11: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 12: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23673), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24539), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23678), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24544), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23693), { 0, 0, height }, - { { 0, 0, height + 33 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24559), { 0, 0, height }, - { { 0, 0, height + 33 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23683), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24549), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23668), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24534), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23688), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24554), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::topRightSide, PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 13: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23674), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24540), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23679), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24545), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23694), { 0, 0, height }, - { { 0, 2, height + 33 }, { 32, 27, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24560), { 0, 0, height }, - { { 0, 2, height + 33 }, { 32, 27, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23684), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24550), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23669), { 0, 0, height }, - { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24535), { 0, 0, height }, - { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23689), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24555), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - /** rct2: 0x008ACB18 */ template static void WoodenRCTrackLeftHalfBankedHelixDownLarge( @@ -7153,11 +6550,11 @@ static void WoodenRCTrackLeftHalfBankedHelixDownLarge( if (trackSequence >= 7) { trackSequence -= 7; - direction = (direction - 1) & 3; + direction = DirectionPrev(direction); } trackSequence = kMapLeftQuarterTurn5TilesToRightQuarterTurn5Tiles[trackSequence]; - WoodenRCTrackRightHalfBankedHelixUpLarge( - session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); + WoodenRCTrackRightHalfBankedHelixUpLarge( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } /** rct2: 0x008ACB28 */ @@ -17303,7 +16700,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::LeftHalfBankedHelixUpLarge: return WoodenRCTrackLeftHalfBankedHelixUpLarge; case TrackElemType::RightHalfBankedHelixUpLarge: - return WoodenRCTrackRightHalfBankedHelixUpLarge; + return WoodenRCTrackRightHalfBankedHelixUpLarge; case TrackElemType::LeftHalfBankedHelixDownLarge: return WoodenRCTrackLeftHalfBankedHelixDownLarge; case TrackElemType::RightHalfBankedHelixDownLarge: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 0866addfa1..b99b07fa54 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -383,4 +383,662 @@ static void WoodenRCTrackBankedRightQuarterTurn5( PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); } +/** rct2: 0x008ACB08 */ +template, 5> imageIds> +static void WoodenRCTrackRightHalfBankedHelixUpLarge( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 27, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 2, height + 27 }, { 32, 27, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, + PaintSegment::topLeftSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 1: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 16, height + 27 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 16, 16, height + 29 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 4: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 5: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 16, 0, height + 27 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 33 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 6: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 6, 0, height + 8 }, { 20, 32, 2 } }); + if (imageIds[4][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].frontTrack, imageIds[4][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 2, 0, height }, { 27, 32, 2 } }); + if (imageIds[4][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].frontTrack, imageIds[4][direction].frontHandrail, + { 0, 0, height }, { { 2, 0, height + 33 }, { 27, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + } + switch (direction) + { + case 0: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 1: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 7: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][1].track, imageIds[0][1].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][2].track, imageIds[0][2].handrail, { 0, 0, height }, + { { 2, 0, height }, { 27, 32, 2 } }); + if (imageIds[0][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][2].frontTrack, imageIds[0][2].frontHandrail, { 0, 0, height }, + { { 2, 0, height + 27 }, { 27, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][3].track, imageIds[0][3].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][0].track, imageIds[0][0].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[0][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][0].frontTrack, imageIds[0][0].frontHandrail, { 0, 0, height }, + { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + } + switch (direction) + { + case 2: + PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + case 3: + PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 8: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 9: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][1].track, imageIds[1][1].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][2].track, imageIds[1][2].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + if (imageIds[1][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][2].frontTrack, imageIds[1][2].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 27 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][3].track, imageIds[1][3].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][0].track, imageIds[1][0].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + if (imageIds[1][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][0].frontTrack, imageIds[1][0].frontHandrail, { 0, 0, height }, + { { 16, 0, height + 27 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 10: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][1].track, imageIds[2][1].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][2].track, imageIds[2][2].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[2][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][2].frontTrack, imageIds[2][2].frontHandrail, { 0, 0, height }, + { { 16, 16, height + 29 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][3].track, imageIds[2][3].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][0].track, imageIds[2][0].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[2][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][0].frontTrack, imageIds[2][0].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 11: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 12: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[3][1].track, imageIds[3][1].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[3][2].track, imageIds[3][2].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + if (imageIds[3][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][2].frontTrack, imageIds[3][2].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 33 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[3][3].track, imageIds[3][3].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[3][0].track, imageIds[3][0].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + if (imageIds[3][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][0].frontTrack, imageIds[3][0].frontHandrail, { 0, 0, height }, + { { 0, 16, height + 27 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide, PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 13: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[4][1].track, imageIds[4][1].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[4][2].track, imageIds[4][2].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 27, 2 } }); + if (imageIds[4][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][2].frontTrack, imageIds[4][2].frontHandrail, { 0, 0, height }, + { { 0, 2, height + 33 }, { 32, 27, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[4][3].track, imageIds[4][3].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[4][0].track, imageIds[4][0].handrail, { 0, 0, height }, + { { 0, 6, height + 8 }, { 32, 20, 2 } }); + if (imageIds[4][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][0].frontTrack, imageIds[4][0].frontHandrail, { 0, 0, height }, + { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + } +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From dc13501161dd57358c8a4402be2750b51a234f20 Mon Sep 17 00:00:00 2001 From: mix Date: Wed, 13 Nov 2024 23:53:16 +0000 Subject: [PATCH 061/139] Implement Classic Wooden Twister large left helix --- .../ClassicWoodenTwisterRollerCoaster.cpp | 197 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 961 ++++-------------- .../track/coaster/WoodenRollerCoaster.hpp | 658 ++++++++++++ 3 files changed, 1034 insertions(+), 782 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index ec3bb01dba..970e4af641 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -138,6 +138,38 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2 = SPR_CSG_BEGIN + 65643, SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2 = SPR_CSG_BEGIN + 65644, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3 = SPR_CSG_BEGIN + 65645, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3 = SPR_CSG_BEGIN + 65646, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3 = SPR_CSG_BEGIN + 65647, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3 = SPR_CSG_BEGIN + 65648, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3 = SPR_CSG_BEGIN + 65649, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0 = SPR_CSG_BEGIN + 65650, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0 = SPR_CSG_BEGIN + 65651, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0 = SPR_CSG_BEGIN + 65652, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0 = SPR_CSG_BEGIN + 65653, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0 = SPR_CSG_BEGIN + 65654, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1 = SPR_CSG_BEGIN + 65655, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1 = SPR_CSG_BEGIN + 65656, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1 = SPR_CSG_BEGIN + 65657, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1 = SPR_CSG_BEGIN + 65658, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1 = SPR_CSG_BEGIN + 65659, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2 = SPR_CSG_BEGIN + 65660, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2 = SPR_CSG_BEGIN + 65661, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2 = SPR_CSG_BEGIN + 65662, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2 = SPR_CSG_BEGIN + 65663, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2 = SPR_CSG_BEGIN + 65664, + + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3 = SPR_CSG_BEGIN + 65665, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3 = SPR_CSG_BEGIN + 65666, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3 = SPR_CSG_BEGIN + 65667, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3 = SPR_CSG_BEGIN + 65668, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3 = SPR_CSG_BEGIN + 65669, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1 = SPR_CSG_BEGIN + 65670, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1 = SPR_CSG_BEGIN + 65671, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1 = SPR_CSG_BEGIN + 65672, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65673, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65674, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -255,6 +287,38 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66398, SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66399, SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66400, + + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66401, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66402, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66403, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66404, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66405, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66406, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66407, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66408, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66409, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66410, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66411, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66412, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66413, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66414, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66415, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66416, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66417, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66418, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66419, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66420, + + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66421, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66422, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66423, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66424, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66425, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66426, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66427, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66428, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66429, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66430, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -515,6 +579,121 @@ static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { + { + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, + }, + } }, + } +}; + static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { { { { @@ -709,6 +888,20 @@ static void ClassicWoodenTwisterRCTrackLeftHalfBankedHelixDownLarge( session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownLarge( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + if (trackSequence >= 7) + { + trackSequence -= 7; + direction = DirectionNext(direction); + } + trackSequence = kMapLeftQuarterTurn5TilesToRightQuarterTurn5Tiles[trackSequence]; + WoodenRCTrackLeftHalfBankedHelixUpLarge( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -756,10 +949,14 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::BankedRightQuarterTurn5Tiles: return WoodenRCTrackBankedRightQuarterTurn5; + case TrackElemType::LeftHalfBankedHelixUpLarge: + return WoodenRCTrackLeftHalfBankedHelixUpLarge; case TrackElemType::RightHalfBankedHelixUpLarge: return WoodenRCTrackRightHalfBankedHelixUpLarge; case TrackElemType::LeftHalfBankedHelixDownLarge: return ClassicWoodenTwisterRCTrackLeftHalfBankedHelixDownLarge; + case TrackElemType::RightHalfBankedHelixDownLarge: + return ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownLarge; default: return GetTrackPaintFunctionWoodenRC(trackType); diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 17498de1c6..e7d986811a 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -224,6 +224,36 @@ enum SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_2 = 23692, SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2 = 23693, SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2 = 23694, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3 = 23695, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3 = 23696, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3 = 23697, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3 = 23698, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3 = 23699, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0 = 23700, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0 = 23701, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0 = 23702, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0 = 23703, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0 = 23704, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1 = 23705, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1 = 23706, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1 = 23707, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1 = 23708, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1 = 23709, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2 = 23710, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2 = 23711, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2 = 23712, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2 = 23713, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2 = 23714, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3 = 23715, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3 = 23716, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3 = 23717, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3 = 23718, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3 = 23719, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1 = 23720, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1 = 23721, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1 = 23722, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1 = 23723, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1 = 23724, SPR_WOODEN_RC_FLAT_CHAIN_SW_NE = 23749, SPR_WOODEN_RC_FLAT_CHAIN_NW_SE = 23750, @@ -487,6 +517,36 @@ enum SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2 = 24558, SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2 = 24559, SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2 = 24560, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = 24561, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = 24562, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = 24563, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = 24564, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = 24565, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = 24566, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = 24567, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = 24568, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = 24569, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = 24570, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = 24571, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = 24572, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = 24573, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = 24574, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = 24575, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = 24576, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = 24577, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = 24578, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = 24579, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = 24580, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3 = 24581, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3 = 24582, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3 = 24583, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3 = 24584, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3 = 24585, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1 = 24586, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1 = 24587, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1 = 24588, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1 = 24589, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1 = 24590, SPR_WOODEN_RC_FLAT_CHAIN_RAILS_SW_NE = 24615, SPR_WOODEN_RC_FLAT_CHAIN_RAILS_NW_SE = 24616, @@ -796,6 +856,121 @@ static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { + { + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, + }, + } }, + } +}; + static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { { { { @@ -5763,784 +5938,6 @@ static void WoodenRCTrackRightHalfBankedHelixDownSmall( session, ride, trackSequence, (direction - 1) & 3, height, trackElement, supportType); } -/** rct2: 0x008ACAF8 */ -template -static void WoodenRCTrackLeftHalfBankedHelixUpLarge( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23704), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24570), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23709), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24575), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23724), { 0, 0, height }, - { { 0, 2, height + 27 }, { 32, 27, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24590), { 0, 0, height }, - { { 0, 2, height + 27 }, { 32, 27, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23714), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24580), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23699), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24565), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23719), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24585), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23703), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24569), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23708), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24574), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23723), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24589), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23713), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24579), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23698), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24564), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23718), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24584), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::topRightSide, PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23702), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24568), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23707), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24573), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23722), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24588), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23712), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24578), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23697), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24563), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23717), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24583), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 4: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 5: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23701), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24567), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23706), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24572), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23721), { 0, 0, height }, - { { 0, 0, height + 33 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24587), { 0, 0, height }, - { { 0, 0, height + 33 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23711), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24577), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23696), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24562), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23716), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24582), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 6: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23700), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24566), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23705), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24571), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23720), { 0, 0, height }, - { { 2, 0, height + 33 }, { 27, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24586), { 0, 0, height }, - { { 2, 0, height + 33 }, { 27, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23710), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24576), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23695), { 0, 0, height }, - { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24561), { 0, 0, height }, - { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23715), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24581), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - } - switch (direction) - { - case 2: - PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - case 3: - PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 7: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23699), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24565), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23719), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24585), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23704), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24570), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23709), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24575), { 0, 0, height }, - { { 2, 0, height }, { 27, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23724), { 0, 0, height }, - { { 2, 0, height + 27 }, { 27, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24590), { 0, 0, height }, - { { 2, 0, height + 27 }, { 27, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23714), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24580), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - } - switch (direction) - { - case 0: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - case 1: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 8: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 9: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23698), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24564), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23718), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24584), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23703), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24569), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23708), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24574), { 0, 0, height }, - { { 0, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23723), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24589), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23713), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24579), { 0, 0, height }, - { { 16, 0, height }, { 16, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 10: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23697), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24563), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23717), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24583), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23702), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24568), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23707), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24573), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23722), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24588), { 0, 0, height }, - { { 16, 16, height + 29 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23712), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24578), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 11: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), - 48, 0x20); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 12: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23696), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24562), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23716), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24582), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23701), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24567), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23706), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24572), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23721), { 0, 0, height }, - { { 0, 0, height + 33 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24587), { 0, 0, height }, - { { 0, 0, height + 33 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23711), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24577), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 13: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23695), { 0, 0, height }, - { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24561), { 0, 0, height }, - { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23715), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24581), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23700), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24566), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23705), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24571), { 0, 0, height }, - { { 0, 2, height }, { 32, 27, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23720), { 0, 0, height }, - { { 0, 2, height + 33 }, { 32, 27, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24586), { 0, 0, height }, - { { 0, 2, height + 33 }, { 32, 27, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23710), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24576), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, - PaintSegment::topLeftSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - /** rct2: 0x008ACB18 */ template static void WoodenRCTrackLeftHalfBankedHelixDownLarge( @@ -6566,11 +5963,11 @@ static void WoodenRCTrackRightHalfBankedHelixDownLarge( if (trackSequence >= 7) { trackSequence -= 7; - direction = (direction + 1) & 3; + direction = DirectionNext(direction); } trackSequence = kMapLeftQuarterTurn5TilesToRightQuarterTurn5Tiles[trackSequence]; - WoodenRCTrackLeftHalfBankedHelixUpLarge( - session, ride, trackSequence, (direction - 1) & 3, height, trackElement, supportType); + WoodenRCTrackLeftHalfBankedHelixUpLarge( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } /** rct2: 0x008ACB98 */ @@ -16698,7 +16095,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::RightHalfBankedHelixDownSmall: return WoodenRCTrackRightHalfBankedHelixDownSmall; case TrackElemType::LeftHalfBankedHelixUpLarge: - return WoodenRCTrackLeftHalfBankedHelixUpLarge; + return WoodenRCTrackLeftHalfBankedHelixUpLarge; case TrackElemType::RightHalfBankedHelixUpLarge: return WoodenRCTrackRightHalfBankedHelixUpLarge; case TrackElemType::LeftHalfBankedHelixDownLarge: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index b99b07fa54..38b903a3d0 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -383,6 +383,664 @@ static void WoodenRCTrackBankedRightQuarterTurn5( PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); } +/** rct2: 0x008ACAF8 */ +template, 5> imageIds> +static void WoodenRCTrackLeftHalfBankedHelixUpLarge( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 27, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 2, height + 27 }, { 32, 27, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 1: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 16, height + 27 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::topRightSide, PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 16, 16, height + 29 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::bottomCorner, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 4: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::rightCorner, PaintSegment::topRightSide, PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 5: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 33 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 16, 0, height + 27 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 6: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 2, 0, height }, { 27, 32, 2 } }); + if (imageIds[4][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].frontTrack, imageIds[4][direction].frontHandrail, + { 0, 0, height }, { { 2, 0, height + 33 }, { 27, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].track, imageIds[4][direction].handrail, { 0, 0, height }, + { { 6, 0, height + 8 }, { 20, 32, 2 } }); + if (imageIds[4][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][direction].frontTrack, imageIds[4][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + } + switch (direction) + { + case 2: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 3: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 7: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][3].track, imageIds[0][3].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[0][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][3].frontTrack, imageIds[0][3].frontHandrail, { 0, 0, height }, + { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][0].track, imageIds[0][0].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][1].track, imageIds[0][1].handrail, { 0, 0, height }, + { { 2, 0, height }, { 27, 32, 2 } }); + if (imageIds[0][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][1].frontTrack, imageIds[0][1].frontHandrail, { 0, 0, height }, + { { 2, 0, height + 27 }, { 27, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][2].track, imageIds[0][2].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + } + switch (direction) + { + case 0: + PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + case 1: + PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 8: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 9: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][3].track, imageIds[1][3].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + if (imageIds[1][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][3].frontTrack, imageIds[1][3].frontHandrail, { 0, 0, height }, + { { 16, 0, height + 27 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][0].track, imageIds[1][0].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][1].track, imageIds[1][1].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 32, 2 } }); + if (imageIds[1][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][1].frontTrack, imageIds[1][1].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 27 }, { 16, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][2].track, imageIds[1][2].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 10: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][3].track, imageIds[2][3].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[2][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][3].frontTrack, imageIds[2][3].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][0].track, imageIds[2][0].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][1].track, imageIds[2][1].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[2][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][1].frontTrack, imageIds[2][1].frontHandrail, { 0, 0, height }, + { { 16, 16, height + 29 }, { 16, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][2].track, imageIds[2][2].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 11: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags(PaintSegment::topCorner, PaintSegment::topLeftSide, PaintSegment::topRightSide), direction), + 48, 0x20); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 12: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[3][3].track, imageIds[3][3].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + if (imageIds[3][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][3].frontTrack, imageIds[3][3].frontHandrail, { 0, 0, height }, + { { 0, 16, height + 27 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[3][0].track, imageIds[3][0].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[3][1].track, imageIds[3][1].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + if (imageIds[3][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][1].frontTrack, imageIds[3][1].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 33 }, { 32, 16, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[3][2].track, imageIds[3][2].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 13: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[4][3].track, imageIds[4][3].handrail, { 0, 0, height }, + { { 0, 6, height + 8 }, { 32, 20, 2 } }); + if (imageIds[4][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][3].frontTrack, imageIds[4][3].frontHandrail, { 0, 0, height }, + { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[4][0].track, imageIds[4][0].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[4][1].track, imageIds[4][1].handrail, { 0, 0, height }, + { { 0, 2, height }, { 32, 27, 2 } }); + if (imageIds[4][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[4][1].frontTrack, imageIds[4][1].frontHandrail, { 0, 0, height }, + { { 0, 2, height + 33 }, { 32, 27, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[4][2].track, imageIds[4][2].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, + PaintSegment::topLeftSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + } +} + /** rct2: 0x008ACB08 */ template, 5> imageIds> static void WoodenRCTrackRightHalfBankedHelixUpLarge( From 759f38a9ec1fcb5749c6b43e561b4341dcb23681 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 02:58:39 +0000 Subject: [PATCH 062/139] Implement Classic Wooden Twister small banked turns --- .../ClassicWoodenTwisterRollerCoaster.cpp | 123 ++++++ .../track/coaster/WoodenRollerCoaster.cpp | 351 ++++++------------ .../track/coaster/WoodenRollerCoaster.hpp | 135 +++++++ 3 files changed, 367 insertions(+), 242 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 970e4af641..9ea6968871 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -170,6 +170,26 @@ enum SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65673, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65674, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_3 = SPR_CSG_BEGIN + 65849, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_3 = SPR_CSG_BEGIN + 65850, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_3 = SPR_CSG_BEGIN + 65851, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_0 = SPR_CSG_BEGIN + 65852, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_0 = SPR_CSG_BEGIN + 65853, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0 = SPR_CSG_BEGIN + 65854, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_1 = SPR_CSG_BEGIN + 65855, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_1 = SPR_CSG_BEGIN + 65856, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_1 = SPR_CSG_BEGIN + 65857, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_2 = SPR_CSG_BEGIN + 65858, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_2 = SPR_CSG_BEGIN + 65859, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_2 = SPR_CSG_BEGIN + 65860, + + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_3 = SPR_CSG_BEGIN + 65861, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_3 = SPR_CSG_BEGIN + 65862, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_3 = SPR_CSG_BEGIN + 65863, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_1 = SPR_CSG_BEGIN + 65864, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1 = SPR_CSG_BEGIN + 65865, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1 = SPR_CSG_BEGIN + 65866, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -319,6 +339,26 @@ enum SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66428, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66429, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66430, + + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66605, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66606, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66607, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66608, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66609, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66610, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66611, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66612, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66613, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66614, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66615, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66616, + + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66617, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66618, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66619, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66620, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66621, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66622, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -466,6 +506,75 @@ static constexpr std::array kRigh }, } }; +static constexpr std::array, 3> kBankedQuarterTurn3Images = { { + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_0, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_1, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_2, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_3, + SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3, + }, + } }, +} }; + static constexpr std::array, 5> kBankedQuarterTurn5Images = { { { { { @@ -865,6 +974,15 @@ static void ClassicWoodenTwisterRCTrack25DegDownToRightBank( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackRightQuarterTurn3Bank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + WoodenRCTrackLeftQuarterTurn3Bank( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} + static void ClassicWoodenTwisterRCTrackBankedLeftQuarterTurn5( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -944,6 +1062,11 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::Down25ToRightBank: return ClassicWoodenTwisterRCTrack25DegDownToRightBank; + case TrackElemType::LeftBankedQuarterTurn3Tiles: + return WoodenRCTrackLeftQuarterTurn3Bank; + case TrackElemType::RightBankedQuarterTurn3Tiles: + return ClassicWoodenTwisterRCTrackRightQuarterTurn3Bank; + case TrackElemType::BankedLeftQuarterTurn5Tiles: return ClassicWoodenTwisterRCTrackBankedLeftQuarterTurn5; case TrackElemType::BankedRightQuarterTurn5Tiles: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index e7d986811a..4a8f8fc17c 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -268,24 +268,24 @@ enum SPR_WOODEN_RC_BLOCK_BRAKES_SW_NE_CLOSED = 23759, SPR_WOODEN_RC_BLOCK_BRAKES_NW_SE_CLOSED = 23760, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_0 = 23841, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_1 = 23842, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_2 = 23843, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_3 = 23844, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_4 = 23845, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_5 = 23846, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_6 = 23847, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_7 = 23848, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_8 = 23849, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_9 = 23850, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_10 = 23851, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_11 = 23852, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_12 = 23853, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_13 = 23854, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_14 = 23855, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_15 = 23856, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_16 = 23857, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_17 = 23858, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_3 = 23841, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_3 = 23842, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_3 = 23843, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_0 = 23844, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_0 = 23845, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0 = 23846, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_1 = 23847, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_1 = 23848, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_1 = 23849, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_2 = 23850, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_2 = 23851, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_2 = 23852, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_3 = 23853, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_3 = 23854, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_3 = 23855, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_1 = 23856, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1 = 23857, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1 = 23858, SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_18 = 23859, SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_19 = 23860, SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_20 = 23861, @@ -559,6 +559,25 @@ enum SPR_WOODEN_RC_BLOCK_BRAKES_RAILS_SW_NE = 24623, SPR_WOODEN_RC_BLOCK_BRAKES_RAILS_NW_SE = 24624, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3 = 24707, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3 = 24708, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3 = 24709, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0 = 24710, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0 = 24711, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0 = 24712, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1 = 24713, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1 = 24714, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1 = 24715, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2 = 24716, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2 = 24717, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2 = 24718, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3 = 24719, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3 = 24720, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3 = 24721, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1 = 24722, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = 24723, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = 24724, + SPR_WOODEN_RC_STATION_RAILS_SW_NE = 24839, SPR_WOODEN_RC_STATION_RAILS_NW_SE = 24840, }; @@ -743,6 +762,75 @@ static constexpr std::array kRigh }, } }; +static constexpr std::array, 3> kBankedQuarterTurn3Images = { { + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_1_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_0, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_1, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_2, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_2_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_3, + SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3, + }, + } }, +} }; + static constexpr std::array, 5> kBankedQuarterTurn5Images = { { { { { @@ -4271,227 +4359,6 @@ static void WoodenRCTrackRightQuarterTurn3( session, ride, trackSequence, (direction - 1) & 3, height, trackElement, supportType); } -/** rct2: 0x008AC808 */ -template -static void WoodenRCTrackLeftQuarterTurn3Bank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_5), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24712), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_8), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24715), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_17), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24724), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_11), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24718), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_2), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24709), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_14), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24721), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_4), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24711), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_7), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24714), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_16), - { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24723), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_10), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24717), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_1), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24708), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_13), - { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24720), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 0 } }); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_3), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24710), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_6), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24713), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_15), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24722), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_9), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24716), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_0), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24707), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_12), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24719), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - switch (direction) - { - case 2: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - case 3: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - /** rct2: 0x008AC818 */ template static void WoodenRCTrackRightQuarterTurn3Bank( @@ -4499,8 +4366,8 @@ static void WoodenRCTrackRightQuarterTurn3Bank( const TrackElement& trackElement, SupportType supportType) { trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; - WoodenRCTrackLeftQuarterTurn3Bank( - session, ride, trackSequence, (direction - 1) & 3, height, trackElement, supportType); + WoodenRCTrackLeftQuarterTurn3Bank( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } /** rct2: 0x008AC828 */ @@ -16075,7 +15942,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::RightQuarterTurn3Tiles: return WoodenRCTrackRightQuarterTurn3; case TrackElemType::LeftBankedQuarterTurn3Tiles: - return WoodenRCTrackLeftQuarterTurn3Bank; + return WoodenRCTrackLeftQuarterTurn3Bank; case TrackElemType::RightBankedQuarterTurn3Tiles: return WoodenRCTrackRightQuarterTurn3Bank; case TrackElemType::LeftQuarterTurn3TilesUp25: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 38b903a3d0..a4a469d1e8 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -165,6 +165,141 @@ static void WoodenRCTrackBankTo25DegUp( PaintUtilSetGeneralSupportHeight(session, height + 48); } +/** rct2: 0x008AC808 */ +template, 3> imageIds> +static void WoodenRCTrackLeftQuarterTurn3Bank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + break; + } + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + } + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + break; + } + } + + TrackPaintUtilLeftQuarterTurn3TilesTunnel(session, kTunnelGroup, TunnelSubType::Flat, height, direction, trackSequence); + + static constexpr int blockedSegments[4] = { + kSegmentsAll, + kSegmentsAll, + EnumsToFlags(PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide), + kSegmentsAll, + }; + + DrawSupportForSequenceA( + session, supportType.wooden, trackSequence, direction, height, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments[trackSequence], direction), 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + template, 5> imageIds> static void WoodenRCTrackBankedRightQuarterTurn5( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, From 9be0d007ecfdc2c299ef0cf3afb81f919ba37188 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 03:36:03 +0000 Subject: [PATCH 063/139] Implement Classic Wooden Twister left small helix --- .../ClassicWoodenTwisterRollerCoaster.cpp | 130 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 663 +++--------------- .../track/coaster/WoodenRollerCoaster.hpp | 421 +++++++++++ 3 files changed, 663 insertions(+), 551 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 9ea6968871..8d786a56c7 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -190,6 +190,26 @@ enum SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1 = SPR_CSG_BEGIN + 65865, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1 = SPR_CSG_BEGIN + 65866, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3 = SPR_CSG_BEGIN + 65885, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3 = SPR_CSG_BEGIN + 65886, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3 = SPR_CSG_BEGIN + 65887, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0 = SPR_CSG_BEGIN + 65888, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0 = SPR_CSG_BEGIN + 65889, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0 = SPR_CSG_BEGIN + 65890, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1 = SPR_CSG_BEGIN + 65891, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1 = SPR_CSG_BEGIN + 65892, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1 = SPR_CSG_BEGIN + 65893, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2 = SPR_CSG_BEGIN + 65894, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2 = SPR_CSG_BEGIN + 65895, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2 = SPR_CSG_BEGIN + 65896, + + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3 = SPR_CSG_BEGIN + 65897, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3 = SPR_CSG_BEGIN + 65898, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3 = SPR_CSG_BEGIN + 65899, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1 = SPR_CSG_BEGIN + 65900, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1 = SPR_CSG_BEGIN + 65901, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1 = SPR_CSG_BEGIN + 65902, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -359,6 +379,26 @@ enum SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66620, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66621, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66622, + + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66641, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66642, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66643, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66644, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66645, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66646, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66647, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66648, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66649, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66650, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66651, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66652, + + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66653, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66654, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66655, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66656, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66657, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66658, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -688,6 +728,77 @@ static constexpr std::array, 3> kLeftHalfBankedHelixUpSmallImages = { + { + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, + }, + } }, + } +}; + static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { { { { @@ -992,6 +1103,20 @@ static void ClassicWoodenTwisterRCTrackBankedLeftQuarterTurn5( session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownSmall( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + if (trackSequence >= 4) + { + trackSequence -= 4; + direction = DirectionNext(direction); + } + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + WoodenRCTrackLeftHalfBankedHelixUpSmall( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} + static void ClassicWoodenTwisterRCTrackLeftHalfBankedHelixDownLarge( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -1072,6 +1197,11 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::BankedRightQuarterTurn5Tiles: return WoodenRCTrackBankedRightQuarterTurn5; + case TrackElemType::LeftHalfBankedHelixUpSmall: + return WoodenRCTrackLeftHalfBankedHelixUpSmall; + case TrackElemType::RightHalfBankedHelixDownSmall: + return ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownSmall; + case TrackElemType::LeftHalfBankedHelixUpLarge: return WoodenRCTrackLeftHalfBankedHelixUpLarge; case TrackElemType::RightHalfBankedHelixUpLarge: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 4a8f8fc17c..088d4f4362 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -304,24 +304,24 @@ enum SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_33 = 23874, SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_34 = 23875, SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_35 = 23876, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_36 = 23877, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_37 = 23878, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_38 = 23879, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_39 = 23880, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_40 = 23881, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_41 = 23882, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_42 = 23883, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_43 = 23884, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_44 = 23885, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_45 = 23886, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_46 = 23887, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_47 = 23888, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_48 = 23889, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_49 = 23890, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_50 = 23891, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_51 = 23892, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_52 = 23893, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_53 = 23894, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3 = 23877, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3 = 23878, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3 = 23879, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0 = 23880, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0 = 23881, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0 = 23882, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1 = 23883, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1 = 23884, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1 = 23885, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2 = 23886, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2 = 23887, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2 = 23888, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3 = 23889, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3 = 23890, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3 = 23891, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1 = 23892, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1 = 23893, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1 = 23894, SPR_WOODEN_RC_STATION_SW_NE = 23973, SPR_WOODEN_RC_STATION_NW_SE = 23974, @@ -578,6 +578,25 @@ enum SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = 24723, SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = 24724, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = 24743, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = 24744, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = 24745, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = 24746, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = 24747, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = 24748, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = 24749, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = 24750, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = 24751, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = 24752, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = 24753, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = 24754, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3 = 24755, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3 = 24756, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3 = 24757, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1 = 24758, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1 = 24759, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1 = 24760, + SPR_WOODEN_RC_STATION_RAILS_SW_NE = 24839, SPR_WOODEN_RC_STATION_RAILS_NW_SE = 24840, }; @@ -944,6 +963,77 @@ static constexpr std::array, 3> kLeftHalfBankedHelixUpSmallImages = { + { + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, + }, + } }, + } +}; + static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { { { { @@ -4716,535 +4806,6 @@ static void WoodenRCTrackRightQuarterTurn325DegDown( session, ride, trackSequence, (direction - 1) & 3, height, trackElement, supportType); } -/** rct2: 0x008ACAB8 */ -template -static void WoodenRCTrackLeftHalfBankedHelixUpSmall( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_41), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24748), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_44), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24751), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_53), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24760), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_47), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24754), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_38), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24745), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_50), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24757), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - } - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_40), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24747), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_43), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24750), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_52), - { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24759), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_46), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24753), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_37), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24744), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_49), - { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24756), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 0 } }); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_39), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24746), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_42), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24749), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_51), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24758), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_45), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24752), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_36), - { 0, 0, height }, { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24743), { 0, 0, height }, - { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_48), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24755), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - switch (direction) - { - case 2: - PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - case 3: - PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 4: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_38), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24745), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_50), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24757), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_41), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24748), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_44), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24751), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_53), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24760), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_47), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24754), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - switch (direction) - { - case 0: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - case 1: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 5: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 6: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_37), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24744), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_49), - { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24756), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 0 } }); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_40), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24747), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_43), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24750), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_52), - { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24759), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_46), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24753), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 7: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_36), - { 0, 0, height }, { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24743), { 0, 0, height }, - { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_48), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24755), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_39), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24746), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_42), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24749), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_51), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24758), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_45), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24752), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, - PaintSegment::topLeftSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - /** rct2: 0x008ACAC8 */ template static void WoodenRCTrackRightHalfBankedHelixUpSmall( @@ -5798,11 +5359,11 @@ static void WoodenRCTrackRightHalfBankedHelixDownSmall( if (trackSequence >= 4) { trackSequence -= 4; - direction = (direction + 1) & 3; + direction = DirectionNext(direction); } trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; - WoodenRCTrackLeftHalfBankedHelixUpSmall( - session, ride, trackSequence, (direction - 1) & 3, height, trackElement, supportType); + WoodenRCTrackLeftHalfBankedHelixUpSmall( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } /** rct2: 0x008ACB18 */ @@ -15954,7 +15515,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::RightQuarterTurn3TilesDown25: return WoodenRCTrackRightQuarterTurn325DegDown; case TrackElemType::LeftHalfBankedHelixUpSmall: - return WoodenRCTrackLeftHalfBankedHelixUpSmall; + return WoodenRCTrackLeftHalfBankedHelixUpSmall; case TrackElemType::RightHalfBankedHelixUpSmall: return WoodenRCTrackRightHalfBankedHelixUpSmall; case TrackElemType::LeftHalfBankedHelixDownSmall: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index a4a469d1e8..aedca3e8bd 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -518,6 +518,427 @@ static void WoodenRCTrackBankedRightQuarterTurn5( PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); } +/** rct2: 0x008ACAB8 */ +template, 3> imageIds> +static void WoodenRCTrackLeftHalfBankedHelixUpSmall( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 1: + switch (direction) + { + case 0: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 1: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 2: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 3: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + } + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height + 8 }, { 20, 32, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + switch (direction) + { + case 2: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 3: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 4: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][3].track, imageIds[0][3].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[0][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][3].frontTrack, imageIds[0][3].frontHandrail, { 0, 0, height }, + { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][0].track, imageIds[0][0].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][1].track, imageIds[0][1].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[0][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][1].frontTrack, imageIds[0][1].frontHandrail, { 0, 0, height }, + { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][2].track, imageIds[0][2].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + switch (direction) + { + case 0: + PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + case 1: + PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 5: + switch (direction) + { + case 0: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 1: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 2: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 3: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + } + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 6: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][3].track, imageIds[1][3].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[1][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][3].frontTrack, imageIds[1][3].frontHandrail, { 0, 0, height }, + { { 16, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][0].track, imageIds[1][0].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][1].track, imageIds[1][1].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[1][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][1].frontTrack, imageIds[1][1].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][2].track, imageIds[1][2].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 7: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][3].track, imageIds[2][3].handrail, { 0, 0, height }, + { { 0, 6, height + 8 }, { 32, 20, 2 } }); + if (imageIds[2][3].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][3].frontTrack, imageIds[2][3].frontHandrail, { 0, 0, height }, + { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][0].track, imageIds[2][0].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][1].track, imageIds[2][1].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[2][1].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][1].frontTrack, imageIds[2][1].frontHandrail, { 0, 0, height }, + { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][2].track, imageIds[2][2].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, + PaintSegment::topLeftSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + } +} + /** rct2: 0x008ACAF8 */ template, 5> imageIds> static void WoodenRCTrackLeftHalfBankedHelixUpLarge( From cd9ee6c108af4d1971685d6b62c8c5b8f7791d06 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 04:07:22 +0000 Subject: [PATCH 064/139] Implement Classic Wooden Twister small right helix --- .../ClassicWoodenTwisterRollerCoaster.cpp | 128 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 662 +++--------------- .../track/coaster/WoodenRollerCoaster.hpp | 421 +++++++++++ 3 files changed, 660 insertions(+), 551 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 8d786a56c7..3df4373245 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -190,6 +190,26 @@ enum SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1 = SPR_CSG_BEGIN + 65865, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1 = SPR_CSG_BEGIN + 65866, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_0 = SPR_CSG_BEGIN + 65867, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_0 = SPR_CSG_BEGIN + 65868, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_0 = SPR_CSG_BEGIN + 65869, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_1 = SPR_CSG_BEGIN + 65870, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_1 = SPR_CSG_BEGIN + 65871, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_1 = SPR_CSG_BEGIN + 65872, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_2 = SPR_CSG_BEGIN + 65873, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_2 = SPR_CSG_BEGIN + 65874, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_2 = SPR_CSG_BEGIN + 65875, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_3 = SPR_CSG_BEGIN + 65876, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_3 = SPR_CSG_BEGIN + 65877, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_3 = SPR_CSG_BEGIN + 65878, + + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_0 = SPR_CSG_BEGIN + 65879, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_0 = SPR_CSG_BEGIN + 65880, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_0 = SPR_CSG_BEGIN + 65881, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_2 = SPR_CSG_BEGIN + 65882, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_2 = SPR_CSG_BEGIN + 65883, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_2 = SPR_CSG_BEGIN + 65884, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3 = SPR_CSG_BEGIN + 65885, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3 = SPR_CSG_BEGIN + 65886, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3 = SPR_CSG_BEGIN + 65887, @@ -380,6 +400,26 @@ enum SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66621, SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66622, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66623, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66624, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66625, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66626, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66627, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66628, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66629, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66630, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66631, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66632, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66633, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66634, + + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66635, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66636, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66637, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66638, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66639, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66640, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66641, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66642, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66643, @@ -799,6 +839,77 @@ static constexpr std::array, 3> kRightHalfBankedHelixUpSmallImages = { + { + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, + }, + } }, + } +}; + static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { { { { @@ -1102,6 +1213,19 @@ static void ClassicWoodenTwisterRCTrackBankedLeftQuarterTurn5( WoodenRCTrackBankedRightQuarterTurn5( session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackLeftHalfBankedHelixDownSmall( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + if (trackSequence >= 4) + { + trackSequence -= 4; + direction = DirectionPrev(direction); + } + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + WoodenRCTrackRightHalfBankedHelixUpSmall( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); +} static void ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownSmall( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, @@ -1199,6 +1323,10 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::LeftHalfBankedHelixUpSmall: return WoodenRCTrackLeftHalfBankedHelixUpSmall; + case TrackElemType::RightHalfBankedHelixUpSmall: + return WoodenRCTrackRightHalfBankedHelixUpSmall; + case TrackElemType::LeftHalfBankedHelixDownSmall: + return ClassicWoodenTwisterRCTrackLeftHalfBankedHelixDownSmall; case TrackElemType::RightHalfBankedHelixDownSmall: return ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownSmall; diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 088d4f4362..281bd0fb89 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -286,24 +286,24 @@ enum SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_1 = 23856, SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1 = 23857, SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1 = 23858, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_18 = 23859, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_19 = 23860, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_20 = 23861, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_21 = 23862, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_22 = 23863, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_23 = 23864, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_24 = 23865, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_25 = 23866, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_26 = 23867, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_27 = 23868, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_28 = 23869, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_29 = 23870, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_30 = 23871, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_31 = 23872, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_32 = 23873, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_33 = 23874, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_34 = 23875, - SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_35 = 23876, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_0 = 23859, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_0 = 23860, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_0 = 23861, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_1 = 23862, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_1 = 23863, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_1 = 23864, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_2 = 23865, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_2 = 23866, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_2 = 23867, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_3 = 23868, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_3 = 23869, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_3 = 23870, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_0 = 23871, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_0 = 23872, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_0 = 23873, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_2 = 23874, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_2 = 23875, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_2 = 23876, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3 = 23877, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3 = 23878, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3 = 23879, @@ -577,7 +577,24 @@ enum SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1 = 24722, SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = 24723, SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = 24724, - + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = 24725, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = 24726, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = 24727, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = 24728, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = 24729, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = 24730, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = 24731, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = 24732, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = 24733, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = 24734, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = 24735, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = 24736, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_0 = 24737, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_0 = 24738, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_0 = 24739, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_2 = 24740, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_2 = 24741, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_2 = 24742, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = 24743, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = 24744, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = 24745, @@ -1034,6 +1051,77 @@ static constexpr std::array, 3> kRightHalfBankedHelixUpSmallImages = { + { + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_0, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_1, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_2, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_3, + SPR_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, + }, + } }, + } +}; + static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { { { { @@ -4806,534 +4894,6 @@ static void WoodenRCTrackRightQuarterTurn325DegDown( session, ride, trackSequence, (direction - 1) & 3, height, trackElement, supportType); } -/** rct2: 0x008ACAC8 */ -template -static void WoodenRCTrackRightHalfBankedHelixUpSmall( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_18), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24725), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_30), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24737), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_21), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24728), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_24), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24731), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_33), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24740), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_27), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24734), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, - PaintSegment::topLeftSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_19), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24726), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_31), - { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24738), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 0 } }); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_22), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24729), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_25), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24732), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_34), - { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24741), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_28), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24735), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_20), - { 0, 0, height }, { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24727), { 0, 0, height }, - { { 6, 0, height + 8 }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_32), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24739), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_23), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24730), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_26), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24733), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_35), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24742), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_29), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24736), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - switch (direction) - { - case 0: - PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - case 1: - PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 4: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_21), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24728), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_24), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24731), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_33), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24740), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_27), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24734), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_18), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24725), { 0, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_30), - { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24737), { 0, 0, height }, - { { 6, 0, height + 27 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - switch (direction) - { - case 2: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - case 3: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, - PaintSegment::topRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 5: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - } - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 6: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_22), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24729), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_25), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24732), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_34), - { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24741), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_28), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24735), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23860), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24726), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_31), - { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24738), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 0 } }); - break; - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 7: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_23), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24730), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_26), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24733), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_35), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24742), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_29), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24736), { 0, 0, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_20), - { 0, 0, height }, { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24727), { 0, 0, height }, - { { 0, 6, height + 8 }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, - WoodenRCGetTrackColour(session).WithIndex(SPR_WOODEN_RC_SMALL_RIGHT_BANKED_TURN_32), - { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24739), { 0, 0, height }, - { { 0, 6, height + 27 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, - PaintSegment::bottomRightSide), - direction), - 48, 0x20); - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - /** rct2: 0x008ACAD8 */ template static void WoodenRCTrackLeftHalfBankedHelixDownSmall( @@ -5343,11 +4903,11 @@ static void WoodenRCTrackLeftHalfBankedHelixDownSmall( if (trackSequence >= 4) { trackSequence -= 4; - direction = (direction - 1) & 3; + direction = DirectionPrev(direction); } trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; - WoodenRCTrackRightHalfBankedHelixUpSmall( - session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); + WoodenRCTrackRightHalfBankedHelixUpSmall( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } /** rct2: 0x008ACAE8 */ @@ -15517,7 +15077,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::LeftHalfBankedHelixUpSmall: return WoodenRCTrackLeftHalfBankedHelixUpSmall; case TrackElemType::RightHalfBankedHelixUpSmall: - return WoodenRCTrackRightHalfBankedHelixUpSmall; + return WoodenRCTrackRightHalfBankedHelixUpSmall; case TrackElemType::LeftHalfBankedHelixDownSmall: return WoodenRCTrackLeftHalfBankedHelixDownSmall; case TrackElemType::RightHalfBankedHelixDownSmall: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index aedca3e8bd..9952458cdb 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -939,6 +939,427 @@ static void WoodenRCTrackLeftHalfBankedHelixUpSmall( } } +/** rct2: 0x008ACAC8 */ +template, 3> imageIds> +static void WoodenRCTrackRightHalfBankedHelixUpSmall( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::bottomCorner, + PaintSegment::topLeftSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::rightCorner, PaintSegment::centre, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 1: + switch (direction) + { + case 0: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 1: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 2: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 3: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + } + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height + 8 }, { 20, 32, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + switch (direction) + { + case 0: + PaintUtilPushTunnelRight(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + case 1: + PaintUtilPushTunnelLeft(session, height + 8, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 4: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][1].track, imageIds[0][1].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][2].track, imageIds[0][2].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[0][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][2].frontTrack, imageIds[0][2].frontHandrail, { 0, 0, height }, + { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][3].track, imageIds[0][3].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][0].track, imageIds[0][0].handrail, { 0, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[0][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][0].frontTrack, imageIds[0][0].frontHandrail, { 0, 0, height }, + { { 6, 0, height + 27 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + switch (direction) + { + case 2: + PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + case 3: + PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::leftCorner, PaintSegment::rightCorner, + PaintSegment::topRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide, PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 5: + switch (direction) + { + case 0: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 1: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 2: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 3: + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + } + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 6: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][1].track, imageIds[1][1].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][2].track, imageIds[1][2].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[1][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][2].frontTrack, imageIds[1][2].frontHandrail, { 0, 0, height }, + { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][3].track, imageIds[1][3].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][0].track, imageIds[1][0].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[1][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][0].frontTrack, imageIds[1][0].frontHandrail, { 0, 0, height }, + { { 16, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + case 7: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][1].track, imageIds[2][1].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][2].track, imageIds[2][2].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[2][2].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][2].frontTrack, imageIds[2][2].frontHandrail, { 0, 0, height }, + { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][3].track, imageIds[2][3].handrail, { 0, 0, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][0].track, imageIds[2][0].handrail, { 0, 0, height }, + { { 0, 6, height + 8 }, { 32, 20, 2 } }); + if (imageIds[2][0].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][0].frontTrack, imageIds[2][0].frontHandrail, { 0, 0, height }, + { { 0, 6, height + 27 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::rightCorner, PaintSegment::bottomCorner, + PaintSegment::bottomRightSide), + direction), + 48, 0x20); + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::topCorner, PaintSegment::centre, PaintSegment::topLeftSide, PaintSegment::topRightSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + break; + } +} + /** rct2: 0x008ACAF8 */ template, 5> imageIds> static void WoodenRCTrackLeftHalfBankedHelixUpLarge( From 7a26c9979a55b8930849ab0377e0bcc5b6dc1082 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 05:04:58 +0000 Subject: [PATCH 065/139] Implement Classic Wooden Twister small right bank to gentle up turn --- .../ClassicWoodenTwisterRollerCoaster.cpp | 94 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 401 ++++-------------- .../track/coaster/WoodenRollerCoaster.hpp | 138 ++++++ 3 files changed, 316 insertions(+), 317 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 3df4373245..a21fef8f0e 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -230,6 +230,21 @@ enum SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1 = SPR_CSG_BEGIN + 65901, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1 = SPR_CSG_BEGIN + 65902, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_0 = SPR_CSG_BEGIN + 65955, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_0 = SPR_CSG_BEGIN + 65956, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_1 = SPR_CSG_BEGIN + 65957, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_1 = SPR_CSG_BEGIN + 65958, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_2 = SPR_CSG_BEGIN + 65959, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_2 = SPR_CSG_BEGIN + 65960, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3 = SPR_CSG_BEGIN + 65961, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3 = SPR_CSG_BEGIN + 65962, + + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0 = SPR_CSG_BEGIN + 65971, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0 = SPR_CSG_BEGIN + 65972, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65973, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2 = SPR_CSG_BEGIN + 65974, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65975, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -439,6 +454,21 @@ enum SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66656, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66657, SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66658, + + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66711, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66712, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66713, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66714, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66715, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66716, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66717, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66718, + + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66727, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66728, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66729, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66730, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66731, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -1140,6 +1170,56 @@ static constexpr std::array, 2> + kRightBankToRightQuarterTurn325DegUpImages = { { + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3, + }, + } }, + } }; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -1269,6 +1349,15 @@ static void ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownLarge( session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackLeftQuarterTurn325DegDownToLeftBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + WoodenRCTrackRightBankToRightQuarterTurn325DegUp( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -1339,6 +1428,11 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::RightHalfBankedHelixDownLarge: return ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownLarge; + case TrackElemType::RightBankToRightQuarterTurn3TilesUp25: + return WoodenRCTrackRightBankToRightQuarterTurn325DegUp; + case TrackElemType::LeftQuarterTurn3TilesDown25ToLeftBank: + return ClassicWoodenTwisterRCTrackLeftQuarterTurn325DegDownToLeftBank; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 281bd0fb89..9ab8a80244 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -323,6 +323,21 @@ enum SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1 = 23893, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1 = 23894, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_0 = 23947, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_0 = 23948, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_1 = 23949, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_1 = 23950, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_2 = 23951, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_2 = 23952, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3 = 23953, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3 = 23954, + + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0 = 23963, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0 = 23964, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = 23965, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2 = 23966, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = 23967, + SPR_WOODEN_RC_STATION_SW_NE = 23973, SPR_WOODEN_RC_STATION_NW_SE = 23974, @@ -614,6 +629,21 @@ enum SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1 = 24759, SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1 = 24760, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = 24813, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = 24814, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = 24815, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = 24816, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = 24817, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = 24818, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = 24819, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = 24820, + + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0 = 24829, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0 = 24830, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = 24831, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2 = 24832, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = 24833, + SPR_WOODEN_RC_STATION_RAILS_SW_NE = 24839, SPR_WOODEN_RC_STATION_RAILS_NW_SE = 24840, }; @@ -1352,6 +1382,56 @@ static constexpr std::array, 2> + kRightBankToRightQuarterTurn325DegUpImages = { { + { { + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_0, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_1, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_2, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_0, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_1, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_2, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3, + SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3, + }, + } }, + } }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -11338,328 +11418,15 @@ static void WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp( } } -/** rct2: 0x008ACB48 */ -template -static void WoodenRCTrackRightBankToRightQuarterTurn325DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23947), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24813), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23963), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24829), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23949), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24815), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23951), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24817), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23966), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24832), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23953), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24819), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - case 1: - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23948), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24814), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23964), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24830), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23950), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24816), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23965), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24831), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23952), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24818), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23967), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24833), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23954), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24820), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - switch (direction) - { - case 0: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); - break; - case 1: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - } -} - /** rct2: 0x008ACB58 */ template static void WoodenRCTrackLeftQuarterTurn325DegDownToLeftBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23950), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24816), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23965), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24831), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23952), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24818), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23967), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24833), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23954), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24820), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23948), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24814), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23964), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24830), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::SlopeEnd); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - case 1: - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23949), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24815), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23951), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24817), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23966), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24832), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23953), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24819), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23947), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24813), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23963), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24829), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - switch (direction) - { - case 2: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - case 3: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - } + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + WoodenRCTrackRightBankToRightQuarterTurn325DegUp( + session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } /** rct2: 0x008ACB68 */ @@ -15193,7 +14960,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::LeftBankToLeftQuarterTurn3TilesUp25: return WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp; case TrackElemType::RightBankToRightQuarterTurn3TilesUp25: - return WoodenRCTrackRightBankToRightQuarterTurn325DegUp; + return WoodenRCTrackRightBankToRightQuarterTurn325DegUp; case TrackElemType::LeftQuarterTurn3TilesDown25ToLeftBank: return WoodenRCTrackLeftQuarterTurn325DegDownToLeftBank; case TrackElemType::RightQuarterTurn3TilesDown25ToRightBank: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 9952458cdb..61f1a8043f 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -2676,4 +2676,142 @@ static void WoodenRCTrackRightHalfBankedHelixUpLarge( } } +/** rct2: 0x008ACB48 */ +template, 2> imageIds> +static void WoodenRCTrackRightBankToRightQuarterTurn325DegUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 6, height }, { { 0, 6, height + 67 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 6, height }, { { 0, 6, height + 67 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 64); + break; + case 1: + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, + PaintSegment::bottomRightSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 6, 0, height }, { { 6, 0, height + 67 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 6, 0, height }, { { 6, 0, height + 67 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 6, 0, height }, { { 6, 0, height + 67 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + } + switch (direction) + { + case 0: + PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); + break; + case 1: + PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); + break; + } + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 64); + break; + } +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From 025be8c298193f94a1cc60841a5a29c474cbcaa5 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 05:34:36 +0000 Subject: [PATCH 066/139] Implement Classic Wooden Twister small left bank to gentle up turn --- .../ClassicWoodenTwisterRollerCoaster.cpp | 93 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 399 ++++-------------- .../track/coaster/WoodenRollerCoaster.hpp | 138 ++++++ 3 files changed, 311 insertions(+), 319 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index a21fef8f0e..f098ff8732 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -239,12 +239,27 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3 = SPR_CSG_BEGIN + 65961, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3 = SPR_CSG_BEGIN + 65962, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_3 = SPR_CSG_BEGIN + 65963, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_3 = SPR_CSG_BEGIN + 65964, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_0 = SPR_CSG_BEGIN + 65965, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_0 = SPR_CSG_BEGIN + 65966, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_1 = SPR_CSG_BEGIN + 65967, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_1 = SPR_CSG_BEGIN + 65968, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_2 = SPR_CSG_BEGIN + 65969, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_2 = SPR_CSG_BEGIN + 65970, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0 = SPR_CSG_BEGIN + 65971, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0 = SPR_CSG_BEGIN + 65972, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65973, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2 = SPR_CSG_BEGIN + 65974, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65975, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_3 = SPR_CSG_BEGIN + 65976, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_3 = SPR_CSG_BEGIN + 65977, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65978, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65979, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65980, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -464,11 +479,26 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66717, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66718, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66719, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66720, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66721, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66722, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66723, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66724, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66725, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66726, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66727, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66728, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66729, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66730, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66731, + + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66732, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66733, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66734, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66735, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66736, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -1170,6 +1200,56 @@ static constexpr std::array, 2> + kLeftBankToLeftQuarterTurn325DegUpImages = { { + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_0, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_2, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_0, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_3, + }, + } }, + } }; + static constexpr std::array, 2> kRightBankToRightQuarterTurn325DegUpImages = { { { { @@ -1358,6 +1438,15 @@ static void ClassicWoodenTwisterRCTrackLeftQuarterTurn325DegDownToLeftBank( session, ride, trackSequence, DirectionNext(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackRightQuarterTurn325DegDownToRightBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -1428,10 +1517,14 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::RightHalfBankedHelixDownLarge: return ClassicWoodenTwisterRCTrackRightHalfBankedHelixDownLarge; + case TrackElemType::LeftBankToLeftQuarterTurn3TilesUp25: + return WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp; case TrackElemType::RightBankToRightQuarterTurn3TilesUp25: return WoodenRCTrackRightBankToRightQuarterTurn325DegUp; case TrackElemType::LeftQuarterTurn3TilesDown25ToLeftBank: return ClassicWoodenTwisterRCTrackLeftQuarterTurn325DegDownToLeftBank; + case TrackElemType::RightQuarterTurn3TilesDown25ToRightBank: + return ClassicWoodenTwisterRCTrackRightQuarterTurn325DegDownToRightBank; default: return GetTrackPaintFunctionWoodenRC(trackType); diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 9ab8a80244..4b580dc338 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -331,12 +331,24 @@ enum SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_2 = 23952, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3 = 23953, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3 = 23954, - + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_3 = 23955, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_3 = 23956, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_0 = 23957, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_0 = 23958, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_1 = 23959, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_1 = 23960, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_2 = 23961, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_2 = 23962, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0 = 23963, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0 = 23964, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = 23965, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2 = 23966, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = 23967, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_3 = 23968, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_3 = 23969, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = 23970, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1 = 23971, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = 23972, SPR_WOODEN_RC_STATION_SW_NE = 23973, SPR_WOODEN_RC_STATION_NW_SE = 23974, @@ -637,12 +649,24 @@ enum SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = 24818, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = 24819, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = 24820, - + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = 24821, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = 24822, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = 24823, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = 24824, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = 24825, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = 24826, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = 24827, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = 24828, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0 = 24829, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0 = 24830, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = 24831, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2 = 24832, SPR_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = 24833, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_3 = 24834, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_3 = 24835, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = 24836, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1 = 24837, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = 24838, SPR_WOODEN_RC_STATION_RAILS_SW_NE = 24839, SPR_WOODEN_RC_STATION_RAILS_NW_SE = 24840, @@ -1382,6 +1406,56 @@ static constexpr std::array, 2> + kLeftBankToLeftQuarterTurn325DegUpImages = { { + { { + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_0, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_1, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_2, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_3, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_3, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_0, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_1, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_2, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_3, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_3, + SPR_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_3, + }, + } }, + } }; + static constexpr std::array, 2> kRightBankToRightQuarterTurn325DegUpImages = { { { { @@ -11256,168 +11330,6 @@ static void WoodenRCTrackDiagRightBank( } } -/** rct2: 0x008ACB38 */ -template -static void WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23958), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24824), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23960), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24826), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23971), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24837), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23962), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24828), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23956), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24822), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23969), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24835), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - case 1: - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, - PaintSegment::bottomLeftSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23957), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24823), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23959), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24825), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23970), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24836), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23961), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24827), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23972), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24838), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23955), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24821), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23968), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24834), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - switch (direction) - { - case 2: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); - break; - case 3: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - } -} - /** rct2: 0x008ACB58 */ template static void WoodenRCTrackLeftQuarterTurn325DegDownToLeftBank( @@ -11435,160 +11347,9 @@ static void WoodenRCTrackRightQuarterTurn325DegDownToRightBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23955), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24821), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23968), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24834), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23957), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24823), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23959), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24825), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23970), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24836), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23961), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24827), { 0, 6, height }, - { { 0, 6, height }, { 32, 20, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23972), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24838), { 0, 6, height }, - { { 0, 6, height + 67 }, { 32, 20, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::SlopeEnd); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - case 1: - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - PaintUtilSetSegmentSupportHeight( - session, - PaintUtilRotateSegments( - EnumsToFlags( - PaintSegment::bottomCorner, PaintSegment::centre, PaintSegment::bottomLeftSide, - PaintSegment::bottomRightSide), - direction), - 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23956), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24822), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23969), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24835), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23958), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24824), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23960), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24826), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23971), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24837), { 6, 0, height }, - { { 6, 0, height + 67 }, { 20, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(23962), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24828), { 6, 0, height }, - { { 6, 0, height }, { 20, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - switch (direction) - { - case 0: - PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - case 1: - PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::Flat); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 64); - break; - } + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } /** rct2: 0x008ACDF8 */ @@ -14958,7 +14719,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::DiagRightBank: return WoodenRCTrackDiagRightBank; case TrackElemType::LeftBankToLeftQuarterTurn3TilesUp25: - return WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp; + return WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp; case TrackElemType::RightBankToRightQuarterTurn3TilesUp25: return WoodenRCTrackRightBankToRightQuarterTurn325DegUp; case TrackElemType::LeftQuarterTurn3TilesDown25ToLeftBank: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 61f1a8043f..b4dcb3c8c5 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -2676,6 +2676,144 @@ static void WoodenRCTrackRightHalfBankedHelixUpLarge( } } +/** rct2: 0x008ACB38 */ +template, 2> imageIds> +static void WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 6, height }, { { 0, 6, height + 67 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 6, height }, + { { 0, 6, height }, { 32, 20, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 6, height }, { { 0, 6, height + 67 }, { 32, 20, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 64); + break; + case 1: + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 2: + PaintUtilSetSegmentSupportHeight( + session, + PaintUtilRotateSegments( + EnumsToFlags( + PaintSegment::leftCorner, PaintSegment::centre, PaintSegment::topLeftSide, + PaintSegment::bottomLeftSide), + direction), + 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); + break; + case 3: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 6, 0, height }, { { 6, 0, height + 67 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 6, 0, height }, { { 6, 0, height + 67 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 6, 0, height }, + { { 6, 0, height }, { 20, 32, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 6, 0, height }, { { 6, 0, height + 67 }, { 20, 32, 0 } }); + } + WoodenASupportsPaintSetup( + session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); + break; + } + switch (direction) + { + case 2: + PaintUtilPushTunnelRight(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); + break; + case 3: + PaintUtilPushTunnelLeft(session, height, kTunnelGroup, TunnelSubType::SlopeEnd); + break; + } + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 64); + break; + } +} + /** rct2: 0x008ACB48 */ template, 2> imageIds> static void WoodenRCTrackRightBankToRightQuarterTurn325DegUp( From 46bfd8888e383a1bec8901424a868d33e5265aa3 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 07:17:55 +0000 Subject: [PATCH 067/139] Implement Classic Wooden Twister diagonal flat to banked --- .../ClassicWoodenTwisterRollerCoaster.cpp | 105 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 512 +++--------------- .../track/coaster/WoodenRollerCoaster.hpp | 68 +++ 3 files changed, 253 insertions(+), 432 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index f098ff8732..942fee641a 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -260,6 +260,22 @@ enum SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65979, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65980, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 66055, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 66056, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 66057, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 66058, + + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66059, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66060, + + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 66061, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 66062, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 66063, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 66064, + + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66065, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66066, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -499,6 +515,22 @@ enum SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66734, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66735, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66736, + + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66811, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66812, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66813, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66814, + + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66815, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66816, + + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66817, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66818, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66819, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66820, + + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66821, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66822, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -1300,6 +1332,52 @@ static constexpr std::array kDiagFlatToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3, + }, +} }; + +static constexpr std::array kDiagFlatToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3, + }, +} }; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -1447,6 +1525,24 @@ static void ClassicWoodenTwisterRCTrackRightQuarterTurn325DegDownToRightBank( session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackDiagLeftBankToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrackDiagRightBankToFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -1526,6 +1622,15 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::RightQuarterTurn3TilesDown25ToRightBank: return ClassicWoodenTwisterRCTrackRightQuarterTurn325DegDownToRightBank; + case TrackElemType::DiagFlatToLeftBank: + return WoodenRCTrackDiagFlatToBank; + case TrackElemType::DiagFlatToRightBank: + return WoodenRCTrackDiagFlatToBank; + case TrackElemType::DiagLeftBankToFlat: + return ClassicWoodenTwisterRCTrackDiagLeftBankToFlat; + case TrackElemType::DiagRightBankToFlat: + return ClassicWoodenTwisterRCTrackDiagRightBankToFlat; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 4b580dc338..d6ef29dee2 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -353,6 +353,19 @@ enum SPR_WOODEN_RC_STATION_SW_NE = 23973, SPR_WOODEN_RC_STATION_NW_SE = 23974, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0 = 24077, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1 = 24078, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2 = 24079, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3 = 24080, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0 = 24081, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2 = 24082, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0 = 24083, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1 = 24084, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2 = 24085, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3 = 24086, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = 24087, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = 24088, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SW_NE = 24363, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NW_SE = 24364, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NE_SW = 24365, @@ -670,6 +683,19 @@ enum SPR_WOODEN_RC_STATION_RAILS_SW_NE = 24839, SPR_WOODEN_RC_STATION_RAILS_NW_SE = 24840, + + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0 = 24943, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1 = 24944, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2 = 24945, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3 = 24946, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0 = 24947, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2 = 24948, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0 = 24949, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1 = 24950, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2 = 24951, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = 24952, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = 24953, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = 24954, }; static constexpr uint32_t _wooden_rc_block_brakes_image_ids[4][3] = { @@ -1506,6 +1532,52 @@ static constexpr std::array kDiagFlatToLeftBankImages = { { + { + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1, + }, + { + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3, + SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3, + }, +} }; + +static constexpr std::array kDiagFlatToRightBankImages = { { + { + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1, + }, + { + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3, + SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3, + }, +} }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -9880,448 +9952,24 @@ static void WoodenRCTrackDiag25DegDownToFlat( } } -/** rct2: 0x008ACA18 */ -template -static void WoodenRCTrackDiagFlatToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24080), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24946), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24077), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24943), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24081), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24947), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24079), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24945), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24082), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24948), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24078), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24944), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - -/** rct2: 0x008AC9F8 */ -template -static void WoodenRCTrackDiagFlatToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24086), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24952), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24083), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24949), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24087), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24953), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24085), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24951), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24088), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24954), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24084), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24950), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - -/** rct2: 0x008ACA08 */ template static void WoodenRCTrackDiagLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24084), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24950), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24085), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24951), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24088), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24954), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24083), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24949), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24087), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24953), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24086), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24952), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } -/** rct2: 0x008ACA28 */ template static void WoodenRCTrackDiagRightBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24078), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24944), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24079), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24945), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24082), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24948), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24077), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24943), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24081), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24947), { -16, -16, height }, - { { -16, -16, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24080), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24946), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } /** rct2: 0x008ACA58 */ @@ -14691,9 +14339,9 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::DiagDown25ToFlat: return WoodenRCTrackDiag25DegDownToFlat; case TrackElemType::DiagFlatToLeftBank: - return WoodenRCTrackDiagFlatToLeftBank; + return WoodenRCTrackDiagFlatToBank; case TrackElemType::DiagFlatToRightBank: - return WoodenRCTrackDiagFlatToRightBank; + return WoodenRCTrackDiagFlatToBank; case TrackElemType::DiagLeftBankToFlat: return WoodenRCTrackDiagLeftBankToFlat; case TrackElemType::DiagRightBankToFlat: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index b4dcb3c8c5..3ca894b9b8 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -2952,4 +2952,72 @@ static void WoodenRCTrackRightBankToRightQuarterTurn325DegUp( } } +/** rct2: 0x008ACA18, 0x008AC9F8 */ +template imageIds> +static void WoodenRCTrackDiagFlatToBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } }); + } + break; + } + break; + case 2: + switch (direction) + { + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } }); + } + break; + } + break; + case 3: + switch (direction) + { + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + } + + DrawSupportForSequenceA( + session, supportType.wooden, trackSequence, direction, height, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From fef2c3770aafd11f791c104bd5c6ec9a1b62da20 Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 08:08:34 +0000 Subject: [PATCH 068/139] Implement Classic Wooden Twister diagonal banked to gentle up --- .../ClassicWoodenTwisterRollerCoaster.cpp | 105 ++++ .../track/coaster/WoodenRollerCoaster.cpp | 520 +++--------------- .../track/coaster/WoodenRollerCoaster.hpp | 68 +++ 3 files changed, 257 insertions(+), 436 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 942fee641a..9d98e36d0d 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -276,6 +276,22 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66065, SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66066, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0 = SPR_CSG_BEGIN + 66079, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1 = SPR_CSG_BEGIN + 66080, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2 = SPR_CSG_BEGIN + 66081, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3 = SPR_CSG_BEGIN + 66082, + + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0 = SPR_CSG_BEGIN + 66083, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2 = SPR_CSG_BEGIN + 66084, + + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0 = SPR_CSG_BEGIN + 66085, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1 = SPR_CSG_BEGIN + 66086, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2 = SPR_CSG_BEGIN + 66087, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3 = SPR_CSG_BEGIN + 66088, + + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0 = SPR_CSG_BEGIN + 66089, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2 = SPR_CSG_BEGIN + 66090, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -531,6 +547,22 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66821, SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66822, + + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0 = SPR_CSG_BEGIN + 66835, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1 = SPR_CSG_BEGIN + 66836, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2 = SPR_CSG_BEGIN + 66837, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3 = SPR_CSG_BEGIN + 66838, + + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66839, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66840, + + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0 = SPR_CSG_BEGIN + 66841, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1 = SPR_CSG_BEGIN + 66842, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2 = SPR_CSG_BEGIN + 66843, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3 = SPR_CSG_BEGIN + 66844, + + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66845, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66846, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -1378,6 +1410,52 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array kDiagLeftBankTo25DegUpImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3, + }, +} }; + +static constexpr std::array kDiagRightBankTo25DegUpImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3, + }, +} }; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -1543,6 +1621,24 @@ static void ClassicWoodenTwisterRCTrackDiagRightBankToFlat( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackDiagDown25ToLeftBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrackDiagDown25ToRightBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -1631,6 +1727,15 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::DiagRightBankToFlat: return ClassicWoodenTwisterRCTrackDiagRightBankToFlat; + case TrackElemType::DiagLeftBankToUp25: + return WoodenRCTrackDiagBankTo25DegUp; + case TrackElemType::DiagRightBankToUp25: + return WoodenRCTrackDiagBankTo25DegUp; + case TrackElemType::DiagDown25ToLeftBank: + return ClassicWoodenTwisterRCTrackDiagDown25ToLeftBank; + case TrackElemType::DiagDown25ToRightBank: + return ClassicWoodenTwisterRCTrackDiagDown25ToRightBank; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index d6ef29dee2..665674bfa2 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -366,6 +366,19 @@ enum SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = 24087, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = 24088, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0 = 24101, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1 = 24102, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2 = 24103, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3 = 24104, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0 = 24105, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2 = 24106, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0 = 24107, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1 = 24108, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2 = 24109, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3 = 24110, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0 = 24111, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2 = 24112, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SW_NE = 24363, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NW_SE = 24364, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NE_SW = 24365, @@ -696,6 +709,19 @@ enum SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = 24952, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = 24953, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = 24954, + + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0 = 24967, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1 = 24968, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2 = 24969, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3 = 24970, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = 24971, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = 24972, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0 = 24973, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1 = 24974, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2 = 24975, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3 = 24976, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = 24977, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = 24978, }; static constexpr uint32_t _wooden_rc_block_brakes_image_ids[4][3] = { @@ -1578,6 +1604,52 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array kDiagLeftBankTo25DegUpImages = { { + { + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, + }, + { + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1, + }, + { + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, + }, + { + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3, + SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3, + }, +} }; + +static constexpr std::array kDiagRightBankTo25DegUpImages = { { + { + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, + }, + { + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1, + }, + { + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, + }, + { + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3, + SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3, + }, +} }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -9972,228 +10044,6 @@ static void WoodenRCTrackDiagRightBankToFlat( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } -/** rct2: 0x008ACA58 */ -template -static void WoodenRCTrackDiagLeftBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24104), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24970), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24101), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24967), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24105), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24971), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24103), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24969), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24106), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24972), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24102), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24968), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - } -} - -/** rct2: 0x008ACA68 */ -template -static void WoodenRCTrackDiagRightBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24110), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24976), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24107), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24973), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24111), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24977), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24109), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24975), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24112), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24978), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24108), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24974), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - } -} - /** rct2: 0x008ACA38 */ template static void WoodenRCTrackDiag25DegUpToLeftBank( @@ -10534,226 +10384,24 @@ static void WoodenRCTrackDiagRightBankTo25DegDown( PaintUtilSetGeneralSupportHeight(session, height + 56); } -/** rct2: 0x008ACA98 */ template -static void WoodenRCTrackDiag25DegDownToLeftBank( +static void WoodenRCTrackDiagDown25ToLeftBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24108), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24974), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24109), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24975), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24112), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24978), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24107), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24973), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24111), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24977), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24110), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24976), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - } + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } -/** rct2: 0x008ACAA8 */ template -static void WoodenRCTrackDiag25DegDownToRightBank( +static void WoodenRCTrackDiagDown25ToRightBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24102), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24968), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24103), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24969), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24106), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24972), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 2: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24101), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24967), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24105), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24971), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24104), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24970), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); - break; - } + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } /** rct2: 0x008AC9D8 */ @@ -14347,9 +13995,9 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::DiagRightBankToFlat: return WoodenRCTrackDiagRightBankToFlat; case TrackElemType::DiagLeftBankToUp25: - return WoodenRCTrackDiagLeftBankTo25DegUp; + return WoodenRCTrackDiagBankTo25DegUp; case TrackElemType::DiagRightBankToUp25: - return WoodenRCTrackDiagRightBankTo25DegUp; + return WoodenRCTrackDiagBankTo25DegUp; case TrackElemType::DiagUp25ToLeftBank: return WoodenRCTrackDiag25DegUpToLeftBank; case TrackElemType::DiagUp25ToRightBank: @@ -14359,9 +14007,9 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::DiagRightBankToDown25: return WoodenRCTrackDiagRightBankTo25DegDown; case TrackElemType::DiagDown25ToLeftBank: - return WoodenRCTrackDiag25DegDownToLeftBank; + return WoodenRCTrackDiagDown25ToLeftBank; case TrackElemType::DiagDown25ToRightBank: - return WoodenRCTrackDiag25DegDownToRightBank; + return WoodenRCTrackDiagDown25ToRightBank; case TrackElemType::DiagLeftBank: return WoodenRCTrackDiagLeftBank; case TrackElemType::DiagRightBank: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 3ca894b9b8..cb270ac3f7 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -3020,4 +3020,72 @@ static void WoodenRCTrackDiagFlatToBank( PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); } +/** rct2: 0x008ACA58, 0x008ACA68 */ +template imageIds> +static void WoodenRCTrackDiagBankTo25DegUp( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } }); + } + break; + } + break; + case 2: + switch (direction) + { + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } }); + } + break; + } + break; + case 3: + switch (direction) + { + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + } + + DrawSupportForSequenceA( + session, supportType.wooden, trackSequence, direction, height, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 48); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From 3afcfc2eb72e3d7e05d1c5611f9fac6994d4c1fc Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 11:32:19 +0000 Subject: [PATCH 069/139] Implement Classic Wooden Twister diagonal gentle up to bank --- .../ClassicWoodenTwisterRollerCoaster.cpp | 105 +++++ .../track/coaster/WoodenRollerCoaster.cpp | 422 ++++-------------- .../track/coaster/WoodenRollerCoaster.hpp | 68 +++ 3 files changed, 257 insertions(+), 338 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 9d98e36d0d..a11f7716ea 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -276,6 +276,22 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66065, SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66066, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 66067, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 66068, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 66069, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 66070, + + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66071, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66072, + + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 66073, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 66074, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 66075, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 66076, + + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66077, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66078, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0 = SPR_CSG_BEGIN + 66079, SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1 = SPR_CSG_BEGIN + 66080, SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2 = SPR_CSG_BEGIN + 66081, @@ -548,6 +564,22 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66821, SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66822, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66823, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66824, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66825, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66826, + + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66827, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66828, + + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66829, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66830, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66831, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66832, + + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66833, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66834, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0 = SPR_CSG_BEGIN + 66835, SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1 = SPR_CSG_BEGIN + 66836, SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2 = SPR_CSG_BEGIN + 66837, @@ -1456,6 +1488,52 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array kDiagUp25ToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3, + }, +} }; + +static constexpr std::array kDiagUp25ToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3, + }, +} }; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -1639,6 +1717,24 @@ static void ClassicWoodenTwisterRCTrackDiagDown25ToRightBank( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackDiagLeftBankToDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagUp25ToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void ClassicWoodenTwisterRCTrackDiagRightBankToDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagUp25ToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -1736,6 +1832,15 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::DiagDown25ToRightBank: return ClassicWoodenTwisterRCTrackDiagDown25ToRightBank; + case TrackElemType::DiagUp25ToLeftBank: + return WoodenRCTrackDiagUp25ToBank; + case TrackElemType::DiagUp25ToRightBank: + return WoodenRCTrackDiagUp25ToBank; + case TrackElemType::DiagLeftBankToDown25: + return ClassicWoodenTwisterRCTrackDiagLeftBankToDown25; + case TrackElemType::DiagRightBankToDown25: + return ClassicWoodenTwisterRCTrackDiagRightBankToDown25; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 665674bfa2..bb3cb5c6ab 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -365,7 +365,18 @@ enum SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3 = 24086, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = 24087, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = 24088, - + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0 = 24089, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_1 = 24090, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_2 = 24091, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_3 = 24092, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0 = 24093, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2 = 24094, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0 = 24095, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_1 = 24096, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_2 = 24097, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_3 = 24098, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0 = 24099, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2 = 24100, SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0 = 24101, SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1 = 24102, SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2 = 24103, @@ -709,7 +720,18 @@ enum SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = 24952, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = 24953, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = 24954, - + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0 = 24955, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1 = 24956, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2 = 24957, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3 = 24958, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0 = 24959, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2 = 24960, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0 = 24961, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1 = 24962, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2 = 24963, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3 = 24964, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = 24965, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = 24966, SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0 = 24967, SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1 = 24968, SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2 = 24969, @@ -1650,6 +1672,52 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array kDiagUp25ToLeftBankImages = { { + { + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_1, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1, + }, + { + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_2, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_3, + SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3, + }, +} }; + +static constexpr std::array kDiagUp25ToRightBankImages = { { + { + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_1, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1, + }, + { + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_2, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_3, + SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3, + }, +} }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -10044,344 +10112,22 @@ static void WoodenRCTrackDiagRightBankToFlat( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } -/** rct2: 0x008ACA38 */ -template -static void WoodenRCTrackDiag25DegUpToLeftBank( +static void WoodenRCTrackDiagLeftBankToDown25( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24092), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24958), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24089), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24955), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24093), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24959), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner0, direction, height + 16, session.SupportColours); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - case 2: - switch (direction) - { - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24091), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24957), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24094), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24960), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner2, direction, height + 16, session.SupportColours); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24090), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24956), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - } + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagUp25ToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } -/** rct2: 0x008ACA48 */ -template -static void WoodenRCTrackDiag25DegUpToRightBank( +static void WoodenRCTrackDiagRightBankToDown25( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24098), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24964), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24095), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24961), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24099), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24965), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner0, direction, height + 16, session.SupportColours); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - case 2: - switch (direction) - { - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24097), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24963), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24100), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24966), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner2, direction, height + 16, session.SupportColours); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24096), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24962), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); - break; - } -} - -/** rct2: 0x008ACA78 */ -template -static void WoodenRCTrackDiagLeftBankTo25DegDown( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24096), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24962), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24097), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24963), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24100), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24966), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner0, direction, height + 16, session.SupportColours); - break; - case 2: - switch (direction) - { - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24095), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24961), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24099), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24965), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner2, direction, height + 16, session.SupportColours); - - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24098), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24964), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - break; - } - - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); -} - -/** rct2: 0x008ACA88 */ -template -static void WoodenRCTrackDiagRightBankTo25DegDown( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24090), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24956), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24091), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24957), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24094), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24960), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner0, direction, height + 16, session.SupportColours); - break; - case 2: - switch (direction) - { - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24089), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24955), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24093), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24959), { -16, -16, height }, - { { -16, -16, height + 35 }, { 32, 32, 0 } }); - break; - } - WoodenBSupportsPaintSetupRotated( - session, supportType.wooden, WoodenSupportSubType::Corner2, direction, height + 16, session.SupportColours); - break; - case 3: - switch (direction) - { - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24092), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(24958), { -16, -16, height }, - { { -16, -16, height }, { 32, 32, 2 } }); - break; - } - break; - } - - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagUp25ToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } template @@ -13995,17 +13741,17 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::DiagRightBankToFlat: return WoodenRCTrackDiagRightBankToFlat; case TrackElemType::DiagLeftBankToUp25: - return WoodenRCTrackDiagBankTo25DegUp; + return WoodenRCTrackDiagBankTo25DegUp; case TrackElemType::DiagRightBankToUp25: - return WoodenRCTrackDiagBankTo25DegUp; + return WoodenRCTrackDiagBankTo25DegUp; case TrackElemType::DiagUp25ToLeftBank: - return WoodenRCTrackDiag25DegUpToLeftBank; + return WoodenRCTrackDiagUp25ToBank; case TrackElemType::DiagUp25ToRightBank: - return WoodenRCTrackDiag25DegUpToRightBank; + return WoodenRCTrackDiagUp25ToBank; case TrackElemType::DiagLeftBankToDown25: - return WoodenRCTrackDiagLeftBankTo25DegDown; + return WoodenRCTrackDiagLeftBankToDown25; case TrackElemType::DiagRightBankToDown25: - return WoodenRCTrackDiagRightBankTo25DegDown; + return WoodenRCTrackDiagRightBankToDown25; case TrackElemType::DiagDown25ToLeftBank: return WoodenRCTrackDiagDown25ToLeftBank; case TrackElemType::DiagDown25ToRightBank: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index cb270ac3f7..55cdc0b68d 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -3088,4 +3088,72 @@ static void WoodenRCTrackDiagBankTo25DegUp( PaintUtilSetGeneralSupportHeight(session, height + 48); } +/** rct2: 0x008ACA38, 0x008ACA48 */ +template imageIds> +static void WoodenRCTrackDiagUp25ToBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } }); + } + break; + } + break; + case 2: + switch (direction) + { + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } }); + } + break; + } + break; + case 3: + switch (direction) + { + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + } + + DrawSupportForSequenceB( + session, supportType.wooden, trackSequence, direction, height + 16, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 56); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From 13dd30f1264536def6dfe8235538237fcc355bbd Mon Sep 17 00:00:00 2001 From: mix Date: Thu, 14 Nov 2024 14:33:41 +0000 Subject: [PATCH 070/139] Implement Classic Wooden Twister right banked eighth to diag --- .../ClassicWoodenTwisterRollerCoaster.cpp | 157 +++++++ .../track/coaster/WoodenRollerCoaster.cpp | 413 ++++++------------ .../track/coaster/WoodenRollerCoaster.hpp | 168 +++++++ 3 files changed, 469 insertions(+), 269 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index a11f7716ea..f27ba2dc5f 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -308,6 +308,32 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0 = SPR_CSG_BEGIN + 66089, SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2 = SPR_CSG_BEGIN + 66090, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 66139, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 66140, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 66141, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 66142, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 66143, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 66144, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 66145, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 66146, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 66147, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 66148, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 66149, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 66150, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 66151, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 66152, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 66153, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 66154, + + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0 = SPR_CSG_BEGIN + 66155, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0 = SPR_CSG_BEGIN + 66156, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0 = SPR_CSG_BEGIN + 66157, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0 = SPR_CSG_BEGIN + 66158, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2 = SPR_CSG_BEGIN + 66159, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2 = SPR_CSG_BEGIN + 66160, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2 = SPR_CSG_BEGIN + 66161, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2 = SPR_CSG_BEGIN + 66162, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -595,6 +621,32 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66845, SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66846, + + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66895, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66896, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66897, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66898, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66899, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66900, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66901, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66902, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66903, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66904, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66905, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66906, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66907, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66908, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66909, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66910, + + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66911, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66912, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66913, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66914, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66915, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66916, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66917, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66918, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -1534,6 +1586,97 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array, 4> kRightEighthBankToDiagImages = { { + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, + }, + } }, +} }; + static void ClassicWoodenTwisterRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -1735,6 +1878,15 @@ static void ClassicWoodenTwisterRCTrackDiagRightBankToDown25( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackLeftEighthBankToOrthogonal( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + WoodenRCTrackRightEighthBankToDiag( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. // As such, all non-banked pieces are simply drawn as regular wooden roller coaster pieces. @@ -1841,6 +1993,11 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::DiagRightBankToDown25: return ClassicWoodenTwisterRCTrackDiagRightBankToDown25; + case TrackElemType::RightEighthBankToDiag: + return WoodenRCTrackRightEighthBankToDiag; + case TrackElemType::LeftEighthBankToOrthogonal: + return ClassicWoodenTwisterRCTrackLeftEighthBankToOrthogonal; + default: return GetTrackPaintFunctionWoodenRC(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index bb3cb5c6ab..7132366cd7 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -390,6 +390,31 @@ enum SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0 = 24111, SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2 = 24112, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0 = 24161, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0 = 24162, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0 = 24163, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0 = 24164, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1 = 24165, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1 = 24166, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1 = 24167, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1 = 24168, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2 = 24169, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2 = 24170, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2 = 24171, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2 = 24172, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3 = 24173, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3 = 24174, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3 = 24175, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3 = 24176, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0 = 24177, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0 = 24178, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0 = 24179, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0 = 24180, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2 = 24181, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2 = 24182, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2 = 24183, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2 = 24184, + SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SW_NE = 24363, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NW_SE = 24364, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NE_SW = 24365, @@ -744,6 +769,31 @@ enum SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3 = 24976, SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = 24977, SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = 24978, + + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = 25027, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = 25028, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = 25029, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = 25030, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = 25031, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = 25032, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = 25033, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = 25034, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = 25035, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = 25036, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = 25037, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = 25038, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = 25039, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = 25040, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = 25041, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = 25042, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0 = 25043, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0 = 25044, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0 = 25045, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0 = 25046, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2 = 25047, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2 = 25048, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2 = 25049, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2 = 25050, }; static constexpr uint32_t _wooden_rc_block_brakes_image_ids[4][3] = { @@ -1718,6 +1768,97 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array, 4> kRightEighthBankToDiagImages = { { + { { + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2, + }, + { + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3, + SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, + }, + } }, +} }; + ImageId WoodenRCGetRailsColour(PaintSession& session) { return session.TrackColours; @@ -7580,272 +7721,6 @@ static void WoodenRCTrackLeftEighthBankToDiag( } } -/** rct2: 0x008AC9A8 */ -template -static void WoodenRCTrackRightEighthBankToDiag( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24161), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25027), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24177), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25043), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24165), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25031), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24169), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25035), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24181), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25047), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24173), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25039), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24162), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25028), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24178), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25044), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24166), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25032), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24170), { 0, 0, height }, - { { 0, 0, height }, { 34, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25036), { 0, 0, height }, - { { 0, 0, height }, { 34, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24182), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25048), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24174), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25040), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24163), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25029), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24179), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25045), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24167), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25033), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24171), { 0, 0, height }, - { { 4, 4, height }, { 28, 28, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25037), { 0, 0, height }, - { { 4, 4, height }, { 28, 28, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24183), { 0, 0, height }, - { { 4, 4, height + 27 }, { 28, 28, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25049), { 0, 0, height }, - { { 4, 4, height + 27 }, { 28, 28, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24175), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25041), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 4: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24164), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25030), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24180), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25046), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 16, 0 } }); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24168), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25034), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24172), { 0, 0, height }, - { { 0, 16, height }, { 16, 18, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25038), { 0, 0, height }, - { { 0, 16, height }, { 16, 18, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24184), { 0, 0, height }, - { { 0, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25050), { 0, 0, height }, - { { 0, 16, height + 27 }, { 16, 16, 0 } }); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24176), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25042), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - /** rct2: 0x008AC9B8 */ template static void WoodenRCTrackLeftEighthBankToOrthogonal( @@ -7853,8 +7728,8 @@ static void WoodenRCTrackLeftEighthBankToOrthogonal( const TrackElement& trackElement, SupportType supportType) { trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; - WoodenRCTrackRightEighthBankToDiag( - session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackRightEighthBankToDiag( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } /** rct2: 0x008AC9C8 */ @@ -13701,7 +13576,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::LeftEighthBankToDiag: return WoodenRCTrackLeftEighthBankToDiag; case TrackElemType::RightEighthBankToDiag: - return WoodenRCTrackRightEighthBankToDiag; + return WoodenRCTrackRightEighthBankToDiag; case TrackElemType::LeftEighthBankToOrthogonal: return WoodenRCTrackLeftEighthBankToOrthogonal; case TrackElemType::RightEighthBankToOrthogonal: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 55cdc0b68d..abe9fc2af5 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -3156,4 +3156,172 @@ static void WoodenRCTrackDiagUp25ToBank( PaintUtilSetGeneralSupportHeight(session, height + 56); } +/** rct2: 0x008AC9A8 */ +template, 4> imageIds> +static void WoodenRCTrackRightEighthBankToDiag( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 32, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 32, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + break; + case 1: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 16, height + 27 }, { 32, 16, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 34, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 4, 4, height }, { 28, 28, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 4, 4, height + 27 }, { 28, 28, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + } + break; + case 4: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 16, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 18, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 0, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + break; + } + break; + } + + DrawSupportForSequenceA( + session, supportType.wooden, trackSequence, direction, height, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRCFallback(OpenRCT2::TrackElemType trackType); From eb0463084b21fdac8a669c746bcc3bb98b5441e9 Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 15 Nov 2024 00:37:47 +0000 Subject: [PATCH 071/139] Implement Classic Wooden Twister left banked eighth to diag --- .../ClassicWoodenTwisterRollerCoaster.cpp | 155 +++++++ .../track/coaster/WoodenRollerCoaster.cpp | 411 ++++++------------ .../track/coaster/WoodenRollerCoaster.hpp | 168 +++++++ 3 files changed, 465 insertions(+), 269 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index f27ba2dc5f..3bb137d6ca 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -334,6 +334,32 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2 = SPR_CSG_BEGIN + 66161, SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2 = SPR_CSG_BEGIN + 66162, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 66163, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 66164, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 66165, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 66166, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 66167, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 66168, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 66169, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 66170, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 66171, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 66172, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 66173, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 66174, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 66175, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 66176, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 66177, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 66178, + + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1 = SPR_CSG_BEGIN + 66179, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1 = SPR_CSG_BEGIN + 66180, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1 = SPR_CSG_BEGIN + 66181, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1 = SPR_CSG_BEGIN + 66182, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3 = SPR_CSG_BEGIN + 66183, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3 = SPR_CSG_BEGIN + 66184, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3 = SPR_CSG_BEGIN + 66185, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3 = SPR_CSG_BEGIN + 66186, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, @@ -647,6 +673,32 @@ enum SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66916, SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66917, SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66918, + + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66919, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66920, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66921, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66922, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66923, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66924, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66925, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66926, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66927, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66928, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66929, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66930, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66931, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66932, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66933, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66934, + + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66935, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66936, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66937, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66938, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66939, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66940, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66941, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66942, }; static constexpr std::array kFlatToLeftBankImages = { { @@ -1586,6 +1638,97 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3, + }, + } }, +} }; + static constexpr std::array, 4> kRightEighthBankToDiagImages = { { { { { @@ -1886,6 +2029,14 @@ static void ClassicWoodenTwisterRCTrackLeftEighthBankToOrthogonal( WoodenRCTrackRightEighthBankToDiag( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackRightEighthBankToOrthogonal( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + WoodenRCTrackLeftEighthBankToDiag( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. // The only difference is the degree of the banking. @@ -1993,10 +2144,14 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::DiagRightBankToDown25: return ClassicWoodenTwisterRCTrackDiagRightBankToDown25; + case TrackElemType::LeftEighthBankToDiag: + return WoodenRCTrackLeftEighthBankToDiag; case TrackElemType::RightEighthBankToDiag: return WoodenRCTrackRightEighthBankToDiag; case TrackElemType::LeftEighthBankToOrthogonal: return ClassicWoodenTwisterRCTrackLeftEighthBankToOrthogonal; + case TrackElemType::RightEighthBankToOrthogonal: + return ClassicWoodenTwisterRCTrackRightEighthBankToOrthogonal; default: return GetTrackPaintFunctionWoodenRC(trackType); diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index 7132366cd7..fa3bc903bf 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -414,6 +414,30 @@ enum SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2 = 24182, SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2 = 24183, SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2 = 24184, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0 = 24185, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0 = 24186, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0 = 24187, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0 = 24188, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1 = 24189, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1 = 24190, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1 = 24191, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1 = 24192, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2 = 24193, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2 = 24194, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2 = 24195, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2 = 24196, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3 = 24197, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3 = 24198, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3 = 24199, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3 = 24200, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1 = 24201, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1 = 24202, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1 = 24203, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1 = 24204, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3 = 24205, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3 = 24206, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3 = 24207, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3 = 24208, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SW_NE = 24363, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_NW_SE = 24364, @@ -794,6 +818,30 @@ enum SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2 = 25048, SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2 = 25049, SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2 = 25050, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = 25051, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = 25052, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = 25053, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = 25054, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = 25055, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = 25056, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = 25057, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = 25058, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = 25059, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = 25060, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = 25061, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = 25062, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = 25063, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = 25064, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = 25065, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = 25066, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1 = 25067, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1 = 25068, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1 = 25069, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1 = 25070, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3 = 25071, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3 = 25072, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3 = 25073, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3 = 25074, }; static constexpr uint32_t _wooden_rc_block_brakes_image_ids[4][3] = { @@ -1768,6 +1816,97 @@ static constexpr std::array kDiag }, } }; +static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { + { { + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, + }, + { + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3, + SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3, + }, + } }, +} }; + static constexpr std::array, 4> kRightEighthBankToDiagImages = { { { { { @@ -7455,272 +7594,6 @@ static void WoodenRCTrackRightEighthToOrthogonal( session, ride, trackSequence, (direction + 3) & 3, height, trackElement, supportType); } -/** rct2: 0x008AC998 */ -template -static void WoodenRCTrackLeftEighthBankToDiag( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - switch (trackSequence) - { - case 0: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24185), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25051), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24189), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25055), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24201), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25067), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24193), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25059), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24197), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25063), { 0, 0, height }, - { { 0, 0, height }, { 32, 32, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24205), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25071), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 32, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 1: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24186), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25052), { 0, 0, height }, - { { 0, 0, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24190), { 0, 0, height }, - { { 0, 0, height }, { 34, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25056), { 0, 0, height }, - { { 0, 0, height }, { 34, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24202), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25068), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24194), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25060), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NeSw, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24198), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25064), { 0, 0, height }, - { { 0, 16, height }, { 32, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24206), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25072), { 0, 0, height }, - { { 0, 16, height + 27 }, { 32, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::NwSe, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 2: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24187), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25053), { 0, 0, height }, - { { 0, 16, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24191), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25057), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24203), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25069), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24195), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25061), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24199), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25065), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24207), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25073), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 16, 0 } }); - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 3: - switch (direction) - { - case 0: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner3, height, session.SupportColours); - break; - case 1: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner0, height, session.SupportColours); - break; - case 2: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner1, height, session.SupportColours); - break; - case 3: - WoodenASupportsPaintSetup( - session, supportType.wooden, WoodenSupportSubType::Corner2, height, session.SupportColours); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - case 4: - switch (direction) - { - case 0: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24188), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25054), { 0, 0, height }, - { { 16, 16, height }, { 16, 16, 2 } }); - break; - case 1: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24192), { 0, 0, height }, - { { 0, 16, height }, { 16, 18, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25058), { 0, 0, height }, - { { 0, 16, height }, { 16, 18, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24204), { 0, 0, height }, - { { 0, 16, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25070), { 0, 0, height }, - { { 0, 16, height + 27 }, { 16, 16, 0 } }); - break; - case 2: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24196), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25062), { 0, 0, height }, - { { 0, 0, height }, { 16, 16, 2 } }); - break; - case 3: - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24200), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25066), { 0, 0, height }, - { { 16, 0, height }, { 16, 16, 2 } }); - PaintAddImageAsParentRotated( - session, direction, WoodenRCGetTrackColour(session).WithIndex(24208), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 16, 0 } }); - PaintAddImageAsChildRotated( - session, direction, WoodenRCGetRailsColour(session).WithIndex(25074), { 0, 0, height }, - { { 16, 0, height + 27 }, { 16, 16, 0 } }); - break; - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); - break; - } -} - /** rct2: 0x008AC9B8 */ template static void WoodenRCTrackLeftEighthBankToOrthogonal( @@ -7739,8 +7612,8 @@ static void WoodenRCTrackRightEighthBankToOrthogonal( const TrackElement& trackElement, SupportType supportType) { trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; - WoodenRCTrackLeftEighthBankToDiag( - session, ride, trackSequence, (direction + 3) & 3, height, trackElement, supportType); + WoodenRCTrackLeftEighthBankToDiag( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } template @@ -13574,7 +13447,7 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionWoodenAndClassicWoodenRC(OpenRCT2::Tra case TrackElemType::RightEighthToOrthogonal: return WoodenRCTrackRightEighthToOrthogonal; case TrackElemType::LeftEighthBankToDiag: - return WoodenRCTrackLeftEighthBankToDiag; + return WoodenRCTrackLeftEighthBankToDiag; case TrackElemType::RightEighthBankToDiag: return WoodenRCTrackRightEighthBankToDiag; case TrackElemType::LeftEighthBankToOrthogonal: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index abe9fc2af5..b6146f6360 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -3156,6 +3156,174 @@ static void WoodenRCTrackDiagUp25ToBank( PaintUtilSetGeneralSupportHeight(session, height + 56); } +/** rct2: 0x008AC998 */ +template, 4> imageIds> +static void WoodenRCTrackLeftEighthBankToDiag( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 32, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].track, imageIds[0][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 32, 2 } }); + if (imageIds[0][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[0][direction].frontTrack, imageIds[0][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 32, 0 } }); + } + break; + } + if (direction == 0 || direction == 3) + { + PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); + } + break; + case 1: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 32, 16, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 34, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].track, imageIds[1][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 32, 16, 2 } }); + if (imageIds[1][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[1][direction].frontTrack, imageIds[1][direction].frontHandrail, + { 0, 0, height }, { { 0, 16, height + 27 }, { 32, 16, 0 } }); + } + break; + } + break; + case 2: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 16, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 16, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].track, imageIds[2][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + if (imageIds[2][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[2][direction].frontTrack, imageIds[2][direction].frontHandrail, + { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + } + break; + case 4: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 16, height }, { 16, 16, 2 } }); + break; + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 16, height }, { 16, 18, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 0, 16, height + 27 }, { 16, 16, 0 } }); + } + break; + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 0, 0, height }, { 16, 16, 2 } }); + break; + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].track, imageIds[3][direction].handrail, { 0, 0, height }, + { { 16, 0, height }, { 16, 16, 2 } }); + if (imageIds[3][direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[3][direction].frontTrack, imageIds[3][direction].frontHandrail, + { 0, 0, height }, { { 16, 0, height + 27 }, { 16, 16, 0 } }); + } + break; + } + break; + } + + DrawSupportForSequenceA( + session, supportType.wooden, trackSequence, direction, height, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + /** rct2: 0x008AC9A8 */ template, 4> imageIds> static void WoodenRCTrackRightEighthBankToDiag( From 42a85a1e6424eb859340eccbf41fe8ca4125aa3a Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 15 Nov 2024 00:47:20 +0000 Subject: [PATCH 072/139] Rename StraightWoodenTrack to WoodenTrackSection --- .../ClassicWoodenTwisterRollerCoaster.cpp | 406 +++++++++--------- .../track/coaster/WoodenRollerCoaster.cpp | 406 +++++++++--------- .../track/coaster/WoodenRollerCoaster.hpp | 36 +- 3 files changed, 420 insertions(+), 428 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 3bb137d6ca..70a040f406 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -701,7 +701,7 @@ enum SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66942, }; -static constexpr std::array kFlatToLeftBankImages = { { +static constexpr std::array kFlatToLeftBankImages = { { { SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_0, SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0, @@ -724,7 +724,7 @@ static constexpr std::array kFlat }, } }; -static constexpr std::array kFlatToRightBankImages = { { +static constexpr std::array kFlatToRightBankImages = { { { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_0, SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0, @@ -747,14 +747,14 @@ static constexpr std::array kFlat }, } }; -static constexpr std::array kLeftBankImages = { { +static constexpr std::array kLeftBankImages = { { { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_0, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_0 }, { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_1, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_1 }, { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_2, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_2 }, { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_3, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_3 }, } }; -static constexpr std::array kUp25ToLeftBankImages = { { +static constexpr std::array kUp25ToLeftBankImages = { { { SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_0, SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_0, @@ -777,7 +777,7 @@ static constexpr std::array kUp25 }, } }; -static constexpr std::array kUp25ToRightBankImages = { { +static constexpr std::array kUp25ToRightBankImages = { { { SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_0, SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_0, @@ -800,7 +800,7 @@ static constexpr std::array kUp25 }, } }; -static constexpr std::array kLeftBankToUp25Images = { { +static constexpr std::array kLeftBankToUp25Images = { { { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_0, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_0, @@ -823,7 +823,7 @@ static constexpr std::array kLeft }, } }; -static constexpr std::array kRightBankToUp25Images = { { +static constexpr std::array kRightBankToUp25Images = { { { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_0, SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_0, @@ -846,7 +846,7 @@ static constexpr std::array kRigh }, } }; -static constexpr std::array, 3> kBankedQuarterTurn3Images = { { +static constexpr std::array, 3> kBankedQuarterTurn3Images = { { { { { SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0, @@ -915,7 +915,7 @@ static constexpr std::array, 5> kBankedQuarterTurn5Images = { { +static constexpr std::array, 5> kBankedQuarterTurn5Images = { { { { { SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_0, @@ -1028,78 +1028,76 @@ static constexpr std::array, 3> kLeftHalfBankedHelixUpSmallImages = { - { - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, - }, - } }, - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, - }, - } }, - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, - }, - } }, - } -}; +static constexpr std::array, 3> kLeftHalfBankedHelixUpSmallImages = { { + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, + }, + } }, +} }; -static constexpr std::array, 3> kRightHalfBankedHelixUpSmallImages = { +static constexpr std::array, 3> kRightHalfBankedHelixUpSmallImages = { { { { { @@ -1170,122 +1168,120 @@ static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { - { - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, - }, - } }, - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, - }, - } }, - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, - }, - } }, - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, - }, - } }, - { { - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, - }, - { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, - }, - } }, - } -}; +static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { { + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, + SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, + }, + } }, +} }; -static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { +static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { { { { { @@ -1400,7 +1396,7 @@ static constexpr std::array, 2> +static constexpr std::array, 2> kLeftBankToLeftQuarterTurn325DegUpImages = { { { { { @@ -1450,7 +1446,7 @@ static constexpr std::array, 2> +static constexpr std::array, 2> kRightBankToRightQuarterTurn325DegUpImages = { { { { { @@ -1500,7 +1496,7 @@ static constexpr std::array kDiagFlatToLeftBankImages = { { +static constexpr std::array kDiagFlatToLeftBankImages = { { { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0, SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0, @@ -1523,7 +1519,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagFlatToRightBankImages = { { +static constexpr std::array kDiagFlatToRightBankImages = { { { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0, SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0, @@ -1546,7 +1542,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagLeftBankTo25DegUpImages = { { +static constexpr std::array kDiagLeftBankTo25DegUpImages = { { { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0, SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0, @@ -1569,7 +1565,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagRightBankTo25DegUpImages = { { +static constexpr std::array kDiagRightBankTo25DegUpImages = { { { SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0, SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0, @@ -1592,7 +1588,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagUp25ToLeftBankImages = { { +static constexpr std::array kDiagUp25ToLeftBankImages = { { { SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0, SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0, @@ -1615,7 +1611,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagUp25ToRightBankImages = { { +static constexpr std::array kDiagUp25ToRightBankImages = { { { SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0, SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0, @@ -1638,7 +1634,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { +static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { { { { SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0, @@ -1729,7 +1725,7 @@ static constexpr std::array, 4> kRightEighthBankToDiagImages = { { +static constexpr std::array, 4> kRightEighthBankToDiagImages = { { { { { SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0, diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp index fa3bc903bf..5d045ebb09 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.cpp @@ -880,7 +880,7 @@ static constexpr const uint32_t WoodenRCDiagBlockBrakeImages[2][kNumOrthogonalDi }, }; -static constexpr std::array kFlatToLeftBankImages = { { +static constexpr std::array kFlatToLeftBankImages = { { { SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_SW_NE, SPR_WOODEN_RC_FLAT_TO_LEFT_BANK_RAILS_SW_NE, @@ -903,7 +903,7 @@ static constexpr std::array kFlat }, } }; -static constexpr std::array kFlatToRightBankImages = { { +static constexpr std::array kFlatToRightBankImages = { { { SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_SW_NE, SPR_WOODEN_RC_FLAT_TO_RIGHT_BANK_RAILS_SW_NE, @@ -926,14 +926,14 @@ static constexpr std::array kFlat }, } }; -static constexpr std::array kLeftBankImages = { { +static constexpr std::array kLeftBankImages = { { { SPR_WOODEN_RC_LEFT_BANK_SW_NE, SPR_WOODEN_RC_LEFT_BANK_RAILS_SW_NE }, { SPR_WOODEN_RC_LEFT_BANK_NW_SE, SPR_WOODEN_RC_LEFT_BANK_RAILS_NW_SE }, { SPR_WOODEN_RC_LEFT_BANK_NE_SW, SPR_WOODEN_RC_LEFT_BANK_RAILS_NE_SW }, { SPR_WOODEN_RC_LEFT_BANK_SE_NW, SPR_WOODEN_RC_LEFT_BANK_RAILS_SE_NW }, } }; -static constexpr std::array kUp25ToLeftBankImages = { { +static constexpr std::array kUp25ToLeftBankImages = { { { SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_SW_NE, SPR_WOODEN_RC_25_DEG_TO_LEFT_BANK_RAILS_SW_NE, @@ -956,7 +956,7 @@ static constexpr std::array kUp25 }, } }; -static constexpr std::array kUp25ToRightBankImages = { { +static constexpr std::array kUp25ToRightBankImages = { { { SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_SW_NE, SPR_WOODEN_RC_25_DEG_TO_RIGHT_BANK_RAILS_SW_NE, @@ -979,7 +979,7 @@ static constexpr std::array kUp25 }, } }; -static constexpr std::array kLeftBankToUp25Images = { { +static constexpr std::array kLeftBankToUp25Images = { { { SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_SW_NE, SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_SW_NE, @@ -1001,7 +1001,7 @@ static constexpr std::array kLeft SPR_WOODEN_RC_LEFT_BANK_TO_25_DEG_RAILS_SE_NW, }, } }; -static constexpr std::array kRightBankToUp25Images = { { +static constexpr std::array kRightBankToUp25Images = { { { SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_SW_NE, SPR_WOODEN_RC_RIGHT_BANK_TO_25_DEG_RAILS_SW_NE, @@ -1024,7 +1024,7 @@ static constexpr std::array kRigh }, } }; -static constexpr std::array, 3> kBankedQuarterTurn3Images = { { +static constexpr std::array, 3> kBankedQuarterTurn3Images = { { { { { SPR_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0, @@ -1093,7 +1093,7 @@ static constexpr std::array, 5> kBankedQuarterTurn5Images = { { +static constexpr std::array, 5> kBankedQuarterTurn5Images = { { { { { SPR_WOODEN_RC_BANKED_QUARTER_TURN_5_SW_SE_SEQ_0, @@ -1206,78 +1206,76 @@ static constexpr std::array, 3> kLeftHalfBankedHelixUpSmallImages = { - { - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, - }, - } }, - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, - }, - } }, - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, - }, - } }, - } -}; +static constexpr std::array, 3> kLeftHalfBankedHelixUpSmallImages = { { + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, + }, + } }, +} }; -static constexpr std::array, 3> kRightHalfBankedHelixUpSmallImages = { +static constexpr std::array, 3> kRightHalfBankedHelixUpSmallImages = { { { { { @@ -1348,122 +1346,120 @@ static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { - { - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, - }, - } }, - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, - }, - } }, - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, - }, - } }, - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, - }, - } }, - { { - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, - }, - { - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, - SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, - }, - } }, - } -}; +static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { { + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, + }, + } }, + { { + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, + }, + { + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, + SPR_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, + }, + } }, +} }; -static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { +static constexpr std::array, 5> kRightHalfBankedHelixUpLargeImages = { { { { { @@ -1578,7 +1574,7 @@ static constexpr std::array, 2> +static constexpr std::array, 2> kLeftBankToLeftQuarterTurn325DegUpImages = { { { { { @@ -1628,7 +1624,7 @@ static constexpr std::array, 2> +static constexpr std::array, 2> kRightBankToRightQuarterTurn325DegUpImages = { { { { { @@ -1678,7 +1674,7 @@ static constexpr std::array kDiagFlatToLeftBankImages = { { +static constexpr std::array kDiagFlatToLeftBankImages = { { { SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0, SPR_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0, @@ -1701,7 +1697,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagFlatToRightBankImages = { { +static constexpr std::array kDiagFlatToRightBankImages = { { { SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0, SPR_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0, @@ -1724,7 +1720,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagLeftBankTo25DegUpImages = { { +static constexpr std::array kDiagLeftBankTo25DegUpImages = { { { SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0, SPR_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0, @@ -1747,7 +1743,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagRightBankTo25DegUpImages = { { +static constexpr std::array kDiagRightBankTo25DegUpImages = { { { SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0, SPR_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0, @@ -1770,7 +1766,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagUp25ToLeftBankImages = { { +static constexpr std::array kDiagUp25ToLeftBankImages = { { { SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0, SPR_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0, @@ -1793,7 +1789,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array kDiagUp25ToRightBankImages = { { +static constexpr std::array kDiagUp25ToRightBankImages = { { { SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0, SPR_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0, @@ -1816,7 +1812,7 @@ static constexpr std::array kDiag }, } }; -static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { +static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { { { { SPR_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0, @@ -1907,7 +1903,7 @@ static constexpr std::array, 4> kRightEighthBankToDiagImages = { { +static constexpr std::array, 4> kRightEighthBankToDiagImages = { { { { { SPR_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0, diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index b6146f6360..895d548bbb 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -23,7 +23,7 @@ static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; -struct StraightWoodenTrack +struct WoodenTrackSection { ImageIndex track; ImageIndex handrail; @@ -93,7 +93,7 @@ void WoodenRCTrackPaintBb(PaintSession& session, const SpriteBoundBox2* bb, int1 } } -template imageIds> +template imageIds> static void WoodenRCTrackStraightBankTrack(PaintSession& session, uint8_t direction, int32_t height) { WoodenRCTrackPaint( @@ -108,7 +108,7 @@ static void WoodenRCTrackStraightBankTrack(PaintSession& session, uint8_t direct } /** rct2: 0x008AC658, 0x008AC668, 0x008AC738 */ -template imageIds> +template imageIds> void WoodenRCTrackFlatToBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -122,7 +122,7 @@ void WoodenRCTrackFlatToBank( } /** rct2: 0x008AC6D8, 0x008AC6E8 */ -template imageIds> +template imageIds> static void WoodenRCTrack25DegUpToBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -144,7 +144,7 @@ static void WoodenRCTrack25DegUpToBank( } /** rct2: 0x008AC6B8, 0x008AC6C8 */ -template imageIds> +template imageIds> static void WoodenRCTrackBankTo25DegUp( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -166,7 +166,7 @@ static void WoodenRCTrackBankTo25DegUp( } /** rct2: 0x008AC808 */ -template, 3> imageIds> +template, 3> imageIds> static void WoodenRCTrackLeftQuarterTurn3Bank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -300,7 +300,7 @@ static void WoodenRCTrackLeftQuarterTurn3Bank( PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); } -template, 5> imageIds> +template, 5> imageIds> static void WoodenRCTrackBankedRightQuarterTurn5( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -519,7 +519,7 @@ static void WoodenRCTrackBankedRightQuarterTurn5( } /** rct2: 0x008ACAB8 */ -template, 3> imageIds> +template, 3> imageIds> static void WoodenRCTrackLeftHalfBankedHelixUpSmall( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -940,7 +940,7 @@ static void WoodenRCTrackLeftHalfBankedHelixUpSmall( } /** rct2: 0x008ACAC8 */ -template, 3> imageIds> +template, 3> imageIds> static void WoodenRCTrackRightHalfBankedHelixUpSmall( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -1361,7 +1361,7 @@ static void WoodenRCTrackRightHalfBankedHelixUpSmall( } /** rct2: 0x008ACAF8 */ -template, 5> imageIds> +template, 5> imageIds> static void WoodenRCTrackLeftHalfBankedHelixUpLarge( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -2019,7 +2019,7 @@ static void WoodenRCTrackLeftHalfBankedHelixUpLarge( } /** rct2: 0x008ACB08 */ -template, 5> imageIds> +template, 5> imageIds> static void WoodenRCTrackRightHalfBankedHelixUpLarge( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -2677,7 +2677,7 @@ static void WoodenRCTrackRightHalfBankedHelixUpLarge( } /** rct2: 0x008ACB38 */ -template, 2> imageIds> +template, 2> imageIds> static void WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -2815,7 +2815,7 @@ static void WoodenRCTrackLeftBankToLeftQuarterTurn325DegUp( } /** rct2: 0x008ACB48 */ -template, 2> imageIds> +template, 2> imageIds> static void WoodenRCTrackRightBankToRightQuarterTurn325DegUp( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -2953,7 +2953,7 @@ static void WoodenRCTrackRightBankToRightQuarterTurn325DegUp( } /** rct2: 0x008ACA18, 0x008AC9F8 */ -template imageIds> +template imageIds> static void WoodenRCTrackDiagFlatToBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -3021,7 +3021,7 @@ static void WoodenRCTrackDiagFlatToBank( } /** rct2: 0x008ACA58, 0x008ACA68 */ -template imageIds> +template imageIds> static void WoodenRCTrackDiagBankTo25DegUp( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -3089,7 +3089,7 @@ static void WoodenRCTrackDiagBankTo25DegUp( } /** rct2: 0x008ACA38, 0x008ACA48 */ -template imageIds> +template imageIds> static void WoodenRCTrackDiagUp25ToBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -3157,7 +3157,7 @@ static void WoodenRCTrackDiagUp25ToBank( } /** rct2: 0x008AC998 */ -template, 4> imageIds> +template, 4> imageIds> static void WoodenRCTrackLeftEighthBankToDiag( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -3325,7 +3325,7 @@ static void WoodenRCTrackLeftEighthBankToDiag( } /** rct2: 0x008AC9A8 */ -template, 4> imageIds> +template, 4> imageIds> static void WoodenRCTrackRightEighthBankToDiag( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) From f0d85b0fc4b325a3e1e902e84cd305bdb1a2d7ae Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 15 Nov 2024 00:53:48 +0000 Subject: [PATCH 073/139] Rename Classic Wooden Twister sprite enums to CLASSIC_WOODEN_TWISTER --- .../ClassicWoodenTwisterRollerCoaster.cpp | 2526 ++++++++--------- 1 file changed, 1263 insertions(+), 1263 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 70a040f406..752740fa93 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -20,897 +20,897 @@ using namespace OpenRCT2; enum { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65447, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65448, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 65449, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 65450, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 65451, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 65452, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65453, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65454, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_0 = SPR_CSG_BEGIN + 65455, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_1 = SPR_CSG_BEGIN + 65456, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_2 = SPR_CSG_BEGIN + 65457, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_3 = SPR_CSG_BEGIN + 65458, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65459, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65460, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 65461, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 65462, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 65463, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 65464, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65465, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65466, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_0 = SPR_CSG_BEGIN + 65467, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_1 = SPR_CSG_BEGIN + 65468, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_2 = SPR_CSG_BEGIN + 65469, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_3 = SPR_CSG_BEGIN + 65470, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_0 = SPR_CSG_BEGIN + 65471, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_1 = SPR_CSG_BEGIN + 65472, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_2 = SPR_CSG_BEGIN + 65473, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_3 = SPR_CSG_BEGIN + 65474, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65475, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_3 = SPR_CSG_BEGIN + 65476, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65477, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65478, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65479, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65480, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65481, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65482, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65483, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65484, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65485, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65486, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_0 = SPR_CSG_BEGIN + 65585, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_0 = SPR_CSG_BEGIN + 65586, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_0 = SPR_CSG_BEGIN + 65587, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_0 = SPR_CSG_BEGIN + 65588, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_0 = SPR_CSG_BEGIN + 65589, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_1 = SPR_CSG_BEGIN + 65590, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_1 = SPR_CSG_BEGIN + 65591, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_1 = SPR_CSG_BEGIN + 65592, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_1 = SPR_CSG_BEGIN + 65593, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_1 = SPR_CSG_BEGIN + 65594, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_2 = SPR_CSG_BEGIN + 65595, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_2 = SPR_CSG_BEGIN + 65596, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_2 = SPR_CSG_BEGIN + 65597, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_2 = SPR_CSG_BEGIN + 65598, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_2 = SPR_CSG_BEGIN + 65599, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_3 = SPR_CSG_BEGIN + 65600, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_3 = SPR_CSG_BEGIN + 65601, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_3 = SPR_CSG_BEGIN + 65602, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_3 = SPR_CSG_BEGIN + 65603, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_3 = SPR_CSG_BEGIN + 65604, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_0 = SPR_CSG_BEGIN + 65605, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_0 = SPR_CSG_BEGIN + 65606, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_0 = SPR_CSG_BEGIN + 65607, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_0 = SPR_CSG_BEGIN + 65608, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_0 = SPR_CSG_BEGIN + 65609, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_2 = SPR_CSG_BEGIN + 65610, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_2 = SPR_CSG_BEGIN + 65611, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_2 = SPR_CSG_BEGIN + 65612, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_2 = SPR_CSG_BEGIN + 65613, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_2 = SPR_CSG_BEGIN + 65614, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_0 = SPR_CSG_BEGIN + 65615, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_0 = SPR_CSG_BEGIN + 65616, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_0 = SPR_CSG_BEGIN + 65617, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_0 = SPR_CSG_BEGIN + 65618, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_0 = SPR_CSG_BEGIN + 65619, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_1 = SPR_CSG_BEGIN + 65620, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_1 = SPR_CSG_BEGIN + 65621, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_1 = SPR_CSG_BEGIN + 65622, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_1 = SPR_CSG_BEGIN + 65623, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_1 = SPR_CSG_BEGIN + 65624, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_2 = SPR_CSG_BEGIN + 65625, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_2 = SPR_CSG_BEGIN + 65626, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_2 = SPR_CSG_BEGIN + 65627, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_2 = SPR_CSG_BEGIN + 65628, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_2 = SPR_CSG_BEGIN + 65629, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_3 = SPR_CSG_BEGIN + 65630, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_3 = SPR_CSG_BEGIN + 65631, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_3 = SPR_CSG_BEGIN + 65632, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_3 = SPR_CSG_BEGIN + 65633, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_3 = SPR_CSG_BEGIN + 65634, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_0 = SPR_CSG_BEGIN + 65635, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_0 = SPR_CSG_BEGIN + 65636, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_0 = SPR_CSG_BEGIN + 65637, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_0 = SPR_CSG_BEGIN + 65638, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_0 = SPR_CSG_BEGIN + 65639, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_2 = SPR_CSG_BEGIN + 65640, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65641, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_2 = SPR_CSG_BEGIN + 65642, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2 = SPR_CSG_BEGIN + 65643, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2 = SPR_CSG_BEGIN + 65644, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3 = SPR_CSG_BEGIN + 65645, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3 = SPR_CSG_BEGIN + 65646, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3 = SPR_CSG_BEGIN + 65647, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3 = SPR_CSG_BEGIN + 65648, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3 = SPR_CSG_BEGIN + 65649, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0 = SPR_CSG_BEGIN + 65650, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0 = SPR_CSG_BEGIN + 65651, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0 = SPR_CSG_BEGIN + 65652, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0 = SPR_CSG_BEGIN + 65653, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0 = SPR_CSG_BEGIN + 65654, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1 = SPR_CSG_BEGIN + 65655, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1 = SPR_CSG_BEGIN + 65656, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1 = SPR_CSG_BEGIN + 65657, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1 = SPR_CSG_BEGIN + 65658, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1 = SPR_CSG_BEGIN + 65659, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2 = SPR_CSG_BEGIN + 65660, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2 = SPR_CSG_BEGIN + 65661, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2 = SPR_CSG_BEGIN + 65662, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2 = SPR_CSG_BEGIN + 65663, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2 = SPR_CSG_BEGIN + 65664, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3 = SPR_CSG_BEGIN + 65665, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3 = SPR_CSG_BEGIN + 65666, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3 = SPR_CSG_BEGIN + 65667, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3 = SPR_CSG_BEGIN + 65668, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3 = SPR_CSG_BEGIN + 65669, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1 = SPR_CSG_BEGIN + 65670, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1 = SPR_CSG_BEGIN + 65671, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1 = SPR_CSG_BEGIN + 65672, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65673, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65674, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_3 = SPR_CSG_BEGIN + 65849, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_3 = SPR_CSG_BEGIN + 65850, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_3 = SPR_CSG_BEGIN + 65851, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_0 = SPR_CSG_BEGIN + 65852, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_0 = SPR_CSG_BEGIN + 65853, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0 = SPR_CSG_BEGIN + 65854, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_1 = SPR_CSG_BEGIN + 65855, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_1 = SPR_CSG_BEGIN + 65856, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_1 = SPR_CSG_BEGIN + 65857, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_2 = SPR_CSG_BEGIN + 65858, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_2 = SPR_CSG_BEGIN + 65859, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_2 = SPR_CSG_BEGIN + 65860, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_3 = SPR_CSG_BEGIN + 65861, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_3 = SPR_CSG_BEGIN + 65862, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_3 = SPR_CSG_BEGIN + 65863, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_1 = SPR_CSG_BEGIN + 65864, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1 = SPR_CSG_BEGIN + 65865, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1 = SPR_CSG_BEGIN + 65866, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_0 = SPR_CSG_BEGIN + 65867, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_0 = SPR_CSG_BEGIN + 65868, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_0 = SPR_CSG_BEGIN + 65869, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_1 = SPR_CSG_BEGIN + 65870, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_1 = SPR_CSG_BEGIN + 65871, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_1 = SPR_CSG_BEGIN + 65872, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_2 = SPR_CSG_BEGIN + 65873, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_2 = SPR_CSG_BEGIN + 65874, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_2 = SPR_CSG_BEGIN + 65875, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_3 = SPR_CSG_BEGIN + 65876, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_3 = SPR_CSG_BEGIN + 65877, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_3 = SPR_CSG_BEGIN + 65878, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_0 = SPR_CSG_BEGIN + 65879, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_0 = SPR_CSG_BEGIN + 65880, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_0 = SPR_CSG_BEGIN + 65881, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_2 = SPR_CSG_BEGIN + 65882, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_2 = SPR_CSG_BEGIN + 65883, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_2 = SPR_CSG_BEGIN + 65884, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3 = SPR_CSG_BEGIN + 65885, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3 = SPR_CSG_BEGIN + 65886, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3 = SPR_CSG_BEGIN + 65887, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0 = SPR_CSG_BEGIN + 65888, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0 = SPR_CSG_BEGIN + 65889, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0 = SPR_CSG_BEGIN + 65890, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1 = SPR_CSG_BEGIN + 65891, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1 = SPR_CSG_BEGIN + 65892, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1 = SPR_CSG_BEGIN + 65893, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2 = SPR_CSG_BEGIN + 65894, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2 = SPR_CSG_BEGIN + 65895, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2 = SPR_CSG_BEGIN + 65896, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3 = SPR_CSG_BEGIN + 65897, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3 = SPR_CSG_BEGIN + 65898, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3 = SPR_CSG_BEGIN + 65899, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1 = SPR_CSG_BEGIN + 65900, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1 = SPR_CSG_BEGIN + 65901, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1 = SPR_CSG_BEGIN + 65902, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_0 = SPR_CSG_BEGIN + 65955, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_0 = SPR_CSG_BEGIN + 65956, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_1 = SPR_CSG_BEGIN + 65957, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_1 = SPR_CSG_BEGIN + 65958, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_2 = SPR_CSG_BEGIN + 65959, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_2 = SPR_CSG_BEGIN + 65960, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3 = SPR_CSG_BEGIN + 65961, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3 = SPR_CSG_BEGIN + 65962, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_3 = SPR_CSG_BEGIN + 65963, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_3 = SPR_CSG_BEGIN + 65964, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_0 = SPR_CSG_BEGIN + 65965, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_0 = SPR_CSG_BEGIN + 65966, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_1 = SPR_CSG_BEGIN + 65967, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_1 = SPR_CSG_BEGIN + 65968, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_2 = SPR_CSG_BEGIN + 65969, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_2 = SPR_CSG_BEGIN + 65970, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0 = SPR_CSG_BEGIN + 65971, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0 = SPR_CSG_BEGIN + 65972, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65973, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2 = SPR_CSG_BEGIN + 65974, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65975, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_3 = SPR_CSG_BEGIN + 65976, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_3 = SPR_CSG_BEGIN + 65977, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65978, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65979, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65980, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 66055, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 66056, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 66057, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 66058, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66059, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66060, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 66061, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 66062, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 66063, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 66064, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66065, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66066, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 66067, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 66068, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 66069, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 66070, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66071, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66072, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 66073, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 66074, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 66075, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 66076, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66077, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66078, - - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0 = SPR_CSG_BEGIN + 66079, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1 = SPR_CSG_BEGIN + 66080, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2 = SPR_CSG_BEGIN + 66081, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3 = SPR_CSG_BEGIN + 66082, - - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0 = SPR_CSG_BEGIN + 66083, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2 = SPR_CSG_BEGIN + 66084, - - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0 = SPR_CSG_BEGIN + 66085, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1 = SPR_CSG_BEGIN + 66086, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2 = SPR_CSG_BEGIN + 66087, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3 = SPR_CSG_BEGIN + 66088, - - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0 = SPR_CSG_BEGIN + 66089, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2 = SPR_CSG_BEGIN + 66090, - - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 66139, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 66140, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 66141, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 66142, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 66143, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 66144, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 66145, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 66146, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 66147, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 66148, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 66149, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 66150, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 66151, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 66152, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 66153, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 66154, - - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0 = SPR_CSG_BEGIN + 66155, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0 = SPR_CSG_BEGIN + 66156, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0 = SPR_CSG_BEGIN + 66157, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0 = SPR_CSG_BEGIN + 66158, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2 = SPR_CSG_BEGIN + 66159, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2 = SPR_CSG_BEGIN + 66160, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2 = SPR_CSG_BEGIN + 66161, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2 = SPR_CSG_BEGIN + 66162, - - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 66163, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 66164, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 66165, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 66166, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 66167, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 66168, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 66169, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 66170, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 66171, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 66172, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 66173, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 66174, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 66175, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 66176, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 66177, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 66178, - - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1 = SPR_CSG_BEGIN + 66179, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1 = SPR_CSG_BEGIN + 66180, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1 = SPR_CSG_BEGIN + 66181, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1 = SPR_CSG_BEGIN + 66182, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3 = SPR_CSG_BEGIN + 66183, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3 = SPR_CSG_BEGIN + 66184, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3 = SPR_CSG_BEGIN + 66185, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3 = SPR_CSG_BEGIN + 66186, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66206, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66207, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66208, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66209, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66210, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66211, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66212, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66213, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66214, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66215, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66216, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66217, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66218, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66219, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66220, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66221, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66222, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_0 = SPR_CSG_BEGIN + 66223, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_1 = SPR_CSG_BEGIN + 66224, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_2 = SPR_CSG_BEGIN + 66225, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_3 = SPR_CSG_BEGIN + 66226, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_0 = SPR_CSG_BEGIN + 66227, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_1 = SPR_CSG_BEGIN + 66228, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_2 = SPR_CSG_BEGIN + 66229, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_3 = SPR_CSG_BEGIN + 66230, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66231, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3 = SPR_CSG_BEGIN + 66232, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66233, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66234, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66235, - - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66236, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66237, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66238, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66239, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66240, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66241, - - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66242, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66341, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66342, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66343, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66344, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66345, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66346, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66347, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66348, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66349, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66350, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66351, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66352, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66353, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66354, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66355, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66356, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66357, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66358, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66359, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66360, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66361, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66362, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66363, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66364, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66365, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66366, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66367, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66368, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66369, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66370, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66371, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66372, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66373, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66374, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66375, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66376, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66377, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66378, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66379, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66380, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66381, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66382, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66383, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66384, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66385, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66386, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66387, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66388, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66389, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66390, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66391, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66392, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66393, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66394, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66395, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66396, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66397, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66398, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66399, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66400, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66401, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66402, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66403, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66404, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66405, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66406, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66407, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66408, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66409, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66410, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66411, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66412, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66413, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66414, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66415, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66416, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66417, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66418, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66419, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66420, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66421, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66422, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66423, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66424, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66425, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66426, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66427, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66428, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66429, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66430, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66605, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66606, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66607, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66608, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66609, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66610, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66611, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66612, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66613, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66614, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66615, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66616, - - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66617, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66618, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66619, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66620, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66621, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66622, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66623, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66624, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66625, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66626, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66627, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66628, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66629, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66630, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66631, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66632, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66633, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66634, - - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66635, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66636, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66637, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66638, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66639, - SPR_CLASSIC_WOODEN_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66640, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66641, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66642, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66643, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66644, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66645, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66646, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66647, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66648, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66649, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66650, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66651, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66652, - - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66653, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66654, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66655, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66656, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66657, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66658, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66711, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66712, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66713, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66714, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66715, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66716, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66717, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66718, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66719, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66720, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66721, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66722, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66723, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66724, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66725, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66726, - - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66727, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66728, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66729, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66730, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66731, - - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66732, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66733, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66734, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66735, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66736, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66811, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66812, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66813, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66814, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66815, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66816, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66817, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66818, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66819, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66820, - - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66821, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66822, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66823, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66824, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66825, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66826, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66827, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66828, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66829, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66830, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66831, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66832, - - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66833, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66834, - - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0 = SPR_CSG_BEGIN + 66835, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1 = SPR_CSG_BEGIN + 66836, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2 = SPR_CSG_BEGIN + 66837, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3 = SPR_CSG_BEGIN + 66838, - - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66839, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66840, - - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0 = SPR_CSG_BEGIN + 66841, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1 = SPR_CSG_BEGIN + 66842, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2 = SPR_CSG_BEGIN + 66843, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3 = SPR_CSG_BEGIN + 66844, - - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66845, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66846, - - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66895, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66896, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66897, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66898, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66899, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66900, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66901, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66902, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66903, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66904, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66905, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66906, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66907, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66908, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66909, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66910, - - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66911, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66912, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66913, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66914, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66915, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66916, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66917, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66918, - - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66919, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66920, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66921, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66922, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66923, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66924, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66925, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66926, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66927, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66928, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66929, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66930, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66931, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66932, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66933, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66934, - - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66935, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66936, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66937, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66938, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66939, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66940, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66941, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66942, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65447, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65448, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 65449, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 65450, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 65451, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 65452, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65453, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65454, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_0 = SPR_CSG_BEGIN + 65455, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_1 = SPR_CSG_BEGIN + 65456, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_2 = SPR_CSG_BEGIN + 65457, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_3 = SPR_CSG_BEGIN + 65458, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65459, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65460, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 65461, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 65462, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 65463, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 65464, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65465, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65466, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_0 = SPR_CSG_BEGIN + 65467, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_1 = SPR_CSG_BEGIN + 65468, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_2 = SPR_CSG_BEGIN + 65469, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_3 = SPR_CSG_BEGIN + 65470, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_0 = SPR_CSG_BEGIN + 65471, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_1 = SPR_CSG_BEGIN + 65472, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_2 = SPR_CSG_BEGIN + 65473, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_3 = SPR_CSG_BEGIN + 65474, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65475, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_3 = SPR_CSG_BEGIN + 65476, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65477, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65478, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65479, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_1 = SPR_CSG_BEGIN + 65480, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65481, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65482, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65483, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_1 = SPR_CSG_BEGIN + 65484, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_2 = SPR_CSG_BEGIN + 65485, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65486, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_0 = SPR_CSG_BEGIN + 65585, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_0 = SPR_CSG_BEGIN + 65586, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_0 = SPR_CSG_BEGIN + 65587, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_0 = SPR_CSG_BEGIN + 65588, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_0 = SPR_CSG_BEGIN + 65589, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_1 = SPR_CSG_BEGIN + 65590, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_1 = SPR_CSG_BEGIN + 65591, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_1 = SPR_CSG_BEGIN + 65592, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_1 = SPR_CSG_BEGIN + 65593, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_1 = SPR_CSG_BEGIN + 65594, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_2 = SPR_CSG_BEGIN + 65595, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_2 = SPR_CSG_BEGIN + 65596, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_2 = SPR_CSG_BEGIN + 65597, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_2 = SPR_CSG_BEGIN + 65598, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_2 = SPR_CSG_BEGIN + 65599, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_3 = SPR_CSG_BEGIN + 65600, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_3 = SPR_CSG_BEGIN + 65601, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_3 = SPR_CSG_BEGIN + 65602, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_3 = SPR_CSG_BEGIN + 65603, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_3 = SPR_CSG_BEGIN + 65604, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_0_0 = SPR_CSG_BEGIN + 65605, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_1_0 = SPR_CSG_BEGIN + 65606, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_2_0 = SPR_CSG_BEGIN + 65607, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_3_0 = SPR_CSG_BEGIN + 65608, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_4_0 = SPR_CSG_BEGIN + 65609, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_0_2 = SPR_CSG_BEGIN + 65610, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_1_2 = SPR_CSG_BEGIN + 65611, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_2_2 = SPR_CSG_BEGIN + 65612, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_3_2 = SPR_CSG_BEGIN + 65613, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_4_2 = SPR_CSG_BEGIN + 65614, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_0 = SPR_CSG_BEGIN + 65615, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_0 = SPR_CSG_BEGIN + 65616, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_0 = SPR_CSG_BEGIN + 65617, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_0 = SPR_CSG_BEGIN + 65618, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_0 = SPR_CSG_BEGIN + 65619, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_1 = SPR_CSG_BEGIN + 65620, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_1 = SPR_CSG_BEGIN + 65621, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_1 = SPR_CSG_BEGIN + 65622, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_1 = SPR_CSG_BEGIN + 65623, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_1 = SPR_CSG_BEGIN + 65624, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_2 = SPR_CSG_BEGIN + 65625, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_2 = SPR_CSG_BEGIN + 65626, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_2 = SPR_CSG_BEGIN + 65627, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_2 = SPR_CSG_BEGIN + 65628, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_2 = SPR_CSG_BEGIN + 65629, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_0_3 = SPR_CSG_BEGIN + 65630, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_1_3 = SPR_CSG_BEGIN + 65631, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_2_3 = SPR_CSG_BEGIN + 65632, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_3_3 = SPR_CSG_BEGIN + 65633, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_4_3 = SPR_CSG_BEGIN + 65634, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_0 = SPR_CSG_BEGIN + 65635, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_0 = SPR_CSG_BEGIN + 65636, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_0 = SPR_CSG_BEGIN + 65637, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_0 = SPR_CSG_BEGIN + 65638, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_0 = SPR_CSG_BEGIN + 65639, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_2 = SPR_CSG_BEGIN + 65640, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65641, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_2 = SPR_CSG_BEGIN + 65642, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_2 = SPR_CSG_BEGIN + 65643, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_2 = SPR_CSG_BEGIN + 65644, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3 = SPR_CSG_BEGIN + 65645, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3 = SPR_CSG_BEGIN + 65646, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3 = SPR_CSG_BEGIN + 65647, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3 = SPR_CSG_BEGIN + 65648, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3 = SPR_CSG_BEGIN + 65649, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0 = SPR_CSG_BEGIN + 65650, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0 = SPR_CSG_BEGIN + 65651, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0 = SPR_CSG_BEGIN + 65652, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0 = SPR_CSG_BEGIN + 65653, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0 = SPR_CSG_BEGIN + 65654, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1 = SPR_CSG_BEGIN + 65655, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1 = SPR_CSG_BEGIN + 65656, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1 = SPR_CSG_BEGIN + 65657, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1 = SPR_CSG_BEGIN + 65658, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1 = SPR_CSG_BEGIN + 65659, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2 = SPR_CSG_BEGIN + 65660, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2 = SPR_CSG_BEGIN + 65661, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2 = SPR_CSG_BEGIN + 65662, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2 = SPR_CSG_BEGIN + 65663, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2 = SPR_CSG_BEGIN + 65664, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3 = SPR_CSG_BEGIN + 65665, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3 = SPR_CSG_BEGIN + 65666, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3 = SPR_CSG_BEGIN + 65667, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3 = SPR_CSG_BEGIN + 65668, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3 = SPR_CSG_BEGIN + 65669, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1 = SPR_CSG_BEGIN + 65670, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1 = SPR_CSG_BEGIN + 65671, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1 = SPR_CSG_BEGIN + 65672, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65673, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65674, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_3 = SPR_CSG_BEGIN + 65849, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_3 = SPR_CSG_BEGIN + 65850, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_3 = SPR_CSG_BEGIN + 65851, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_0 = SPR_CSG_BEGIN + 65852, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_0 = SPR_CSG_BEGIN + 65853, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_0 = SPR_CSG_BEGIN + 65854, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_1 = SPR_CSG_BEGIN + 65855, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_1 = SPR_CSG_BEGIN + 65856, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_1 = SPR_CSG_BEGIN + 65857, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_2 = SPR_CSG_BEGIN + 65858, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_2 = SPR_CSG_BEGIN + 65859, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_2 = SPR_CSG_BEGIN + 65860, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_2_3 = SPR_CSG_BEGIN + 65861, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_1_3 = SPR_CSG_BEGIN + 65862, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_0_3 = SPR_CSG_BEGIN + 65863, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_2_1 = SPR_CSG_BEGIN + 65864, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_1_1 = SPR_CSG_BEGIN + 65865, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_0_1 = SPR_CSG_BEGIN + 65866, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_0 = SPR_CSG_BEGIN + 65867, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_0 = SPR_CSG_BEGIN + 65868, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_0 = SPR_CSG_BEGIN + 65869, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_1 = SPR_CSG_BEGIN + 65870, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_1 = SPR_CSG_BEGIN + 65871, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_1 = SPR_CSG_BEGIN + 65872, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_2 = SPR_CSG_BEGIN + 65873, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_2 = SPR_CSG_BEGIN + 65874, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_2 = SPR_CSG_BEGIN + 65875, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_0_3 = SPR_CSG_BEGIN + 65876, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_1_3 = SPR_CSG_BEGIN + 65877, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_2_3 = SPR_CSG_BEGIN + 65878, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_0 = SPR_CSG_BEGIN + 65879, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_0 = SPR_CSG_BEGIN + 65880, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_0 = SPR_CSG_BEGIN + 65881, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_2 = SPR_CSG_BEGIN + 65882, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_2 = SPR_CSG_BEGIN + 65883, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_2 = SPR_CSG_BEGIN + 65884, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3 = SPR_CSG_BEGIN + 65885, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3 = SPR_CSG_BEGIN + 65886, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3 = SPR_CSG_BEGIN + 65887, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0 = SPR_CSG_BEGIN + 65888, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0 = SPR_CSG_BEGIN + 65889, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0 = SPR_CSG_BEGIN + 65890, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1 = SPR_CSG_BEGIN + 65891, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1 = SPR_CSG_BEGIN + 65892, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1 = SPR_CSG_BEGIN + 65893, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2 = SPR_CSG_BEGIN + 65894, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2 = SPR_CSG_BEGIN + 65895, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2 = SPR_CSG_BEGIN + 65896, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3 = SPR_CSG_BEGIN + 65897, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3 = SPR_CSG_BEGIN + 65898, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3 = SPR_CSG_BEGIN + 65899, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1 = SPR_CSG_BEGIN + 65900, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1 = SPR_CSG_BEGIN + 65901, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1 = SPR_CSG_BEGIN + 65902, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_0 = SPR_CSG_BEGIN + 65955, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_0 = SPR_CSG_BEGIN + 65956, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_1 = SPR_CSG_BEGIN + 65957, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_1 = SPR_CSG_BEGIN + 65958, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_2 = SPR_CSG_BEGIN + 65959, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_2 = SPR_CSG_BEGIN + 65960, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_0_3 = SPR_CSG_BEGIN + 65961, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_1_3 = SPR_CSG_BEGIN + 65962, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_3 = SPR_CSG_BEGIN + 65963, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_3 = SPR_CSG_BEGIN + 65964, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_0 = SPR_CSG_BEGIN + 65965, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_0 = SPR_CSG_BEGIN + 65966, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_1 = SPR_CSG_BEGIN + 65967, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_1 = SPR_CSG_BEGIN + 65968, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_1_2 = SPR_CSG_BEGIN + 65969, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_0_2 = SPR_CSG_BEGIN + 65970, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_0 = SPR_CSG_BEGIN + 65971, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_0 = SPR_CSG_BEGIN + 65972, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65973, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_2 = SPR_CSG_BEGIN + 65974, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65975, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_3 = SPR_CSG_BEGIN + 65976, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_3 = SPR_CSG_BEGIN + 65977, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_1 = SPR_CSG_BEGIN + 65978, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65979, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65980, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 66055, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 66056, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 66057, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 66058, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66059, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66060, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 66061, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 66062, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 66063, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 66064, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66065, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66066, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 66067, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 66068, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 66069, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 66070, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66071, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66072, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 66073, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 66074, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 66075, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 66076, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66077, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66078, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0 = SPR_CSG_BEGIN + 66079, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1 = SPR_CSG_BEGIN + 66080, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2 = SPR_CSG_BEGIN + 66081, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3 = SPR_CSG_BEGIN + 66082, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0 = SPR_CSG_BEGIN + 66083, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2 = SPR_CSG_BEGIN + 66084, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0 = SPR_CSG_BEGIN + 66085, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1 = SPR_CSG_BEGIN + 66086, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2 = SPR_CSG_BEGIN + 66087, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3 = SPR_CSG_BEGIN + 66088, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0 = SPR_CSG_BEGIN + 66089, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2 = SPR_CSG_BEGIN + 66090, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 66139, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 66140, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 66141, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 66142, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 66143, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 66144, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 66145, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 66146, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 66147, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 66148, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 66149, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 66150, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 66151, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 66152, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 66153, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 66154, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0 = SPR_CSG_BEGIN + 66155, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0 = SPR_CSG_BEGIN + 66156, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0 = SPR_CSG_BEGIN + 66157, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0 = SPR_CSG_BEGIN + 66158, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2 = SPR_CSG_BEGIN + 66159, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2 = SPR_CSG_BEGIN + 66160, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2 = SPR_CSG_BEGIN + 66161, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2 = SPR_CSG_BEGIN + 66162, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 66163, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 66164, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 66165, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 66166, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 66167, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 66168, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 66169, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 66170, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 66171, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 66172, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 66173, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 66174, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 66175, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 66176, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 66177, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 66178, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1 = SPR_CSG_BEGIN + 66179, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1 = SPR_CSG_BEGIN + 66180, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1 = SPR_CSG_BEGIN + 66181, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1 = SPR_CSG_BEGIN + 66182, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3 = SPR_CSG_BEGIN + 66183, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3 = SPR_CSG_BEGIN + 66184, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3 = SPR_CSG_BEGIN + 66185, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3 = SPR_CSG_BEGIN + 66186, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66203, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66204, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66205, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66206, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66207, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66208, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66209, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66210, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66211, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66212, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66213, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66214, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66215, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66216, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66217, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66218, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66219, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66220, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66221, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66222, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_0 = SPR_CSG_BEGIN + 66223, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_1 = SPR_CSG_BEGIN + 66224, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_2 = SPR_CSG_BEGIN + 66225, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_3 = SPR_CSG_BEGIN + 66226, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_0 = SPR_CSG_BEGIN + 66227, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_1 = SPR_CSG_BEGIN + 66228, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_2 = SPR_CSG_BEGIN + 66229, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_3 = SPR_CSG_BEGIN + 66230, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66231, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3 = SPR_CSG_BEGIN + 66232, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66233, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66234, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66235, + + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66236, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66237, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66238, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66239, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_1 = SPR_CSG_BEGIN + 66240, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66241, + + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66242, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66341, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66342, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66343, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66344, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66345, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66346, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66347, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66348, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66349, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66350, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66351, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66352, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66353, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66354, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66355, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66356, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66357, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66358, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66359, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66360, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66361, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66362, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66363, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66364, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66365, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66366, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66367, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66368, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66369, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66370, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66371, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66372, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66373, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66374, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66375, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66376, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66377, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66378, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66379, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66380, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66381, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66382, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66383, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66384, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66385, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66386, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66387, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66388, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66389, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66390, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66391, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66392, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66393, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66394, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66395, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66396, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66397, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66398, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66399, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66400, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66401, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66402, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66403, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66404, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66405, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0 = SPR_CSG_BEGIN + 66406, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66407, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66408, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66409, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66410, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66411, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66412, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66413, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66414, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66415, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2 = SPR_CSG_BEGIN + 66416, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66417, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66418, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66419, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66420, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3 = SPR_CSG_BEGIN + 66421, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66422, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66423, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66424, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66425, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1 = SPR_CSG_BEGIN + 66426, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66427, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66428, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66429, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66430, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66605, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66606, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66607, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66608, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66609, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66610, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66611, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66612, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66613, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66614, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66615, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66616, + + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66617, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66618, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66619, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66620, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66621, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66622, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66623, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66624, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66625, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66626, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66627, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66628, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66629, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66630, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66631, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66632, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66633, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66634, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66635, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66636, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66637, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66638, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66639, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66640, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66641, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66642, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66643, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66644, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66645, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66646, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66647, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66648, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66649, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66650, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66651, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66652, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66653, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66654, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66655, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66656, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66657, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66658, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66711, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66712, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66713, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66714, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66715, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66716, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66717, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66718, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66719, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66720, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66721, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66722, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66723, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66724, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66725, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66726, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66727, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66728, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66729, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66730, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66731, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66732, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66733, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66734, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66735, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66736, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66811, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66812, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66813, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66814, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66815, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66816, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66817, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66818, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66819, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66820, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66821, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66822, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66823, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66824, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66825, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66826, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66827, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66828, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66829, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66830, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66831, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66832, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66833, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66834, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0 = SPR_CSG_BEGIN + 66835, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1 = SPR_CSG_BEGIN + 66836, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2 = SPR_CSG_BEGIN + 66837, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3 = SPR_CSG_BEGIN + 66838, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66839, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66840, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0 = SPR_CSG_BEGIN + 66841, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1 = SPR_CSG_BEGIN + 66842, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2 = SPR_CSG_BEGIN + 66843, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3 = SPR_CSG_BEGIN + 66844, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66845, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66846, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66895, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66896, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66897, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66898, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66899, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66900, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66901, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66902, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66903, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66904, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66905, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66906, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66907, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66908, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66909, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66910, + + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66911, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66912, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66913, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66914, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66915, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66916, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66917, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66918, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0 = SPR_CSG_BEGIN + 66919, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0 = SPR_CSG_BEGIN + 66920, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0 = SPR_CSG_BEGIN + 66921, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0 = SPR_CSG_BEGIN + 66922, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66923, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66924, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66925, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66926, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2 = SPR_CSG_BEGIN + 66927, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66928, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2 = SPR_CSG_BEGIN + 66929, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2 = SPR_CSG_BEGIN + 66930, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66931, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66932, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66933, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66934, + + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66935, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1 = SPR_CSG_BEGIN + 66936, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1 = SPR_CSG_BEGIN + 66937, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1 = SPR_CSG_BEGIN + 66938, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3 = SPR_CSG_BEGIN + 66939, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3 = SPR_CSG_BEGIN + 66940, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3 = SPR_CSG_BEGIN + 66941, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3 = SPR_CSG_BEGIN + 66942, }; static constexpr std::array kFlatToLeftBankImages = { { { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_0, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_1, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_1, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_2, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_3, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_HANDRAIL_3, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_3, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_3, }, } }; static constexpr std::array kFlatToRightBankImages = { { { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_0, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_0, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_1, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_2, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_2, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_3, - SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_FLAT_TO_RIGHT_BANK_HANDRAIL_3, }, } }; static constexpr std::array kLeftBankImages = { { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_0, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_0 }, - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_1, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_1 }, - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_2, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_2 }, - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_3, SPR_CLASSIC_WOODEN_RC_LEFT_BANK_HANDRAIL_3 }, + { SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_0, SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_0 }, + { SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_1, SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_1 }, + { SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_2, SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_2 }, + { SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_3, SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_HANDRAIL_3 }, } }; static constexpr std::array kUp25ToLeftBankImages = { { { - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_0, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_1, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_1, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_1, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_2, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_2, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_3, - SPR_CLASSIC_WOODEN_RC_UP25_TO_LEFT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_LEFT_BANK_HANDRAIL_3, }, } }; static constexpr std::array kUp25ToRightBankImages = { { { - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_0, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_1, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_1, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_1, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_2, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_2, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_3, - SPR_CLASSIC_WOODEN_RC_UP25_TO_RIGHT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_UP25_TO_RIGHT_BANK_HANDRAIL_3, }, } }; static constexpr std::array kLeftBankToUp25Images = { { { - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_0, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_1, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_1, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_1, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_2, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_2, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_3, - SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_UP25_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_UP25_HANDRAIL_3, }, } }; static constexpr std::array kRightBankToUp25Images = { { { - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_1, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_1, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_1, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_3, - SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_UP25_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_BANK_TO_UP25_HANDRAIL_3, }, } }; static constexpr std::array, 3> kBankedQuarterTurn3Images = { { { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_0_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_0_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_0_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_1_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_1_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_1_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_2_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_2_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_3_FRONT_HANDRAIL_2_3, }, } }, } }; @@ -918,112 +918,112 @@ static constexpr std::array, 5> kBankedQuarterTurn5Images = { { { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_0_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_0_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_0_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_0_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_1_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_1_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_1_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_1_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_2_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_2_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_2_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_2_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_3_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_3_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_3_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_3_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_0, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_4_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_0, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_1, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_1, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_4_2, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_4_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_FRONT_HANDRAIL_4_2, }, { - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_4_3, - SPR_CLASSIC_WOODEN_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_4_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_BANKED_QUARTER_TURN_5_HANDRAIL_4_3, }, } }, } }; @@ -1031,68 +1031,68 @@ static constexpr std::array, 3> kLeftHalfBankedHelixUpSmallImages = { { { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_0_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_1_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_UP_SMALL_FRONT_HANDRAIL_2_3, }, } }, } }; @@ -1101,68 +1101,68 @@ static constexpr std::array, 5> kLeftHalfBankedHelixUpLargeImages = { { { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_0_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_1_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_2_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_3_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, - SPR_CLASSIC_WOODEN_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_4_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_HANDRAIL_4_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_4_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_HALF_BANKED_HELIX_LARGE_UP_FRONT_HANDRAIL_4_3, }, } }, } }; @@ -1285,112 +1285,112 @@ static constexpr std::array kDiagFlatToLeftBankImages = { { { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_3, }, } }; static constexpr std::array kDiagFlatToRightBankImages = { { { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_RIGHT_BANK_HANDRAIL_3, }, } }; static constexpr std::array kDiagLeftBankTo25DegUpImages = { { { - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3, - SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_TO_25_DEG_UP_HANDRAIL_3, }, } }; static constexpr std::array kDiagRightBankTo25DegUpImages = { { { - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3, - SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_RIGHT_BANK_TO_25_DEG_UP_HANDRAIL_3, }, } }; static constexpr std::array kDiagUp25ToLeftBankImages = { { { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_0, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_1, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_2, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_3, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_LEFT_BANK_HANDRAIL_3, }, } }; static constexpr std::array kDiagUp25ToRightBankImages = { { { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_0, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_0, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_1, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_1, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_2, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_FRONT_HANDRAIL_2, }, { - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_3, - SPR_CLASSIC_WOODEN_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_HANDRAIL_3, }, } }; static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { { { { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_1, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, }, { - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3, - SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_3, }, } }, } }; @@ -1728,90 +1728,90 @@ static constexpr std::array, 4> kRightEighthBankToDiagImages = { { { { { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_0, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_1, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_0_2, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_0_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_0, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_1, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_1_2, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_1_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_0, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_1, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_2_2, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_2_3, }, } }, { { { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_0, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_1, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_HANDRAIL_3_2, }, { - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3, - SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_RIGHT_EIGHTH_BANK_TO_DIAG_HANDRAIL_3_3, }, } }, } }; From 273fa9a4795750ab3e91ee723d8dd56360cab45b Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 15 Nov 2024 05:22:09 +0000 Subject: [PATCH 074/139] Implement Classic Wooden Twister diagonal bank --- .../ClassicWoodenTwisterRollerCoaster.cpp | 53 +++++++++++++++ .../track/coaster/WoodenRollerCoaster.hpp | 68 +++++++++++++++++++ 2 files changed, 121 insertions(+) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp index 752740fa93..4e79ec7c67 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenTwisterRollerCoaster.cpp @@ -260,6 +260,14 @@ enum SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_0_1 = SPR_CSG_BEGIN + 65979, SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_1_2 = SPR_CSG_BEGIN + 65980, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_0 = SPR_CSG_BEGIN + 66049, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_1 = SPR_CSG_BEGIN + 66050, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_2 = SPR_CSG_BEGIN + 66051, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_3 = SPR_CSG_BEGIN + 66052, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 66053, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 66054, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 66055, SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 66056, SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 66057, @@ -600,6 +608,14 @@ enum SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_0_1 = SPR_CSG_BEGIN + 66735, SPR_CLASSIC_WOODEN_TWISTER_RC_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_25_DEG_UP_FRONT_HANDRAIL_1_2 = SPR_CSG_BEGIN + 66736, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66805, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66806, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66807, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_3 = SPR_CSG_BEGIN + 66808, + + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_HANDRAIL_0 = SPR_CSG_BEGIN + 66809, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_HANDRAIL_2 = SPR_CSG_BEGIN + 66810, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_0 = SPR_CSG_BEGIN + 66811, SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_1 = SPR_CSG_BEGIN + 66812, SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_FLAT_TO_LEFT_BANK_HANDRAIL_2 = SPR_CSG_BEGIN + 66813, @@ -1611,6 +1627,29 @@ static constexpr std::array kDiagU }, } }; +static constexpr std::array kDiagLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_0, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_HANDRAIL_0, + }, + { + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_1, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_1, + }, + { + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_2, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_FRONT_HANDRAIL_2, + }, + { + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_3, + SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_LEFT_BANK_HANDRAIL_3, + }, +} }; + static constexpr std::array kDiagUp25ToRightBankImages = { { { SPR_CLASSIC_WOODEN_TWISTER_RC_DIAG_UP_25_TO_RIGHT_BANK_0, @@ -2017,6 +2056,15 @@ static void ClassicWoodenTwisterRCTrackDiagRightBankToDown25( session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } +static void ClassicWoodenTwisterRCTrackDiagRightBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagLeftBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + static void ClassicWoodenTwisterRCTrackLeftEighthBankToOrthogonal( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) @@ -2140,6 +2188,11 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenTwisterRC(OpenRCT2::Track case TrackElemType::DiagRightBankToDown25: return ClassicWoodenTwisterRCTrackDiagRightBankToDown25; + case TrackElemType::DiagLeftBank: + return WoodenRCTrackDiagLeftBank; + case TrackElemType::DiagRightBank: + return ClassicWoodenTwisterRCTrackDiagRightBank; + case TrackElemType::LeftEighthBankToDiag: return WoodenRCTrackLeftEighthBankToDiag; case TrackElemType::RightEighthBankToDiag: diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index 895d548bbb..f6fa9b2cd7 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -3156,6 +3156,74 @@ static void WoodenRCTrackDiagUp25ToBank( PaintUtilSetGeneralSupportHeight(session, height + 56); } +/** rct2: 0x008AC9D8 */ +template imageIds> +static void WoodenRCTrackDiagLeftBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } }); + } + break; + } + break; + case 2: + switch (direction) + { + case 2: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + if (imageIds[direction].frontTrack != ImageIndexUndefined) + { + WoodenRCTrackPaint( + session, direction, imageIds[direction].frontTrack, imageIds[direction].frontHandrail, + { -16, -16, height }, { { -16, -16, height + 27 }, { 32, 32, 0 } }); + } + break; + } + break; + case 3: + switch (direction) + { + case 1: + WoodenRCTrackPaint( + session, direction, imageIds[direction].track, imageIds[direction].handrail, { -16, -16, height }, + { { -16, -16, height }, { 32, 32, 2 } }); + break; + } + break; + } + + DrawSupportForSequenceA( + session, supportType.wooden, trackSequence, direction, height, session.SupportColours); + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +} + /** rct2: 0x008AC998 */ template, 4> imageIds> static void WoodenRCTrackLeftEighthBankToDiag( From 836786a70729dbfea950cb60a91583d9b7dbba43 Mon Sep 17 00:00:00 2001 From: mix Date: Fri, 15 Nov 2024 05:41:14 +0000 Subject: [PATCH 075/139] Convert Classic Wooden RC track to shared track paint functions --- .../coaster/ClassicWoodenRollerCoaster.cpp | 2074 +++++------------ .../track/coaster/WoodenRollerCoaster.hpp | 19 +- 2 files changed, 570 insertions(+), 1523 deletions(-) diff --git a/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp b/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp index 98dd180af4..024eb5261f 100644 --- a/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/ClassicWoodenRollerCoaster.cpp @@ -26,8 +26,6 @@ using namespace OpenRCT2; -// static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; - enum { SPR_CLASSIC_WOODEN_RC_BRAKE_0 = SPR_CSG_BEGIN + 64985, @@ -137,19 +135,19 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65313, SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65314, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_0 = SPR_CSG_BEGIN + 65315, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_1 = SPR_CSG_BEGIN + 65316, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_2 = SPR_CSG_BEGIN + 65317, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_3 = SPR_CSG_BEGIN + 65318, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_FRONT_0 = SPR_CSG_BEGIN + 65319, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_FRONT_2 = SPR_CSG_BEGIN + 65320, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65315, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65316, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2 = SPR_CSG_BEGIN + 65317, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3 = SPR_CSG_BEGIN + 65318, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65319, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65320, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_0 = SPR_CSG_BEGIN + 65321, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_1 = SPR_CSG_BEGIN + 65322, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_2 = SPR_CSG_BEGIN + 65323, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_3 = SPR_CSG_BEGIN + 65324, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_FRONT_0 = SPR_CSG_BEGIN + 65325, - SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_FRONT_2 = SPR_CSG_BEGIN + 65326, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0 = SPR_CSG_BEGIN + 65321, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1 = SPR_CSG_BEGIN + 65322, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2 = SPR_CSG_BEGIN + 65323, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3 = SPR_CSG_BEGIN + 65324, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0 = SPR_CSG_BEGIN + 65325, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2 = SPR_CSG_BEGIN + 65326, SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_0 = SPR_CSG_BEGIN + 65327, SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_1 = SPR_CSG_BEGIN + 65328, @@ -179,378 +177,511 @@ enum SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_FRONT_0 = SPR_CSG_BEGIN + 65349, SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_FRONT_2 = SPR_CSG_BEGIN + 65350, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_0 = SPR_CSG_BEGIN + 65399, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_1 = SPR_CSG_BEGIN + 65400, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_2 = SPR_CSG_BEGIN + 65401, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_4 = SPR_CSG_BEGIN + 65402, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_0 = SPR_CSG_BEGIN + 65415, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_1 = SPR_CSG_BEGIN + 65416, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_2 = SPR_CSG_BEGIN + 65417, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_4 = SPR_CSG_BEGIN + 65418, - - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_0 = SPR_CSG_BEGIN + 65403, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_1 = SPR_CSG_BEGIN + 65404, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_2 = SPR_CSG_BEGIN + 65405, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_4 = SPR_CSG_BEGIN + 65406, - - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_0 = SPR_CSG_BEGIN + 65407, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_1 = SPR_CSG_BEGIN + 65408, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_2 = SPR_CSG_BEGIN + 65409, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_4 = SPR_CSG_BEGIN + 65410, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_0 = SPR_CSG_BEGIN + 65419, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_1 = SPR_CSG_BEGIN + 65420, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_2 = SPR_CSG_BEGIN + 65421, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_4 = SPR_CSG_BEGIN + 65422, - - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_0 = SPR_CSG_BEGIN + 65411, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_1 = SPR_CSG_BEGIN + 65412, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_2 = SPR_CSG_BEGIN + 65413, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_4 = SPR_CSG_BEGIN + 65414, - - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_0 = SPR_CSG_BEGIN + 65399 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_1 = SPR_CSG_BEGIN + 65400 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_2 = SPR_CSG_BEGIN + 65401 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_4 = SPR_CSG_BEGIN + 65402 + 24, - - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_0 = SPR_CSG_BEGIN + 65403 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_1 = SPR_CSG_BEGIN + 65404 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_2 = SPR_CSG_BEGIN + 65405 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_4 = SPR_CSG_BEGIN + 65406 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_0 = SPR_CSG_BEGIN + 65439, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_1 = SPR_CSG_BEGIN + 65440, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_2 = SPR_CSG_BEGIN + 65441, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_4 = SPR_CSG_BEGIN + 65442, - - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_0 = SPR_CSG_BEGIN + 65407 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_1 = SPR_CSG_BEGIN + 65408 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_2 = SPR_CSG_BEGIN + 65409 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_4 = SPR_CSG_BEGIN + 65410 + 24, - - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_0 = SPR_CSG_BEGIN + 65411 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_1 = SPR_CSG_BEGIN + 65412 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_2 = SPR_CSG_BEGIN + 65413 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_4 = SPR_CSG_BEGIN + 65414 + 24, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_0 = SPR_CSG_BEGIN + 65443, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_1 = SPR_CSG_BEGIN + 65444, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_2 = SPR_CSG_BEGIN + 65445, - SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_4 = SPR_CSG_BEGIN + 65446, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 65399, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 65400, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 65401, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 65402, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 65403, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 65404, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 65405, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 65406, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 65407, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 65408, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 65409, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 65410, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 65411, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 65412, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 65413, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 65414, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0 = SPR_CSG_BEGIN + 65415, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0 = SPR_CSG_BEGIN + 65416, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0 = SPR_CSG_BEGIN + 65417, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0 = SPR_CSG_BEGIN + 65418, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2 = SPR_CSG_BEGIN + 65419, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2 = SPR_CSG_BEGIN + 65420, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2 = SPR_CSG_BEGIN + 65421, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2 = SPR_CSG_BEGIN + 65422, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0 = SPR_CSG_BEGIN + 65423, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0 = SPR_CSG_BEGIN + 65424, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0 = SPR_CSG_BEGIN + 65425, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0 = SPR_CSG_BEGIN + 65426, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1 = SPR_CSG_BEGIN + 65427, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1 = SPR_CSG_BEGIN + 65428, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1 = SPR_CSG_BEGIN + 65429, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1 = SPR_CSG_BEGIN + 65430, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2 = SPR_CSG_BEGIN + 65431, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2 = SPR_CSG_BEGIN + 65432, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2 = SPR_CSG_BEGIN + 65433, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2 = SPR_CSG_BEGIN + 65434, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3 = SPR_CSG_BEGIN + 65435, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3 = SPR_CSG_BEGIN + 65436, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3 = SPR_CSG_BEGIN + 65437, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3 = SPR_CSG_BEGIN + 65438, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1 = SPR_CSG_BEGIN + 65439, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1 = SPR_CSG_BEGIN + 65440, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1 = SPR_CSG_BEGIN + 65441, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1 = SPR_CSG_BEGIN + 65442, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3 = SPR_CSG_BEGIN + 65443, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3 = SPR_CSG_BEGIN + 65444, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3 = SPR_CSG_BEGIN + 65445, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3 = SPR_CSG_BEGIN + 65446, }; -static void ClassicWoodenRCTrackFlatToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) +static constexpr std::array kFlatToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_SW_NE, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_NW_SE, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_NW_SE, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_NE_SW, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_SE_NW, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_SE_NW, + }, +} }; -{ - static constexpr SpriteBoundBox2 imageIds[4][1][2] = { - { { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_SW_NE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 26, 0, 5 }, { 1, 32, 9 }) }, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_LEFT_BANK_FRONT_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 26, 0, 5 }, { 1, 32, 9 }) }, - } } - }; - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} +static constexpr std::array kFlatToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_SW_NE, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_NW_SE, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_NE_SW, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_NE_SW, + }, + { + SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_SE_NW, + }, +} }; -static void ClassicWoodenRCTrackFlatToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][1][2] = { - { { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_SW_NE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - } }, +static constexpr std::array kLeftBankImages = { { + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_SW_NE }, + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_NW_SE }, + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_NE_SW }, + { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_SE_NW }, +} }; - { { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_FRONT_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 26, 5 }, { 32, 1, 9 }) }, - } }, +static constexpr std::array kUp25ToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_SW_NE, + }, + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_NW_SE, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_FRONT_NW_SE, + }, + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_NE_SW, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_FRONT_NE_SW, + }, + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_SE_NW, + }, +} }; + +static constexpr std::array kUp25ToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_SW_NE, + }, + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_NW_SE, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_FRONT_NW_SE, + }, + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_NE_SW, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_FRONT_NE_SW, + }, + { + SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_SE_NW, + }, +} }; + +static constexpr std::array kLeftBankToUp25Images = { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_SW_NE, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_NW_SE, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_FRONT_NW_SE, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_NE_SW, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_FRONT_NE_SW, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_SE_NW, + }, +} }; +static constexpr std::array kRightBankToUp25Images = { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_SW_NE, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_NW_SE, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_FRONT_NW_SE, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_NE_SW, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_FRONT_NE_SW, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_SE_NW, + }, +} }; + +static constexpr std::array kDiagFlatToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_FRONT_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_LEFT_BANK_3, + }, +} }; + +static constexpr std::array kDiagFlatToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_FRONT_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_RIGHT_BANK_3, + }, +} }; + +static constexpr std::array kDiagLeftBankTo25DegUpImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_FRONT_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_FRONT_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_3, + }, +} }; + +static constexpr std::array kDiagRightBankTo25DegUpImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_FRONT_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_FRONT_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_3, + }, +} }; + +static constexpr std::array kDiagUp25ToLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_FRONT_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_FRONT_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_3, + }, +} }; + +static constexpr std::array kDiagLeftBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_FRONT_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_FRONT_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_3, + }, +} }; + +static constexpr std::array kDiagUp25ToRightBankImages = { { + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_FRONT_0, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_1, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_FRONT_2, + }, + { + SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_3, + }, +} }; + +static constexpr std::array, 4> kLeftEighthBankToDiagImages = { { + { { { - { - { SPR_CLASSIC_WOODEN_RC_FLAT_TO_RIGHT_BANK_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - }, - } - }; - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_1, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_0_3, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_1, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_1_3, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_1, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_2_3, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_1, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_3_3, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_LEFT_EIGHTH_BANK_TO_DIAG_FRONT_3_3, + }, + } }, +} }; + +static constexpr std::array, 4> kRightEighthBankToDiagImages = { { + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_0_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_0_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_1_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_1_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_2_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_2_3, + }, + } }, + { { + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_0, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_0, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_1, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_2, + ImageIndexUndefined, + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_FRONT_3_2, + }, + { + SPR_CLASSIC_WOODEN_RC_RIGHT_EIGHTH_BANK_TO_DIAG_3_3, + }, + } }, +} }; static void ClassicWoodenRCTrackLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrackFlatToRightBank(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrackRightBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrackFlatToLeftBank(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][1][2] = { - { { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_SW_NE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - } }, - - { { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { - { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - }, - } - }; - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + WoodenRCTrackFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrackRightBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrackLeftBank(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackLeftBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][1][2] = { - { { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_SW_NE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_FRONT_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 26, 0, 5 }, { 1, 32, 9 }) }, - } }, - - { { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_FRONT_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 26, 5 }, { 32, 1, 9 }) }, - } }, - { - { - { SPR_CLASSIC_WOODEN_RC_LEFT_BANK_TO_25_UP_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - }, - } - }; - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::SlopeEnd); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); -} - -static void ClassicWoodenRCTrackRightBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][1][2] = { - { { - { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_SW_NE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_FRONT_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 26, 0, 5 }, { 1, 32, 9 }) }, - } }, - - { { - { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_FRONT_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 26, 5 }, { 32, 1, 9 }) }, - } }, - { - { - { SPR_CLASSIC_WOODEN_RC_RIGHT_BANK_TO_25_UP_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - }, - } - }; - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::SlopeEnd); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 48); -} - -static void ClassicWoodenRCTrack25DegUpToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][1][2] = { - { { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_SW_NE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_FRONT_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 26, 0, 5 }, { 1, 32, 9 }) }, - } }, - - { { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_FRONT_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 26, 5 }, { 32, 1, 9 }) }, - } }, - { - { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_LEFT_BANK_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - }, - } - }; - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::FlatTo25Deg); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 40); -} - -static void ClassicWoodenRCTrack25DegUpToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][1][2] = { - { { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_SW_NE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - {}, - } }, - { { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_FRONT_NW_SE, 0, { 0, 0, 0 }, BoundBoxXYZ({ 26, 0, 5 }, { 1, 32, 9 }) }, - } }, - - { { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 3, 0 }, { 32, 25, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_FRONT_NE_SW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 0, 26, 5 }, { 32, 1, 9 }) }, - } }, - { - { - { SPR_CLASSIC_WOODEN_RC_25_UP_TO_RIGHT_BANK_SE_NW, 0, { 0, 0, 0 }, BoundBoxXYZ({ 3, 0, 0 }, { 25, 32, 2 }) }, - {}, - }, - } - }; - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - if (direction == 0 || direction == 3) - { - PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::Flat); - } - else - { - PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::FlatTo25Deg); - } - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 40); + WoodenRCTrackFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrackLeftBankTo25DegDown( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrack25DegUpToRightBank( - session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrack25DegUpToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrackRightBankTo25DegDown( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrack25DegUpToLeftBank(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrack25DegUpToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrack25DegDownToLeftBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrackRightBankTo25DegUp( - session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrack25DegDownToRightBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrackLeftBankTo25DegUp(session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrackBankedRightQuarterTurn5( @@ -967,374 +1098,58 @@ static void ClassicWoodenRCTrackLeftQuarterTurn3Bank( session, ride, trackSequence, (direction + 1) & 3, height, trackElement, supportType); } -static void ClassicWoodenRCTrackLeftEighthBankToDiag( +static void ClassicWoodenRCTrackDiagLeftBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - static constexpr SpriteBoundBox2 imageIds[4][5][2] = { - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 16, 2 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 16, 16, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_0_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 16, 0 }, { 16, 16, 2 }) }, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 32, 32, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 34, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 16, 32, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 16, 0 }, { 16, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 16, 27 }, { 16, 16, 0 }) }, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_1_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 18, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_1_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 27 }, { 16, 16, 0 }) }, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 32, 16, 2 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 16, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_2_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 16, 2 }) }, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 32, 32, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 27 }, { 16, 32, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 16, 16, 0 }) }, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_3_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 16, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_LEFT_BANKED_FRONT_3_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 27 }, { 16, 16, 0 }) }, - }, - }, - }; - - static constexpr int blockedSegments[5] = { - kSegmentsAll, kSegmentsAll, kSegmentsAll, kSegmentsAll, kSegmentsAll, - }; - - if (trackSequence == 0 && (direction == 0 || direction == 3)) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - - PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments[trackSequence], direction), 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } -static void ClassicWoodenRCTrackRightEighthBankToDiag( +static void ClassicWoodenRCTrackDiagRightBankToFlat( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - static constexpr SpriteBoundBox2 imageIds[4][5][2] = { - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 32, 32, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 32, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 27 }, { 32, 16, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 16, 16, 0 }) }, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_0_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_0_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 27 }, { 16, 16, 0 }) }, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 32, 0 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 16, 16, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_1_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 16, 2 }) }, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 32, 32, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 34, 16, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 27 }, { 32, 16, 0 }) }, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 4, 4, 0 }, { 28, 28, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 4, 4, 27 }, { 28, 28, 0 }) }, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_2_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 0 }, { 16, 18, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_FRONT_2_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 16, 27 }, { 16, 16, 0 }) }, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_0, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_1, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 0, 0, 0 }, { 16, 32, 0 }) }, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_2, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 0, 0 }, { 16, 16, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_ORTHO_TO_DIAG_RIGHT_BANKED_3_SEQ_4, - 0, - { 0, 0, 0 }, - BoundBoxXYZ({ 16, 16, 0 }, { 16, 16, 2 }) }, - {}, - }, - }, - }; + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagFlatToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} - static constexpr int blockedSegments[5] = { - kSegmentsAll, kSegmentsAll, kSegmentsAll, kSegmentsAll, kSegmentsAll, - }; +static void ClassicWoodenRCTrackDiagDown25ToLeftBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} - if (trackSequence == 0 && (direction == 0 || direction == 3)) - { - PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); - } +static void ClassicWoodenRCTrackDiagDown25ToRightBank( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagBankTo25DegUp( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); +static void ClassicWoodenRCTrackDiagLeftBankToDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagUp25ToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} - PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments[trackSequence], direction), 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); +static void ClassicWoodenRCTrackDiagRightBankToDown25( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagUp25ToBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrackLeftEighthBankToOrthogonal( @@ -1342,802 +1157,25 @@ static void ClassicWoodenRCTrackLeftEighthBankToOrthogonal( const TrackElement& trackElement, SupportType supportType) { trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; - ClassicWoodenRCTrackRightEighthBankToDiag( - session, ride, trackSequence, (direction + 2) & 3, height, trackElement, supportType); + WoodenRCTrackRightEighthBankToDiag( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } - static void ClassicWoodenRCTrackRightEighthBankToOrthogonal( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; - ClassicWoodenRCTrackLeftEighthBankToDiag( - session, ride, trackSequence, (direction + 3) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackDiagFlatToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][4][2] = { - { - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_FRONT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 27 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_1, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 23, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_FRONT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 27 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_LEFT_3, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - }; - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} - -static void ClassicWoodenRCTrackDiagFlatToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][4][2] = { - { - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_FRONT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 27 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_1, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 23, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_FRONT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 27 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_DIAG_FLAT_TO_BANK_RIGHT_3, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - }; - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); -} - -static void ClassicWoodenRCTrackDiagLeftBankToFlat( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - ClassicWoodenRCTrackDiagFlatToRightBank( - session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackDiagRightBankToFlat( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - ClassicWoodenRCTrackDiagFlatToLeftBank( - session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackDiagLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][4][2] = { - { - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_0, 0, { -16, -16, 0 }, BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_FRONT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 27 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_1, 0, { -16, -16, 0 }, BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_2, 0, { -16, -16, 0 }, BoundBoxXYZ({ -16, -16, 0 }, { 32, 23, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_FRONT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 27 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_3, 0, { -16, -16, 0 }, BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - }; - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + WoodenRCTrackLeftEighthBankToDiag( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); } static void ClassicWoodenRCTrackDiagRightBank( PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - ClassicWoodenRCTrackDiagLeftBank(session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackDiagLeftBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][4][2] = { - { - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_FRONT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_1, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 23, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_FRONT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_DIAG_LEFT_BANK_TO_25_UP_3, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - }; - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); -} - -static void ClassicWoodenRCTrackDiagRightBankTo25DegUp( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][4][2] = { - { - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_FRONT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_1, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 23, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_FRONT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_DIAG_RIGHT_BANK_TO_25_UP_3, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - }; - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); -} - -static void ClassicWoodenRCTrackDiag25DegUpToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][4][2] = { - { - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_FRONT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_1, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 23, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_FRONT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_LEFT_BANK_3, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - }; - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); -} - -static void ClassicWoodenRCTrackDiag25DegUpToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - static constexpr SpriteBoundBox2 imageIds[4][4][2] = { - { - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_FRONT_0, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_1, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - }, - { - { - {}, - {}, - }, - { - {}, - {}, - }, - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 23, 2 }) }, - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_FRONT_2, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 35 }, { 32, 32, 0 }) }, - }, - { - {}, - {}, - }, - }, - { - { - { SPR_CLASSIC_WOODEN_RC_DIAG_25_UP_TO_RIGHT_BANK_3, - 0, - { -16, -16, 0 }, - BoundBoxXYZ({ -16, -16, 0 }, { 32, 32, 2 }) }, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - { - {}, - {}, - }, - }, - }; - - DrawSupportForSequenceA( - session, supportType.wooden, trackSequence, direction, height, session.SupportColours); - - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][0], height); - WoodenRCTrackPaintBb(session, &imageIds[direction][trackSequence][1], height); - PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + 56); -} - -static void ClassicWoodenRCTrackDiagLeftBankTo25DegDown( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - ClassicWoodenRCTrackDiag25DegUpToRightBank( - session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackDiagRightBankTo25DegDown( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - ClassicWoodenRCTrackDiag25DegUpToLeftBank( - session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackDiag25DegDownToLeftBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - ClassicWoodenRCTrackDiagRightBankTo25DegUp( - session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); -} - -static void ClassicWoodenRCTrackDiag25DegDownToRightBank( - PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, - const TrackElement& trackElement, SupportType supportType) -{ - ClassicWoodenRCTrackDiagLeftBankTo25DegUp( - session, ride, 3 - trackSequence, (direction + 2) & 3, height, trackElement, supportType); + trackSequence = kMapReversedDiagonalStraight[trackSequence]; + return WoodenRCTrackDiagLeftBank( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); } // Stylistically, this coaster is _very_ similar to the regular Wooden Roller Coaster. @@ -2153,77 +1191,77 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionClassicWoodenRC(OpenRCT2::TrackElemTyp switch (trackType) { case TrackElemType::FlatToLeftBank: - return ClassicWoodenRCTrackFlatToLeftBank; + return WoodenRCTrackFlatToBank; case TrackElemType::FlatToRightBank: - return ClassicWoodenRCTrackFlatToRightBank; + return WoodenRCTrackFlatToBank; case TrackElemType::LeftBankToFlat: return ClassicWoodenRCTrackLeftBankToFlat; case TrackElemType::RightBankToFlat: return ClassicWoodenRCTrackRightBankToFlat; - case TrackElemType::BankedLeftQuarterTurn5Tiles: - return ClassicWoodenRCTrackBankedLeftQuarterTurn5; - case TrackElemType::BankedRightQuarterTurn5Tiles: - return ClassicWoodenRCTrackBankedRightQuarterTurn5; - case TrackElemType::LeftBankToUp25: - return ClassicWoodenRCTrackLeftBankTo25DegUp; - case TrackElemType::RightBankToUp25: - return ClassicWoodenRCTrackRightBankTo25DegUp; + case TrackElemType::LeftBank: + return WoodenRCTrackFlatToBank; + case TrackElemType::RightBank: + return ClassicWoodenRCTrackRightBank; case TrackElemType::Up25ToLeftBank: - return ClassicWoodenRCTrack25DegUpToLeftBank; + return WoodenRCTrack25DegUpToBank; case TrackElemType::Up25ToRightBank: - return ClassicWoodenRCTrack25DegUpToRightBank; + return WoodenRCTrack25DegUpToBank; case TrackElemType::LeftBankToDown25: return ClassicWoodenRCTrackLeftBankTo25DegDown; case TrackElemType::RightBankToDown25: return ClassicWoodenRCTrackRightBankTo25DegDown; + case TrackElemType::LeftBankToUp25: + return WoodenRCTrackBankTo25DegUp; + case TrackElemType::RightBankToUp25: + return WoodenRCTrackBankTo25DegUp; case TrackElemType::Down25ToLeftBank: return ClassicWoodenRCTrack25DegDownToLeftBank; case TrackElemType::Down25ToRightBank: return ClassicWoodenRCTrack25DegDownToRightBank; - case TrackElemType::LeftBank: - return ClassicWoodenRCTrackLeftBank; - case TrackElemType::RightBank: - return ClassicWoodenRCTrackRightBank; + case TrackElemType::BankedLeftQuarterTurn5Tiles: + return ClassicWoodenRCTrackBankedLeftQuarterTurn5; + case TrackElemType::BankedRightQuarterTurn5Tiles: + return ClassicWoodenRCTrackBankedRightQuarterTurn5; case TrackElemType::LeftBankedQuarterTurn3Tiles: return ClassicWoodenRCTrackLeftQuarterTurn3Bank; case TrackElemType::RightBankedQuarterTurn3Tiles: return ClassicWoodenRCTrackRightQuarterTurn3Bank; - case TrackElemType::LeftEighthBankToDiag: - return ClassicWoodenRCTrackLeftEighthBankToDiag; - case TrackElemType::RightEighthBankToDiag: - return ClassicWoodenRCTrackRightEighthBankToDiag; - case TrackElemType::LeftEighthBankToOrthogonal: - return ClassicWoodenRCTrackLeftEighthBankToOrthogonal; - case TrackElemType::RightEighthBankToOrthogonal: - return ClassicWoodenRCTrackRightEighthBankToOrthogonal; case TrackElemType::DiagFlatToLeftBank: - return ClassicWoodenRCTrackDiagFlatToLeftBank; + return WoodenRCTrackDiagFlatToBank; case TrackElemType::DiagFlatToRightBank: - return ClassicWoodenRCTrackDiagFlatToRightBank; + return WoodenRCTrackDiagFlatToBank; case TrackElemType::DiagLeftBankToFlat: return ClassicWoodenRCTrackDiagLeftBankToFlat; case TrackElemType::DiagRightBankToFlat: return ClassicWoodenRCTrackDiagRightBankToFlat; case TrackElemType::DiagLeftBankToUp25: - return ClassicWoodenRCTrackDiagLeftBankTo25DegUp; + return WoodenRCTrackDiagBankTo25DegUp; case TrackElemType::DiagRightBankToUp25: - return ClassicWoodenRCTrackDiagRightBankTo25DegUp; - case TrackElemType::DiagUp25ToLeftBank: - return ClassicWoodenRCTrackDiag25DegUpToLeftBank; - case TrackElemType::DiagUp25ToRightBank: - return ClassicWoodenRCTrackDiag25DegUpToRightBank; - case TrackElemType::DiagLeftBankToDown25: - return ClassicWoodenRCTrackDiagLeftBankTo25DegDown; - case TrackElemType::DiagRightBankToDown25: - return ClassicWoodenRCTrackDiagRightBankTo25DegDown; + return WoodenRCTrackDiagBankTo25DegUp; case TrackElemType::DiagDown25ToLeftBank: - return ClassicWoodenRCTrackDiag25DegDownToLeftBank; + return ClassicWoodenRCTrackDiagDown25ToLeftBank; case TrackElemType::DiagDown25ToRightBank: - return ClassicWoodenRCTrackDiag25DegDownToRightBank; + return ClassicWoodenRCTrackDiagDown25ToRightBank; + case TrackElemType::DiagUp25ToLeftBank: + return WoodenRCTrackDiagUp25ToBank; + case TrackElemType::DiagUp25ToRightBank: + return WoodenRCTrackDiagUp25ToBank; + case TrackElemType::DiagLeftBankToDown25: + return ClassicWoodenRCTrackDiagLeftBankToDown25; + case TrackElemType::DiagRightBankToDown25: + return ClassicWoodenRCTrackDiagRightBankToDown25; case TrackElemType::DiagLeftBank: - return ClassicWoodenRCTrackDiagLeftBank; + return WoodenRCTrackDiagLeftBank; case TrackElemType::DiagRightBank: return ClassicWoodenRCTrackDiagRightBank; + case TrackElemType::LeftEighthBankToDiag: + return WoodenRCTrackLeftEighthBankToDiag; + case TrackElemType::RightEighthBankToDiag: + return WoodenRCTrackRightEighthBankToDiag; + case TrackElemType::LeftEighthBankToOrthogonal: + return ClassicWoodenRCTrackLeftEighthBankToOrthogonal; + case TrackElemType::RightEighthBankToOrthogonal: + return ClassicWoodenRCTrackRightEighthBankToOrthogonal; default: return GetTrackPaintFunctionClassicWoodenRCFallback(trackType); } diff --git a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp index f6fa9b2cd7..4f0e197580 100644 --- a/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp +++ b/src/openrct2/paint/track/coaster/WoodenRollerCoaster.hpp @@ -26,7 +26,7 @@ static constexpr TunnelGroup kTunnelGroup = TunnelGroup::Square; struct WoodenTrackSection { ImageIndex track; - ImageIndex handrail; + ImageIndex handrail = ImageIndexUndefined; ImageIndex frontTrack = ImageIndexUndefined; ImageIndex frontHandrail = ImageIndexUndefined; }; @@ -67,11 +67,20 @@ PaintStruct* WoodenRCTrackPaint( PaintSession& session, uint8_t direction, ImageIndex imageIdTrack, ImageIndex imageIdRails, const CoordsXYZ& offset, const BoundBoxXYZ& boundBox) { - ImageId imageId = WoodenRCGetTrackColour(session).WithIndex(imageIdTrack); - ImageId railsImageId = WoodenRCGetRailsColour(session).WithIndex(imageIdRails); + if (isClassic) + { + const ImageId imageId = session.TrackColours.WithIndex(imageIdTrack); - PaintAddImageAsParentRotated(session, direction, imageId, offset, boundBox); - return PaintAddImageAsChildRotated(session, direction, railsImageId, offset, boundBox); + return PaintAddImageAsParentRotated(session, direction, imageId, offset, boundBox); + } + else + { + const ImageId imageId = session.SupportColours.WithIndex(imageIdTrack); + const ImageId railsImageId = WoodenRCGetRailsColour(session).WithIndex(imageIdRails); + + PaintAddImageAsParentRotated(session, direction, imageId, offset, boundBox); + return PaintAddImageAsChildRotated(session, direction, railsImageId, offset, boundBox); + } } template From 4931c47b01bbacd0da6a8bccbde74519fcaeb756 Mon Sep 17 00:00:00 2001 From: ZeeMaji <42477864+ZeeMaji@users.noreply.github.com> Date: Tue, 19 Nov 2024 08:01:28 -0500 Subject: [PATCH 076/139] Add missing pieces to wooden twister --- .../ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h index c621802826..faf9f244b2 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h @@ -22,8 +22,8 @@ constexpr RideTypeDescriptor ClassicWoodenTwisterRollerCoasterRTD = .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionClassicWoodenTwisterRC, .supportType = WoodenSupportType::Truss, - .enabledTrackGroups = { TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::blockBrakes, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeSteepLong, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::slopeCurveSteep }, - .extraTrackGroups = { TrackGroup::verticalLoop, TrackGroup::waterSplash }, + .enabledTrackGroups = { TrackGroup::flat, TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::liftHill, TrackGroup::flatRollBanking, TrackGroup::slope, TrackGroup::slopeSteepUp, TrackGroup::slopeSteepDown, TrackGroup::slopeCurve, TrackGroup::sBend, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::brakes, TrackGroup::onridePhoto, TrackGroup::blockBrakes, TrackGroup::diagBrakes, TrackGroup::diagBlockBrakes, TrackGroup::slopeSteepLong, TrackGroup::helixDownBankedHalf, TrackGroup::helixUpBankedHalf, TrackGroup::slopeCurveSteep, TrackGroup::slopeCurveBanked }, + .extraTrackGroups = { TrackGroup::verticalLoop, TrackGroup::waterSplash, TrackGroup::booster, TrackGroup::halfLoopMedium, TrackGroup::halfLoopLarge }, }), .InvertedTrackPaintFunctions = {}, .Flags = kRtdFlagsHasThreeColours | kRtdFlagsCommonCoaster | kRtdFlagsCommonCoasterNonAlt | From 02bedffa1b4c57b422b1739d7e195e48906d103a Mon Sep 17 00:00:00 2001 From: ZeeMaji <42477864+ZeeMaji@users.noreply.github.com> Date: Wed, 20 Nov 2024 19:03:39 -0500 Subject: [PATCH 077/139] Use rct2 wooden coaster preview images --- .../ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h index faf9f244b2..267797a52d 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h @@ -55,7 +55,7 @@ constexpr RideTypeDescriptor ClassicWoodenTwisterRollerCoasterRTD = { COLOUR_LIGHT_BLUE, COLOUR_BLACK, COLOUR_BLACK }, { COLOUR_LIGHT_BLUE, COLOUR_BLACK, COLOUR_DARK_BROWN }, ), - .ColourPreview = { SPR_RIDE_DESIGN_PREVIEW_CLASSIC_WOODEN_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_CLASSIC_WOODEN_ROLLER_COASTER_SUPPORTS }, + .ColourPreview = { SPR_RIDE_DESIGN_PREVIEW_WOODEN_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_WOODEN_ROLLER_COASTER_SUPPORTS }, .ColourKey = RideColourKey::Ride, .Name = "classic_wooden_twister_rc", .RatingsData = From dc02b14ec37b1b2411a0f8315d39628a7ab4c7de Mon Sep 17 00:00:00 2001 From: ZeeMaji <42477864+ZeeMaji@users.noreply.github.com> Date: Wed, 20 Nov 2024 19:04:30 -0500 Subject: [PATCH 078/139] Fix base excitement rating --- .../ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h index 267797a52d..3dba4af10b 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h @@ -61,7 +61,7 @@ constexpr RideTypeDescriptor ClassicWoodenTwisterRollerCoasterRTD = .RatingsData = { RatingsCalculationType::Normal, - { RIDE_RATING(2, 80), RIDE_RATING(2, 60), RIDE_RATING(2, 00) }, + { RIDE_RATING(3, 20), RIDE_RATING(2, 60), RIDE_RATING(2, 00) }, 19, -1, false, From b6662ab68279042cdf3a03438edbcefc48ad6493 Mon Sep 17 00:00:00 2001 From: ZeeMaji <42477864+ZeeMaji@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:11:11 -0500 Subject: [PATCH 079/139] Remove carried over OpenRCT2 color preset --- .../ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h index 3dba4af10b..8fb97ceb01 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h @@ -53,7 +53,6 @@ constexpr RideTypeDescriptor ClassicWoodenTwisterRollerCoasterRTD = { COLOUR_YELLOW, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN }, { COLOUR_TEAL, COLOUR_BORDEAUX_RED, COLOUR_WHITE }, { COLOUR_LIGHT_BLUE, COLOUR_BLACK, COLOUR_BLACK }, - { COLOUR_LIGHT_BLUE, COLOUR_BLACK, COLOUR_DARK_BROWN }, ), .ColourPreview = { SPR_RIDE_DESIGN_PREVIEW_WOODEN_ROLLER_COASTER_TRACK, SPR_RIDE_DESIGN_PREVIEW_WOODEN_ROLLER_COASTER_SUPPORTS }, .ColourKey = RideColourKey::Ride, From 6a591d58c13a370073bf1f86cff88ef112b7eaff Mon Sep 17 00:00:00 2001 From: ZeeMaji <42477864+ZeeMaji@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:57:32 -0500 Subject: [PATCH 080/139] Divide intensity when failing requirements --- .../rtd/coaster/ClassicWoodenTwisterRollerCoaster.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h index 8fb97ceb01..beb8c97ef6 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h @@ -78,11 +78,11 @@ constexpr RideTypeDescriptor ClassicWoodenTwisterRollerCoasterRTD = { RatingsModifierType::BonusReversedTrains, 0, 2, 12, 22 }, { RatingsModifierType::BonusProximity, 0, 22367, 0, 0 }, { RatingsModifierType::BonusScenery, 0, 11155, 0, 0 }, - { RatingsModifierType::RequirementDropHeight, 12, 2, 1, 2 }, - { RatingsModifierType::RequirementMaxSpeed, 0xA0000, 2, 1, 2 }, - { RatingsModifierType::RequirementNegativeGs, FIXED_2DP(0, 10), 2, 1, 2 }, - { RatingsModifierType::RequirementLength, 0x1720000, 2, 1, 2 }, - { RatingsModifierType::RequirementNumDrops, 2, 2, 1, 2 }, + { RatingsModifierType::RequirementDropHeight, 12, 2, 2, 2 }, + { RatingsModifierType::RequirementMaxSpeed, 0xA0000, 2, 2, 2 }, + { RatingsModifierType::RequirementNegativeGs, FIXED_2DP(0, 10), 2, 2, 2 }, + { RatingsModifierType::RequirementLength, 0x1720000, 2, 2, 2 }, + { RatingsModifierType::RequirementNumDrops, 2, 2, 2, 2 }, { RatingsModifierType::PenaltyLateralGs, 0, 40960, 34555, 49648 }, }, }, From b32a31f51729a4033b5ad507aac4fc2eb6a1943d Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 22 Nov 2024 20:57:56 +0100 Subject: [PATCH 081/139] Update objects+changelog and bump network+park version --- CMakeLists.txt | 4 ++-- distribution/changelog.txt | 3 +++ openrct2.proj | 4 ++-- src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/park/ParkFile.h | 4 ++-- src/openrct2/rct1/Tables.cpp | 4 ++-- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e76f1d9c7..1c27e4179c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,9 +69,9 @@ set(TITLE_SEQUENCE_VERSION "0.4.14") set(TITLE_SEQUENCE_URL "https://github.com/OpenRCT2/title-sequences/releases/download/v${TITLE_SEQUENCE_VERSION}/title-sequences.zip") set(TITLE_SEQUENCE_SHA1 "6c04781b959b468e1f65ec2d2f21f5aaa5e5724d") -set(OBJECTS_VERSION "1.4.10") +set(OBJECTS_VERSION "1.4.11") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip") -set(OBJECTS_SHA1 "e4953075d8dbe13ef48e8c4e87621cf3503a9d23") +set(OBJECTS_SHA1 "da04330679de2eff53a94a6505802512bfec6403") set(OPENSFX_VERSION "1.0.5") set(OPENSFX_URL "https://github.com/OpenRCT2/OpenSoundEffects/releases/download/v${OPENSFX_VERSION}/opensound.zip") diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b0ab155f4c..74feb991f6 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -1,12 +1,15 @@ 0.4.17 (in development) ------------------------------------------------------------------------ - Feature: [#23166] Add Galician translation. +- Feature: [#23227] Add Classic Wooden Twister roller coaster, for better compatibility with RCT1. - Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). - Fix: [#22726] ‘Force park rating’ cheat is not saved with the park. - Fix: [#23206] Multiplayer desyncs when FPS is uncapped. - Fix: [#23238] Updating a guest’s favourite ride works differently from vanilla RCT2. +- Fix: [objects#355] Fix colour preset settings of the Stand-Up Roller Coaster trains. +- Fix: [objects#355] Fix colour preset settings of many vehicles from Wacky Worlds and Time Twister. 0.4.16 (2024-11-03) ------------------------------------------------------------------------ diff --git a/openrct2.proj b/openrct2.proj index f48b09c334..a25d37c4f0 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -45,8 +45,8 @@ 9984c1e317dcfb3aaf8e17f1db2ebb0f771e2373 https://github.com/OpenRCT2/title-sequences/releases/download/v0.4.14/title-sequences.zip 6c04781b959b468e1f65ec2d2f21f5aaa5e5724d - https://github.com/OpenRCT2/objects/releases/download/v1.4.10/objects.zip - e4953075d8dbe13ef48e8c4e87621cf3503a9d23 + https://github.com/OpenRCT2/objects/releases/download/v1.4.11/objects.zip + da04330679de2eff53a94a6505802512bfec6403 https://github.com/OpenRCT2/OpenSoundEffects/releases/download/v1.0.5/opensound.zip b1b1f1b241d2cbff63a1889c4dc5a09bdf769bfb https://github.com/OpenRCT2/OpenMusic/releases/download/v1.6/openmusic.zip diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 0ffe91152a..73226b6e07 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -49,7 +49,7 @@ using namespace OpenRCT2; // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -constexpr uint8_t kNetworkStreamVersion = 3; +constexpr uint8_t kNetworkStreamVersion = 4; const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion); diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index 69cb1289a6..92d883c79c 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -11,10 +11,10 @@ namespace OpenRCT2 struct GameState_t; // Current version that is saved. - constexpr uint32_t PARK_FILE_CURRENT_VERSION = 43; + constexpr uint32_t PARK_FILE_CURRENT_VERSION = 44; // The minimum version that is forwards compatible with the current version. - constexpr uint32_t PARK_FILE_MIN_VERSION = 42; + constexpr uint32_t PARK_FILE_MIN_VERSION = 44; // 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/rct1/Tables.cpp b/src/openrct2/rct1/Tables.cpp index 1323448093..234f136035 100644 --- a/src/openrct2/rct1/Tables.cpp +++ b/src/openrct2/rct1/Tables.cpp @@ -755,7 +755,7 @@ namespace OpenRCT2::RCT1 "rct2.ride.circus1", // RCT1_RIDE_TYPE_CIRCUS "rct1aa.ride.ghost_train_cars", // RCT1_RIDE_TYPE_GHOST_TRAIN "rct1aa.ride.twister_trains", // RCT1_RIDE_TYPE_STEEL_TWISTER_ROLLER_COASTER - "rct1aa.ride.woodtrc", // RCT1_RIDE_TYPE_WOODEN_TWISTER_ROLLER_COASTER + "rct1aa.ride.wooden_articulated_trains", // RCT1_RIDE_TYPE_WOODEN_TWISTER_ROLLER_COASTER "rct1aa.ride.side_friction_cars", // RCT1_RIDE_TYPE_WOODEN_SIDE_FRICTION_ROLLER_COASTER "rct1aa.ride.steel_wild_mouse_cars", // RCT1_RIDE_TYPE_STEEL_WILD_MOUSE_ROLLER_COASTER "rct2.ride.hotds", // RCT1_RIDE_TYPE_HOT_DOG_STALL @@ -856,7 +856,7 @@ namespace OpenRCT2::RCT1 "rct2.ride.circus1", // VehicleType::CircusTent "rct1aa.ride.ghost_train_cars", // VehicleType::GhostTrainCars "rct1aa.ride.twister_trains", // VehicleType::SteelTwisterRollerCoasterTrain - "rct1aa.ride.woodtrc", // VehicleType::WoodenTwisterRollerCoasterTrain + "rct1aa.ride.wooden_articulated_trains", // VehicleType::WoodenTwisterRollerCoasterTrain "rct1aa.ride.side_friction_cars", // VehicleType::WoodenSideFrictionCars "rct1aa.ride.vintage_cars", // VehicleType::VintageCars "rct1aa.ride.steam_trains_covered", // VehicleType::SteamTrainCoveredCars From 11fba79e89f54e594cc02c7ddc5bd3424de413b5 Mon Sep 17 00:00:00 2001 From: Arek Durlik <72689308+arekdurlik@users.noreply.github.com> Date: Sun, 24 Nov 2024 09:45:13 +0100 Subject: [PATCH 082/139] pl-PL: Add translation to Flathub package --- distribution/linux/openrct2.appdata.xml | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/distribution/linux/openrct2.appdata.xml b/distribution/linux/openrct2.appdata.xml index 43e3340151..e05577c825 100644 --- a/distribution/linux/openrct2.appdata.xml +++ b/distribution/linux/openrct2.appdata.xml @@ -7,9 +7,11 @@ Amusement park simulation Simulador de parcs d’atraccions 놀이공원 시뮬레이션 + Symulator parku rozrywki The OpenRCT2 Team OpenRCT2 팀 Equip de l’OpenRCT2 + Zespół OpenRCT2 openrct2.desktop

@@ -39,6 +41,15 @@ 모래상자에서는 플레이어가 자금이타 금지 행위에 대한 제한 없이 더 유연한 공원을 만들 수 있습니다.

+

+ OpenRCT2 to open-source'owa reimplementacja gry RollerCoaster Tycoon 2 (RCT2). + Rozgrywka polega na budowaniu i zarządzaniu parkiem rozrywki zawierającym + przeróżne atrakcje, sklepy i udogodnienia. Gracz musi starać się osiągnąć zysk i utrzymać + dobrą reputację parku, jednocześnie dbając o zadowolenie gości. OpenRCT2 umożliwia + rozgrywkę w scenariuszach oraz w trybie sandbox. Scenariusze wymagają od gracza ukończenia + określonego celu w wyznaczonym czasie, podczas gdy tryb sandbox pozwala na + swobodne budowanie parku, z możliwością wyłączenia ograniczeń i finansów. +

OpenRCT2 features many changes compared to the original RollerCoaster Tycoon 2 game. A few of them are listed here. @@ -49,43 +60,55 @@

OpenRCT2는 오리지널 RollerCoaster Tycoon 2 게임에 비해 많은 기능적 변화가 있습니다. 여기에 일부 기능이 나열되어 있습니다.

+

+ OpenRCT2 zawiera wiele zmian w porównaniu do oryginalnej gry RollerCoaster Tycoon 2. Oto kilka z nich: +

  • User Interface theming.
  • Temes per a la interfície gràfica
  • 유저 인터페이스 커스터마이징
  • +
  • Edycja motywów interfejsu użytkownika
  • Fast-forwarding gameplay.
  • Diferents velocitats de joc disponibles durant la partida
  • 게임 속도 조절
  • +
  • Przyspieszanie rozgrywki
  • Multiplayer support.
  • Suport multijugador
  • 멀티플레이 지원
  • +
  • Tryb wieloosobowy
  • Multilingual. Improved translations.
  • Traduït a diversos idiomes i amb traduccions millorades
  • 다국어 지원 및 번역 개선
  • +
  • Wielojęzyczność i ulepszone tłumaczenia
  • OpenGL hardware rendering.
  • Renderització OpenGL per maquinari
  • OpenGL 하드웨어 렌더링
  • +
  • Obsługa renderowania OpenGL
  • Various fixes and improvements for bugs in the original game.
  • Correccions i millores dels errors del joc original
  • 오리지널 게임에 있던 다양한 버그 수정 및 개선
  • +
  • Poprawki błędów i usprawnienia względem oryginalnej gry
  • Native support for Linux and macOS.
  • Suport natiu per a Linux i macOS
  • Linux 및 macOS 자체 지원
  • +
  • Natywna obsługa systemów Linux i macOS
  • Added hacks and cheats.
  • Es poden fer trucs i trampes
  • 치트 기능 지원
  • +
  • Kody i hacki
  • Auto-saving and giant screenshots.
  • Desades automàtiques i captures de pantalla gegants
  • 자동 저장 및 대형 스크린 샷
  • +
  • Autozapis i możliwość robienia ogromnych zrzutów ekranu

@@ -97,12 +120,16 @@

OpenRCT2를 플레이하기 위해서는 오리지널 RollerCoaster Tycoon 2 또는 RollerCoaster Tycoon Classic 게임 파일이 필요합니다.

+

+ Do działania OpenRCT2 wymagane są pliki z RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic. +

https://camo.githubusercontent.com/f513bc551e2c9e04e292724113ea4789726d23921d286f21dad39a6e955b5a56/68747470733a2f2f692e696d6775722e636f6d2f6537434b3553632e706e67 Amusement park featuring an inverted roller coaster, a river rapids ride and custom scenery 인버티드 롤러코스터를 구현한 놀이공원과 리버 래피드 기구 및 커스텀 풍경 오브젝트 + Park rozrywki z odwróconą kolejką górską, spływem rwącą rzeką i niestandardową scenerią https://openrct2.io/ From ad0dfc6f0a94e7e598e830388906264b035aa34d Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 23 Nov 2024 00:05:31 +0100 Subject: [PATCH 083/139] Remove one check for RIDE_TYPE_CHAIRLIFT --- src/openrct2-ui/windows/RideConstruction.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 43d6aa7419..566cc20512 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -2760,8 +2760,9 @@ namespace OpenRCT2::Ui::Windows continue; // Non-default vehicle visuals do not use this system, so we have to assume it supports all the track pieces. - if (currentRideEntry->Cars[0].PaintStyle != VEHICLE_VISUAL_DEFAULT || rideType == RIDE_TYPE_CHAIRLIFT - || (currentRideEntry->Cars[0].flags & CAR_ENTRY_FLAG_SLIDE_SWING)) + auto& firstCar = currentRideEntry->Cars[0]; + if (firstCar.PaintStyle != VEHICLE_VISUAL_DEFAULT || (firstCar.flags & CAR_ENTRY_FLAG_CHAIRLIFT) + || (firstCar.flags & CAR_ENTRY_FLAG_SLIDE_SWING)) { disabledGroups.reset(); break; From 192e7662cc6eafa9521e966128eef35ccedfc3a6 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 23 Nov 2024 00:28:11 +0100 Subject: [PATCH 084/139] Replace check for RIDE_TYPE_MERRY_GO_ROUND --- src/openrct2/rct1/S4Importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index c7058a5277..1944ea4331 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1153,7 +1153,7 @@ namespace OpenRCT2::RCT1 } } - if (_gameVersion < FILE_VERSION_RCT1_LL && dst->type == RIDE_TYPE_MERRY_GO_ROUND) + if (_gameVersion < FILE_VERSION_RCT1_LL && src->Type == RideType::MerryGoRound) { // The merry-go-round in pre-LL versions was always yellow with red dst->vehicle_colours[0].Body = COLOUR_YELLOW; From 0979cf61adb43052e649a56313ab7796201f667a Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 23 Nov 2024 00:28:37 +0100 Subject: [PATCH 085/139] Replace direct check for RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER --- src/openrct2/actions/TrackRemoveAction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/actions/TrackRemoveAction.cpp b/src/openrct2/actions/TrackRemoveAction.cpp index 59e21498bf..4a76c160ab 100644 --- a/src/openrct2/actions/TrackRemoveAction.cpp +++ b/src/openrct2/actions/TrackRemoveAction.cpp @@ -469,7 +469,7 @@ GameActions::Result TrackRemoveAction::Execute() const { ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_OPERATING; RideMode newMode = RideMode::ContinuousCircuit; - if (ride->type == RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER) + if (ride->mode == RideMode::PoweredLaunchBlockSectioned) { newMode = RideMode::PoweredLaunch; } From 8243cf755a2dd791f4ebe3017bc72ab658873014 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 23 Nov 2024 10:55:45 +0100 Subject: [PATCH 086/139] Replace direct check for RIDE_TYPE_INFORMATION_KIOSK --- src/openrct2/ride/TrackPaint.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/openrct2/ride/TrackPaint.cpp b/src/openrct2/ride/TrackPaint.cpp index 587b6ade6c..9d2f14dc0a 100644 --- a/src/openrct2/ride/TrackPaint.cpp +++ b/src/openrct2/ride/TrackPaint.cpp @@ -1975,7 +1975,8 @@ void PaintTrack(PaintSession& session, Direction direction, int32_t height, cons if (rtd.HasFlag(RtdFlag::isToilet) || rtd.HasFlag(RtdFlag::isFirstAid) || rtd.HasFlag(RtdFlag::isCashMachine)) zOffset = 23; - if (ride->type == RIDE_TYPE_INFORMATION_KIOSK) + const auto* originElement = ride->GetOriginElement(StationIndex::FromUnderlying(0)); + if (originElement != nullptr && originElement->GetTrackType() == TrackElemType::FlatTrack1x1B) LightFxAddKioskLights(session.MapPosition, height, zOffset); else if (RideTypeDescriptors[ride->type].HasFlag(RtdFlag::isShopOrFacility)) LightFxAddShopLights(session.MapPosition, trackElement.GetDirection(), height, zOffset); From 6de1ac1ec7826edc1c8f07f434466826a76db067 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sat, 23 Nov 2024 00:10:18 +0100 Subject: [PATCH 087/139] Remove EnumName from RTD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only used by tests, update to use `Name` (same what’s already used in the JSON files). --- src/openrct2/ride/RideData.h | 2 - .../rtd/coaster/AirPoweredVerticalCoaster.h | 1 - src/openrct2/ride/rtd/coaster/AlpineCoaster.h | 1 - .../ride/rtd/coaster/BobsleighCoaster.h | 1 - .../rtd/coaster/ClassicMiniRollerCoaster.h | 1 - .../rtd/coaster/ClassicStandUpRollerCoaster.h | 1 - .../rtd/coaster/ClassicWoodenRollerCoaster.h | 1 - .../ClassicWoodenTwisterRollerCoaster.h | 1 - .../ride/rtd/coaster/CompactInvertedCoaster.h | 1 - .../ride/rtd/coaster/CorkscrewRollerCoaster.h | 1 - .../ride/rtd/coaster/FlyingRollerCoaster.h | 2 - src/openrct2/ride/rtd/coaster/GigaCoaster.h | 1 - .../rtd/coaster/HeartlineTwisterCoaster.h | 1 - src/openrct2/ride/rtd/coaster/HybridCoaster.h | 1 - src/openrct2/ride/rtd/coaster/HyperTwister.h | 1 - src/openrct2/ride/rtd/coaster/Hypercoaster.h | 1 - .../ride/rtd/coaster/InvertedHairpinCoaster.h | 1 - .../ride/rtd/coaster/InvertedImpulseCoaster.h | 1 - .../ride/rtd/coaster/InvertedRollerCoaster.h | 1 - .../ride/rtd/coaster/JuniorRollerCoaster.h | 1 - .../rtd/coaster/LIMLaunchedRollerCoaster.h | 1 - .../rtd/coaster/LSMLaunchedRollerCoaster.h | 1 - .../ride/rtd/coaster/LayDownRollerCoaster.h | 2 - .../ride/rtd/coaster/LoopingRollerCoaster.h | 1 - src/openrct2/ride/rtd/coaster/MineRide.h | 1 - .../ride/rtd/coaster/MineTrainCoaster.h | 1 - .../ride/rtd/coaster/MiniRollerCoaster.h | 1 - .../ride/rtd/coaster/MiniSuspendedCoaster.h | 1 - .../rtd/coaster/MultiDimensionRollerCoaster.h | 2 - .../ride/rtd/coaster/ReverseFreefallCoaster.h | 1 - .../ride/rtd/coaster/ReverserRollerCoaster.h | 1 - .../rtd/coaster/SideFrictionRollerCoaster.h | 1 - .../rtd/coaster/SingleRailRollerCoaster.h | 1 - .../ride/rtd/coaster/SpinningWildMouse.h | 1 - .../ride/rtd/coaster/SpiralRollerCoaster.h | 1 - .../ride/rtd/coaster/StandUpRollerCoaster.h | 1 - .../ride/rtd/coaster/SteelWildMouse.h | 1 - src/openrct2/ride/rtd/coaster/Steeplechase.h | 1 - .../rtd/coaster/SuspendedSwingingCoaster.h | 1 - .../ride/rtd/coaster/TwisterRollerCoaster.h | 1 - .../ride/rtd/coaster/VerticalDropCoaster.h | 1 - src/openrct2/ride/rtd/coaster/VirginiaReel.h | 1 - src/openrct2/ride/rtd/coaster/WaterCoaster.h | 1 - .../ride/rtd/coaster/WoodenRollerCoaster.h | 1 - .../ride/rtd/coaster/WoodenWildMouse.h | 1 - src/openrct2/ride/rtd/gentle/CarRide.h | 1 - src/openrct2/ride/rtd/gentle/Circus.h | 1 - src/openrct2/ride/rtd/gentle/CrookedHouse.h | 1 - src/openrct2/ride/rtd/gentle/Dodgems.h | 1 - src/openrct2/ride/rtd/gentle/FerrisWheel.h | 1 - src/openrct2/ride/rtd/gentle/FlyingSaucers.h | 1 - src/openrct2/ride/rtd/gentle/GhostTrain.h | 1 - src/openrct2/ride/rtd/gentle/HauntedHouse.h | 1 - src/openrct2/ride/rtd/gentle/Maze.h | 1 - src/openrct2/ride/rtd/gentle/MerryGoRound.h | 1 - src/openrct2/ride/rtd/gentle/MiniGolf.h | 1 - .../ride/rtd/gentle/MiniHelicopters.h | 1 - src/openrct2/ride/rtd/gentle/MonorailCycles.h | 1 - src/openrct2/ride/rtd/gentle/MonsterTrucks.h | 1 - .../ride/rtd/gentle/ObservationTower.h | 1 - src/openrct2/ride/rtd/gentle/SpaceRings.h | 1 - src/openrct2/ride/rtd/gentle/SpiralSlide.h | 1 - src/openrct2/ride/rtd/shops/CashMachine.h | 1 - src/openrct2/ride/rtd/shops/DrinkStall.h | 1 - src/openrct2/ride/rtd/shops/FirstAid.h | 1 - src/openrct2/ride/rtd/shops/FoodStall.h | 1 - .../ride/rtd/shops/InformationKiosk.h | 1 - src/openrct2/ride/rtd/shops/Shop.h | 1 - src/openrct2/ride/rtd/shops/Toilets.h | 1 - src/openrct2/ride/rtd/thrill/3DCinema.h | 1 - src/openrct2/ride/rtd/thrill/Enterprise.h | 1 - src/openrct2/ride/rtd/thrill/GoKarts.h | 1 - .../ride/rtd/thrill/LaunchedFreefall.h | 1 - src/openrct2/ride/rtd/thrill/MagicCarpet.h | 1 - .../ride/rtd/thrill/MotionSimulator.h | 1 - src/openrct2/ride/rtd/thrill/RotoDrop.h | 1 - .../ride/rtd/thrill/SwingingInverterShip.h | 1 - src/openrct2/ride/rtd/thrill/SwingingShip.h | 1 - src/openrct2/ride/rtd/thrill/TopSpin.h | 1 - src/openrct2/ride/rtd/thrill/Twist.h | 1 - src/openrct2/ride/rtd/transport/Chairlift.h | 1 - src/openrct2/ride/rtd/transport/Lift.h | 1 - .../ride/rtd/transport/MiniatureRailway.h | 1 - src/openrct2/ride/rtd/transport/Monorail.h | 1 - .../ride/rtd/transport/SuspendedMonorail.h | 1 - src/openrct2/ride/rtd/water/BoatHire.h | 1 - src/openrct2/ride/rtd/water/DinghySlide.h | 1 - src/openrct2/ride/rtd/water/LogFlume.h | 1 - src/openrct2/ride/rtd/water/RiverRafts.h | 1 - src/openrct2/ride/rtd/water/RiverRapids.h | 1 - src/openrct2/ride/rtd/water/SplashBoats.h | 1 - src/openrct2/ride/rtd/water/SubmarineRide.h | 1 - test/tests/RideRatings.cpp | 5 +- .../tests/testdata/ratings/BigMapTest.sv6.txt | 200 ++-- .../testdata/ratings/EverythingPark.park.txt | 1058 ++++++++--------- test/tests/testdata/ratings/bpb.sv6.txt | 268 ++--- .../ratings/testReversedTrains.park.txt | 4 +- 97 files changed, 768 insertions(+), 863 deletions(-) diff --git a/src/openrct2/ride/RideData.h b/src/openrct2/ride/RideData.h index f82759026c..9e2b56e18d 100644 --- a/src/openrct2/ride/RideData.h +++ b/src/openrct2/ride/RideData.h @@ -468,7 +468,6 @@ struct RideTypeDescriptor RideLegacyBoosterSettings LegacyBoosterSettings{}; RideNaming Naming{}; RideNameConvention NameConvention{}; - const char* EnumName{}; uint8_t AvailableBreakdowns{}; /** rct2: 0x0097D218 */ RideHeights Heights{}; @@ -601,7 +600,6 @@ constexpr RideTypeDescriptor DummyRTD = .LegacyBoosterSettings = {}, .Naming = { STR_UNKNOWN_RIDE, STR_RIDE_DESCRIPTION_UNKNOWN }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "(INVALID)", .AvailableBreakdowns = 0, .Heights = { 12, 64, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/coaster/AirPoweredVerticalCoaster.h b/src/openrct2/ride/rtd/coaster/AirPoweredVerticalCoaster.h index b58156c4f3..32ab9e11d2 100644 --- a/src/openrct2/ride/rtd/coaster/AirPoweredVerticalCoaster.h +++ b/src/openrct2/ride/rtd/coaster/AirPoweredVerticalCoaster.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor AirPoweredVerticalCoasterRTD = .LegacyBoosterSettings = { 40, 40 }, .Naming = { STR_RIDE_NAME_AIR_POWERED_VERTICAL_COASTER, STR_RIDE_DESCRIPTION_AIR_POWERED_VERTICAL_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 32, 4, 7, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/coaster/AlpineCoaster.h b/src/openrct2/ride/rtd/coaster/AlpineCoaster.h index 60808acb0d..2682f74699 100644 --- a/src/openrct2/ride/rtd/coaster/AlpineCoaster.h +++ b/src/openrct2/ride/rtd/coaster/AlpineCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor AlpineCoasterRTD = .TrackSpeedSettings = { 10, 10 }, .Naming = { STR_RIDE_NAME_ALPINE_COASTER, STR_RIDE_DESCRIPTION_ALPINE_COASTER }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_ALPINE_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = {18, 24, 3, 7}, .MaxMass = 4, diff --git a/src/openrct2/ride/rtd/coaster/BobsleighCoaster.h b/src/openrct2/ride/rtd/coaster/BobsleighCoaster.h index e0be886193..fd8b2c670a 100644 --- a/src/openrct2/ride/rtd/coaster/BobsleighCoaster.h +++ b/src/openrct2/ride/rtd/coaster/BobsleighCoaster.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor BobsleighCoasterRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_BOBSLEIGH_COASTER, STR_RIDE_DESCRIPTION_BOBSLEIGH_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_BOBSLEIGH_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 19, 24, 5, 7, }, .MaxMass = 25, diff --git a/src/openrct2/ride/rtd/coaster/ClassicMiniRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicMiniRollerCoaster.h index 65a288f231..9724307f17 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicMiniRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicMiniRollerCoaster.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor ClassicMiniRollerCoasterRTD = .LegacyBoosterSettings = { 17, 16, 1 }, .Naming = { STR_RIDE_NAME_CLASSIC_MINI_ROLLER_COASTER, STR_RIDE_DESCRIPTION_CLASSIC_MINI_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 15, 24, 4, 7, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/ClassicStandUpRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicStandUpRollerCoaster.h index ae0e34dc8e..6681a653ff 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicStandUpRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicStandUpRollerCoaster.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor ClassicStandUpRollerCoasterRTD = .OperatingSettings = { 7, 27 }, .Naming = { STR_RIDE_NAME_CLASSIC_STAND_UP_ROLLER_COASTER, STR_RIDE_DESCRIPTION_CLASSIC_STAND_UP_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CLASSIC_STAND_UP_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 30, 24, 9, 11, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h index b7565f38eb..15cbf79853 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenRollerCoaster.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor ClassicWoodenRollerCoasterRTD = .LegacyBoosterSettings = { 0, 68 }, .Naming = { STR_RIDE_NAME_CLASSIC_WOODEN_ROLLER_COASTER, STR_RIDE_DESCRIPTION_CLASSIC_WOODEN_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 24, 24, 8, 11, }, .MaxMass = 19, diff --git a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h index beb8c97ef6..6e1101a056 100644 --- a/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ClassicWoodenTwisterRollerCoaster.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor ClassicWoodenTwisterRollerCoasterRTD = .LegacyBoosterSettings = { 0, 68 }, .Naming = { STR_RIDE_NAME_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER, STR_RIDE_DESCRIPTION_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CLASSIC_WOODEN_TWISTER_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 24, 24, 8, 11, }, .MaxMass = 19, diff --git a/src/openrct2/ride/rtd/coaster/CompactInvertedCoaster.h b/src/openrct2/ride/rtd/coaster/CompactInvertedCoaster.h index 62c945bab2..493a6f8b2f 100644 --- a/src/openrct2/ride/rtd/coaster/CompactInvertedCoaster.h +++ b/src/openrct2/ride/rtd/coaster/CompactInvertedCoaster.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor CompactInvertedCoasterRTD = .OperatingSettings = { 7, 27 }, .Naming = { STR_RIDE_NAME_COMPACT_INVERTED_COASTER, STR_RIDE_DESCRIPTION_COMPACT_INVERTED_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_COMPACT_INVERTED_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 27, 40, 29, 8, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/CorkscrewRollerCoaster.h b/src/openrct2/ride/rtd/coaster/CorkscrewRollerCoaster.h index dfc385ca61..f6605a4b7e 100644 --- a/src/openrct2/ride/rtd/coaster/CorkscrewRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/CorkscrewRollerCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor CorkscrewRollerCoasterRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_CORKSCREW_ROLLER_COASTER, STR_RIDE_DESCRIPTION_CORKSCREW_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CORKSCREW_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 28, 24, 8, 11, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h b/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h index e1b61c3e99..c3222863b0 100644 --- a/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/FlyingRollerCoaster.h @@ -42,7 +42,6 @@ constexpr RideTypeDescriptor FlyingRollerCoasterRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_FLYING_ROLLER_COASTER, STR_RIDE_DESCRIPTION_FLYING_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_FLYING_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 30, 24, 8, 11, }, .MaxMass = 35, @@ -118,7 +117,6 @@ constexpr RideTypeDescriptor FlyingRollerCoasterAltRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_3A, STR_RIDE_DESCRIPTION_UNKNOWN }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_FLYING_ROLLER_COASTER_ALT", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 30, 24, 8, 11, }, .MaxMass = 35, diff --git a/src/openrct2/ride/rtd/coaster/GigaCoaster.h b/src/openrct2/ride/rtd/coaster/GigaCoaster.h index fdb2ae56d1..520670b421 100644 --- a/src/openrct2/ride/rtd/coaster/GigaCoaster.h +++ b/src/openrct2/ride/rtd/coaster/GigaCoaster.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor GigaCoasterRTD = .LegacyBoosterSettings = { 17, 68, 4 }, .Naming = { STR_RIDE_NAME_GIGA_COASTER, STR_RIDE_DESCRIPTION_GIGA_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_GIGA_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 86, 24, 9, 11, }, .MaxMass = 31, diff --git a/src/openrct2/ride/rtd/coaster/HeartlineTwisterCoaster.h b/src/openrct2/ride/rtd/coaster/HeartlineTwisterCoaster.h index 653299e25d..020ddefb49 100644 --- a/src/openrct2/ride/rtd/coaster/HeartlineTwisterCoaster.h +++ b/src/openrct2/ride/rtd/coaster/HeartlineTwisterCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor HeartlineTwisterCoasterRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_HEARTLINE_TWISTER_COASTER, STR_RIDE_DESCRIPTION_HEARTLINE_TWISTER_COASTER }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_HEARTLINE_TWISTER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 22, 24, 15, 9, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/HybridCoaster.h b/src/openrct2/ride/rtd/coaster/HybridCoaster.h index 7953ba25cd..2b3cb147b1 100644 --- a/src/openrct2/ride/rtd/coaster/HybridCoaster.h +++ b/src/openrct2/ride/rtd/coaster/HybridCoaster.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor HybridCoasterRTD = .LegacyBoosterSettings = { 15, 52 }, .Naming = { STR_RIDE_NAME_HYBRID_COASTER, STR_RIDE_DESCRIPTION_HYBRID_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_HYBRID_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 43, 24, 13, 13}, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/HyperTwister.h b/src/openrct2/ride/rtd/coaster/HyperTwister.h index 7a34b8c36b..78497c07c7 100644 --- a/src/openrct2/ride/rtd/coaster/HyperTwister.h +++ b/src/openrct2/ride/rtd/coaster/HyperTwister.h @@ -38,7 +38,6 @@ constexpr RideTypeDescriptor HyperTwisterRTD = .LegacyBoosterSettings = { 17, 68 }, .Naming = { STR_RIDE_NAME_HYPER_TWISTER, STR_RIDE_DESCRIPTION_HYPER_TWISTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station}, - .EnumName = "RIDE_TYPE_HYPER_TWISTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 61, 24, 8, 9, }, .MaxMass = 31, diff --git a/src/openrct2/ride/rtd/coaster/Hypercoaster.h b/src/openrct2/ride/rtd/coaster/Hypercoaster.h index 6e900c5df1..255fe8a4b3 100644 --- a/src/openrct2/ride/rtd/coaster/Hypercoaster.h +++ b/src/openrct2/ride/rtd/coaster/Hypercoaster.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor HypercoasterRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_HYPERCOASTER, STR_RIDE_DESCRIPTION_HYPERCOASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_HYPERCOASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 55, 24, 8, 11, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/InvertedHairpinCoaster.h b/src/openrct2/ride/rtd/coaster/InvertedHairpinCoaster.h index 001953d5a6..6b800a7752 100644 --- a/src/openrct2/ride/rtd/coaster/InvertedHairpinCoaster.h +++ b/src/openrct2/ride/rtd/coaster/InvertedHairpinCoaster.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor InvertedHairpinCoasterRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_INVERTED_HAIRPIN_COASTER, STR_RIDE_DESCRIPTION_INVERTED_HAIRPIN_COASTER }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_INVERTED_HAIRPIN_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 16, 24, 24, 7, }, .MaxMass = 4, diff --git a/src/openrct2/ride/rtd/coaster/InvertedImpulseCoaster.h b/src/openrct2/ride/rtd/coaster/InvertedImpulseCoaster.h index 44bc1cc819..16aa3bbdb4 100644 --- a/src/openrct2/ride/rtd/coaster/InvertedImpulseCoaster.h +++ b/src/openrct2/ride/rtd/coaster/InvertedImpulseCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor InvertedImpulseCoasterRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_INVERTED_IMPULSE_COASTER, STR_RIDE_DESCRIPTION_INVERTED_IMPULSE_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_INVERTED_IMPULSE_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 45, 40, 29, 8, }, .MaxMass = 23, diff --git a/src/openrct2/ride/rtd/coaster/InvertedRollerCoaster.h b/src/openrct2/ride/rtd/coaster/InvertedRollerCoaster.h index f9dec13985..8905fc4930 100644 --- a/src/openrct2/ride/rtd/coaster/InvertedRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/InvertedRollerCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor InvertedRollerCoasterRTD = .LegacyBoosterSettings = { 0, 38 }, .Naming = { STR_RIDE_NAME_INVERTED_ROLLER_COASTER, STR_RIDE_DESCRIPTION_INVERTED_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_INVERTED_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 42, 40, 29, 8, }, .MaxMass = 27, diff --git a/src/openrct2/ride/rtd/coaster/JuniorRollerCoaster.h b/src/openrct2/ride/rtd/coaster/JuniorRollerCoaster.h index f658415a03..3b37d59a9a 100644 --- a/src/openrct2/ride/rtd/coaster/JuniorRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/JuniorRollerCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor JuniorRollerCoasterRTD = .LegacyBoosterSettings = { 17, 16, 1 }, .Naming = { STR_RIDE_NAME_JUNIOR_ROLLER_COASTER, STR_RIDE_DESCRIPTION_JUNIOR_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_JUNIOR_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 12, 24, 4, 7, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/LIMLaunchedRollerCoaster.h b/src/openrct2/ride/rtd/coaster/LIMLaunchedRollerCoaster.h index 43cb578e63..ced016c7c4 100644 --- a/src/openrct2/ride/rtd/coaster/LIMLaunchedRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/LIMLaunchedRollerCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor LIMLaunchedRollerCoasterRTD = .LegacyBoosterSettings = { 18, 52 }, .Naming = { STR_RIDE_NAME_LIM_LAUNCHED_ROLLER_COASTER, STR_RIDE_DESCRIPTION_LIM_LAUNCHED_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 35, 24, 5, 7, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h b/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h index 75c8103dbe..e84afaf332 100644 --- a/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor LSMLaunchedRollerCoasterRTD = .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, diff --git a/src/openrct2/ride/rtd/coaster/LayDownRollerCoaster.h b/src/openrct2/ride/rtd/coaster/LayDownRollerCoaster.h index 69ad588bcd..bfa128e60d 100644 --- a/src/openrct2/ride/rtd/coaster/LayDownRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/LayDownRollerCoaster.h @@ -45,7 +45,6 @@ constexpr RideTypeDescriptor LayDownRollerCoasterRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_LAY_DOWN_ROLLER_COASTER, STR_RIDE_DESCRIPTION_LAY_DOWN_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_LAY_DOWN_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 26, 24, 8, 11, }, .MaxMass = 25, @@ -117,7 +116,6 @@ constexpr RideTypeDescriptor LayDownRollerCoasterAltRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_40, STR_RIDE_DESCRIPTION_UNKNOWN }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_LAY_DOWN_ROLLER_COASTER_ALT", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 26, 24, 8, 11, }, .MaxMass = 25, diff --git a/src/openrct2/ride/rtd/coaster/LoopingRollerCoaster.h b/src/openrct2/ride/rtd/coaster/LoopingRollerCoaster.h index e31df2c416..f7d0ed27cb 100644 --- a/src/openrct2/ride/rtd/coaster/LoopingRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/LoopingRollerCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor LoopingRollerCoasterRTD = .LegacyBoosterSettings = { 18, 18 }, .Naming = { STR_RIDE_NAME_LOOPING_ROLLER_COASTER, STR_RIDE_DESCRIPTION_LOOPING_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_LOOPING_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 35, 24, 5, 7, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/MineRide.h b/src/openrct2/ride/rtd/coaster/MineRide.h index 8464c6d511..5418c4188b 100644 --- a/src/openrct2/ride/rtd/coaster/MineRide.h +++ b/src/openrct2/ride/rtd/coaster/MineRide.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor MineRideRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MINE_RIDE, STR_RIDE_DESCRIPTION_MINE_RIDE }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MINE_RIDE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 13, 24, 9, 11, }, .MaxMass = 27, diff --git a/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h b/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h index 8bfda9bbec..eda3c1d5d3 100644 --- a/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h +++ b/src/openrct2/ride/rtd/coaster/MineTrainCoaster.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor MineTrainCoasterRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MINE_TRAIN_COASTER, STR_RIDE_DESCRIPTION_MINE_TRAIN_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MINE_TRAIN_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 21, 24, 4, 7, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/coaster/MiniRollerCoaster.h b/src/openrct2/ride/rtd/coaster/MiniRollerCoaster.h index 0955641cd6..73606db057 100644 --- a/src/openrct2/ride/rtd/coaster/MiniRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/MiniRollerCoaster.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor MiniRollerCoasterRTD = .LegacyBoosterSettings = { 0, 68, 4 }, .Naming = { STR_RIDE_NAME_MINI_ROLLER_COASTER, STR_RIDE_DESCRIPTION_MINI_ROLLER_COASTER }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MINI_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 16, 24, 9, 11, }, .MaxMass = 10, diff --git a/src/openrct2/ride/rtd/coaster/MiniSuspendedCoaster.h b/src/openrct2/ride/rtd/coaster/MiniSuspendedCoaster.h index 4db6112200..e69174d1fa 100644 --- a/src/openrct2/ride/rtd/coaster/MiniSuspendedCoaster.h +++ b/src/openrct2/ride/rtd/coaster/MiniSuspendedCoaster.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor MiniSuspendedCoasterRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MINI_SUSPENDED_COASTER, STR_RIDE_DESCRIPTION_MINI_SUSPENDED_COASTER }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MINI_SUSPENDED_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 10, 24, 24, 8, }, .MaxMass = 3, diff --git a/src/openrct2/ride/rtd/coaster/MultiDimensionRollerCoaster.h b/src/openrct2/ride/rtd/coaster/MultiDimensionRollerCoaster.h index 28967895ac..c3faf1c9a6 100644 --- a/src/openrct2/ride/rtd/coaster/MultiDimensionRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/MultiDimensionRollerCoaster.h @@ -42,7 +42,6 @@ constexpr RideTypeDescriptor MultiDimensionRollerCoasterRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_MULTI_DIMENSION_ROLLER_COASTER, STR_RIDE_DESCRIPTION_MULTI_DIMENSION_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 40, 24, 8, 11, }, .MaxMass = 78, @@ -117,7 +116,6 @@ constexpr RideTypeDescriptor MultiDimensionRollerCoasterAltRTD = .LegacyBoosterSettings = { 25, 25 }, .Naming = { STR_RIDE_NAME_38, STR_RIDE_DESCRIPTION_UNKNOWN }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER_ALT", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 40, 24, 8, 11, }, .MaxMass = 78, diff --git a/src/openrct2/ride/rtd/coaster/ReverseFreefallCoaster.h b/src/openrct2/ride/rtd/coaster/ReverseFreefallCoaster.h index 7c9a858af4..1f662b5e3e 100644 --- a/src/openrct2/ride/rtd/coaster/ReverseFreefallCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ReverseFreefallCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor ReverseFreefallCoasterRTD = .LegacyBoosterSettings = { 40, 40 }, .Naming = { STR_RIDE_NAME_REVERSE_FREEFALL_COASTER, STR_RIDE_DESCRIPTION_REVERSE_FREEFALL_COASTER }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_REVERSE_FREEFALL_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 32, 4, 7, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/coaster/ReverserRollerCoaster.h b/src/openrct2/ride/rtd/coaster/ReverserRollerCoaster.h index e171a308c3..3a0a12aa29 100644 --- a/src/openrct2/ride/rtd/coaster/ReverserRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/ReverserRollerCoaster.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor ReverserRollerCoasterRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_REVERSER_ROLLER_COASTER, STR_RIDE_DESCRIPTION_REVERSER_ROLLER_COASTER }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_REVERSER_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 18, 24, 8, 11, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/coaster/SideFrictionRollerCoaster.h b/src/openrct2/ride/rtd/coaster/SideFrictionRollerCoaster.h index f3fe4f0f16..7e23552977 100644 --- a/src/openrct2/ride/rtd/coaster/SideFrictionRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/SideFrictionRollerCoaster.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor SideFrictionRollerCoasterRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_SIDE_FRICTION_ROLLER_COASTER, STR_RIDE_DESCRIPTION_SIDE_FRICTION_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 18, 24, 4, 11, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/coaster/SingleRailRollerCoaster.h b/src/openrct2/ride/rtd/coaster/SingleRailRollerCoaster.h index 5ee27b781c..735c561b0e 100644 --- a/src/openrct2/ride/rtd/coaster/SingleRailRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/SingleRailRollerCoaster.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor SingleRailRollerCoasterRTD = .LegacyBoosterSettings = { 15, 52 }, .Naming = { STR_RIDE_NAME_SINGLE_RAIL_ROLLER_COASTER, STR_RIDE_DESCRIPTION_SINGLE_RAIL_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 28, 24, 5, 7}, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/SpinningWildMouse.h b/src/openrct2/ride/rtd/coaster/SpinningWildMouse.h index d92370ce92..d32207c972 100644 --- a/src/openrct2/ride/rtd/coaster/SpinningWildMouse.h +++ b/src/openrct2/ride/rtd/coaster/SpinningWildMouse.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor SpinningWildMouseRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_SPINNING_WILD_MOUSE, STR_RIDE_DESCRIPTION_SPINNING_WILD_MOUSE }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SPINNING_WILD_MOUSE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 16, 24, 4, 7, }, .MaxMass = 4, diff --git a/src/openrct2/ride/rtd/coaster/SpiralRollerCoaster.h b/src/openrct2/ride/rtd/coaster/SpiralRollerCoaster.h index 963127fb04..89785d79e7 100644 --- a/src/openrct2/ride/rtd/coaster/SpiralRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/SpiralRollerCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor SpiralRollerCoasterRTD = .LegacyBoosterSettings = { 17, 17 }, .Naming = { STR_RIDE_NAME_SPIRAL_ROLLER_COASTER, STR_RIDE_DESCRIPTION_SPIRAL_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SPIRAL_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 19, 24, 9, 11, }, .MaxMass = 31, diff --git a/src/openrct2/ride/rtd/coaster/StandUpRollerCoaster.h b/src/openrct2/ride/rtd/coaster/StandUpRollerCoaster.h index ba38784585..2d6c9555d6 100644 --- a/src/openrct2/ride/rtd/coaster/StandUpRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/StandUpRollerCoaster.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor StandUpRollerCoasterRTD = .OperatingSettings = { 7, 27 }, .Naming = { STR_RIDE_NAME_STAND_UP_ROLLER_COASTER, STR_RIDE_DESCRIPTION_STAND_UP_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_STAND_UP_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 25, 24, 9, 11, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/coaster/SteelWildMouse.h b/src/openrct2/ride/rtd/coaster/SteelWildMouse.h index 1bbc323db8..553bc49ceb 100644 --- a/src/openrct2/ride/rtd/coaster/SteelWildMouse.h +++ b/src/openrct2/ride/rtd/coaster/SteelWildMouse.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor SteelWildMouseRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_WILD_MOUSE, STR_RIDE_DESCRIPTION_WILD_MOUSE }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_STEEL_WILD_MOUSE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 16, 24, 4, 7, }, .MaxMass = 4, diff --git a/src/openrct2/ride/rtd/coaster/Steeplechase.h b/src/openrct2/ride/rtd/coaster/Steeplechase.h index 57262e10cb..f57690723b 100644 --- a/src/openrct2/ride/rtd/coaster/Steeplechase.h +++ b/src/openrct2/ride/rtd/coaster/Steeplechase.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor SteeplechaseRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_STEEPLECHASE, STR_RIDE_DESCRIPTION_STEEPLECHASE }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_STEEPLECHASE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 14, 24, 7, 7, }, .MaxMass = 4, diff --git a/src/openrct2/ride/rtd/coaster/SuspendedSwingingCoaster.h b/src/openrct2/ride/rtd/coaster/SuspendedSwingingCoaster.h index c8fb3f555f..53ba3f6834 100644 --- a/src/openrct2/ride/rtd/coaster/SuspendedSwingingCoaster.h +++ b/src/openrct2/ride/rtd/coaster/SuspendedSwingingCoaster.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor SuspendedSwingingCoasterRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_SUSPENDED_SWINGING_COASTER, STR_RIDE_DESCRIPTION_SUSPENDED_SWINGING_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SUSPENDED_SWINGING_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 24, 40, 29, 8, }, .MaxMass = 26, diff --git a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h index e69594d296..841f8f6249 100644 --- a/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/TwisterRollerCoaster.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor TwisterRollerCoasterRTD = .LegacyBoosterSettings = { 17, 68 }, .Naming = { STR_RIDE_NAME_TWISTER_ROLLER_COASTER, STR_RIDE_DESCRIPTION_TWISTER_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_TWISTER_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 40, 24, 8, 9, }, .MaxMass = 31, diff --git a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h index a24af87074..1b159dceab 100644 --- a/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h +++ b/src/openrct2/ride/rtd/coaster/VerticalDropCoaster.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor VerticalDropCoasterRTD = .LegacyBoosterSettings = { 17, 68 }, .Naming = { STR_RIDE_NAME_VERTICAL_DROP_ROLLER_COASTER, STR_RIDE_DESCRIPTION_VERTICAL_DROP_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 55, 24, 8, 11, }, .MaxMass = 25, diff --git a/src/openrct2/ride/rtd/coaster/VirginiaReel.h b/src/openrct2/ride/rtd/coaster/VirginiaReel.h index e98045dd52..0b536b1d99 100644 --- a/src/openrct2/ride/rtd/coaster/VirginiaReel.h +++ b/src/openrct2/ride/rtd/coaster/VirginiaReel.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor VirginiaReelRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_VIRGINIA_REEL, STR_RIDE_DESCRIPTION_VIRGINIA_REEL }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_VIRGINIA_REEL", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 14, 24, 6, 7, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/coaster/WaterCoaster.h b/src/openrct2/ride/rtd/coaster/WaterCoaster.h index 639aeb2917..7d7745523f 100644 --- a/src/openrct2/ride/rtd/coaster/WaterCoaster.h +++ b/src/openrct2/ride/rtd/coaster/WaterCoaster.h @@ -49,7 +49,6 @@ constexpr RideTypeDescriptor WaterCoasterRTD = .LegacyBoosterSettings = { 17, 16, 1 }, .Naming = { STR_RIDE_NAME_WATER_COASTER, STR_RIDE_DESCRIPTION_WATER_COASTER }, .NameConvention = { RideComponentType::Boat, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_WATER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 18, 24, 4, 7, }, .MaxMass = 13, diff --git a/src/openrct2/ride/rtd/coaster/WoodenRollerCoaster.h b/src/openrct2/ride/rtd/coaster/WoodenRollerCoaster.h index 5cf58d8ffe..b1947d6fe3 100644 --- a/src/openrct2/ride/rtd/coaster/WoodenRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/WoodenRollerCoaster.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor WoodenRollerCoasterRTD = .LegacyBoosterSettings = { 0, 68 }, .Naming = { STR_RIDE_NAME_WOODEN_ROLLER_COASTER, STR_RIDE_DESCRIPTION_WOODEN_ROLLER_COASTER }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_WOODEN_ROLLER_COASTER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 41, 24, 8, 11, }, .MaxMass = 19, diff --git a/src/openrct2/ride/rtd/coaster/WoodenWildMouse.h b/src/openrct2/ride/rtd/coaster/WoodenWildMouse.h index 54aaadbb7a..5ca73a52cf 100644 --- a/src/openrct2/ride/rtd/coaster/WoodenWildMouse.h +++ b/src/openrct2/ride/rtd/coaster/WoodenWildMouse.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor WoodenWildMouseRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_WOODEN_WILD_MOUSE, STR_RIDE_DESCRIPTION_WOODEN_WILD_MOUSE }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_WOODEN_WILD_MOUSE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), .Heights = { 14, 24, 4, 7, }, .MaxMass = 4, diff --git a/src/openrct2/ride/rtd/gentle/CarRide.h b/src/openrct2/ride/rtd/gentle/CarRide.h index 2ca48f56a0..eaf8841c62 100644 --- a/src/openrct2/ride/rtd/gentle/CarRide.h +++ b/src/openrct2/ride/rtd/gentle/CarRide.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor CarRideRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_CAR_RIDE, STR_RIDE_DESCRIPTION_CAR_RIDE }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CAR_RIDE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 6, 24, 4, 7, }, .MaxMass = 2, diff --git a/src/openrct2/ride/rtd/gentle/Circus.h b/src/openrct2/ride/rtd/gentle/Circus.h index ad5ab81412..bec6193f99 100644 --- a/src/openrct2/ride/rtd/gentle/Circus.h +++ b/src/openrct2/ride/rtd/gentle/Circus.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor CircusRTD = .DefaultMode = RideMode::Circus, .Naming = { STR_RIDE_NAME_CIRCUS, STR_RIDE_DESCRIPTION_CIRCUS }, .NameConvention = { RideComponentType::Building, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CIRCUS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 12, 128, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/CrookedHouse.h b/src/openrct2/ride/rtd/gentle/CrookedHouse.h index b2a38d768c..1d30eae8f2 100644 --- a/src/openrct2/ride/rtd/gentle/CrookedHouse.h +++ b/src/openrct2/ride/rtd/gentle/CrookedHouse.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor CrookedHouseRTD = .DefaultMode = RideMode::CrookedHouse, .Naming = { STR_RIDE_NAME_CROOKED_HOUSE, STR_RIDE_DESCRIPTION_CROOKED_HOUSE }, .NameConvention = { RideComponentType::Building, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CROOKED_HOUSE", .AvailableBreakdowns = 0, .Heights = { 16, 96, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/Dodgems.h b/src/openrct2/ride/rtd/gentle/Dodgems.h index 44067abeea..3b48d42e76 100644 --- a/src/openrct2/ride/rtd/gentle/Dodgems.h +++ b/src/openrct2/ride/rtd/gentle/Dodgems.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor DodgemsRTD = .OperatingSettings = { 20, 180 }, .Naming = { STR_RIDE_NAME_DODGEMS, STR_RIDE_DESCRIPTION_DODGEMS }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_DODGEMS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 9, 48, 2, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/FerrisWheel.h b/src/openrct2/ride/rtd/gentle/FerrisWheel.h index fd7070bfa8..afae1776c3 100644 --- a/src/openrct2/ride/rtd/gentle/FerrisWheel.h +++ b/src/openrct2/ride/rtd/gentle/FerrisWheel.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor FerrisWheelRTD = .OperatingSettings = { 1, 3 }, .Naming = { STR_RIDE_NAME_FERRIS_WHEEL, STR_RIDE_DESCRIPTION_FERRIS_WHEEL }, .NameConvention = { RideComponentType::Wheel, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_FERRIS_WHEEL", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 16, 176, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/FlyingSaucers.h b/src/openrct2/ride/rtd/gentle/FlyingSaucers.h index fc6ca4c05c..15d37f137d 100644 --- a/src/openrct2/ride/rtd/gentle/FlyingSaucers.h +++ b/src/openrct2/ride/rtd/gentle/FlyingSaucers.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor FlyingSaucersRTD = .OperatingSettings = { 20, 180 }, .Naming = { STR_RIDE_NAME_FLYING_SAUCERS, STR_RIDE_DESCRIPTION_FLYING_SAUCERS }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_FLYING_SAUCERS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 9, 48, 2, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/GhostTrain.h b/src/openrct2/ride/rtd/gentle/GhostTrain.h index 8ec480ea23..f9c00ea842 100644 --- a/src/openrct2/ride/rtd/gentle/GhostTrain.h +++ b/src/openrct2/ride/rtd/gentle/GhostTrain.h @@ -38,7 +38,6 @@ constexpr RideTypeDescriptor GhostTrainRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_GHOST_TRAIN, STR_RIDE_DESCRIPTION_GHOST_TRAIN }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_GHOST_TRAIN", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 8, 24, 6, 7, }, .MaxMass = 2, diff --git a/src/openrct2/ride/rtd/gentle/HauntedHouse.h b/src/openrct2/ride/rtd/gentle/HauntedHouse.h index 9ad736cfb2..33f64c420d 100644 --- a/src/openrct2/ride/rtd/gentle/HauntedHouse.h +++ b/src/openrct2/ride/rtd/gentle/HauntedHouse.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor HauntedHouseRTD = .DefaultMode = RideMode::HauntedHouse, .Naming = { STR_RIDE_NAME_HAUNTED_HOUSE, STR_RIDE_DESCRIPTION_HAUNTED_HOUSE }, .NameConvention = { RideComponentType::Building, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_HAUNTED_HOUSE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 16, 160, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/Maze.h b/src/openrct2/ride/rtd/gentle/Maze.h index ff9891c763..e3dc2616b4 100644 --- a/src/openrct2/ride/rtd/gentle/Maze.h +++ b/src/openrct2/ride/rtd/gentle/Maze.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor MazeRTD = .OperatingSettings = { 1, 64 }, .Naming = { STR_RIDE_NAME_MAZE, STR_RIDE_DESCRIPTION_MAZE }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MAZE", .AvailableBreakdowns = 0, .Heights = { 6, 24, 0, 1, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/gentle/MerryGoRound.h b/src/openrct2/ride/rtd/gentle/MerryGoRound.h index 44ac6657f2..2525ccf736 100644 --- a/src/openrct2/ride/rtd/gentle/MerryGoRound.h +++ b/src/openrct2/ride/rtd/gentle/MerryGoRound.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor MerryGoRoundRTD = .OperatingSettings = { 4, 25 }, .Naming = { STR_RIDE_NAME_MERRY_GO_ROUND, STR_RIDE_DESCRIPTION_MERRY_GO_ROUND }, .NameConvention = { RideComponentType::Car, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MERRY_GO_ROUND", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), .Heights = { 12, 64, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/MiniGolf.h b/src/openrct2/ride/rtd/gentle/MiniGolf.h index ac1766ee68..f06e988df1 100644 --- a/src/openrct2/ride/rtd/gentle/MiniGolf.h +++ b/src/openrct2/ride/rtd/gentle/MiniGolf.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor MiniGolfRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MINI_GOLF, STR_RIDE_DESCRIPTION_MINI_GOLF }, .NameConvention = { RideComponentType::Player, RideComponentType::Course, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MINI_GOLF", .AvailableBreakdowns = 0, .Heights = { 7, 32, 2, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/MiniHelicopters.h b/src/openrct2/ride/rtd/gentle/MiniHelicopters.h index d58025d9ca..221757b64f 100644 --- a/src/openrct2/ride/rtd/gentle/MiniHelicopters.h +++ b/src/openrct2/ride/rtd/gentle/MiniHelicopters.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor MiniHelicoptersRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MINI_HELICOPTERS, STR_RIDE_DESCRIPTION_MINI_HELICOPTERS }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MINI_HELICOPTERS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 7, 24, 4, 7, }, .MaxMass = 2, diff --git a/src/openrct2/ride/rtd/gentle/MonorailCycles.h b/src/openrct2/ride/rtd/gentle/MonorailCycles.h index 73bd5cdb19..60e36a770c 100644 --- a/src/openrct2/ride/rtd/gentle/MonorailCycles.h +++ b/src/openrct2/ride/rtd/gentle/MonorailCycles.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor MonorailCyclesRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MONORAIL_CYCLES, STR_RIDE_DESCRIPTION_MONORAIL_CYCLES }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MONORAIL_CYCLES", .AvailableBreakdowns = (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 5, 24, 8, 7, }, .MaxMass = 2, diff --git a/src/openrct2/ride/rtd/gentle/MonsterTrucks.h b/src/openrct2/ride/rtd/gentle/MonsterTrucks.h index d3a5e432fa..8c8f203b38 100644 --- a/src/openrct2/ride/rtd/gentle/MonsterTrucks.h +++ b/src/openrct2/ride/rtd/gentle/MonsterTrucks.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor MonsterTrucksRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MONSTER_TRUCKS, STR_RIDE_DESCRIPTION_MONSTER_TRUCKS }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MONSTER_TRUCKS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 18, 24, 4, 7, }, .MaxMass = 2, diff --git a/src/openrct2/ride/rtd/gentle/ObservationTower.h b/src/openrct2/ride/rtd/gentle/ObservationTower.h index baa711be27..1e5169f263 100644 --- a/src/openrct2/ride/rtd/gentle/ObservationTower.h +++ b/src/openrct2/ride/rtd/gentle/ObservationTower.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor ObservationTowerRTD = .DefaultMode = RideMode::RotatingLift, .Naming = { STR_RIDE_NAME_OBSERVATION_TOWER, STR_RIDE_DESCRIPTION_OBSERVATION_TOWER }, .NameConvention = { RideComponentType::Cabin, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_OBSERVATION_TOWER", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 32, 3, 2, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/gentle/SpaceRings.h b/src/openrct2/ride/rtd/gentle/SpaceRings.h index 793a9e0c8c..59b5b0504b 100644 --- a/src/openrct2/ride/rtd/gentle/SpaceRings.h +++ b/src/openrct2/ride/rtd/gentle/SpaceRings.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor SpaceRingsRTD = .DefaultMode = RideMode::SpaceRings, .Naming = { STR_RIDE_NAME_SPACE_RINGS, STR_RIDE_DESCRIPTION_SPACE_RINGS }, .NameConvention = { RideComponentType::Ring, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SPACE_RINGS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 16, 48, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/gentle/SpiralSlide.h b/src/openrct2/ride/rtd/gentle/SpiralSlide.h index 2e33bd06d3..be22034f39 100644 --- a/src/openrct2/ride/rtd/gentle/SpiralSlide.h +++ b/src/openrct2/ride/rtd/gentle/SpiralSlide.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor SpiralSlideRTD = .OperatingSettings = { 1, 5 }, .Naming = { STR_RIDE_NAME_SPIRAL_SLIDE, STR_RIDE_DESCRIPTION_SPIRAL_SLIDE }, .NameConvention = { RideComponentType::Train, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SPIRAL_SLIDE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 15, 128, 0, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/shops/CashMachine.h b/src/openrct2/ride/rtd/shops/CashMachine.h index 3ed5d112c4..8865bbf4a8 100644 --- a/src/openrct2/ride/rtd/shops/CashMachine.h +++ b/src/openrct2/ride/rtd/shops/CashMachine.h @@ -31,7 +31,6 @@ constexpr RideTypeDescriptor CashMachineRTD = .DefaultMode = RideMode::ShopStall, .Naming = { STR_RIDE_NAME_CASH_MACHINE, STR_RIDE_DESCRIPTION_CASH_MACHINE }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CASH_MACHINE", .AvailableBreakdowns = 0, .Heights = { 12, DefaultCashMachineHeight, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/shops/DrinkStall.h b/src/openrct2/ride/rtd/shops/DrinkStall.h index 4a65a7363c..562933a666 100644 --- a/src/openrct2/ride/rtd/shops/DrinkStall.h +++ b/src/openrct2/ride/rtd/shops/DrinkStall.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor DrinkStallRTD = .DefaultMode = RideMode::ShopStall, .Naming = { STR_RIDE_NAME_DRINK_STALL, STR_RIDE_DESCRIPTION_DRINK_STALL }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_DRINK_STALL", .AvailableBreakdowns = 0, .Heights = { 12, DefaultDrinksStallHeight, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/shops/FirstAid.h b/src/openrct2/ride/rtd/shops/FirstAid.h index ca60bbf063..553f3f4fd0 100644 --- a/src/openrct2/ride/rtd/shops/FirstAid.h +++ b/src/openrct2/ride/rtd/shops/FirstAid.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor FirstAidRTD = .OperatingSettings = { 8, 8 }, .Naming = { STR_RIDE_NAME_FIRST_AID, STR_RIDE_DESCRIPTION_FIRST_AID }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_FIRST_AID", .AvailableBreakdowns = 0, .Heights = { 12, DefaultFirstAidHeight, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/shops/FoodStall.h b/src/openrct2/ride/rtd/shops/FoodStall.h index 8c545c60ee..62d63a91b1 100644 --- a/src/openrct2/ride/rtd/shops/FoodStall.h +++ b/src/openrct2/ride/rtd/shops/FoodStall.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor FoodStallRTD = .DefaultMode = RideMode::ShopStall, .Naming = { STR_RIDE_NAME_FOOD_STALL, STR_RIDE_DESCRIPTION_FOOD_STALL }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_FOOD_STALL", .AvailableBreakdowns = 0, .Heights = { 12, DefaultFoodStallHeight, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/shops/InformationKiosk.h b/src/openrct2/ride/rtd/shops/InformationKiosk.h index 89b509173c..cb9ec5b63d 100644 --- a/src/openrct2/ride/rtd/shops/InformationKiosk.h +++ b/src/openrct2/ride/rtd/shops/InformationKiosk.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor InformationKioskRTD = .DefaultMode = RideMode::ShopStall, .Naming = { STR_RIDE_NAME_INFORMATION_KIOSK, STR_RIDE_DESCRIPTION_INFORMATION_KIOSK }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_INFORMATION_KIOSK", .AvailableBreakdowns = 0, .Heights = { 12, DefaultInformationKioskHeight, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/shops/Shop.h b/src/openrct2/ride/rtd/shops/Shop.h index 239a3bab27..a4ab313758 100644 --- a/src/openrct2/ride/rtd/shops/Shop.h +++ b/src/openrct2/ride/rtd/shops/Shop.h @@ -32,7 +32,6 @@ constexpr RideTypeDescriptor ShopRTD = .DefaultMode = RideMode::ShopStall, .Naming = { STR_RIDE_NAME_SHOP, STR_RIDE_DESCRIPTION_SHOP }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SHOP", .AvailableBreakdowns = 0, .Heights = { 12, DefaultShopHeight, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/shops/Toilets.h b/src/openrct2/ride/rtd/shops/Toilets.h index adff80f683..5e60e15896 100644 --- a/src/openrct2/ride/rtd/shops/Toilets.h +++ b/src/openrct2/ride/rtd/shops/Toilets.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor ToiletsRTD = .OperatingSettings = { 4, 4 }, .Naming = { STR_RIDE_NAME_TOILETS, STR_RIDE_DESCRIPTION_TOILETS }, .NameConvention = { RideComponentType::Car, RideComponentType::Building, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_TOILETS", .AvailableBreakdowns = 0, .Heights = { 12, DefaultToiletHeight, 0, 0, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/3DCinema.h b/src/openrct2/ride/rtd/thrill/3DCinema.h index 3fe96de6ff..d9234a99ea 100644 --- a/src/openrct2/ride/rtd/thrill/3DCinema.h +++ b/src/openrct2/ride/rtd/thrill/3DCinema.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor CinemaRTD = .DefaultMode = RideMode::MouseTails3DFilm, .Naming = { STR_RIDE_NAME_3D_CINEMA, STR_RIDE_DESCRIPTION_3D_CINEMA }, .NameConvention = { RideComponentType::Building, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_3D_CINEMA", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 12, 128, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/Enterprise.h b/src/openrct2/ride/rtd/thrill/Enterprise.h index 9a794dd58e..58ea36848f 100644 --- a/src/openrct2/ride/rtd/thrill/Enterprise.h +++ b/src/openrct2/ride/rtd/thrill/Enterprise.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor EnterpriseRTD = .OperatingSettings = { 10, 20 }, .Naming = { STR_RIDE_NAME_ENTERPRISE, STR_RIDE_DESCRIPTION_ENTERPRISE }, .NameConvention = { RideComponentType::Wheel, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_ENTERPRISE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 16, 160, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/GoKarts.h b/src/openrct2/ride/rtd/thrill/GoKarts.h index 411fbd751e..1b9dd6b837 100644 --- a/src/openrct2/ride/rtd/thrill/GoKarts.h +++ b/src/openrct2/ride/rtd/thrill/GoKarts.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor GoKartsRTD = .OperatingSettings = { 1, 10 }, .Naming = { STR_RIDE_NAME_GO_KARTS, STR_RIDE_DESCRIPTION_GO_KARTS }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_GO_KARTS", .AvailableBreakdowns = (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 7, 24, 2, 1, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/LaunchedFreefall.h b/src/openrct2/ride/rtd/thrill/LaunchedFreefall.h index 8619ecc566..0a80e45a99 100644 --- a/src/openrct2/ride/rtd/thrill/LaunchedFreefall.h +++ b/src/openrct2/ride/rtd/thrill/LaunchedFreefall.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor LaunchedFreefallRTD = .OperatingSettings = { 10, 40 }, .Naming = { STR_RIDE_NAME_LAUNCHED_FREEFALL, STR_RIDE_DESCRIPTION_LAUNCHED_FREEFALL }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_LAUNCHED_FREEFALL", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 32, 3, 2, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/thrill/MagicCarpet.h b/src/openrct2/ride/rtd/thrill/MagicCarpet.h index 6830542abe..40cede2fdb 100644 --- a/src/openrct2/ride/rtd/thrill/MagicCarpet.h +++ b/src/openrct2/ride/rtd/thrill/MagicCarpet.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor MagicCarpetRTD = .OperatingSettings = { 7, 15 }, .Naming = { STR_RIDE_NAME_MAGIC_CARPET, STR_RIDE_DESCRIPTION_MAGIC_CARPET }, .NameConvention = { RideComponentType::Car, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MAGIC_CARPET", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 15, 176, 7, 11, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/MotionSimulator.h b/src/openrct2/ride/rtd/thrill/MotionSimulator.h index b1d1bf0d89..f600dc221e 100644 --- a/src/openrct2/ride/rtd/thrill/MotionSimulator.h +++ b/src/openrct2/ride/rtd/thrill/MotionSimulator.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor MotionSimulatorRTD = .DefaultMode = RideMode::FilmAvengingAviators, .Naming = { STR_RIDE_NAME_MOTION_SIMULATOR, STR_RIDE_DESCRIPTION_MOTION_SIMULATOR }, .NameConvention = { RideComponentType::Car, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MOTION_SIMULATOR", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 12, 64, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/RotoDrop.h b/src/openrct2/ride/rtd/thrill/RotoDrop.h index f60e4bf93e..a6271bf6a1 100644 --- a/src/openrct2/ride/rtd/thrill/RotoDrop.h +++ b/src/openrct2/ride/rtd/thrill/RotoDrop.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor RotoDropRTD = .DefaultMode = RideMode::FreefallDrop, .Naming = { STR_RIDE_NAME_ROTO_DROP, STR_RIDE_DESCRIPTION_ROTO_DROP }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_ROTO_DROP", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 32, 3, 2, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/thrill/SwingingInverterShip.h b/src/openrct2/ride/rtd/thrill/SwingingInverterShip.h index 66af0b1981..6b2275719f 100644 --- a/src/openrct2/ride/rtd/thrill/SwingingInverterShip.h +++ b/src/openrct2/ride/rtd/thrill/SwingingInverterShip.h @@ -35,7 +35,6 @@ constexpr RideTypeDescriptor SwingingInverterShipRTD = .OperatingSettings = { 7, 15 }, .Naming = { STR_RIDE_NAME_SWINGING_INVERTER_SHIP, STR_RIDE_DESCRIPTION_SWINGING_INVERTER_SHIP }, .NameConvention = { RideComponentType::Ship, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SWINGING_INVERTER_SHIP", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 15, 176, 7, 11, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/SwingingShip.h b/src/openrct2/ride/rtd/thrill/SwingingShip.h index 9e6a8d3a65..30dca2caa5 100644 --- a/src/openrct2/ride/rtd/thrill/SwingingShip.h +++ b/src/openrct2/ride/rtd/thrill/SwingingShip.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor SwingingShipRTD = .OperatingSettings = { 7, 25 }, .Naming = { STR_RIDE_NAME_SWINGING_SHIP, STR_RIDE_DESCRIPTION_SWINGING_SHIP }, .NameConvention = { RideComponentType::Ship, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SWINGING_SHIP", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 12, 112, 7, 11, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/TopSpin.h b/src/openrct2/ride/rtd/thrill/TopSpin.h index f46cdbfe4a..41c5d022eb 100644 --- a/src/openrct2/ride/rtd/thrill/TopSpin.h +++ b/src/openrct2/ride/rtd/thrill/TopSpin.h @@ -34,7 +34,6 @@ constexpr RideTypeDescriptor TopSpinRTD = .DefaultMode = RideMode::Beginners, .Naming = { STR_RIDE_NAME_TOP_SPIN, STR_RIDE_DESCRIPTION_TOP_SPIN }, .NameConvention = { RideComponentType::Car, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_TOP_SPIN", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 16, 112, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/thrill/Twist.h b/src/openrct2/ride/rtd/thrill/Twist.h index 5ab908ae3d..958d1177ec 100644 --- a/src/openrct2/ride/rtd/thrill/Twist.h +++ b/src/openrct2/ride/rtd/thrill/Twist.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor TwistRTD = .OperatingSettings = { 3, 6, 3 }, .Naming = { STR_RIDE_NAME_TWIST, STR_RIDE_DESCRIPTION_TWIST }, .NameConvention = { RideComponentType::Structure, RideComponentType::Structure, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_TWIST", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 12, 64, 3, 2, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/transport/Chairlift.h b/src/openrct2/ride/rtd/transport/Chairlift.h index 937e60eec4..d2d4f96ff4 100644 --- a/src/openrct2/ride/rtd/transport/Chairlift.h +++ b/src/openrct2/ride/rtd/transport/Chairlift.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor ChairliftRTD = .OperatingSettings = { 1, 4 }, .Naming = { STR_RIDE_NAME_CHAIRLIFT, STR_RIDE_DESCRIPTION_CHAIRLIFT }, .NameConvention = { RideComponentType::Car, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_CHAIRLIFT", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 40, 32, 28, 2, }, .MaxMass = 18, diff --git a/src/openrct2/ride/rtd/transport/Lift.h b/src/openrct2/ride/rtd/transport/Lift.h index cef2d8980f..5e0c763ee3 100644 --- a/src/openrct2/ride/rtd/transport/Lift.h +++ b/src/openrct2/ride/rtd/transport/Lift.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor LiftRTD = .DefaultMode = RideMode::Shuttle, .Naming = { STR_RIDE_NAME_LIFT, STR_RIDE_DESCRIPTION_LIFT }, .NameConvention = { RideComponentType::Cabin, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_LIFT", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 32, 3, 2, }, .MaxMass = 15, diff --git a/src/openrct2/ride/rtd/transport/MiniatureRailway.h b/src/openrct2/ride/rtd/transport/MiniatureRailway.h index b6201d9fb8..b254ec344c 100644 --- a/src/openrct2/ride/rtd/transport/MiniatureRailway.h +++ b/src/openrct2/ride/rtd/transport/MiniatureRailway.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor MiniatureRailwayRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MINIATURE_RAILWAY, STR_RIDE_DESCRIPTION_MINIATURE_RAILWAY }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MINIATURE_RAILWAY", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 7, 32, 5, 9, }, .MaxMass = 39, diff --git a/src/openrct2/ride/rtd/transport/Monorail.h b/src/openrct2/ride/rtd/transport/Monorail.h index a27ce1ebcd..5933298fed 100644 --- a/src/openrct2/ride/rtd/transport/Monorail.h +++ b/src/openrct2/ride/rtd/transport/Monorail.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor MonorailRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_MONORAIL, STR_RIDE_DESCRIPTION_MONORAIL }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_MONORAIL", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 8, 32, 8, 9, }, .MaxMass = 78, diff --git a/src/openrct2/ride/rtd/transport/SuspendedMonorail.h b/src/openrct2/ride/rtd/transport/SuspendedMonorail.h index e94ca6b30c..b0fd090aee 100644 --- a/src/openrct2/ride/rtd/transport/SuspendedMonorail.h +++ b/src/openrct2/ride/rtd/transport/SuspendedMonorail.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor SuspendedMonorailRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_SUSPENDED_MONORAIL, STR_RIDE_DESCRIPTION_SUSPENDED_MONORAIL }, .NameConvention = { RideComponentType::Train, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SUSPENDED_MONORAIL", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 12, 40, 32, 8, }, .MaxMass = 78, diff --git a/src/openrct2/ride/rtd/water/BoatHire.h b/src/openrct2/ride/rtd/water/BoatHire.h index 3d9ab1844c..cafff1d78f 100644 --- a/src/openrct2/ride/rtd/water/BoatHire.h +++ b/src/openrct2/ride/rtd/water/BoatHire.h @@ -33,7 +33,6 @@ constexpr RideTypeDescriptor BoatHireRTD = .DefaultMode = RideMode::BoatHire, .Naming = { STR_RIDE_NAME_BOAT_HIRE, STR_RIDE_DESCRIPTION_BOAT_HIRE }, .NameConvention = { RideComponentType::Boat, RideComponentType::DockingPlatform, RideComponentType::DockingPlatform }, - .EnumName = "RIDE_TYPE_BOAT_HIRE", .AvailableBreakdowns = (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 16, 0, 3, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/water/DinghySlide.h b/src/openrct2/ride/rtd/water/DinghySlide.h index fbd0f8eea9..a1314111b4 100644 --- a/src/openrct2/ride/rtd/water/DinghySlide.h +++ b/src/openrct2/ride/rtd/water/DinghySlide.h @@ -50,7 +50,6 @@ constexpr RideTypeDescriptor DinghySlideRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_DINGHY_SLIDE, STR_RIDE_DESCRIPTION_DINGHY_SLIDE }, .NameConvention = { RideComponentType::Boat, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_DINGHY_SLIDE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 15, 24, 5, 7, }, .MaxMass = 5, diff --git a/src/openrct2/ride/rtd/water/LogFlume.h b/src/openrct2/ride/rtd/water/LogFlume.h index 7909fb109d..f4bae6ee9d 100644 --- a/src/openrct2/ride/rtd/water/LogFlume.h +++ b/src/openrct2/ride/rtd/water/LogFlume.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor LogFlumeRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_LOG_FLUME, STR_RIDE_DESCRIPTION_LOG_FLUME }, .NameConvention = { RideComponentType::Boat, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_LOG_FLUME", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), .Heights = { 10, 24, 7, 9, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/water/RiverRafts.h b/src/openrct2/ride/rtd/water/RiverRafts.h index 6ed052bd83..ae7febaa55 100644 --- a/src/openrct2/ride/rtd/water/RiverRafts.h +++ b/src/openrct2/ride/rtd/water/RiverRafts.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor RiverRaftsRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_RIVER_RAFTS, STR_RIDE_DESCRIPTION_RIVER_RAFTS }, .NameConvention = { RideComponentType::Boat, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_RIVER_RAFTS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT), .Heights = { 12, 24, 7, 11, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/water/RiverRapids.h b/src/openrct2/ride/rtd/water/RiverRapids.h index 8ab7b5c81a..81bd264283 100644 --- a/src/openrct2/ride/rtd/water/RiverRapids.h +++ b/src/openrct2/ride/rtd/water/RiverRapids.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor RiverRapidsRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_RIVER_RAPIDS, STR_RIDE_DESCRIPTION_RIVER_RAPIDS }, .NameConvention = { RideComponentType::Boat, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_RIVER_RAPIDS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), .Heights = { 9, 32, 14, 15, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/water/SplashBoats.h b/src/openrct2/ride/rtd/water/SplashBoats.h index bef454e92f..a44c58c82c 100644 --- a/src/openrct2/ride/rtd/water/SplashBoats.h +++ b/src/openrct2/ride/rtd/water/SplashBoats.h @@ -37,7 +37,6 @@ constexpr RideTypeDescriptor SplashBoatsRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_SPLASH_BOATS, STR_RIDE_DESCRIPTION_SPLASH_BOATS }, .NameConvention = { RideComponentType::Boat, RideComponentType::Track, RideComponentType::Station }, - .EnumName = "RIDE_TYPE_SPLASH_BOATS", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), .Heights = { 16, 24, 7, 11, }, .MaxMass = 255, diff --git a/src/openrct2/ride/rtd/water/SubmarineRide.h b/src/openrct2/ride/rtd/water/SubmarineRide.h index 1fe2f9dd6e..81f115837b 100644 --- a/src/openrct2/ride/rtd/water/SubmarineRide.h +++ b/src/openrct2/ride/rtd/water/SubmarineRide.h @@ -36,7 +36,6 @@ constexpr RideTypeDescriptor SubmarineRideRTD = .DefaultMode = RideMode::ContinuousCircuit, .Naming = { STR_RIDE_NAME_SUBMARINE_RIDE, STR_RIDE_DESCRIPTION_SUBMARINE_RIDE }, .NameConvention = { RideComponentType::Boat, RideComponentType::Track, RideComponentType::DockingPlatform }, - .EnumName = "RIDE_TYPE_SUBMARINE_RIDE", .AvailableBreakdowns = (1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), .Heights = { 255, 16, 0, 3, }, .MaxMass = 255, diff --git a/test/tests/RideRatings.cpp b/test/tests/RideRatings.cpp index c37fa03421..2348896267 100644 --- a/test/tests/RideRatings.cpp +++ b/test/tests/RideRatings.cpp @@ -47,9 +47,10 @@ protected: std::string FormatRatings(const Ride& ride) { RatingTuple ratings = ride.ratings; + auto name = std::string(ride.GetRideTypeDescriptor().Name); std::string line = String::StdFormat( - "%s: (%d, %d, %d)", ride.GetRideTypeDescriptor().EnumName, static_cast(ratings.excitement), - static_cast(ratings.intensity), static_cast(ratings.nausea)); + "%s: (%d, %d, %d)", name.c_str(), static_cast(ratings.excitement), static_cast(ratings.intensity), + static_cast(ratings.nausea)); return line; } diff --git a/test/tests/testdata/ratings/BigMapTest.sv6.txt b/test/tests/testdata/ratings/BigMapTest.sv6.txt index 7febcdaf81..f3f684f653 100644 --- a/test/tests/testdata/ratings/BigMapTest.sv6.txt +++ b/test/tests/testdata/ratings/BigMapTest.sv6.txt @@ -1,100 +1,100 @@ -RIDE_TYPE_MINIATURE_RAILWAY: (150, 15, 1) -RIDE_TYPE_MONORAIL: (299, 14, 6) -RIDE_TYPE_SUSPENDED_MONORAIL: (141, 19, 5) -RIDE_TYPE_CHAIRLIFT: (98, 23, 25) -RIDE_TYPE_LIFT: (579, 35, 102) -RIDE_TYPE_MONORAIL_CYCLES: (212, 28, 1) -RIDE_TYPE_CROOKED_HOUSE: (215, 62, 34) -RIDE_TYPE_HAUNTED_HOUSE: (341, 153, 10) -RIDE_TYPE_FERRIS_WHEEL: (88, 50, 55) -RIDE_TYPE_MAZE: (166, 122, 0) -RIDE_TYPE_MERRY_GO_ROUND: (167, 60, 75) -RIDE_TYPE_MINI_GOLF: (295, 90, 0) -RIDE_TYPE_OBSERVATION_TOWER: (302, 0, 74) -RIDE_TYPE_CAR_RIDE: (39, 29, 1) -RIDE_TYPE_MONSTER_TRUCKS: (376, 69, 6) -RIDE_TYPE_MINI_HELICOPTERS: (322, 48, 2) -RIDE_TYPE_SPIRAL_SLIDE: (150, 140, 90) -RIDE_TYPE_DODGEMS: (270, 80, 35) -RIDE_TYPE_SPACE_RINGS: (150, 210, 650) -RIDE_TYPE_CIRCUS: (210, 30, 0) -RIDE_TYPE_GHOST_TRAIN: (282, 42, 19) -RIDE_TYPE_FLYING_SAUCERS: (380, 85, 39) -RIDE_TYPE_VIRGINIA_REEL: (512, 487, 542) -RIDE_TYPE_REVERSER_ROLLER_COASTER: (506, 525, 388) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (626, 683, 382) -RIDE_TYPE_STEEL_WILD_MOUSE: (709, 784, 475) -RIDE_TYPE_SPINNING_WILD_MOUSE: (618, 667, 523) -RIDE_TYPE_INVERTED_HAIRPIN_COASTER: (656, 769, 460) -RIDE_TYPE_JUNIOR_ROLLER_COASTER: (475, 550, 366) -RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER: (279, 1158, 917) -RIDE_TYPE_MINI_ROLLER_COASTER: (495, 572, 383) -RIDE_TYPE_SPIRAL_ROLLER_COASTER: (591, 370, 192) -RIDE_TYPE_MINE_TRAIN_COASTER: (642, 708, 468) -RIDE_TYPE_LOOPING_ROLLER_COASTER: (606, 564, 264) -RIDE_TYPE_STAND_UP_ROLLER_COASTER: (536, 943, 644) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (613, 830, 365) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (632, 937, 529) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (784, 645, 372) -RIDE_TYPE_HYPER_TWISTER: (737, 620, 344) -RIDE_TYPE_GIGA_COASTER: (851, 545, 305) -RIDE_TYPE_INVERTED_ROLLER_COASTER: (703, 906, 716) -RIDE_TYPE_INVERTED_IMPULSE_COASTER: (648, 713, 567) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (533, 711, 480) -RIDE_TYPE_STEEPLECHASE: (573, 541, 390) -RIDE_TYPE_BOBSLEIGH_COASTER: (619, 657, 466) -RIDE_TYPE_MINE_RIDE: (564, 454, 376) -RIDE_TYPE_HEARTLINE_TWISTER_COASTER: (523, 837, 545) -RIDE_TYPE_LAY_DOWN_ROLLER_COASTER: (696, 664, 538) -RIDE_TYPE_FLYING_ROLLER_COASTER: (744, 690, 668) -RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER: (674, 833, 762) -RIDE_TYPE_REVERSE_FREEFALL_COASTER: (472, 744, 532) -RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER: (852, 892, 698) -RIDE_TYPE_WATER_COASTER: (-1, 0, 0) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_MAGIC_CARPET: (335, 340, 440) -RIDE_TYPE_LAUNCHED_FREEFALL: (368, 941, 563) -RIDE_TYPE_SWINGING_SHIP: (205, 245, 251) -RIDE_TYPE_GO_KARTS: (-1, 0, 0) -RIDE_TYPE_SWINGING_INVERTER_SHIP: (350, 468, 472) -RIDE_TYPE_MOTION_SIMULATOR: (290, 350, 300) -RIDE_TYPE_3D_CINEMA: (350, 240, 140) -RIDE_TYPE_TOP_SPIN: (200, 480, 574) -RIDE_TYPE_ROTO_DROP: (270, 1444, 1444) -RIDE_TYPE_ENTERPRISE: (374, 647, 764) -RIDE_TYPE_DINGHY_SLIDE: (484, 589, 354) -RIDE_TYPE_LOG_FLUME: (459, 236, 117) -RIDE_TYPE_RIVER_RAPIDS: (581, 169, 108) -RIDE_TYPE_SPLASH_BOATS: (422, 203, 102) -RIDE_TYPE_SUBMARINE_RIDE: (246, 180, 140) -RIDE_TYPE_BOAT_HIRE: (202, 80, 90) -RIDE_TYPE_RIVER_RAFTS: (243, 45, 43) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) +miniature_railway: (150, 15, 1) +monorail: (299, 14, 6) +suspended_monorail: (141, 19, 5) +chairlift: (98, 23, 25) +lift: (579, 35, 102) +monorail_cycles: (212, 28, 1) +crooked_house: (215, 62, 34) +haunted_house: (341, 153, 10) +ferris_wheel: (88, 50, 55) +maze: (166, 122, 0) +merry_go_round: (167, 60, 75) +mini_golf: (295, 90, 0) +observation_tower: (302, 0, 74) +car_ride: (39, 29, 1) +monster_trucks: (376, 69, 6) +mini_helicopters: (322, 48, 2) +spiral_slide: (150, 140, 90) +dodgems: (270, 80, 35) +space_rings: (150, 210, 650) +circus: (210, 30, 0) +ghost_train: (282, 42, 19) +flying_saucers: (380, 85, 39) +virginia_reel: (512, 487, 542) +reverser_rc: (506, 525, 388) +wooden_rc: (626, 683, 382) +steel_wild_mouse: (709, 784, 475) +spinning_wild_mouse: (618, 667, 523) +inverted_hairpin_rc: (656, 769, 460) +junior_rc: (475, 550, 366) +classic_mini_rc: (279, 1158, 917) +mini_rc: (495, 572, 383) +spiral_rc: (591, 370, 192) +mine_train_rc: (642, 708, 468) +looping_rc: (606, 564, 264) +stand_up_rc: (536, 943, 644) +corkscrew_rc: (613, 830, 365) +lim_launched_rc: (632, 937, 529) +twister_rc: (784, 645, 372) +hyper_twister: (737, 620, 344) +giga_rc: (851, 545, 305) +inverted_rc: (703, 906, 716) +inverted_impulse_rc: (648, 713, 567) +mini_suspended_rc: (533, 711, 480) +steeplechase: (573, 541, 390) +bobsleigh_rc: (619, 657, 466) +mine_ride: (564, 454, 376) +heartline_twister_rc: (523, 837, 545) +lay_down_rc: (696, 664, 538) +flying_rc: (744, 690, 668) +multi_dimension_rc: (674, 833, 762) +reverse_freefall_rc: (472, 744, 532) +air_powered_vertical_rc: (852, 892, 698) +water_coaster: (-1, 0, 0) +twist: (173, 157, 250) +magic_carpet: (335, 340, 440) +launched_freefall: (368, 941, 563) +swinging_ship: (205, 245, 251) +go_karts: (-1, 0, 0) +swinging_inverter_ship: (350, 468, 472) +motion_simulator: (290, 350, 300) +3d_cinema: (350, 240, 140) +top_spin: (200, 480, 574) +roto_drop: (270, 1444, 1444) +enterprise: (374, 647, 764) +dinghy_slide: (484, 589, 354) +log_flume: (459, 236, 117) +river_rapids: (581, 169, 108) +splash_boats: (422, 203, 102) +submarine_ride: (246, 180, 140) +boat_hire: (202, 80, 90) +river_rafts: (243, 45, 43) +information_kiosk: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +shop: (-1, 0, 0) +first_aid: (-1, 0, 0) +drink_stall: (-1, 0, 0) +first_aid: (-1, 0, 0) +shop: (-1, 0, 0) +food_stall: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +food_stall: (-1, 0, 0) +toilets: (-1, 0, 0) +toilets: (-1, 0, 0) +toilets: (-1, 0, 0) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +shop: (-1, 0, 0) +toilets: (-1, 0, 0) +first_aid: (-1, 0, 0) +first_aid: (-1, 0, 0) +first_aid: (-1, 0, 0) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +toilets: (-1, 0, 0) diff --git a/test/tests/testdata/ratings/EverythingPark.park.txt b/test/tests/testdata/ratings/EverythingPark.park.txt index 812c92259e..4a670df88f 100644 --- a/test/tests/testdata/ratings/EverythingPark.park.txt +++ b/test/tests/testdata/ratings/EverythingPark.park.txt @@ -1,529 +1,529 @@ -RIDE_TYPE_MERRY_GO_ROUND: (105, 60, 75) -RIDE_TYPE_LOOPING_ROLLER_COASTER: (646, 612, 271) -RIDE_TYPE_FOOD_STALL: (-1, 702, 346) -RIDE_TYPE_DRINK_STALL: (-1, 886, 620) -RIDE_TYPE_TOILETS: (-1, 245, 251) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 157, 250) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_JUNIOR_ROLLER_COASTER: (479, 583, 384) -RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER: (746, 768, 369) -RIDE_TYPE_MAZE: (155, 90, 0) -RIDE_TYPE_SWINGING_SHIP: (207, 245, 251) -RIDE_TYPE_BOAT_HIRE: (213, 80, 90) -RIDE_TYPE_ENTERPRISE: (372, 647, 764) -RIDE_TYPE_TOP_SPIN: (200, 480, 574) -RIDE_TYPE_HAUNTED_HOUSE: (341, 153, 10) -RIDE_TYPE_FOOD_STALL: (-1, 678, 684) -RIDE_TYPE_FOOD_STALL: (-1, 248, 131) -RIDE_TYPE_FOOD_STALL: (-1, 113, 67) -RIDE_TYPE_FOOD_STALL: (-1, 947, 763) -RIDE_TYPE_FOOD_STALL: (-1, 968, 559) -RIDE_TYPE_FOOD_STALL: (-1, 242, 118) -RIDE_TYPE_FOOD_STALL: (-1, 60, 75) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 157, 250) -RIDE_TYPE_FOOD_STALL: (-1, 80, 35) -RIDE_TYPE_FOOD_STALL: (-1, 647, 764) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 50, 55) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 254, 41) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 30, 0) -RIDE_TYPE_FIRST_AID: (-1, 62, 34) -RIDE_TYPE_CASH_MACHINE: (-1, 350, 300) -RIDE_TYPE_TOILETS: (-1, 157, 250) -RIDE_TYPE_TOILETS: (-1, 153, 10) -RIDE_TYPE_TOILETS: (-1, 850, 809) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (622, 763, 369) -RIDE_TYPE_HEARTLINE_TWISTER_COASTER: (546, 918, 606) -RIDE_TYPE_MERRY_GO_ROUND: (119, 61, 75) -RIDE_TYPE_DODGEMS: (270, 80, 35) -RIDE_TYPE_DODGEMS: (271, 80, 35) -RIDE_TYPE_DODGEMS: (273, 80, 35) -RIDE_TYPE_TOP_SPIN: (206, 480, 574) -RIDE_TYPE_TOP_SPIN: (206, 480, 574) -RIDE_TYPE_MOTION_SIMULATOR: (290, 350, 300) -RIDE_TYPE_MOTION_SIMULATOR: (290, 350, 300) -RIDE_TYPE_3D_CINEMA: (350, 240, 140) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_WOODEN_WILD_MOUSE: (727, 873, 495) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CROOKED_HOUSE: (215, 62, 34) -RIDE_TYPE_CROOKED_HOUSE: (215, 62, 34) -RIDE_TYPE_CROOKED_HOUSE: (340, 62, 34) -RIDE_TYPE_CROOKED_HOUSE: (215, 62, 34) -RIDE_TYPE_MAGIC_CARPET: (335, 340, 440) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (672, 939, 477) -RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER: (634, 747, 408) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (680, 706, 387) -RIDE_TYPE_ENTERPRISE: (382, 647, 764) -RIDE_TYPE_GIGA_COASTER: (1030, 898, 444) -RIDE_TYPE_SUBMARINE_RIDE: (256, 180, 140) -RIDE_TYPE_OBSERVATION_TOWER: (428, 0, 117) -RIDE_TYPE_SWINGING_INVERTER_SHIP: (351, 468, 472) -RIDE_TYPE_SWINGING_INVERTER_SHIP: (352, 468, 472) -RIDE_TYPE_HAUNTED_HOUSE: (341, 153, 10) -RIDE_TYPE_SPACE_RINGS: (161, 210, 650) -RIDE_TYPE_MINI_GOLF: (342, 90, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_ROTO_DROP: (507, 1078, 1078) -RIDE_TYPE_TOP_SPIN: (202, 480, 574) -RIDE_TYPE_TOP_SPIN: (204, 480, 574) -RIDE_TYPE_LAUNCHED_FREEFALL: (380, 982, 577) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (417, 456, 182) -RIDE_TYPE_GO_KARTS: (518, 262, 49) -RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER: (687, 822, 833) -RIDE_TYPE_HYBRID_COASTER: (799, 786, 363) -RIDE_TYPE_SINGLE_RAIL_ROLLER_COASTER: (734, 613, 283) -RIDE_TYPE_MINIATURE_RAILWAY: (165, 12, 1) -RIDE_TYPE_MONORAIL: (138, 9, 1) -RIDE_TYPE_MONORAIL: (136, 7, 1) -RIDE_TYPE_MONORAIL: (137, 8, 2) -RIDE_TYPE_SUSPENDED_MONORAIL: (146, 21, 5) -RIDE_TYPE_CHAIRLIFT: (234, 71, 52) -RIDE_TYPE_MONORAIL_CYCLES: (95, 14, 0) -RIDE_TYPE_LIFT: (181, 35, 46) -RIDE_TYPE_SPIRAL_SLIDE: (151, 140, 90) -RIDE_TYPE_SPIRAL_SLIDE: (153, 140, 90) -RIDE_TYPE_SPIRAL_SLIDE: (153, 140, 90) -RIDE_TYPE_SPIRAL_SLIDE: (153, 140, 90) -RIDE_TYPE_SPIRAL_SLIDE: (153, 140, 90) -RIDE_TYPE_SPIRAL_SLIDE: (151, 140, 90) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_MERRY_GO_ROUND: (106, 60, 75) -RIDE_TYPE_CIRCUS: (210, 30, 0) -RIDE_TYPE_INVERTED_ROLLER_COASTER: (602, 799, 635) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_BOBSLEIGH_COASTER: (590, 650, 487) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_CAR_RIDE: (377, 58, 4) -RIDE_TYPE_SPACE_RINGS: (275, 333, 751) -RIDE_TYPE_SPACE_RINGS: (165, 210, 650) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (509, 635, 448) -RIDE_TYPE_HYPER_TWISTER: (849, 761, 379) -RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER: (785, 826, 375) -RIDE_TYPE_REVERSE_FREEFALL_COASTER: (164, 241, 184) -RIDE_TYPE_MINI_ROLLER_COASTER: (549, 760, 497) -RIDE_TYPE_MONSTER_TRUCKS: (411, 69, 6) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (648, 885, 503) -RIDE_TYPE_VIRGINIA_REEL: (655, 684, 674) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_LOG_FLUME: (529, 293, 141) -RIDE_TYPE_SPLASH_BOATS: (795, 503, 229) -RIDE_TYPE_MERRY_GO_ROUND: (106, 60, 75) -RIDE_TYPE_DINGHY_SLIDE: (550, 647, 410) -RIDE_TYPE_RIVER_RAPIDS: (362, 144, 83) -RIDE_TYPE_RIVER_RAFTS: (217, 45, 43) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (28, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_CAR_RIDE: (29, 29, 1) -RIDE_TYPE_GO_KARTS: (397, 253, 42) -RIDE_TYPE_GO_KARTS: (400, 253, 42) -RIDE_TYPE_GO_KARTS: (397, 253, 42) -RIDE_TYPE_GO_KARTS: (397, 253, 42) -RIDE_TYPE_FLYING_SAUCERS: (393, 85, 39) -RIDE_TYPE_FLYING_SAUCERS: (394, 85, 39) -RIDE_TYPE_FLYING_SAUCERS: (394, 85, 39) -RIDE_TYPE_FLYING_SAUCERS: (624, 111, 42) -RIDE_TYPE_FLYING_SAUCERS: (394, 85, 39) -RIDE_TYPE_MINI_HELICOPTERS: (302, 48, 1) -RIDE_TYPE_BOAT_HIRE: (259, 89, 100) -RIDE_TYPE_BOAT_HIRE: (208, 80, 90) -RIDE_TYPE_BOAT_HIRE: (208, 80, 90) -RIDE_TYPE_BOAT_HIRE: (329, 126, 118) -RIDE_TYPE_BOAT_HIRE: (329, 126, 118) -RIDE_TYPE_BOAT_HIRE: (214, 80, 91) -RIDE_TYPE_BOAT_HIRE: (256, 89, 100) -RIDE_TYPE_BOAT_HIRE: (216, 81, 90) -RIDE_TYPE_BOAT_HIRE: (208, 80, 90) -RIDE_TYPE_BOAT_HIRE: (208, 80, 90) -RIDE_TYPE_BOAT_HIRE: (223, 81, 90) -RIDE_TYPE_WOODEN_WILD_MOUSE: (63, 77, 43) -RIDE_TYPE_WOODEN_WILD_MOUSE: (63, 78, 43) -RIDE_TYPE_STEEL_WILD_MOUSE: (123, 145, 86) -RIDE_TYPE_STEEL_WILD_MOUSE: (125, 145, 86) -RIDE_TYPE_REVERSER_ROLLER_COASTER: (482, 439, 340) -RIDE_TYPE_REVERSER_ROLLER_COASTER: (482, 440, 340) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (12, 11, 7) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (12, 11, 7) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (12, 10, 7) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (12, 11, 7) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (12, 11, 7) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (12, 11, 7) -RIDE_TYPE_CLASSIC_WOODEN_ROLLER_COASTER: (10, 385, 8) -RIDE_TYPE_LAY_DOWN_ROLLER_COASTER: (166, 1630, 1072) -RIDE_TYPE_LAY_DOWN_ROLLER_COASTER: (169, 1612, 1064) -RIDE_TYPE_MINI_ROLLER_COASTER: (39, 37, 28) -RIDE_TYPE_MINI_ROLLER_COASTER: (39, 37, 28) -RIDE_TYPE_MINI_ROLLER_COASTER: (38, 37, 28) -RIDE_TYPE_MINI_ROLLER_COASTER: (38, 37, 28) -RIDE_TYPE_MINI_ROLLER_COASTER: (39, 37, 28) -RIDE_TYPE_MINI_ROLLER_COASTER: (38, 37, 28) -RIDE_TYPE_MINI_ROLLER_COASTER: (38, 37, 28) -RIDE_TYPE_STEEPLECHASE: (20, 18, 13) -RIDE_TYPE_STEEPLECHASE: (20, 18, 13) -RIDE_TYPE_STEEPLECHASE: (20, 18, 13) -RIDE_TYPE_STEEPLECHASE: (20, 18, 13) -RIDE_TYPE_STEEPLECHASE: (20, 18, 13) -RIDE_TYPE_STEEPLECHASE: (20, 18, 13) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (21, 21, 19) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (21, 21, 19) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (21, 21, 19) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (21, 21, 19) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (21, 21, 19) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (22, 25, 21) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (415, 432, 161) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (415, 431, 160) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (415, 431, 160) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (415, 432, 161) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (415, 432, 161) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (415, 432, 161) -RIDE_TYPE_SPINNING_WILD_MOUSE: (599, 716, 549) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (575, 790, 439) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (539, 623, 272) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (532, 562, 254) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (537, 640, 279) -RIDE_TYPE_INVERTED_HAIRPIN_COASTER: (671, 828, 481) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (24, 22, 25) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (24, 22, 25) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (24, 22, 25) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (24, 22, 25) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (26, 22, 26) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (24, 22, 25) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (24, 22, 25) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (24, 22, 25) -RIDE_TYPE_JUNIOR_ROLLER_COASTER: (343, 512, 329) -RIDE_TYPE_JUNIOR_ROLLER_COASTER: (344, 512, 329) -RIDE_TYPE_JUNIOR_ROLLER_COASTER: (380, 533, 330) -RIDE_TYPE_JUNIOR_ROLLER_COASTER: (343, 512, 329) -RIDE_TYPE_COMPACT_INVERTED_COASTER: (46, 44, 45) -RIDE_TYPE_COMPACT_INVERTED_COASTER: (47, 48, 48) -RIDE_TYPE_COMPACT_INVERTED_COASTER: (48, 49, 48) -RIDE_TYPE_COMPACT_INVERTED_COASTER: (47, 49, 48) -RIDE_TYPE_COMPACT_INVERTED_COASTER: (53, 58, 53) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER: (58, 1412, 1165) -RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER: (785, 863, 666) -RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER: (58, 1412, 1165) -RIDE_TYPE_BOBSLEIGH_COASTER: (44, 47, 36) -RIDE_TYPE_BOBSLEIGH_COASTER: (44, 47, 36) -RIDE_TYPE_BOBSLEIGH_COASTER: (44, 47, 36) -RIDE_TYPE_BOBSLEIGH_COASTER: (43, 47, 36) -RIDE_TYPE_SPIRAL_ROLLER_COASTER: (24, 6, 4) -RIDE_TYPE_SPIRAL_ROLLER_COASTER: (24, 6, 4) -RIDE_TYPE_SPIRAL_ROLLER_COASTER: (24, 6, 4) -RIDE_TYPE_STAND_UP_ROLLER_COASTER: (77, 97, 86) -RIDE_TYPE_STAND_UP_ROLLER_COASTER: (77, 97, 86) -RIDE_TYPE_STAND_UP_ROLLER_COASTER: (77, 97, 86) -RIDE_TYPE_WATER_COASTER: (44, 44, 33) -RIDE_TYPE_WATER_COASTER: (44, 44, 32) -RIDE_TYPE_WATER_COASTER: (44, 44, 32) -RIDE_TYPE_WATER_COASTER: (44, 44, 32) -RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER: (388, 1108, 462) -RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER: (174, 265, 166) -RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER: (175, 263, 165) -RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER: (177, 260, 166) -RIDE_TYPE_GIGA_COASTER: (460, 1219, 505) -RIDE_TYPE_MAZE: (139, 52, 0) -RIDE_TYPE_SUBMARINE_RIDE: (247, 180, 140) -RIDE_TYPE_SUBMARINE_RIDE: (247, 180, 140) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (53, 61, 40) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (53, 61, 40) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (53, 61, 40) -RIDE_TYPE_FLYING_ROLLER_COASTER: (31, 282, 473) -RIDE_TYPE_FLYING_ROLLER_COASTER: (31, 282, 473) -RIDE_TYPE_FLYING_ROLLER_COASTER: (31, 282, 473) -RIDE_TYPE_HYPER_TWISTER: (29, 7, 4) -RIDE_TYPE_HYPER_TWISTER: (28, 7, 4) -RIDE_TYPE_HYPERCOASTER: (24, 8, 3) -RIDE_TYPE_HYPERCOASTER: (24, 8, 3) -RIDE_TYPE_HEARTLINE_TWISTER_COASTER: (423, 565, 393) -RIDE_TYPE_HEARTLINE_TWISTER_COASTER: (423, 568, 395) -RIDE_TYPE_REVERSE_FREEFALL_COASTER: (594, 811, 568) -RIDE_TYPE_REVERSE_FREEFALL_COASTER: (594, 811, 568) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER: (486, 681, 370) -RIDE_TYPE_LOOPING_ROLLER_COASTER: (22, 8, 3) -RIDE_TYPE_LOOPING_ROLLER_COASTER: (22, 8, 3) -RIDE_TYPE_LOOPING_ROLLER_COASTER: (485, 628, 252) -RIDE_TYPE_INVERTED_IMPULSE_COASTER: (715, 826, 555) -RIDE_TYPE_INVERTED_IMPULSE_COASTER: (706, 814, 555) -RIDE_TYPE_MINE_TRAIN_COASTER: (601, 752, 454) -RIDE_TYPE_MINE_RIDE: (523, 451, 352) -RIDE_TYPE_ALPINE_ROLLER_COASTER: (170, 141, 65) -RIDE_TYPE_OBSERVATION_TOWER: (354, 0, 97) -RIDE_TYPE_OBSERVATION_TOWER: (313, 0, 74) -RIDE_TYPE_GHOST_TRAIN: (132, 24, 8) -RIDE_TYPE_GHOST_TRAIN: (132, 24, 8) -RIDE_TYPE_LOG_FLUME: (446, 265, 125) -RIDE_TYPE_RIVER_RAFTS: (225, 45, 43) -RIDE_TYPE_RIVER_RAPIDS: (354, 181, 114) -RIDE_TYPE_MAZE: (150, 90, 0) -RIDE_TYPE_MAZE: (150, 90, 0) -RIDE_TYPE_MAZE: (150, 90, 0) -RIDE_TYPE_MAZE: (150, 90, 0) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (482, 510, 220) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (528, 730, 443) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (532, 727, 436) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (530, 812, 472) -RIDE_TYPE_MINIATURE_RAILWAY: (154, 12, 1) -RIDE_TYPE_MINIATURE_RAILWAY: (154, 12, 1) -RIDE_TYPE_MINIATURE_RAILWAY: (149, 12, 1) -RIDE_TYPE_MINIATURE_RAILWAY: (151, 12, 1) -RIDE_TYPE_MINIATURE_RAILWAY: (157, 12, 1) -RIDE_TYPE_MINIATURE_RAILWAY: (154, 12, 1) -RIDE_TYPE_MINIATURE_RAILWAY: (150, 12, 1) -RIDE_TYPE_MINIATURE_RAILWAY: (149, 12, 1) -RIDE_TYPE_SUSPENDED_MONORAIL: (137, 19, 5) -RIDE_TYPE_SUSPENDED_MONORAIL: (137, 19, 5) -RIDE_TYPE_LIFT: (176, 35, 51) -RIDE_TYPE_LIFT: (208, 35, 51) -RIDE_TYPE_CHAIRLIFT: (99, 35, 26) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (701, 623, 407) -RIDE_TYPE_MOTION_SIMULATOR: (290, 350, 300) -RIDE_TYPE_MOTION_SIMULATOR: (325, 410, 330) -RIDE_TYPE_3D_CINEMA: (350, 240, 140) -RIDE_TYPE_3D_CINEMA: (400, 265, 155) -RIDE_TYPE_3D_CINEMA: (420, 260, 148) -RIDE_TYPE_TOP_SPIN: (200, 480, 574) -RIDE_TYPE_TOP_SPIN: (300, 575, 664) -RIDE_TYPE_TOP_SPIN: (320, 680, 794) -RIDE_TYPE_LAUNCHED_FREEFALL: (339, 713, 487) -RIDE_TYPE_LAUNCHED_FREEFALL: (550, 729, 759) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_SPIRAL_ROLLER_COASTER: (581, 467, 249) -RIDE_TYPE_SPIRAL_SLIDE: (190, 160, 115) -RIDE_TYPE_SPIRAL_SLIDE: (150, 140, 90) -RIDE_TYPE_GIGA_COASTER: (637, 447, 239) -RIDE_TYPE_ROTO_DROP: (306, 350, 350) -RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER: (50, 42, 30) -RIDE_TYPE_GIGA_COASTER: (171, 1624, 980) -RIDE_TYPE_CHAIRLIFT: (0, 11, 25) -RIDE_TYPE_COMPACT_INVERTED_COASTER: (-1, 1042, 811) -RIDE_TYPE_MERRY_GO_ROUND: (185, 140, 155) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_GO_KARTS: (422, 255, 42) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_BOAT_HIRE: (201, 80, 90) -RIDE_TYPE_INVERTED_HAIRPIN_COASTER: (703, 936, 520) -RIDE_TYPE_HAUNTED_HOUSE: (-1, 0, 0) -RIDE_TYPE_WOODEN_WILD_MOUSE: (5, 5, 3) -RIDE_TYPE_CAR_RIDE: (329, 59, 10) -RIDE_TYPE_MINIATURE_RAILWAY: (154, 12, 1) \ No newline at end of file +merry_go_round: (105, 60, 75) +looping_rc: (646, 612, 271) +food_stall: (-1, 702, 346) +drink_stall: (-1, 886, 620) +toilets: (-1, 245, 251) +information_kiosk: (-1, 157, 250) +shop: (-1, 0, 0) +cash_machine: (-1, 0, 0) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +twist: (173, 157, 250) +junior_rc: (479, 583, 384) +single_rail_rc: (746, 768, 369) +maze: (155, 90, 0) +swinging_ship: (207, 245, 251) +boat_hire: (213, 80, 90) +enterprise: (372, 647, 764) +top_spin: (200, 480, 574) +haunted_house: (341, 153, 10) +food_stall: (-1, 678, 684) +food_stall: (-1, 248, 131) +food_stall: (-1, 113, 67) +food_stall: (-1, 947, 763) +food_stall: (-1, 968, 559) +food_stall: (-1, 242, 118) +food_stall: (-1, 60, 75) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 157, 250) +food_stall: (-1, 80, 35) +food_stall: (-1, 647, 764) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 50, 55) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 254, 41) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +information_kiosk: (-1, 30, 0) +first_aid: (-1, 62, 34) +cash_machine: (-1, 350, 300) +toilets: (-1, 157, 250) +toilets: (-1, 153, 10) +toilets: (-1, 850, 809) +corkscrew_rc: (622, 763, 369) +heartline_twister_rc: (546, 918, 606) +merry_go_round: (119, 61, 75) +dodgems: (270, 80, 35) +dodgems: (271, 80, 35) +dodgems: (273, 80, 35) +top_spin: (206, 480, 574) +top_spin: (206, 480, 574) +motion_simulator: (290, 350, 300) +motion_simulator: (290, 350, 300) +3d_cinema: (350, 240, 140) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +wooden_wild_mouse: (727, 873, 495) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +cash_machine: (-1, 0, 0) +drink_stall: (-1, 0, 0) +shop: (-1, 0, 0) +toilets: (-1, 0, 0) +crooked_house: (215, 62, 34) +crooked_house: (215, 62, 34) +crooked_house: (340, 62, 34) +crooked_house: (215, 62, 34) +magic_carpet: (335, 340, 440) +twister_rc: (672, 939, 477) +classic_wooden_rc: (634, 747, 408) +wooden_rc: (680, 706, 387) +enterprise: (382, 647, 764) +giga_rc: (1030, 898, 444) +submarine_ride: (256, 180, 140) +observation_tower: (428, 0, 117) +swinging_inverter_ship: (351, 468, 472) +swinging_inverter_ship: (352, 468, 472) +haunted_house: (341, 153, 10) +space_rings: (161, 210, 650) +mini_golf: (342, 90, 0) +cash_machine: (-1, 0, 0) +toilets: (-1, 0, 0) +first_aid: (-1, 0, 0) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +shop: (-1, 0, 0) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +first_aid: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +roto_drop: (507, 1078, 1078) +top_spin: (202, 480, 574) +top_spin: (204, 480, 574) +launched_freefall: (380, 982, 577) +corkscrew_rc: (417, 456, 182) +go_karts: (518, 262, 49) +multi_dimension_rc: (687, 822, 833) +hybrid_rc: (799, 786, 363) +single_rail_rc: (734, 613, 283) +miniature_railway: (165, 12, 1) +monorail: (138, 9, 1) +monorail: (136, 7, 1) +monorail: (137, 8, 2) +suspended_monorail: (146, 21, 5) +chairlift: (234, 71, 52) +monorail_cycles: (95, 14, 0) +lift: (181, 35, 46) +spiral_slide: (151, 140, 90) +spiral_slide: (153, 140, 90) +spiral_slide: (153, 140, 90) +spiral_slide: (153, 140, 90) +spiral_slide: (153, 140, 90) +spiral_slide: (151, 140, 90) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +first_aid: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +shop: (-1, 0, 0) +merry_go_round: (106, 60, 75) +circus: (210, 30, 0) +inverted_rc: (602, 799, 635) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +first_aid: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +bobsleigh_rc: (590, 650, 487) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +toilets: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +cash_machine: (-1, 0, 0) +first_aid: (-1, 0, 0) +shop: (-1, 0, 0) +car_ride: (377, 58, 4) +space_rings: (275, 333, 751) +space_rings: (165, 210, 650) +mini_suspended_rc: (509, 635, 448) +hyper_twister: (849, 761, 379) +vertical_drop_rc: (785, 826, 375) +reverse_freefall_rc: (164, 241, 184) +mini_rc: (549, 760, 497) +monster_trucks: (411, 69, 6) +wooden_rc: (648, 885, 503) +virginia_reel: (655, 684, 674) +food_stall: (-1, 0, 0) +toilets: (-1, 0, 0) +drink_stall: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +cash_machine: (-1, 0, 0) +shop: (-1, 0, 0) +first_aid: (-1, 0, 0) +log_flume: (529, 293, 141) +splash_boats: (795, 503, 229) +merry_go_round: (106, 60, 75) +dinghy_slide: (550, 647, 410) +river_rapids: (362, 144, 83) +river_rafts: (217, 45, 43) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +shop: (-1, 0, 0) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +first_aid: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +cash_machine: (-1, 0, 0) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (28, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +car_ride: (29, 29, 1) +go_karts: (397, 253, 42) +go_karts: (400, 253, 42) +go_karts: (397, 253, 42) +go_karts: (397, 253, 42) +flying_saucers: (393, 85, 39) +flying_saucers: (394, 85, 39) +flying_saucers: (394, 85, 39) +flying_saucers: (624, 111, 42) +flying_saucers: (394, 85, 39) +mini_helicopters: (302, 48, 1) +boat_hire: (259, 89, 100) +boat_hire: (208, 80, 90) +boat_hire: (208, 80, 90) +boat_hire: (329, 126, 118) +boat_hire: (329, 126, 118) +boat_hire: (214, 80, 91) +boat_hire: (256, 89, 100) +boat_hire: (216, 81, 90) +boat_hire: (208, 80, 90) +boat_hire: (208, 80, 90) +boat_hire: (223, 81, 90) +wooden_wild_mouse: (63, 77, 43) +wooden_wild_mouse: (63, 78, 43) +steel_wild_mouse: (123, 145, 86) +steel_wild_mouse: (125, 145, 86) +reverser_rc: (482, 439, 340) +reverser_rc: (482, 440, 340) +wooden_rc: (12, 11, 7) +wooden_rc: (12, 11, 7) +wooden_rc: (12, 10, 7) +wooden_rc: (12, 11, 7) +wooden_rc: (12, 11, 7) +wooden_rc: (12, 11, 7) +classic_wooden_rc: (10, 385, 8) +lay_down_rc: (166, 1630, 1072) +lay_down_rc: (169, 1612, 1064) +mini_rc: (39, 37, 28) +mini_rc: (39, 37, 28) +mini_rc: (38, 37, 28) +mini_rc: (38, 37, 28) +mini_rc: (39, 37, 28) +mini_rc: (38, 37, 28) +mini_rc: (38, 37, 28) +steeplechase: (20, 18, 13) +steeplechase: (20, 18, 13) +steeplechase: (20, 18, 13) +steeplechase: (20, 18, 13) +steeplechase: (20, 18, 13) +steeplechase: (20, 18, 13) +mini_suspended_rc: (21, 21, 19) +mini_suspended_rc: (21, 21, 19) +mini_suspended_rc: (21, 21, 19) +mini_suspended_rc: (21, 21, 19) +mini_suspended_rc: (21, 21, 19) +mini_suspended_rc: (22, 25, 21) +corkscrew_rc: (415, 432, 161) +corkscrew_rc: (415, 431, 160) +corkscrew_rc: (415, 431, 160) +corkscrew_rc: (415, 432, 161) +corkscrew_rc: (415, 432, 161) +corkscrew_rc: (415, 432, 161) +spinning_wild_mouse: (599, 716, 549) +twister_rc: (575, 790, 439) +twister_rc: (539, 623, 272) +twister_rc: (532, 562, 254) +twister_rc: (537, 640, 279) +inverted_hairpin_rc: (671, 828, 481) +suspended_swinging_rc: (24, 22, 25) +suspended_swinging_rc: (24, 22, 25) +suspended_swinging_rc: (24, 22, 25) +suspended_swinging_rc: (24, 22, 25) +suspended_swinging_rc: (26, 22, 26) +suspended_swinging_rc: (24, 22, 25) +suspended_swinging_rc: (24, 22, 25) +suspended_swinging_rc: (24, 22, 25) +junior_rc: (343, 512, 329) +junior_rc: (344, 512, 329) +junior_rc: (380, 533, 330) +junior_rc: (343, 512, 329) +compact_inverted_rc: (46, 44, 45) +compact_inverted_rc: (47, 48, 48) +compact_inverted_rc: (48, 49, 48) +compact_inverted_rc: (47, 49, 48) +compact_inverted_rc: (53, 58, 53) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +cash_machine: (-1, 0, 0) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +toilets: (-1, 0, 0) +shop: (-1, 0, 0) +air_powered_vertical_rc: (58, 1412, 1165) +air_powered_vertical_rc: (785, 863, 666) +air_powered_vertical_rc: (58, 1412, 1165) +bobsleigh_rc: (44, 47, 36) +bobsleigh_rc: (44, 47, 36) +bobsleigh_rc: (44, 47, 36) +bobsleigh_rc: (43, 47, 36) +spiral_rc: (24, 6, 4) +spiral_rc: (24, 6, 4) +spiral_rc: (24, 6, 4) +stand_up_rc: (77, 97, 86) +stand_up_rc: (77, 97, 86) +stand_up_rc: (77, 97, 86) +water_coaster: (44, 44, 33) +water_coaster: (44, 44, 32) +water_coaster: (44, 44, 32) +water_coaster: (44, 44, 32) +vertical_drop_rc: (388, 1108, 462) +classic_mini_rc: (174, 265, 166) +classic_mini_rc: (175, 263, 165) +classic_mini_rc: (177, 260, 166) +giga_rc: (460, 1219, 505) +maze: (139, 52, 0) +submarine_ride: (247, 180, 140) +submarine_ride: (247, 180, 140) +lim_launched_rc: (53, 61, 40) +lim_launched_rc: (53, 61, 40) +lim_launched_rc: (53, 61, 40) +flying_rc: (31, 282, 473) +flying_rc: (31, 282, 473) +flying_rc: (31, 282, 473) +hyper_twister: (29, 7, 4) +hyper_twister: (28, 7, 4) +hypercoaster: (24, 8, 3) +hypercoaster: (24, 8, 3) +heartline_twister_rc: (423, 565, 393) +heartline_twister_rc: (423, 568, 395) +reverse_freefall_rc: (594, 811, 568) +reverse_freefall_rc: (594, 811, 568) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +first_aid: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +side_friction_rc: (486, 681, 370) +looping_rc: (22, 8, 3) +looping_rc: (22, 8, 3) +looping_rc: (485, 628, 252) +inverted_impulse_rc: (715, 826, 555) +inverted_impulse_rc: (706, 814, 555) +mine_train_rc: (601, 752, 454) +mine_ride: (523, 451, 352) +alpine_rc: (170, 141, 65) +observation_tower: (354, 0, 97) +observation_tower: (313, 0, 74) +ghost_train: (132, 24, 8) +ghost_train: (132, 24, 8) +log_flume: (446, 265, 125) +river_rafts: (225, 45, 43) +river_rapids: (354, 181, 114) +maze: (150, 90, 0) +maze: (150, 90, 0) +maze: (150, 90, 0) +maze: (150, 90, 0) +corkscrew_rc: (482, 510, 220) +lim_launched_rc: (528, 730, 443) +lim_launched_rc: (532, 727, 436) +lim_launched_rc: (530, 812, 472) +miniature_railway: (154, 12, 1) +miniature_railway: (154, 12, 1) +miniature_railway: (149, 12, 1) +miniature_railway: (151, 12, 1) +miniature_railway: (157, 12, 1) +miniature_railway: (154, 12, 1) +miniature_railway: (150, 12, 1) +miniature_railway: (149, 12, 1) +suspended_monorail: (137, 19, 5) +suspended_monorail: (137, 19, 5) +lift: (176, 35, 51) +lift: (208, 35, 51) +chairlift: (99, 35, 26) +twister_rc: (701, 623, 407) +motion_simulator: (290, 350, 300) +motion_simulator: (325, 410, 330) +3d_cinema: (350, 240, 140) +3d_cinema: (400, 265, 155) +3d_cinema: (420, 260, 148) +top_spin: (200, 480, 574) +top_spin: (300, 575, 664) +top_spin: (320, 680, 794) +launched_freefall: (339, 713, 487) +launched_freefall: (550, 729, 759) +ferris_wheel: (85, 50, 55) +ferris_wheel: (85, 50, 55) +spiral_rc: (581, 467, 249) +spiral_slide: (190, 160, 115) +spiral_slide: (150, 140, 90) +giga_rc: (637, 447, 239) +roto_drop: (306, 350, 350) +classic_mini_rc: (50, 42, 30) +giga_rc: (171, 1624, 980) +chairlift: (0, 11, 25) +compact_inverted_rc: (-1, 1042, 811) +merry_go_round: (185, 140, 155) +lim_launched_rc: (-1, 0, 0) +shop: (-1, 0, 0) +go_karts: (422, 255, 42) +toilets: (-1, 0, 0) +cash_machine: (-1, 0, 0) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +boat_hire: (201, 80, 90) +inverted_hairpin_rc: (703, 936, 520) +haunted_house: (-1, 0, 0) +wooden_wild_mouse: (5, 5, 3) +car_ride: (329, 59, 10) +miniature_railway: (154, 12, 1) diff --git a/test/tests/testdata/ratings/bpb.sv6.txt b/test/tests/testdata/ratings/bpb.sv6.txt index c3d1da1555..9910aa43f5 100644 --- a/test/tests/testdata/ratings/bpb.sv6.txt +++ b/test/tests/testdata/ratings/bpb.sv6.txt @@ -1,134 +1,134 @@ -RIDE_TYPE_HYPERCOASTER: (840, 766, 346) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (643, 1011, 626) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (700, 734, 428) -RIDE_TYPE_MINIATURE_RAILWAY: (465, 37, 27) -RIDE_TYPE_LOG_FLUME: (522, 199, 107) -RIDE_TYPE_BOBSLEIGH_COASTER: (555, 548, 440) -RIDE_TYPE_CORKSCREW_ROLLER_COASTER: (501, 533, 204) -RIDE_TYPE_CAR_RIDE: (410, 58, 3) -RIDE_TYPE_WOODEN_WILD_MOUSE: (323, 381, 220) -RIDE_TYPE_LOG_FLUME: (208, 69, 52) -RIDE_TYPE_3D_CINEMA: (350, 240, 140) -RIDE_TYPE_HAUNTED_HOUSE: (341, 153, 10) -RIDE_TYPE_MONORAIL: (434, 25, 5) -RIDE_TYPE_MINI_GOLF: (306, 90, 0) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (634, 648, 377) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (71, 68, 41) -RIDE_TYPE_STEEPLECHASE: (609, 509, 351) -RIDE_TYPE_STEEPLECHASE: (587, 492, 338) -RIDE_TYPE_CLASSIC_MINI_ROLLER_COASTER: (244, 245, 170) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_LOG_FLUME: (133, 37, 19) -RIDE_TYPE_CAR_RIDE: (38, 29, 1) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_CROOKED_HOUSE: (215, 62, 34) -RIDE_TYPE_MINE_TRAIN_COASTER: (35, 32, 22) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_GHOST_TRAIN: (389, 43, 22) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_CAR_RIDE: (40, 29, 2) -RIDE_TYPE_SPIRAL_SLIDE: (178, 140, 90) -RIDE_TYPE_TWIST: (193, 157, 250) -RIDE_TYPE_MERRY_GO_ROUND: (125, 60, 75) -RIDE_TYPE_MERRY_GO_ROUND: (106, 60, 75) -RIDE_TYPE_DODGEMS: (275, 80, 35) -RIDE_TYPE_TWIST: (173, 157, 250) -RIDE_TYPE_LAUNCHED_FREEFALL: (379, 879, 543) -RIDE_TYPE_BOAT_HIRE: (269, 89, 100) -RIDE_TYPE_MOTION_SIMULATOR: (290, 350, 300) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_CHAIRLIFT: (287, 55, 51) -RIDE_TYPE_GO_KARTS: (509, 288, 45) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_MAZE: (191, 104, 0) -RIDE_TYPE_TWIST: (180, 157, 250) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_TOILETS: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_LOG_FLUME: (586, 268, 172) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_WOODEN_ROLLER_COASTER: (124, 150, 87) -RIDE_TYPE_FOOD_STALL: (-1, 30, 0) -RIDE_TYPE_CROOKED_HOUSE: (215, 62, 34) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_INFORMATION_KIOSK: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_DRINK_STALL: (-1, 0, 0) -RIDE_TYPE_DODGEMS: (270, 80, 35) -RIDE_TYPE_DODGEMS: (274, 80, 35) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_FOOD_STALL: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_SHOP: (-1, 0, 0) -RIDE_TYPE_FIRST_AID: (-1, 0, 0) -RIDE_TYPE_CASH_MACHINE: (-1, 0, 0) -RIDE_TYPE_MULTI_DIMENSION_ROLLER_COASTER: (694, 833, 772) -RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER: (486, 586, 338) -RIDE_TYPE_REVERSER_ROLLER_COASTER: (548, 525, 387) -RIDE_TYPE_INVERTED_HAIRPIN_COASTER: (670, 770, 470) -RIDE_TYPE_VIRGINIA_REEL: (531, 542, 588) -RIDE_TYPE_STEEL_WILD_MOUSE: (631, 768, 473) -RIDE_TYPE_MINI_ROLLER_COASTER: (539, 563, 397) -RIDE_TYPE_SPIRAL_ROLLER_COASTER: (620, 373, 215) -RIDE_TYPE_LOOPING_ROLLER_COASTER: (467, 441, 182) -RIDE_TYPE_STAND_UP_ROLLER_COASTER: (553, 790, 558) -RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER: (680, 944, 573) -RIDE_TYPE_TWISTER_ROLLER_COASTER: (778, 769, 425) -RIDE_TYPE_GIGA_COASTER: (624, 359, 200) -RIDE_TYPE_INVERTED_ROLLER_COASTER: (678, 850, 686) -RIDE_TYPE_INVERTED_IMPULSE_COASTER: (643, 750, 569) -RIDE_TYPE_MINI_SUSPENDED_COASTER: (512, 696, 475) -RIDE_TYPE_MINE_RIDE: (644, 458, 381) -RIDE_TYPE_HEARTLINE_TWISTER_COASTER: (474, 658, 462) -RIDE_TYPE_LAY_DOWN_ROLLER_COASTER: (682, 666, 548) -RIDE_TYPE_FLYING_ROLLER_COASTER: (719, 711, 678) -RIDE_TYPE_REVERSE_FREEFALL_COASTER: (518, 747, 534) -RIDE_TYPE_VERTICAL_DROP_ROLLER_COASTER: (639, 618, 282) -RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER: (873, 895, 701) -RIDE_TYPE_SUSPENDED_MONORAIL: (336, 47, 23) -RIDE_TYPE_LIFT: (563, 35, 102) -RIDE_TYPE_MONORAIL_CYCLES: (226, 29, 1) -RIDE_TYPE_FERRIS_WHEEL: (85, 50, 55) -RIDE_TYPE_OBSERVATION_TOWER: (594, 0, 61) -RIDE_TYPE_SPIRAL_SLIDE: (157, 140, 90) -RIDE_TYPE_SPACE_RINGS: (167, 210, 650) -RIDE_TYPE_CIRCUS: (210, 30, 0) -RIDE_TYPE_FLYING_SAUCERS: (381, 85, 39) -RIDE_TYPE_MAGIC_CARPET: (374, 340, 440) -RIDE_TYPE_SWINGING_SHIP: (264, 245, 251) -RIDE_TYPE_SWINGING_INVERTER_SHIP: (349, 468, 472) -RIDE_TYPE_TOP_SPIN: (201, 480, 574) -RIDE_TYPE_ROTO_DROP: (395, 1148, 1148) -RIDE_TYPE_ENTERPRISE: (392, 647, 764) -RIDE_TYPE_RIVER_RAPIDS: (376, 153, 90) -RIDE_TYPE_RIVER_RAFTS: (263, 45, 43) -RIDE_TYPE_DINGHY_SLIDE: (477, 577, 358) -RIDE_TYPE_MINI_HELICOPTERS: (315, 50, 4) -RIDE_TYPE_SUSPENDED_SWINGING_COASTER: (690, 691, 720) -RIDE_TYPE_COMPACT_INVERTED_COASTER: (680, 830, 698) -RIDE_TYPE_SPLASH_BOATS: (474, 204, 113) -RIDE_TYPE_SUBMARINE_RIDE: (255, 180, 140) +hypercoaster: (840, 766, 346) +wooden_rc: (643, 1011, 626) +wooden_rc: (700, 734, 428) +miniature_railway: (465, 37, 27) +log_flume: (522, 199, 107) +bobsleigh_rc: (555, 548, 440) +corkscrew_rc: (501, 533, 204) +car_ride: (410, 58, 3) +wooden_wild_mouse: (323, 381, 220) +log_flume: (208, 69, 52) +3d_cinema: (350, 240, 140) +haunted_house: (341, 153, 10) +monorail: (434, 25, 5) +mini_golf: (306, 90, 0) +wooden_rc: (634, 648, 377) +wooden_rc: (71, 68, 41) +steeplechase: (609, 509, 351) +steeplechase: (587, 492, 338) +classic_mini_rc: (244, 245, 170) +shop: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +food_stall: (-1, 0, 0) +log_flume: (133, 37, 19) +car_ride: (38, 29, 1) +food_stall: (-1, 0, 0) +crooked_house: (215, 62, 34) +mine_train_rc: (35, 32, 22) +toilets: (-1, 0, 0) +drink_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +ghost_train: (389, 43, 22) +shop: (-1, 0, 0) +car_ride: (40, 29, 2) +spiral_slide: (178, 140, 90) +twist: (193, 157, 250) +merry_go_round: (125, 60, 75) +merry_go_round: (106, 60, 75) +dodgems: (275, 80, 35) +twist: (173, 157, 250) +launched_freefall: (379, 879, 543) +boat_hire: (269, 89, 100) +motion_simulator: (290, 350, 300) +drink_stall: (-1, 0, 0) +chairlift: (287, 55, 51) +go_karts: (509, 288, 45) +information_kiosk: (-1, 0, 0) +food_stall: (-1, 0, 0) +shop: (-1, 0, 0) +maze: (191, 104, 0) +twist: (180, 157, 250) +drink_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +shop: (-1, 0, 0) +toilets: (-1, 0, 0) +toilets: (-1, 0, 0) +toilets: (-1, 0, 0) +toilets: (-1, 0, 0) +food_stall: (-1, 0, 0) +log_flume: (586, 268, 172) +information_kiosk: (-1, 0, 0) +wooden_rc: (124, 150, 87) +food_stall: (-1, 30, 0) +crooked_house: (215, 62, 34) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +shop: (-1, 0, 0) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +shop: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +information_kiosk: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +drink_stall: (-1, 0, 0) +dodgems: (270, 80, 35) +dodgems: (274, 80, 35) +food_stall: (-1, 0, 0) +food_stall: (-1, 0, 0) +shop: (-1, 0, 0) +shop: (-1, 0, 0) +first_aid: (-1, 0, 0) +cash_machine: (-1, 0, 0) +multi_dimension_rc: (694, 833, 772) +side_friction_rc: (486, 586, 338) +reverser_rc: (548, 525, 387) +inverted_hairpin_rc: (670, 770, 470) +virginia_reel: (531, 542, 588) +steel_wild_mouse: (631, 768, 473) +mini_rc: (539, 563, 397) +spiral_rc: (620, 373, 215) +looping_rc: (467, 441, 182) +stand_up_rc: (553, 790, 558) +lim_launched_rc: (680, 944, 573) +twister_rc: (778, 769, 425) +giga_rc: (624, 359, 200) +inverted_rc: (678, 850, 686) +inverted_impulse_rc: (643, 750, 569) +mini_suspended_rc: (512, 696, 475) +mine_ride: (644, 458, 381) +heartline_twister_rc: (474, 658, 462) +lay_down_rc: (682, 666, 548) +flying_rc: (719, 711, 678) +reverse_freefall_rc: (518, 747, 534) +vertical_drop_rc: (639, 618, 282) +air_powered_vertical_rc: (873, 895, 701) +suspended_monorail: (336, 47, 23) +lift: (563, 35, 102) +monorail_cycles: (226, 29, 1) +ferris_wheel: (85, 50, 55) +observation_tower: (594, 0, 61) +spiral_slide: (157, 140, 90) +space_rings: (167, 210, 650) +circus: (210, 30, 0) +flying_saucers: (381, 85, 39) +magic_carpet: (374, 340, 440) +swinging_ship: (264, 245, 251) +swinging_inverter_ship: (349, 468, 472) +top_spin: (201, 480, 574) +roto_drop: (395, 1148, 1148) +enterprise: (392, 647, 764) +river_rapids: (376, 153, 90) +river_rafts: (263, 45, 43) +dinghy_slide: (477, 577, 358) +mini_helicopters: (315, 50, 4) +suspended_swinging_rc: (690, 691, 720) +compact_inverted_rc: (680, 830, 698) +splash_boats: (474, 204, 113) +submarine_ride: (255, 180, 140) diff --git a/test/tests/testdata/ratings/testReversedTrains.park.txt b/test/tests/testdata/ratings/testReversedTrains.park.txt index 80a0810a2e..05b5c8049b 100644 --- a/test/tests/testdata/ratings/testReversedTrains.park.txt +++ b/test/tests/testdata/ratings/testReversedTrains.park.txt @@ -1,2 +1,2 @@ -RIDE_TYPE_HYPERCOASTER: (592, 537, 239) -RIDE_TYPE_HYPERCOASTER: (600, 624, 294) \ No newline at end of file +hypercoaster: (592, 537, 239) +hypercoaster: (600, 624, 294) From d9d5df509e66462fe7bce355134bd691866cf153 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 22 Nov 2024 23:57:09 +0100 Subject: [PATCH 088/139] Add RtdSpecialType to replace checks for maze and other naughty types --- src/openrct2-ui/windows/InstallTrack.cpp | 4 +- src/openrct2-ui/windows/NewCampaign.cpp | 2 +- src/openrct2-ui/windows/Ride.cpp | 34 +++-- src/openrct2-ui/windows/RideConstruction.cpp | 12 +- src/openrct2-ui/windows/TrackDesignPlace.cpp | 2 +- src/openrct2-ui/windows/TrackList.cpp | 4 +- src/openrct2/actions/RideCreateAction.cpp | 2 +- src/openrct2/actions/RideSetPriceAction.cpp | 4 +- src/openrct2/actions/RideSetVehicleAction.cpp | 6 +- src/openrct2/entity/Guest.cpp | 44 +++--- src/openrct2/entity/Peep.cpp | 2 +- src/openrct2/management/Award.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/rct1/T4Importer.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/rct2/T6Exporter.cpp | 6 +- src/openrct2/rct2/T6Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 20 +-- src/openrct2/ride/RideConstruction.cpp | 4 +- src/openrct2/ride/RideData.h | 137 ++++++++++-------- src/openrct2/ride/RideRatings.cpp | 6 +- src/openrct2/ride/TrackDesign.cpp | 4 +- src/openrct2/ride/TrackPaint.cpp | 3 +- src/openrct2/ride/rtd/gentle/Maze.h | 3 +- src/openrct2/ride/rtd/gentle/MiniGolf.h | 1 + src/openrct2/ride/rtd/gentle/SpiralSlide.h | 3 +- src/openrct2/ride/rtd/shops/CashMachine.h | 3 +- src/openrct2/ride/rtd/shops/FirstAid.h | 3 +- src/openrct2/ride/rtd/shops/Toilets.h | 3 +- .../bindings/world/ScTileElement.cpp | 16 +- 30 files changed, 185 insertions(+), 153 deletions(-) diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index 6636334a91..453617d46f 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -239,9 +239,9 @@ namespace OpenRCT2::Ui::Windows } const auto& rtd = GetRideTypeDescriptor(td.trackAndVehicle.rtdIndex); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) { - if (td.trackAndVehicle.rtdIndex == RIDE_TYPE_MINI_GOLF) + if (rtd.specialType == RtdSpecialType::miniGolf) { // Holes auto ft = Formatter(); diff --git a/src/openrct2-ui/windows/NewCampaign.cpp b/src/openrct2-ui/windows/NewCampaign.cpp index 0e82515560..dd78ff9e20 100644 --- a/src/openrct2-ui/windows/NewCampaign.cpp +++ b/src/openrct2-ui/windows/NewCampaign.cpp @@ -151,7 +151,7 @@ namespace OpenRCT2::Ui::Windows continue; if (rtd.HasFlag(RtdFlag::sellsDrinks)) continue; - if (rtd.HasFlag(RtdFlag::isToilet)) + if (rtd.specialType == RtdSpecialType::toilet) continue; RideList.push_back(curRide.id); diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 7825032de6..4b8cba0e74 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -1362,7 +1362,7 @@ namespace OpenRCT2::Ui::Windows if (!rtd.HasFlag(RtdFlag::hasDataLogging)) disabledTabs |= (1uLL << WIDX_TAB_8); // 0x800 - if (ride->type == RIDE_TYPE_MINI_GOLF) + if (rtd.specialType == RtdSpecialType::miniGolf) disabledTabs |= (1uLL << WIDX_TAB_2 | 1uLL << WIDX_TAB_3 | 1uLL << WIDX_TAB_4); // 0xE0 if (rtd.HasFlag(RtdFlag::noVehicles)) @@ -1383,7 +1383,7 @@ namespace OpenRCT2::Ui::Windows disabledTabs |= (1uLL << WIDX_TAB_6); // 0x200 } - if (rtd.HasFlag(RtdFlag::isCashMachine) || rtd.HasFlag(RtdFlag::isFirstAid) + if (rtd.specialType == RtdSpecialType::cashMachine || rtd.specialType == RtdSpecialType::firstAid || (GetGameState().Park.Flags & PARK_FLAGS_NO_MONEY) != 0) disabledTabs |= (1uLL << WIDX_TAB_9); // 0x1000 @@ -2010,7 +2010,9 @@ namespace OpenRCT2::Ui::Windows const auto& gameState = GetGameState(); const auto& rtd = ride.GetRideTypeDescriptor(); if (gameState.Cheats.ShowVehiclesFromOtherTrackTypes - && !(rtd.HasFlag(RtdFlag::isFlatRide) || rtd.HasFlag(RtdFlag::isMaze) || ride.type == RIDE_TYPE_MINI_GOLF)) + && !( + rtd.HasFlag(RtdFlag::isFlatRide) || rtd.specialType == RtdSpecialType::maze + || rtd.specialType == RtdSpecialType::miniGolf)) { selectionShouldBeExpanded = true; rideTypeIterator = 0; @@ -2037,7 +2039,7 @@ namespace OpenRCT2::Ui::Windows if (selectionShouldBeExpanded && rtdIterator.HasFlag(RtdFlag::isFlatRide)) continue; if (selectionShouldBeExpanded - && (rtdIterator.HasFlag(RtdFlag::isMaze) || rideTypeIterator == RIDE_TYPE_MINI_GOLF)) + && (rtdIterator.specialType == RtdSpecialType::maze || rtd.specialType == RtdSpecialType::miniGolf)) continue; auto& rideEntries = objManager.GetAllRideEntries(rideTypeIterator); @@ -2486,6 +2488,7 @@ namespace OpenRCT2::Ui::Windows if (vehicle == nullptr) return STR_EMPTY; + auto& rtd = ride->GetRideTypeDescriptor(); if (vehicle->status != Vehicle::Status::Crashing && vehicle->status != Vehicle::Status::Crashed) { auto trackType = vehicle->GetTrackType(); @@ -2494,7 +2497,7 @@ namespace OpenRCT2::Ui::Windows || trackType == TrackElemType::DiagUp25ToFlat || trackType == TrackElemType::DiagUp60ToFlat || trackType == TrackElemType::DiagBlockBrakes) { - if (ride->GetRideTypeDescriptor().SupportsTrackGroup(TrackGroup::blockBrakes) && vehicle->velocity == 0) + if (rtd.SupportsTrackGroup(TrackGroup::blockBrakes) && vehicle->velocity == 0) { ft.Add(STR_STOPPED_BY_BLOCK_BRAKES); return STR_BLACK_STRING; @@ -2502,7 +2505,7 @@ namespace OpenRCT2::Ui::Windows } } - if (ride->type == RIDE_TYPE_MINI_GOLF) + if (rtd.specialType == RtdSpecialType::miniGolf) return STR_EMPTY; auto stringId = VehicleStatusNames[EnumValue(vehicle->status)]; @@ -4622,7 +4625,7 @@ namespace OpenRCT2::Ui::Windows // Maze style const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { widgets[WIDX_MAZE_STYLE].type = WindowWidgetType::DropdownMenu; widgets[WIDX_MAZE_STYLE_DROPDOWN].type = WindowWidgetType::Button; @@ -4689,7 +4692,7 @@ namespace OpenRCT2::Ui::Windows } // Track supports colour - if (HasTrackColour(*ride, 2) && !rtd.HasFlag(RtdFlag::isMaze)) + if (HasTrackColour(*ride, 2) && rtd.specialType != RtdSpecialType::maze) { widgets[WIDX_TRACK_SUPPORT_COLOUR].type = WindowWidgetType::ColourBtn; widgets[WIDX_TRACK_SUPPORT_COLOUR].image = GetColourButtonImage(trackColour.supports); @@ -4872,7 +4875,7 @@ namespace OpenRCT2::Ui::Windows // Track const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { GfxDrawSprite(dpi, ImageId(MazeOptions[trackColour.supports].sprite), screenCoords); } @@ -5721,7 +5724,7 @@ namespace OpenRCT2::Ui::Windows if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_NO_RAW_STATS)) { - if (ride->type == RIDE_TYPE_MINI_GOLF) + if (ride->GetRideTypeDescriptor().specialType == RtdSpecialType::miniGolf) { // Holes ft = Formatter(); @@ -5873,7 +5876,7 @@ namespace OpenRCT2::Ui::Windows screenCoords.y += kListRowHeight; } - if (ride->type != RIDE_TYPE_MINI_GOLF) + if (ride->GetRideTypeDescriptor().specialType != RtdSpecialType::miniGolf) { // Inversions if (ride->inversions != 0) @@ -6314,7 +6317,7 @@ namespace OpenRCT2::Ui::Windows ShopItem shopItem; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isToilet)) + if (rtd.specialType == RtdSpecialType::toilet) { shopItem = ShopItem::Admission; } @@ -6420,7 +6423,7 @@ namespace OpenRCT2::Ui::Windows auto rideEntry = ride->GetRideEntry(); const auto& rtd = ride->GetRideTypeDescriptor(); - return Park::RidePricesUnlocked() || rtd.HasFlag(RtdFlag::isToilet) + return Park::RidePricesUnlocked() || rtd.specialType == RtdSpecialType::toilet || (rideEntry != nullptr && rideEntry->shop_item[0] != ShopItem::None); } @@ -6595,7 +6598,8 @@ namespace OpenRCT2::Ui::Windows // If ride prices are locked, do not allow setting the price, unless we're dealing with a shop or toilet. const auto& rtd = ride->GetRideTypeDescriptor(); - if (!Park::RidePricesUnlocked() && rideEntry->shop_item[0] == ShopItem::None && !rtd.HasFlag(RtdFlag::isToilet)) + if (!Park::RidePricesUnlocked() && rideEntry->shop_item[0] == ShopItem::None + && rtd.specialType != RtdSpecialType::toilet) { disabled_widgets |= (1uLL << WIDX_PRIMARY_PRICE); widgets[WIDX_PRIMARY_PRICE_LABEL].tooltip = STR_RIDE_INCOME_ADMISSION_PAY_FOR_ENTRY_TIP; @@ -6614,7 +6618,7 @@ namespace OpenRCT2::Ui::Windows widgets[WIDX_PRIMARY_PRICE].text = STR_FREE; ShopItem primaryItem = ShopItem::Admission; - if (rtd.HasFlag(RtdFlag::isToilet) || ((primaryItem = rideEntry->shop_item[0]) != ShopItem::None)) + if (rtd.specialType == RtdSpecialType::toilet || ((primaryItem = rideEntry->shop_item[0]) != ShopItem::None)) { widgets[WIDX_PRIMARY_PRICE_SAME_THROUGHOUT_PARK].type = WindowWidgetType::Checkbox; diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 566cc20512..e624a8f4e0 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -3059,7 +3059,7 @@ namespace OpenRCT2::Ui::Windows { WindowRideConstructionUpdateEnabledTrackPieces(); if (auto currentRide = GetRide(_currentRideIndex); - !currentRide || currentRide->GetRideTypeDescriptor().HasFlag(RtdFlag::isMaze)) + !currentRide || currentRide->GetRideTypeDescriptor().specialType == RtdSpecialType::maze) { return; } @@ -3293,7 +3293,7 @@ namespace OpenRCT2::Ui::Windows } const auto& rtd = ride->GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) { auto window = static_cast(WindowFindByClass(WindowClass::RideConstruction)); if (!window) @@ -3349,7 +3349,7 @@ namespace OpenRCT2::Ui::Windows // search for appropriate z value for ghost, up to max ride height int numAttempts = (z <= MAX_TRACK_HEIGHT ? ((MAX_TRACK_HEIGHT - z) / kCoordsZStep + 1) : 2); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { for (int zAttempts = 0; zAttempts < numAttempts; ++zAttempts) { @@ -3586,7 +3586,7 @@ namespace OpenRCT2::Ui::Windows int numAttempts = (z <= MAX_TRACK_HEIGHT ? ((MAX_TRACK_HEIGHT - z) / kCoordsZStep + 1) : 2); const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { for (int32_t zAttempts = 0; zAttempts < numAttempts; ++zAttempts) { @@ -4689,7 +4689,7 @@ namespace OpenRCT2::Ui::Windows RideConstructionRemoveGhosts(); const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { int32_t flags = GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; auto gameAction = MazeSetTrackAction(CoordsXYZD{ trackPos, 0 }, true, rideIndex, GC_SET_MAZE_TRACK_BUILD); @@ -5051,7 +5051,7 @@ namespace OpenRCT2::Ui::Windows int32_t z = _unkF440C5.z; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { const int32_t flags = GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED | GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST; const CoordsXYZD quadrants[kNumOrthogonalDirections] = { diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index c1c83bf06c..54ae966d59 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -415,7 +415,7 @@ namespace OpenRCT2::Ui::Windows } const auto& rtd = GetRideTypeDescriptor(td.trackAndVehicle.rtdIndex); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { DrawMiniPreviewMaze(td, pass, origin, min, max); } diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index 60ef169386..de95175fed 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -562,9 +562,9 @@ namespace OpenRCT2::Ui::Windows if (GetRideTypeDescriptor(_loadedTrackDesign->trackAndVehicle.rtdIndex).HasFlag(RtdFlag::hasTrack)) { const auto& rtd = GetRideTypeDescriptor(_loadedTrackDesign->trackAndVehicle.rtdIndex); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) { - if (_loadedTrackDesign->trackAndVehicle.rtdIndex == RIDE_TYPE_MINI_GOLF) + if (rtd.specialType == RtdSpecialType::miniGolf) { // Holes ft = Formatter(); diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 04435ae9c8..1d781d284c 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -235,7 +235,7 @@ GameActions::Result RideCreateAction::Execute() const ride->price[0] = 0; } - if (rtd.HasFlag(RtdFlag::isToilet)) + if (rtd.specialType == RtdSpecialType::toilet) { if (ShopItemHasCommonPrice(ShopItem::Admission)) { diff --git a/src/openrct2/actions/RideSetPriceAction.cpp b/src/openrct2/actions/RideSetPriceAction.cpp index de24307cdc..c5a018e3b8 100644 --- a/src/openrct2/actions/RideSetPriceAction.cpp +++ b/src/openrct2/actions/RideSetPriceAction.cpp @@ -112,7 +112,7 @@ GameActions::Result RideSetPriceAction::Execute() const shopItem = ShopItem::Admission; const auto& rtd = ride->GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isToilet)) + if (rtd.specialType != RtdSpecialType::toilet) { shopItem = rideEntry->shop_item[0]; if (shopItem == ShopItem::None) @@ -165,7 +165,7 @@ void RideSetPriceAction::RideSetCommonPrice(ShopItem shopItem) const auto invalidate = false; auto rideEntry = GetRideEntryByIndex(ride.subtype); const auto& rtd = ride.GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isToilet) && shopItem == ShopItem::Admission) + if (rtd.specialType == RtdSpecialType::toilet && shopItem == ShopItem::Admission) { if (ride.price[0] != _price) { diff --git a/src/openrct2/actions/RideSetVehicleAction.cpp b/src/openrct2/actions/RideSetVehicleAction.cpp index b24dce20c6..3b1d994ad2 100644 --- a/src/openrct2/actions/RideSetVehicleAction.cpp +++ b/src/openrct2/actions/RideSetVehicleAction.cpp @@ -232,8 +232,8 @@ bool RideSetVehicleAction::RideIsVehicleTypeValid(const Ride& ride) const const auto& rtd = ride.GetRideTypeDescriptor(); if (gameState.Cheats.ShowVehiclesFromOtherTrackTypes && !( - ride.GetRideTypeDescriptor().HasFlag(RtdFlag::isFlatRide) || rtd.HasFlag(RtdFlag::isMaze) - || ride.type == RIDE_TYPE_MINI_GOLF)) + ride.GetRideTypeDescriptor().HasFlag(RtdFlag::isFlatRide) || rtd.specialType == RtdSpecialType::maze + || rtd.specialType == RtdSpecialType::miniGolf)) { selectionShouldBeExpanded = true; rideTypeIterator = 0; @@ -255,7 +255,7 @@ bool RideSetVehicleAction::RideIsVehicleTypeValid(const Ride& ride) const continue; const auto& rtd = GetRideTypeDescriptor(rideTypeIterator); - if (rtd.HasFlag(RtdFlag::isMaze) || rideTypeIterator == RIDE_TYPE_MINI_GOLF) + if (rtd.specialType == RtdSpecialType::maze || rtd.specialType == RtdSpecialType::miniGolf) continue; } diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index 13a160e37f..e13d43a9ed 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -452,6 +452,7 @@ static void PeepUpdateHunger(Guest* peep); static void PeepDecideWhetherToLeavePark(Guest* peep); static void PeepLeavePark(Guest* peep); static void PeepHeadForNearestRideWithFlag(Guest* peep, bool considerOnlyCloseRides, RtdFlag rtdFlag); +static void GuestHeadForNearestRideWithSpecialType(Guest& guest, bool considerOnlyCloseRides, RtdSpecialType specialType); bool Loc690FD0(Peep* peep, RideId* rideToView, uint8_t* rideSeatToView, TileElement* tileElement); template<> @@ -1122,10 +1123,10 @@ void Guest::Tick128UpdateGuest(uint32_t index) PeepHeadForNearestRideWithFlag(this, false, RtdFlag::sellsDrinks); break; case PeepThoughtType::Toilet: - PeepHeadForNearestRideWithFlag(this, false, RtdFlag::isToilet); + GuestHeadForNearestRideWithSpecialType(*this, false, RtdSpecialType::toilet); break; case PeepThoughtType::RunningOut: - PeepHeadForNearestRideWithFlag(this, false, RtdFlag::isCashMachine); + GuestHeadForNearestRideWithSpecialType(*this, false, RtdSpecialType::cashMachine); break; default: break; @@ -1145,7 +1146,7 @@ void Guest::Tick128UpdateGuest(uint32_t index) if (Nausea >= 200) { thought_type = PeepThoughtType::VerySick; - PeepHeadForNearestRideWithFlag(this, true, RtdFlag::isFirstAid); + GuestHeadForNearestRideWithSpecialType(*this, true, RtdSpecialType::firstAid); } InsertNewThought(thought_type); } @@ -2240,7 +2241,7 @@ bool Guest::ShouldGoToShop(Ride& ride, bool peepAtShop) } const auto& rtd = ride.GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isToilet)) + if (rtd.specialType == RtdSpecialType::toilet) { if (Toilet < 70) { @@ -2266,7 +2267,7 @@ bool Guest::ShouldGoToShop(Ride& ride, bool peepAtShop) } } - if (rtd.HasFlag(RtdFlag::isFirstAid)) + if (rtd.specialType == RtdSpecialType::firstAid) { if (Nausea < 128) { @@ -3251,12 +3252,19 @@ static void PeepHeadForNearestRide(Guest* peep, bool considerOnlyCloseRides, T p static void PeepHeadForNearestRideWithFlag(Guest* peep, bool considerOnlyCloseRides, RtdFlag rtdFlag) { - if ((rtdFlag == RtdFlag::isToilet) && peep->HasFoodOrDrink()) + PeepHeadForNearestRide( + peep, considerOnlyCloseRides, [rtdFlag](const Ride& ride) { return ride.GetRideTypeDescriptor().HasFlag(rtdFlag); }); +} + +static void GuestHeadForNearestRideWithSpecialType(Guest& guest, bool considerOnlyCloseRides, RtdSpecialType specialType) +{ + if ((specialType == RtdSpecialType::toilet) && guest.HasFoodOrDrink()) { return; } - PeepHeadForNearestRide( - peep, considerOnlyCloseRides, [rtdFlag](const Ride& ride) { return ride.GetRideTypeDescriptor().HasFlag(rtdFlag); }); + PeepHeadForNearestRide(&guest, considerOnlyCloseRides, [specialType](const Ride& ride) { + return ride.GetRideTypeDescriptor().specialType == specialType; + }); } /** @@ -3277,10 +3285,10 @@ void Guest::StopPurchaseThought(ride_type_t rideType) if (!rtd.HasFlag(RtdFlag::sellsDrinks)) { thoughtType = PeepThoughtType::RunningOut; - if (!rtd.HasFlag(RtdFlag::isCashMachine)) + if (rtd.specialType != RtdSpecialType::cashMachine) { thoughtType = PeepThoughtType::Toilet; - if (!rtd.HasFlag(RtdFlag::isToilet)) + if (rtd.specialType != RtdSpecialType::toilet) { return; } @@ -3365,7 +3373,7 @@ void Guest::UpdateBuying() } const auto& rtd = GetRideTypeDescriptor(ride->type); - if (rtd.HasFlag(RtdFlag::isCashMachine)) + if (rtd.specialType == RtdSpecialType::cashMachine) { if (CurrentRide != PreviousRide) { @@ -3388,7 +3396,7 @@ void Guest::UpdateBuying() if (CurrentRide != PreviousRide) { const auto& rtd = GetRideTypeDescriptor(ride->type); - if (rtd.HasFlag(RtdFlag::isCashMachine)) + if (rtd.specialType == RtdSpecialType::cashMachine) { item_bought = PeepShouldUseCashMachine(this, CurrentRide); if (!item_bought) @@ -3907,7 +3915,7 @@ void Guest::UpdateRideFreeVehicleEnterRide(Ride& ride) } const auto& rtd = ride.GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isSpiralSlide)) + if (rtd.specialType == RtdSpecialType::spiralSlide) { SwitchToSpecialSprite(1); } @@ -4697,7 +4705,7 @@ void Guest::UpdateRideApproachSpiralSlide() Var37 = (directionTemp * 4) | (Var37 & 0x30) | waypoint; CoordsXY targetLoc = ride->GetStation(CurrentRideStation).Start; - assert(rtd.HasFlag(RtdFlag::isSpiralSlide)); + assert(rtd.specialType == RtdSpecialType::spiralSlide); targetLoc += SpiralSlideWalkingPath[Var37]; SetDestination(targetLoc); @@ -4711,7 +4719,7 @@ void Guest::UpdateRideApproachSpiralSlide() CoordsXY targetLoc = ride->GetStation(CurrentRideStation).Start; - assert(rtd.HasFlag(RtdFlag::isSpiralSlide)); + assert(rtd.specialType == RtdSpecialType::spiralSlide); targetLoc += SpiralSlideWalkingPath[Var37]; SetDestination(targetLoc); @@ -4745,7 +4753,7 @@ void Guest::UpdateRideOnSpiralSlide() return; const auto& rtd = ride->GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isSpiralSlide)) + if (rtd.specialType != RtdSpecialType::spiralSlide) return; auto destination = GetDestination(); @@ -4850,7 +4858,7 @@ void Guest::UpdateRideLeaveSpiralSlide() CoordsXY targetLoc = ride->GetStation(CurrentRideStation).Start; [[maybe_unused]] const auto& rtd = ride->GetRideTypeDescriptor(); - assert(rtd.HasFlag(RtdFlag::isSpiralSlide)); + assert(rtd.specialType == RtdSpecialType::spiralSlide); targetLoc += SpiralSlideWalkingPath[Var37]; SetDestination(targetLoc); @@ -5110,7 +5118,7 @@ void Guest::UpdateRideShopInteract() const int16_t tileCentreY = NextLoc.y + 16; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isFirstAid)) + if (rtd.specialType == RtdSpecialType::firstAid) { if (Nausea <= 35) { diff --git a/src/openrct2/entity/Peep.cpp b/src/openrct2/entity/Peep.cpp index a3806d5077..f60602f70f 100644 --- a/src/openrct2/entity/Peep.cpp +++ b/src/openrct2/entity/Peep.cpp @@ -1141,7 +1141,7 @@ void PeepProblemWarningsUpdate() break; } ride = GetRide(peep->GuestHeadingToRideId); - if (ride != nullptr && !ride->GetRideTypeDescriptor().HasFlag(RtdFlag::isToilet)) + if (ride != nullptr && ride->GetRideTypeDescriptor().specialType != RtdSpecialType::toilet) toiletCounter++; break; diff --git a/src/openrct2/management/Award.cpp b/src/openrct2/management/Award.cpp index 4220040320..e692c8299c 100644 --- a/src/openrct2/management/Award.cpp +++ b/src/openrct2/management/Award.cpp @@ -374,7 +374,7 @@ static bool AwardIsDeservedBestToilets([[maybe_unused]] int32_t activeAwardTypes const auto& rideManager = GetRideManager(); auto numToilets = static_cast(std::count_if(rideManager.begin(), rideManager.end(), [](const Ride& ride) { const auto& rtd = ride.GetRideTypeDescriptor(); - return rtd.HasFlag(RtdFlag::isToilet) && ride.status == RideStatus::Open; + return rtd.specialType == RtdSpecialType::toilet && ride.status == RideStatus::Open; })); // At least 4 open toilets diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 1944ea4331..4b47a6e9aa 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1050,7 +1050,7 @@ namespace OpenRCT2::RCT1 dst->dropsPoweredLifts = src->NumDrops; dst->start_drop_height = src->StartDropHeight / 2; dst->highest_drop_height = src->HighestDropHeight / 2; - if (dst->type == RIDE_TYPE_MINI_GOLF) + if (src->Type == RideType::MiniatureGolf) dst->holes = src->NumInversions & kRCT12InversionAndHoleMask; else dst->inversions = src->NumInversions & kRCT12InversionAndHoleMask; diff --git a/src/openrct2/rct1/T4Importer.cpp b/src/openrct2/rct1/T4Importer.cpp index 1b35758eaa..12703b1629 100644 --- a/src/openrct2/rct1/T4Importer.cpp +++ b/src/openrct2/rct1/T4Importer.cpp @@ -235,7 +235,7 @@ namespace OpenRCT2::RCT1 td->operation.operationSetting, GetRideTypeDescriptor(td->trackAndVehicle.rtdIndex).OperatingSettings.MaxValue); const auto& rtd = GetRideTypeDescriptor(td->trackAndVehicle.rtdIndex); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { TD46MazeElement t4MazeElement{}; t4MazeElement.All = !0; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 72ad05dd03..86642a1968 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1382,7 +1382,7 @@ namespace OpenRCT2::RCT2 // This has to be done last, since the maze entry shares fields with the colour and sequence fields. const auto& rtd = GetRideTypeDescriptor(rideType); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { dst2->SetMazeEntry(src2->GetMazeEntry()); } diff --git a/src/openrct2/rct2/T6Exporter.cpp b/src/openrct2/rct2/T6Exporter.cpp index 25bcce1aef..c68106bbd3 100644 --- a/src/openrct2/rct2/T6Exporter.cpp +++ b/src/openrct2/rct2/T6Exporter.cpp @@ -51,6 +51,7 @@ namespace OpenRCT2::RCT2 bool T6Exporter::SaveTrack(OpenRCT2::IStream* stream) { + auto& rtd = GetRideTypeDescriptor(_trackDesign.trackAndVehicle.rtdIndex); auto td6rideType = OpenRCT2RideTypeToRCT2RideType(_trackDesign.trackAndVehicle.rtdIndex); OpenRCT2::MemoryStream tempStream; tempStream.WriteValue(td6rideType); @@ -81,7 +82,7 @@ namespace OpenRCT2::RCT2 tempStream.WriteValue(_trackDesign.statistics.maxNegativeVerticalG / kTD46GForcesMultiplier); tempStream.WriteValue(_trackDesign.statistics.maxLateralG / kTD46GForcesMultiplier); - if (td6rideType == RIDE_TYPE_MINI_GOLF) + if (rtd.specialType == RtdSpecialType::miniGolf) tempStream.WriteValue(_trackDesign.statistics.holes & kRCT12InversionAndHoleMask); else tempStream.WriteValue(_trackDesign.statistics.inversions & kRCT12InversionAndHoleMask); @@ -114,8 +115,7 @@ namespace OpenRCT2::RCT2 } tempStream.WriteValue(_trackDesign.operation.liftHillSpeed | (_trackDesign.operation.numCircuits << 5)); - const auto& rtd = GetRideTypeDescriptor(_trackDesign.trackAndVehicle.rtdIndex); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { for (const auto& mazeElement : _trackDesign.mazeElements) { diff --git a/src/openrct2/rct2/T6Importer.cpp b/src/openrct2/rct2/T6Importer.cpp index 5bc7ffa78e..605a3e3941 100644 --- a/src/openrct2/rct2/T6Importer.cpp +++ b/src/openrct2/rct2/T6Importer.cpp @@ -132,7 +132,7 @@ namespace OpenRCT2::RCT2 td->operation.operationSetting, GetRideTypeDescriptor(td->trackAndVehicle.rtdIndex).OperatingSettings.MaxValue); const auto& rtd = GetRideTypeDescriptor(td->trackAndVehicle.rtdIndex); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { TD46MazeElement t6MazeElement{}; t6MazeElement.All = !0; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9262504fb2..9decc64683 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -298,11 +298,11 @@ size_t Ride::GetNumPrices() const { size_t result = 0; const auto& rtd = GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isCashMachine) || rtd.HasFlag(RtdFlag::isFirstAid)) + if (rtd.specialType == RtdSpecialType::cashMachine || rtd.specialType == RtdSpecialType::firstAid) { result = 0; } - else if (rtd.HasFlag(RtdFlag::isToilet)) + else if (rtd.specialType == RtdSpecialType::toilet) { result = 1; } @@ -795,7 +795,7 @@ bool Ride::FindTrackGap(const CoordsXYE& input, CoordsXYE* output) const return false; const auto& rtd = GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) return false; WindowBase* w = WindowFindByClass(WindowClass::RideConstruction); @@ -1108,7 +1108,7 @@ void Ride::Update() // Update stations const auto& rtd = GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) for (StationIndex::UnderlyingType i = 0; i < OpenRCT2::Limits::kMaxStationsPerRide; i++) RideUpdateStation(*this, StationIndex::FromUnderlying(i)); @@ -2630,7 +2630,7 @@ static StationIndexWithMessage RideModeCheckStationPresent(const Ride& ride) if (!rtd.HasFlag(RtdFlag::hasTrack)) return { StationIndex::GetNull(), STR_NOT_YET_CONSTRUCTED }; - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) return { StationIndex::GetNull(), STR_NOT_YET_CONSTRUCTED }; return { StationIndex::GetNull(), STR_REQUIRES_A_STATION_PLATFORM }; @@ -2793,7 +2793,7 @@ static bool RideCheckTrackContainsInversions(const CoordsXYE& input, CoordsXYE* if (ride != nullptr) { const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) return true; } @@ -2854,7 +2854,7 @@ static bool RideCheckTrackContainsBanked(const CoordsXYE& input, CoordsXYE* outp return false; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) return true; WindowBase* w = WindowFindByClass(WindowClass::RideConstruction); @@ -3189,7 +3189,7 @@ static void RideSetStartFinishPoints(RideId rideIndex, const CoordsXYE& startEle return; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) RideSetMazeEntranceExitPoints(*ride); else if (ride->type == RIDE_TYPE_BOAT_HIRE) RideSetBoatHireReturnPoint(*ride, startElement); @@ -3974,7 +3974,7 @@ void Ride::ConstructMissingEntranceOrExit() const } const auto& rtd = GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) { auto location = incompleteStation->GetStart(); WindowScrollToLocation(*w, location); @@ -5906,7 +5906,7 @@ ResultWithMessage Ride::ChangeStatusGetStartElement(StationIndex stationIndex, C { // Maze is strange, station start is 0... investigation required const auto& rtd = GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) return { false }; } diff --git a/src/openrct2/ride/RideConstruction.cpp b/src/openrct2/ride/RideConstruction.cpp index d310e5c3f1..ebb333b08e 100644 --- a/src/openrct2/ride/RideConstruction.cpp +++ b/src/openrct2/ride/RideConstruction.cpp @@ -960,7 +960,7 @@ bool RideModify(const CoordsXYE& input) ride_create_or_find_construction_window(rideIndex); const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { return ride_modify_maze(tileElement); } @@ -1147,7 +1147,7 @@ money64 SetOperatingSettingNested(RideId rideId, RideSetSetting setting, uint8_t void Ride::ValidateStations() { const auto& rtd = GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) { // find the stations of the ride to begin stepping over track elements from for (const auto& station : stations) diff --git a/src/openrct2/ride/RideData.h b/src/openrct2/ride/RideData.h index 9e2b56e18d..ba133232ba 100644 --- a/src/openrct2/ride/RideData.h +++ b/src/openrct2/ride/RideData.h @@ -328,114 +328,126 @@ struct TrackDrawerDescriptor enum class RtdFlag : uint8_t { - hasTrackColourMain = 0, - hasTrackColourAdditional = 1, - hasTrackColourSupports = 2, + hasTrackColourMain, + hasTrackColourAdditional, + hasTrackColourSupports, // Set by flat rides, tower rides and shops/stalls. - hasSinglePieceStation = 3, + hasSinglePieceStation, - hasLeaveWhenAnotherVehicleArrivesAtStation = 4, - canSynchroniseWithAdjacentStations = 5, + hasLeaveWhenAnotherVehicleArrivesAtStation, + canSynchroniseWithAdjacentStations, // Used only by boat Hire and submarine ride - trackMustBeOnWater = 6, + trackMustBeOnWater, - hasGForces = 7, + hasGForces, // Used by rides that can't have gaps, like those with a vertical tower, // such as the observation tower. - cannotHaveGaps = 8, + cannotHaveGaps, - hasDataLogging = 9, - hasDrops = 10, + hasDataLogging, + hasDrops, + + noTestMode, - noTestMode = 11, // Set on rides with two varieties, like the u and o shapes of the dinghy slide // and the dry and submerged track of the water coaster. - - hasCoveredPieces = 12, + hasCoveredPieces, // Used only by maze, spiral slide and shops - noVehicles = 13, + noVehicles, - hasLoadOptions = 14, - hasLsmBehaviourOnFlat = 15, + hasLoadOptions, + hasLsmBehaviourOnFlat, // Set by flat rides where the vehicle is integral to the structure, like // Merry-go-round and swinging ships. (Contrast with rides like dodgems.) - vehicleIsIntegral = 16, + vehicleIsIntegral, - isShopOrFacility = 17, + isShopOrFacility, // If set, wall scenery can not share a tile with the ride's track - noWallsAroundTrack = 18, + noWallsAroundTrack, - isFlatRide = 19, + isFlatRide, // Whether or not guests will go on the ride again if they liked it // (this is usually applied to everything apart from transport rides). - guestsWillRideAgain = 20, + guestsWillRideAgain, // Used by Toilets and First Aid to mark that guest should go // inside the building (rather than 'buying' at the counter) - guestsShouldGoInsideFacility = 21, + guestsShouldGoInsideFacility, // Guests are "IN" (ride) rather than "ON" (ride) - describeAsInside = 22, + describeAsInside, - sellsFood = 23, - sellsDrinks = 24, - isToilet = 25, + sellsFood, + sellsDrinks, // Whether or not vehicle colours can be set - hasVehicleColours = 26, + hasVehicleColours, - checkForStalling = 27, - hasTrack = 28, + checkForStalling, + hasTrack, // Only set by lift - allowExtraTowerBases = 29, + allowExtraTowerBases, // Only set by reverser coaster - layeredVehiclePreview = 30, + layeredVehiclePreview, - supportsMultipleColourSchemes = 31, - allowDoorsOnTrack = 32, - hasMusicByDefault = 33, - allowMusic = 34, + supportsMultipleColourSchemes, + allowDoorsOnTrack, + hasMusicByDefault, + allowMusic, // Used by the Flying RC, Lay-down RC, Multi-dimension RC - hasInvertedVariant = 35, + hasInvertedVariant, - checkGForces = 36, - hasEntranceAndExit = 37, - allowMoreVehiclesThanStationFits = 38, - hasAirTime = 39, - singleSession = 40, - allowMultipleCircuits = 41, - allowCableLiftHill = 42, - showInTrackDesigner = 43, - isTransportRide = 44, - interestingToLookAt = 45, - slightlyInterestingToLookAt = 46, + checkGForces, + hasEntranceAndExit, + allowMoreVehiclesThanStationFits, + hasAirTime, + singleSession, + allowMultipleCircuits, + allowCableLiftHill, + showInTrackDesigner, + isTransportRide, + interestingToLookAt, + slightlyInterestingToLookAt, // This is only set on the Flying RC and its alternative type. - startConstructionInverted = 47, + startConstructionInverted, - listVehiclesSeparately = 48, - supportsLevelCrossings = 49, - isSuspended = 50, - hasLandscapeDoors = 51, - upInclineRequiresLift = 52, - guestsCanUseUmbrella = 53, - isCashMachine = 54, - hasOneStation = 55, - hasSeatRotation = 56, - isFirstAid = 57, - isMaze = 58, - isSpiralSlide = 59, - allowReversedTrains = 60, + listVehiclesSeparately, + supportsLevelCrossings, + isSuspended, + hasLandscapeDoors, + upInclineRequiresLift, + guestsCanUseUmbrella, + hasOneStation, + hasSeatRotation, + allowReversedTrains, +}; + +/** + * Some rides are so different from others that they need some special code. + * This replaces direct ride type checks. + * + * Note: only add to this list if behaviour cannot sufficiently be altered using flags. + */ +enum class RtdSpecialType +{ + none, + maze, + miniGolf, + spiralSlide, + toilet, + cashMachine, + firstAid, }; // Set on ride types that have a main colour, additional colour and support colour. @@ -517,6 +529,7 @@ struct RideTypeDescriptor MusicTrackOffsetLengthFunc MusicTrackOffsetLength = OpenRCT2::RideAudio::RideMusicGetTrackOffsetLength_Default; UpdateRideApproachVehicleWaypointsFunction UpdateRideApproachVehicleWaypoints = UpdateRideApproachVehicleWaypointsDefault; + RtdSpecialType specialType = RtdSpecialType::none; bool HasFlag(RtdFlag flag) const; /** @deprecated */ diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 2a0a4e2540..7d251e7371 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -526,7 +526,7 @@ static void ride_ratings_begin_proximity_loop(RideRatingUpdateState& state) } const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { state.State = RIDE_RATINGS_STATE_CALCULATE; return; @@ -1632,7 +1632,7 @@ static RatingTuple ride_ratings_get_turns_ratings(const Ride& ride) intensity += slopedTurnsRating.intensity; nausea += slopedTurnsRating.nausea; - auto inversions = (ride.type == RIDE_TYPE_MINI_GOLF) ? ride.holes : ride.inversions; + auto inversions = ride.GetRideTypeDescriptor().specialType == RtdSpecialType::miniGolf ? ride.holes : ride.inversions; RatingTuple inversionsRating = get_inversions_ratings(inversions); excitement += inversionsRating.excitement; intensity += inversionsRating.intensity; @@ -1769,7 +1769,7 @@ static int32_t ride_ratings_get_scenery_score(const Ride& ride) } const auto& rtd = ride.GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { location = ride.GetStation().Entrance.ToCoordsXY(); } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 817a86ec89..15415a5d8f 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -906,7 +906,7 @@ static void TrackDesignMirrorMaze(TrackDesign& td) void TrackDesignMirror(TrackDesign& td) { const auto& rtd = GetRideTypeDescriptor(td.trackAndVehicle.rtdIndex); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { TrackDesignMirrorMaze(td); } @@ -1767,7 +1767,7 @@ static GameActions::Result TrackDesignPlaceVirtual( GameActions::Result trackPlaceRes; const auto& rtd = GetRideTypeDescriptor(td.trackAndVehicle.rtdIndex); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) { trackPlaceRes = TrackDesignPlaceMaze(tds, td, coords, ride); } diff --git a/src/openrct2/ride/TrackPaint.cpp b/src/openrct2/ride/TrackPaint.cpp index 9d2f14dc0a..f8e66b6bff 100644 --- a/src/openrct2/ride/TrackPaint.cpp +++ b/src/openrct2/ride/TrackPaint.cpp @@ -1972,7 +1972,8 @@ void PaintTrack(PaintSession& session, Direction direction, int32_t height, cons { uint8_t zOffset = 16; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isToilet) || rtd.HasFlag(RtdFlag::isFirstAid) || rtd.HasFlag(RtdFlag::isCashMachine)) + if (rtd.specialType == RtdSpecialType::toilet || rtd.specialType == RtdSpecialType::firstAid + || rtd.specialType == RtdSpecialType::cashMachine) zOffset = 23; const auto* originElement = ride->GetOriginElement(StationIndex::FromUnderlying(0)); diff --git a/src/openrct2/ride/rtd/gentle/Maze.h b/src/openrct2/ride/rtd/gentle/Maze.h index e3dc2616b4..4e53d6a5b4 100644 --- a/src/openrct2/ride/rtd/gentle/Maze.h +++ b/src/openrct2/ride/rtd/gentle/Maze.h @@ -29,7 +29,7 @@ constexpr RideTypeDescriptor MazeRTD = .InvertedTrackPaintFunctions = {}, .Flags = EnumsToFlags(RtdFlag::hasTrackColourSupports, RtdFlag::hasSinglePieceStation, RtdFlag::noTestMode, RtdFlag::noVehicles, RtdFlag::noWallsAroundTrack, RtdFlag::describeAsInside, RtdFlag::hasTrack, RtdFlag::hasEntranceAndExit, - RtdFlag::guestsCanUseUmbrella, RtdFlag::isMaze), + RtdFlag::guestsCanUseUmbrella), .RideModes = EnumsToFlags(RideMode::Maze), .DefaultMode = RideMode::Maze, .OperatingSettings = { 1, 64 }, @@ -74,5 +74,6 @@ constexpr RideTypeDescriptor MazeRTD = .SpecialElementRatingAdjustment = SpecialTrackElementRatingsAjustment_Default, .GetGuestWaypointLocation = GetGuestWaypointLocationDefault, .ConstructionWindowContext = RideConstructionWindowContext::Maze, + .specialType = RtdSpecialType::maze, }; // clang-format on diff --git a/src/openrct2/ride/rtd/gentle/MiniGolf.h b/src/openrct2/ride/rtd/gentle/MiniGolf.h index f06e988df1..78a8be78f8 100644 --- a/src/openrct2/ride/rtd/gentle/MiniGolf.h +++ b/src/openrct2/ride/rtd/gentle/MiniGolf.h @@ -80,5 +80,6 @@ constexpr RideTypeDescriptor MiniGolfRTD = .ConstructionWindowContext = RideConstructionWindowContext::Default, .RideUpdate = nullptr, .UpdateMeasurementsSpecialElements = RideUpdateMeasurementsSpecialElements_MiniGolf, + .specialType = RtdSpecialType::miniGolf, }; // clang-format on diff --git a/src/openrct2/ride/rtd/gentle/SpiralSlide.h b/src/openrct2/ride/rtd/gentle/SpiralSlide.h index be22034f39..883b48e81e 100644 --- a/src/openrct2/ride/rtd/gentle/SpiralSlide.h +++ b/src/openrct2/ride/rtd/gentle/SpiralSlide.h @@ -29,7 +29,7 @@ constexpr RideTypeDescriptor SpiralSlideRTD = RtdFlag::cannotHaveGaps, RtdFlag::noTestMode, RtdFlag::noVehicles, RtdFlag::noWallsAroundTrack, RtdFlag::isFlatRide, RtdFlag::allowMusic, RtdFlag::hasEntranceAndExit, RtdFlag::interestingToLookAt, - RtdFlag::listVehiclesSeparately, RtdFlag::isSpiralSlide), + RtdFlag::listVehiclesSeparately), .RideModes = EnumsToFlags(RideMode::SingleRidePerAdmission, RideMode::UnlimitedRidesPerAdmission), .DefaultMode = RideMode::SingleRidePerAdmission, .OperatingSettings = { 1, 5 }, @@ -78,5 +78,6 @@ constexpr RideTypeDescriptor SpiralSlideRTD = .GetGuestWaypointLocation = GetGuestWaypointLocationDefault, .ConstructionWindowContext = RideConstructionWindowContext::Default, .RideUpdate = UpdateSpiralSlide, + .specialType = RtdSpecialType::spiralSlide, }; // clang-format on diff --git a/src/openrct2/ride/rtd/shops/CashMachine.h b/src/openrct2/ride/rtd/shops/CashMachine.h index 8865bbf4a8..b78f85e4e8 100644 --- a/src/openrct2/ride/rtd/shops/CashMachine.h +++ b/src/openrct2/ride/rtd/shops/CashMachine.h @@ -25,7 +25,7 @@ constexpr RideTypeDescriptor CashMachineRTD = }), .InvertedTrackPaintFunctions = {}, .Flags = EnumsToFlags(RtdFlag::hasSinglePieceStation, RtdFlag::cannotHaveGaps, RtdFlag::noTestMode, - RtdFlag::noVehicles, RtdFlag::isCashMachine, RtdFlag::isShopOrFacility, + RtdFlag::noVehicles, RtdFlag::isShopOrFacility, RtdFlag::noWallsAroundTrack, RtdFlag::isFlatRide, RtdFlag::listVehiclesSeparately), .RideModes = EnumsToFlags(RideMode::ShopStall), .DefaultMode = RideMode::ShopStall, @@ -61,5 +61,6 @@ constexpr RideTypeDescriptor CashMachineRTD = .DesignCreateMode = TrackDesignCreateMode::Default, .MusicUpdateFunction = DefaultMusicUpdate, .Classification = RideClassification::KioskOrFacility, + .specialType = RtdSpecialType::cashMachine, }; // clang-format on diff --git a/src/openrct2/ride/rtd/shops/FirstAid.h b/src/openrct2/ride/rtd/shops/FirstAid.h index 553f3f4fd0..da13a5d2c3 100644 --- a/src/openrct2/ride/rtd/shops/FirstAid.h +++ b/src/openrct2/ride/rtd/shops/FirstAid.h @@ -26,7 +26,7 @@ constexpr RideTypeDescriptor FirstAidRTD = .InvertedTrackPaintFunctions = {}, .Flags = EnumsToFlags(RtdFlag::hasSinglePieceStation, RtdFlag::cannotHaveGaps, RtdFlag::noTestMode, RtdFlag::noVehicles, RtdFlag::isShopOrFacility, RtdFlag::noWallsAroundTrack, - RtdFlag::isFlatRide, RtdFlag::isFirstAid, RtdFlag::guestsShouldGoInsideFacility, + RtdFlag::isFlatRide, RtdFlag::guestsShouldGoInsideFacility, RtdFlag::describeAsInside, RtdFlag::listVehiclesSeparately), .RideModes = EnumsToFlags(RideMode::ShopStall), .DefaultMode = RideMode::ShopStall, @@ -63,5 +63,6 @@ constexpr RideTypeDescriptor FirstAidRTD = .DesignCreateMode = TrackDesignCreateMode::Default, .MusicUpdateFunction = DefaultMusicUpdate, .Classification = RideClassification::KioskOrFacility, + .specialType = RtdSpecialType::firstAid, }; // clang-format on diff --git a/src/openrct2/ride/rtd/shops/Toilets.h b/src/openrct2/ride/rtd/shops/Toilets.h index 5e60e15896..d88e44a25b 100644 --- a/src/openrct2/ride/rtd/shops/Toilets.h +++ b/src/openrct2/ride/rtd/shops/Toilets.h @@ -27,7 +27,7 @@ constexpr RideTypeDescriptor ToiletsRTD = .Flags = EnumsToFlags(RtdFlag::hasSinglePieceStation, RtdFlag::cannotHaveGaps, RtdFlag::noTestMode, RtdFlag::noVehicles, RtdFlag::isShopOrFacility, RtdFlag::noWallsAroundTrack, RtdFlag::isFlatRide, RtdFlag::guestsShouldGoInsideFacility, RtdFlag::describeAsInside, - RtdFlag::isToilet, RtdFlag::listVehiclesSeparately), + RtdFlag::listVehiclesSeparately), .RideModes = EnumsToFlags(RideMode::ShopStall), .DefaultMode = RideMode::ShopStall, .OperatingSettings = { 4, 4 }, @@ -63,5 +63,6 @@ constexpr RideTypeDescriptor ToiletsRTD = .DesignCreateMode = TrackDesignCreateMode::Default, .MusicUpdateFunction = DefaultMusicUpdate, .Classification = RideClassification::KioskOrFacility, + .specialType = RtdSpecialType::toilet, }; // clang-format on diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.cpp b/src/openrct2/scripting/bindings/world/ScTileElement.cpp index 7ec82c4171..dbd13a201c 100644 --- a/src/openrct2/scripting/bindings/world/ScTileElement.cpp +++ b/src/openrct2/scripting/bindings/world/ScTileElement.cpp @@ -508,7 +508,7 @@ namespace OpenRCT2::Scripting if (ride != nullptr) { const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) throw DukException() << "Cannot read 'sequence' property, TrackElement belongs to a maze."; } @@ -561,7 +561,7 @@ namespace OpenRCT2::Scripting if (ride != nullptr) { const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) throw DukException() << "Cannot set 'sequence' property, TrackElement belongs to a maze."; } @@ -834,7 +834,7 @@ namespace OpenRCT2::Scripting throw DukException() << "Cannot read 'mazeEntry' property, ride is invalid."; const auto& rtd = ride->GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) throw DukException() << "Cannot read 'mazeEntry' property, ride is not a maze."; duk_push_int(ctx, el->GetMazeEntry()); @@ -864,7 +864,7 @@ namespace OpenRCT2::Scripting throw DukException() << "Cannot set 'mazeEntry' property, ride is invalid."; const auto& rtd = ride->GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) throw DukException() << "Cannot set 'mazeEntry' property, ride is not a maze."; el->SetMazeEntry(value.as_uint()); @@ -892,7 +892,7 @@ namespace OpenRCT2::Scripting throw DukException() << "Cannot read 'colourScheme' property, ride is invalid."; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) throw DukException() << "Cannot read 'colourScheme' property, TrackElement belongs to a maze."; duk_push_int(ctx, el->GetColourScheme()); @@ -922,7 +922,7 @@ namespace OpenRCT2::Scripting throw DukException() << "Cannot set 'colourScheme', ride is invalid."; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) throw DukException() << "Cannot set 'colourScheme' property, TrackElement belongs to a maze."; el->SetColourScheme(static_cast(value.as_uint())); @@ -950,7 +950,7 @@ namespace OpenRCT2::Scripting throw DukException() << "Cannot read 'seatRotation' property, ride is invalid."; const auto& rtd = ride->GetRideTypeDescriptor(); - if (rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType == RtdSpecialType::maze) throw DukException() << "Cannot read 'seatRotation' property, TrackElement belongs to a maze."; duk_push_int(ctx, el->GetSeatRotation()); @@ -980,7 +980,7 @@ namespace OpenRCT2::Scripting throw DukException() << "Cannot set 'seatRotation' property, ride is invalid."; const auto& rtd = ride->GetRideTypeDescriptor(); - if (!rtd.HasFlag(RtdFlag::isMaze)) + if (rtd.specialType != RtdSpecialType::maze) throw DukException() << "Cannot set 'seatRotation' property, TrackElement belongs to a maze."; el->SetSeatRotation(value.as_uint()); From d94d92e197b4dd9890bfb55736498ea6192f3edb Mon Sep 17 00:00:00 2001 From: Tulio Leao Date: Sun, 24 Nov 2024 16:07:35 -0300 Subject: [PATCH 089/139] Add translation to Flathub package for de-DE and pt-BR Co-authored-by: Wuzzy --- distribution/changelog.txt | 2 +- distribution/linux/openrct2.appdata.xml | 58 ++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 74feb991f6..f1a895a343 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -30,7 +30,7 @@ - Fix: [#23015] Crash when loading a save game when the construction window is still open. - Fix: [#23018] Crash when loading a new game when the construction window is still open. - Fix: [#23023] Large scenery clearance height interpreted as negative when greater than 127. -- Fix: [#23044] "remove_unused_objects" command causes blank peep names. +- Fix: [#23044] “remove_unused_objects” command causes blank peep names. - Fix: [#23048] Map generator allows map sizes out of range through text input. - Fix: [#23058] [Plugin] Changing window colours doesn’t trigger the window to be fully redrawn. - Fix: [#23085] LIM Launched Roller Coaster medium half loops clip into each other when built back-to-back. diff --git a/distribution/linux/openrct2.appdata.xml b/distribution/linux/openrct2.appdata.xml index e05577c825..28396fa99e 100644 --- a/distribution/linux/openrct2.appdata.xml +++ b/distribution/linux/openrct2.appdata.xml @@ -6,12 +6,16 @@ OpenRCT2 Amusement park simulation Simulador de parcs d’atraccions + Freizeitparksimulation 놀이공원 시뮬레이션 Symulator parku rozrywki + Simulador de parque de diversões The OpenRCT2 Team - OpenRCT2 팀 Equip de l’OpenRCT2 + Das OpenRCT2-Team + OpenRCT2 팀 Zespół OpenRCT2 + Equipe do OpenRCT2 openrct2.desktop

@@ -32,6 +36,16 @@ alguns objectius en un determinat període de temps, mentre que al mode lliure pot construir amb més flexibilitat, fins i tot sense restriccions.

+

+ OpenRCT2 ist eine Open-Source-Reimplementierung von RollerCoaster Tycoon 2 (RCT2). + Im Spiel geht es um den Bau und die Verwaltung eines Freizeitparks mit Attraktionen, + Läden und Einrichtungen. Der Spieler muss versuchen, Profit zu erwirtschaften und + eine gute Parkreputation aufrecht zu erhalten, während die Gäste bei Laune gehalten + werden. In OpenRCT2 kann mal sowohl Szenarien als auch in einen Sandboxmodus + spielen. In Szenarien muss der Spieler ein bestimmtes Ziel innerhalb eines Zeitlimits + erfüllen. In der Sandbox kann der Spieler einen flexibleren Park bauen – falls + gewünscht ohne Einschränkungen. +

OpenRCT는 RollerCoaster Tycoon 2 (RCT2)의 오픈 소스 재구현판입니다. 놀이기구, 상점, 매점 등을 건설하고 유지하는 것이 게임 플레이의 중심이 됩니다. @@ -50,6 +64,16 @@ określonego celu w wyznaczonym czasie, podczas gdy tryb sandbox pozwala na swobodne budowanie parku, z możliwością wyłączenia ograniczeń i finansów.

+

+ OpenRCT2 é uma reimplementação de código aberto do RollerCoaster Tycoon 2 (RCT2). + A dinâmica de jogo gira em torno de construir e manter um parque de diversões contendo + atrações, lojas e instalações. O jogador deve tentar gerar lucro e manter uma boa + reputação para o parque, enquanto tenta fazer com que os visitantes continuem felizes. + O OpenRCT2 permite tanto jogos em cenários quanto em “caixa de areia”. Os cenários + demandam que o jogador atinja um certo objetivo em um determinado prazo, enquanto a + “caixa de areia” deixa o jogador construir um parque mais flexível, opcionalmente sem + restrições ou finanças. +

OpenRCT2 features many changes compared to the original RollerCoaster Tycoon 2 game. A few of them are listed here. @@ -57,58 +81,82 @@

L’OpenRCT2 té molts canvis respecte al joc RollerCoaster Tycoon 2 original, com ara:

+

+ OpenRCT2 hat viele Änderungen im Verleich mit dem Originalspiel RollerCoaster Tycoon 2. Hier sind einige von ihnen aufgelistet. +

OpenRCT2는 오리지널 RollerCoaster Tycoon 2 게임에 비해 많은 기능적 변화가 있습니다. 여기에 일부 기능이 나열되어 있습니다.

OpenRCT2 zawiera wiele zmian w porównaniu do oryginalnej gry RollerCoaster Tycoon 2. Oto kilka z nich:

+

+ O OpenRCT2 conta com muitas mudanças quando comparado ao jogo RollerCoaster Tycoon 2 original. Aqui são listadas algumas delas. +

  • User Interface theming.
  • Temes per a la interfície gràfica
  • +
  • Thematische User-Interface-Anpassung.
  • 유저 인터페이스 커스터마이징
  • Edycja motywów interfejsu użytkownika
  • +
  • Customização por temas da interface de usuário.
  • Fast-forwarding gameplay.
  • Diferents velocitats de joc disponibles durant la partida
  • +
  • Spielsimulation beschleunigen.
  • 게임 속도 조절
  • Przyspieszanie rozgrywki
  • +
  • Dinâmica de jogo acelerável.
  • Multiplayer support.
  • Suport multijugador
  • +
  • Mehrspielerunterstützung.
  • 멀티플레이 지원
  • Tryb wieloosobowy
  • +
  • Suporte multijogador.
  • Multilingual. Improved translations.
  • Traduït a diversos idiomes i amb traduccions millorades
  • +
  • Mehrsprachig. Verbesserte Übersetzungen.
  • 다국어 지원 및 번역 개선
  • Wielojęzyczność i ulepszone tłumaczenia
  • +
  • Multilíngue. Traduções aperfeiçoadas.
  • OpenGL hardware rendering.
  • Renderització OpenGL per maquinari
  • +
  • OpenGL-Hardwarerendering.
  • OpenGL 하드웨어 렌더링
  • Obsługa renderowania OpenGL
  • +
  • Renderização por hardware OpenGL.
  • Various fixes and improvements for bugs in the original game.
  • Correccions i millores dels errors del joc original
  • +
  • Diverse Fehlerkorrekturen und Verbesserungen für Fehler im Originalspiel.
  • 오리지널 게임에 있던 다양한 버그 수정 및 개선
  • Poprawki błędów i usprawnienia względem oryginalnej gry
  • +
  • Várias correções e melhorias para problemas no jogo original.
  • Native support for Linux and macOS.
  • Suport natiu per a Linux i macOS
  • +
  • Native Unterstützung für Linux und macOS.
  • Linux 및 macOS 자체 지원
  • Natywna obsługa systemów Linux i macOS
  • +
  • Suporte nativo para Linux e macOS.
  • Added hacks and cheats.
  • Es poden fer trucs i trampes
  • +
  • Eingebaute Hacks und Cheats.
  • 치트 기능 지원
  • Kody i hacki
  • +
  • Trapaças e hacks adicionados.
  • Auto-saving and giant screenshots.
  • Desades automàtiques i captures de pantalla gegants
  • +
  • Automatisches Speichern und gigantische Screenshots.
  • 자동 저장 및 대형 스크린 샷
  • Autozapis i możliwość robienia ogromnych zrzutów ekranu
  • +
  • Salvamento automático e capturas de tela gigantes.

@@ -117,19 +165,27 @@

Per a jugar a l’OpenRCT2, fan falta els fitxers originals del RollerCoaster Tycoon 2 o del RollerCoaster Tycoon clàssic.

+

+ Die Originaldateien von RollerCoaster Tycoon 2 oder RollerCoaster Tycoon Classic werden benötigt, um OpenRCT2 zu spielen. +

OpenRCT2를 플레이하기 위해서는 오리지널 RollerCoaster Tycoon 2 또는 RollerCoaster Tycoon Classic 게임 파일이 필요합니다.

Do działania OpenRCT2 wymagane są pliki z RollerCoaster Tycoon 2 lub RollerCoaster Tycoon Classic.

+

+ Arquivos dos jogos originais RollerCoaster Tycoon 2 ou RollerCoaster Tycoon Classic são necessários para jogar OpenRCT2. +

https://camo.githubusercontent.com/f513bc551e2c9e04e292724113ea4789726d23921d286f21dad39a6e955b5a56/68747470733a2f2f692e696d6775722e636f6d2f6537434b3553632e706e67 Amusement park featuring an inverted roller coaster, a river rapids ride and custom scenery + Freizeitpark mit einer umgekehrten Achterbahn, einer Stromschnellenattraktion und einer eigens errichteten Szenerie 인버티드 롤러코스터를 구현한 놀이공원과 리버 래피드 기구 및 커스텀 풍경 오브젝트 Park rozrywki z odwróconą kolejką górską, spływem rwącą rzeką i niestandardową scenerią + Parque de diversões que conta com uma montanha-russa invertida, corredeira de rio e cenários customizados https://openrct2.io/ From d5b769bcc438fc4f2792cc79e8705e65112b1097 Mon Sep 17 00:00:00 2001 From: Enriath Date: Sun, 24 Nov 2024 19:09:48 +0000 Subject: [PATCH 090/139] Require the correct minimum version of nlohmann json --- debian/control | 2 +- readme.md | 2 +- src/openrct2/core/Json.hpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/debian/control b/debian/control index cda461f2c9..92701ff896 100644 --- a/debian/control +++ b/debian/control @@ -4,7 +4,7 @@ Section: misc Priority: optional Standards-Version: 3.9.2 Multi-Arch: same -Build-Depends: debhelper (>= 9), cmake (>= 3.8), libsdl2-dev, g++ (>= 4:10), pkg-config, nlohmann-json3-dev (>= 3.6.0), libspeex-dev, libspeexdsp-dev, libcurl4-openssl-dev, libcrypto++-dev, libfontconfig1-dev, libfreetype6-dev, libpng-dev, libssl-dev, libzip-dev (>= 1.0.0), libicu-dev (>= 59.0), libflac-dev, libvorbis-dev +Build-Depends: debhelper (>= 9), cmake (>= 3.8), libsdl2-dev, g++ (>= 4:10), pkg-config, nlohmann-json3-dev (>= 3.9.0), libspeex-dev, libspeexdsp-dev, libcurl4-openssl-dev, libcrypto++-dev, libfontconfig1-dev, libfreetype6-dev, libpng-dev, libssl-dev, libzip-dev (>= 1.0.0), libicu-dev (>= 59.0), libflac-dev, libvorbis-dev Package: openrct2 Architecture: any diff --git a/readme.md b/readme.md index 83b455715f..482cddf14e 100644 --- a/readme.md +++ b/readme.md @@ -128,7 +128,7 @@ OpenRCT2 requires original files of RollerCoaster Tycoon 2 to play. It can be bo - libpng (>= 1.2) - speexdsp (only for UI client) - curl (only if building with http support) - - nlohmann-json (>= 3.6.0) + - nlohmann-json (>= 3.9.0) - openssl (>= 1.0; only if building with multiplayer support) - icu (>= 59.0) - zlib diff --git a/src/openrct2/core/Json.hpp b/src/openrct2/core/Json.hpp index c66ffd6ece..43490d1c1c 100644 --- a/src/openrct2/core/Json.hpp +++ b/src/openrct2/core/Json.hpp @@ -15,9 +15,9 @@ #include #include -#if NLOHMANN_JSON_VERSION_MAJOR < 3 || (NLOHMANN_JSON_VERSION_MAJOR == 3 && NLOHMANN_JSON_VERSION_MINOR < 6) -# error "Unsupported version of nlohmann json library, must be >= 3.6" -#endif // NLOHMANN_JSON_VERSION_MAJOR < 3 || (NLOHMANN_JSON_VERSION_MAJOR == 3 && NLOHMANN_JSON_VERSION_MINOR < 6) +#if NLOHMANN_JSON_VERSION_MAJOR < 3 || (NLOHMANN_JSON_VERSION_MAJOR == 3 && NLOHMANN_JSON_VERSION_MINOR < 9) +# error "Unsupported version of nlohmann json library, must be >= 3.9" +#endif // NLOHMANN_JSON_VERSION_MAJOR < 3 || (NLOHMANN_JSON_VERSION_MAJOR == 3 && NLOHMANN_JSON_VERSION_MINOR < 9) using json_t = nlohmann::json; From 76a40bb52a9bad01a821ecb9aedd2c3f8a64f2e8 Mon Sep 17 00:00:00 2001 From: AuraSpecs Date: Sun, 24 Nov 2024 21:12:51 +0100 Subject: [PATCH 091/139] Add diagonal booster to LSM Launched Coaster --- distribution/changelog.txt | 1 + resources/g2/sprites.json | 30 ++++++++++++++++++ .../lattice_triangle/diagonal_booster_0.png | Bin 0 -> 1232 bytes .../lattice_triangle/diagonal_booster_1.png | Bin 0 -> 1169 bytes .../diagonal_booster_alt_0.png | Bin 0 -> 1257 bytes .../diagonal_booster_alt_1.png | Bin 0 -> 1164 bytes .../diagonal_booster_alt_2.png | Bin 0 -> 1223 bytes .../diagonal_booster_alt_3.png | Bin 0 -> 1167 bytes src/openrct2-ui/ride/Construction.h | 3 +- src/openrct2/network/NetworkBase.cpp | 2 +- .../track/coaster/LatticeTriangleTrack.cpp | 14 ++++++++ .../track/coaster/LatticeTriangleTrackAlt.cpp | 14 ++++++++ src/openrct2/park/ParkFile.h | 4 +-- src/openrct2/ride/Ride.cpp | 1 + src/openrct2/ride/Track.cpp | 9 +++++- src/openrct2/ride/Track.h | 4 ++- src/openrct2/ride/TrackData.cpp | 17 ++++++++-- src/openrct2/ride/VehicleSubpositionData.cpp | 7 ++-- src/openrct2/ride/rtd/coaster/GigaCoaster.h | 2 +- .../rtd/coaster/LSMLaunchedRollerCoaster.h | 2 +- src/openrct2/sprites.h | 8 ++++- 21 files changed, 103 insertions(+), 15 deletions(-) create mode 100644 resources/g2/track/lattice_triangle/diagonal_booster_0.png create mode 100644 resources/g2/track/lattice_triangle/diagonal_booster_1.png create mode 100644 resources/g2/track/lattice_triangle/diagonal_booster_alt_0.png create mode 100644 resources/g2/track/lattice_triangle/diagonal_booster_alt_1.png create mode 100644 resources/g2/track/lattice_triangle/diagonal_booster_alt_2.png create mode 100644 resources/g2/track/lattice_triangle/diagonal_booster_alt_3.png diff --git a/distribution/changelog.txt b/distribution/changelog.txt index f1a895a343..b4c76b4d27 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -5,6 +5,7 @@ - Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). +- Improved: [#23233] Add diagonal booster to LSM Launched Coaster. - Fix: [#22726] ‘Force park rating’ cheat is not saved with the park. - Fix: [#23206] Multiplayer desyncs when FPS is uncapped. - Fix: [#23238] Updating a guest’s favourite ride works differently from vanilla RCT2. diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 7b2079f8a4..f2d753e98c 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -2847,6 +2847,36 @@ "y": -9, "palette": "keep" }, + { + "path": "track/lattice_triangle/diagonal_booster_0.png", + "x": -32, + "y": 3 + }, + { + "path": "track/lattice_triangle/diagonal_booster_1.png", + "x": -8, + "y": -9 + }, + { + "path": "track/lattice_triangle/diagonal_booster_alt_0.png", + "x": -32, + "y": 2 + }, + { + "path": "track/lattice_triangle/diagonal_booster_alt_1.png", + "x": -8, + "y": -9 + }, + { + "path": "track/lattice_triangle/diagonal_booster_alt_2.png", + "x": -32, + "y": 3 + }, + { + "path": "track/lattice_triangle/diagonal_booster_alt_3.png", + "x": -8, + "y": -9 + }, { "path": "track/lattice_triangle/drive_tyre_1.png", "x": -22, diff --git a/resources/g2/track/lattice_triangle/diagonal_booster_0.png b/resources/g2/track/lattice_triangle/diagonal_booster_0.png new file mode 100644 index 0000000000000000000000000000000000000000..b3260656d3c3e1ef821240fbd78dadc53aa62f3d GIT binary patch literal 1232 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 literal 0 HcmV?d00001 diff --git a/src/openrct2-ui/ride/Construction.h b/src/openrct2-ui/ride/Construction.h index 42d2f347c1..392edf426c 100644 --- a/src/openrct2-ui/ride/Construction.h +++ b/src/openrct2-ui/ride/Construction.h @@ -47,6 +47,7 @@ namespace OpenRCT2 TrackElemType::LeftHalfBankedHelixDownLarge, TrackElemType::RightHalfBankedHelixDownLarge, TrackElemType::Booster, + TrackElemType::DiagBooster, TrackElemType::Brakes, TrackElemType::DiagBrakes, TrackElemType::Down25Brakes, @@ -143,7 +144,7 @@ namespace OpenRCT2 constexpr size_t DropdownLength = DropdownOrder.size(); // Update the magic number with the current number of track elements to silence - static_assert(EnumValue(TrackElemType::Count) == 340, "Reminder to add new track element to special dropdown list"); + static_assert(EnumValue(TrackElemType::Count) == 341, "Reminder to add new track element to special dropdown list"); constexpr bool TrackPieceDirectionIsDiagonal(const uint8_t direction) { diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 73226b6e07..1ec9033c2f 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -49,7 +49,7 @@ using namespace OpenRCT2; // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -constexpr uint8_t kNetworkStreamVersion = 4; +constexpr uint8_t kNetworkStreamVersion = 5; const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion); diff --git a/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp b/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp index 84f425a21f..a6d1f7a09a 100644 --- a/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp +++ b/src/openrct2/paint/track/coaster/LatticeTriangleTrack.cpp @@ -18421,6 +18421,18 @@ static void LatticeTriangleTrackDiagBrakes( PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); } +static void LatticeTriangleTrackDiagBooster( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + constexpr ImageIndex images[kNumOrthogonalDirections] = { SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_1, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_2, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_1, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_2 }; + + TrackPaintUtilDiagTilesPaintExtra(session, 3, height, direction, trackSequence, images, supportType.metal); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionLatticeTriangleTrack(OpenRCT2::TrackElemType trackType) { switch (trackType) @@ -18910,6 +18922,8 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionLatticeTriangleTrack(OpenRCT2::TrackEl case TrackElemType::DiagBlockBrakes: case TrackElemType::DiagBrakes: return LatticeTriangleTrackDiagBrakes; + case TrackElemType::DiagBooster: + return LatticeTriangleTrackDiagBooster; default: return nullptr; } diff --git a/src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp b/src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp index f2623d6649..fce98ceb48 100644 --- a/src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp +++ b/src/openrct2/paint/track/coaster/LatticeTriangleTrackAlt.cpp @@ -194,6 +194,18 @@ static void LatticeTriangleTrackAltPoweredLift( PaintUtilSetGeneralSupportHeight(session, height + 56); } +static void LatticeTriangleTrackAltDiagBooster( + PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + constexpr ImageIndex images[kNumOrthogonalDirections] = { SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_1, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_2, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_3, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_4 }; + + TrackPaintUtilDiagTilesPaintExtra(session, 3, height, direction, trackSequence, images, supportType.metal); +} + TRACK_PAINT_FUNCTION GetTrackPaintFunctionLatticeTriangleTrackAlt(TrackElemType trackType) { switch (trackType) @@ -210,6 +222,8 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionLatticeTriangleTrackAlt(TrackElemType return LatticeTriangleTrackAltBooster; case TrackElemType::PoweredLift: return LatticeTriangleTrackAltPoweredLift; + case TrackElemType::DiagBooster: + return LatticeTriangleTrackAltDiagBooster; default: return GetTrackPaintFunctionLatticeTriangleTrack(trackType); diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index 92d883c79c..5d9a6d3ad5 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -11,10 +11,10 @@ namespace OpenRCT2 struct GameState_t; // Current version that is saved. - constexpr uint32_t PARK_FILE_CURRENT_VERSION = 44; + constexpr uint32_t PARK_FILE_CURRENT_VERSION = 45; // The minimum version that is forwards compatible with the current version. - constexpr uint32_t PARK_FILE_MIN_VERSION = 44; + constexpr uint32_t PARK_FILE_MIN_VERSION = 45; // 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.cpp b/src/openrct2/ride/Ride.cpp index 9262504fb2..c9ffa62b2c 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -4939,6 +4939,7 @@ OpenRCT2::BitSet RideEntryGetSupportedTrackPieces( { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites8 }, // TrackGroup::diagBrakes { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites8 }, // TrackGroup::diagBlockBrakes { SpriteGroupType::Slopes25, SpritePrecision::Sprites4 }, // TrackGroup::inclinedBrakes + { SpriteGroupType::SlopeFlat, SpritePrecision::Sprites8 }, // TrackGroup::diagBooster }; static_assert(std::size(trackPieceRequiredSprites) == EnumValue(TrackGroup::count)); diff --git a/src/openrct2/ride/Track.cpp b/src/openrct2/ride/Track.cpp index 78fd353d65..0c080fef7d 100644 --- a/src/openrct2/ride/Track.cpp +++ b/src/openrct2/ride/Track.cpp @@ -599,7 +599,14 @@ bool TrackTypeIsBlockBrakes(OpenRCT2::TrackElemType trackType) bool TrackTypeIsBooster(OpenRCT2::TrackElemType trackType) { - return trackType == TrackElemType::Booster; + switch (trackType) + { + case TrackElemType::Booster: + case TrackElemType::DiagBooster: + return true; + default: + return false; + } } bool TrackElementIsCovered(OpenRCT2::TrackElemType trackElementType) diff --git a/src/openrct2/ride/Track.h b/src/openrct2/ride/Track.h index 9a37c76438..bc7a1a0fcc 100644 --- a/src/openrct2/ride/Track.h +++ b/src/openrct2/ride/Track.h @@ -146,6 +146,7 @@ enum class TrackGroup : uint8_t diagBrakes, diagBlockBrakes, inclinedBrakes, + diagBooster, count, }; @@ -600,8 +601,9 @@ namespace OpenRCT2 DiagBrakes = 337, DiagBlockBrakes = 338, Down25Brakes = 339, + DiagBooster = 340, - Count = 340, + Count = 341, None = 65535, }; } diff --git a/src/openrct2/ride/TrackData.cpp b/src/openrct2/ride/TrackData.cpp index 8b7db7a82a..1396e5aead 100644 --- a/src/openrct2/ride/TrackData.cpp +++ b/src/openrct2/ride/TrackData.cpp @@ -368,7 +368,8 @@ namespace OpenRCT2::TrackMetaData { 4, 1, 0,-48, -32, 64 }, // TrackElemType::RightEighthBankToOrthogonalDown25 { 4, 4, 0, 0, -32, 32 }, // TrackElemType::DiagBrakes { 4, 4, 0, 0, -32, 32 }, // TrackElemType::DiagBlockBrakes - { 0, 0, 16, 0, 0, 0 } // TrackElemType::Down25Brakes + { 0, 0, 16, 0, 0, 0 }, // TrackElemType::Down25Brakes + { 4, 4, 0, 0, -32, 32 }, // TrackElemType::DiagBooster }; static_assert(std::size(_trackCoordinates) == EnumValue(TrackElemType::Count)); @@ -713,6 +714,7 @@ namespace OpenRCT2::TrackMetaData 45, // TrackElemType::DiagBrakes 45, // TrackElemType::DiagBlockBrakes 33, // TrackElemType::Down25Brakes + 45, // TrackElemType::DiagBooster }; static_assert(std::size(TrackPieceLengths) == EnumValue(TrackElemType::Count)); @@ -1058,6 +1060,7 @@ namespace OpenRCT2::TrackMetaData { TrackElemType::DiagBrakes, TrackElemType::DiagBrakes }, // TrackElemType::DiagBrakes { TrackCurve::None, TrackCurve::None }, // TrackElemType::DiagBlockBrakes { TrackElemType::Down25Brakes, TrackElemType::Down25Brakes }, // TrackElemType::Down25Brakes + { TrackElemType::DiagBooster, TrackElemType::DiagBooster }, // TrackElemType::DiagBooster }; static_assert(std::size(gTrackCurveChain) == EnumValue(TrackElemType::Count)); @@ -1592,6 +1595,7 @@ namespace OpenRCT2::TrackMetaData TrackElemType::None, // TrackElemType::DiagBrakes TrackElemType::None, // TrackElemType::DiagBlockBrakes TrackElemType::None, // TrackElemType::Down25Brakes + TrackElemType::None, // TrackElemType::DiagBooster }; static_assert(std::size(AlternativeTrackTypes) == EnumValue(TrackElemType::Count)); @@ -1937,6 +1941,7 @@ namespace OpenRCT2::TrackMetaData 123456, // TrackElemType::DiagBrakes 123456, // TrackElemType::DiagBlockBrakes 109824, // TrackElemType::Down25Brakes + 123456, // TrackElemType::DiagBooster }; static_assert(std::size(TrackPricing) == EnumValue(TrackElemType::Count)); @@ -2282,6 +2287,7 @@ namespace OpenRCT2::TrackMetaData TrackElemType::DiagBrakes, TrackElemType::DiagBlockBrakes, TrackElemType::Down25Brakes, + TrackElemType::DiagBooster, }; static_assert(std::size(TrackElementMirrorMap) == EnumValue(TrackElemType::Count)); @@ -2627,6 +2633,7 @@ namespace OpenRCT2::TrackMetaData (1 << 0), // TrackElemType::DiagBrakes (1 << 0), // TrackElemType::DiagBlockBrakes (1 << 0), // TrackElemType::Down25Brakes + (1 << 0), // TrackElemType::DiagBooster }; static_assert(std::size(TrackHeightMarkerPositions) == EnumValue(TrackElemType::Count)); @@ -2975,6 +2982,7 @@ namespace OpenRCT2::TrackMetaData /* TrackElemType::DiagBrakes */ 0, /* TrackElemType::DiagBlockBrakes */ 0, /* TrackElemType::Down25Brakes */ TRACK_ELEM_FLAG_DOWN | TRACK_ELEM_FLAG_STARTS_AT_HALF_HEIGHT, + /* TrackElemType::DiagBooster */ 0, }; static_assert(std::size(TrackFlags) == EnumValue(TrackElemType::Count)); // clang-format on @@ -3324,6 +3332,7 @@ namespace OpenRCT2::TrackMetaData { TrackGroup::diagBrakes, TrackPitch::None, TrackPitch::None, TrackRoll::None, TrackRoll::None, 0 }, // TrackElemType::DiagBrakes { TrackGroup::diagBlockBrakes, TrackPitch::None, TrackPitch::None, TrackRoll::None, TrackRoll::None, 0 }, // TrackElemType::DiagBlockBrakes { TrackGroup::inclinedBrakes, TrackPitch::Down25, TrackPitch::Down25, TrackRoll::None, TrackRoll::None, 0 }, // TrackElemType::Down25Brakes + { TrackGroup::diagBooster, TrackPitch::None, TrackPitch::None, TrackRoll::None, TrackRoll::None, 0 }, // TrackElemType::DiagBooster }; static_assert(std::size(TrackDefinitions) == EnumValue(TrackElemType::Count)); @@ -3386,7 +3395,7 @@ namespace OpenRCT2::TrackMetaData SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::L9, SpinFunction::R9, SpinFunction::L9, SpinFunction::R9, SpinFunction::L9, SpinFunction::R9, SpinFunction::L9, - SpinFunction::R9, SpinFunction::None, SpinFunction::None, SpinFunction::None + SpinFunction::R9, SpinFunction::None, SpinFunction::None, SpinFunction::None, SpinFunction::None }; static_assert(std::size(TrackTypeToSpinFunction) == EnumValue(TrackElemType::Count)); @@ -4681,6 +4690,7 @@ namespace OpenRCT2::TrackMetaData STR_BRAKES, // TrackElemType::DiagBrakes STR_BLOCK_BRAKES, // TrackElemType::DiagBlockBrakes STR_BRAKES, // TrackElemType::Down25Brakes + STR_BOOSTER, // TrackElemType::DiagBooster }; static_assert(std::size(RideConfigurationStringIds) == EnumValue(TrackElemType::Count)); @@ -12597,7 +12607,8 @@ namespace OpenRCT2::TrackMetaData /* TrackElemType::DiagBlockBrakes */ { 4, { kDiagBlockBrakesSeq0, kDiagBlockBrakesSeq1, kDiagBlockBrakesSeq2, kDiagBlockBrakesSeq3 } }, /* TrackElemType::InclinedBrakes */ - { 1, { kDown25Seq0 } } + { 1, { kDown25Seq0 } }, + /* TrackElemType::DiagBooster */ { 4, { kDiagFlatSeq0, kDiagFlatSeq1, kDiagFlatSeq2, kDiagFlatSeq3 } }, }; static constexpr auto BuildDescriptorTable() diff --git a/src/openrct2/ride/VehicleSubpositionData.cpp b/src/openrct2/ride/VehicleSubpositionData.cpp index e206fa8cde..fd979d5032 100644 --- a/src/openrct2/ride/VehicleSubpositionData.cpp +++ b/src/openrct2/ride/VehicleSubpositionData.cpp @@ -30078,9 +30078,10 @@ static constexpr const VehicleInfoList *TrackVehicleInfoListDefault[] = { &TrackVehicleInfoRightEighthBankToOrthogonalUp250, &TrackVehicleInfoRightEighthBankToOrthogonalUp251, &TrackVehicleInfoRightEighthBankToOrthogonalUp252, &TrackVehicleInfoRightEighthBankToOrthogonalUp253, // TrackElemType::RightEighthBankBankToOrthogonalUp25 &TrackVehicleInfoLeftEighthBankToOrthogonalDown250, &TrackVehicleInfoLeftEighthBankToOrthogonalDown251, &TrackVehicleInfoLeftEighthBankToOrthogonalDown252, &TrackVehicleInfoLeftEighthBankToOrthogonalDown253, // TrackElemType::LeftEighthBankBankToOrthogonalDown25 &TrackVehicleInfoRightEighthBankToOrthogonalDown250, &TrackVehicleInfoRightEighthBankToOrthogonalDown251, &TrackVehicleInfoRightEighthBankToOrthogonalDown252, &TrackVehicleInfoRightEighthBankToOrthogonalDown253, // TrackElemType::RightEighthBankBankToOrthogonalDown25 - &TrackVehicleInfo_9162E6, &TrackVehicleInfo_916408, &TrackVehicleInfo_91652A, &TrackVehicleInfo_91664C, // DiagBrakes - &TrackVehicleInfo_9162E6, &TrackVehicleInfo_916408, &TrackVehicleInfo_91652A, &TrackVehicleInfo_91664C, // DiagBlockBrakes - &TrackVehicleInfo_8C27B2, &TrackVehicleInfo_8C28D4, &TrackVehicleInfo_8C29F6, &TrackVehicleInfo_8C2B18, // SlopedBrakes + &TrackVehicleInfo_9162E6, &TrackVehicleInfo_916408, &TrackVehicleInfo_91652A, &TrackVehicleInfo_91664C, // DiagBrakes + &TrackVehicleInfo_9162E6, &TrackVehicleInfo_916408, &TrackVehicleInfo_91652A, &TrackVehicleInfo_91664C, // DiagBlockBrakes + &TrackVehicleInfo_8C27B2, &TrackVehicleInfo_8C28D4, &TrackVehicleInfo_8C29F6, &TrackVehicleInfo_8C2B18, // SlopedBrakes + &TrackVehicleInfo_9162E6, &TrackVehicleInfo_916408, &TrackVehicleInfo_91652A, &TrackVehicleInfo_91664C, // DiagBooster }; static_assert(std::size(TrackVehicleInfoListDefault) == VehicleTrackSubpositionSizeDefault); diff --git a/src/openrct2/ride/rtd/coaster/GigaCoaster.h b/src/openrct2/ride/rtd/coaster/GigaCoaster.h index fdb2ae56d1..8ee1c30894 100644 --- a/src/openrct2/ride/rtd/coaster/GigaCoaster.h +++ b/src/openrct2/ride/rtd/coaster/GigaCoaster.h @@ -23,7 +23,7 @@ constexpr RideTypeDescriptor GigaCoasterRTD = .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::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}, + .extraTrackGroups = {TrackGroup::barrelRoll, TrackGroup::quarterLoop, TrackGroup::halfLoop, TrackGroup::halfLoopMedium, TrackGroup::halfLoopLarge, TrackGroup::verticalLoop, TrackGroup::corkscrew, TrackGroup::corkscrewLarge, TrackGroup::zeroGRoll, TrackGroup::zeroGRollLarge, TrackGroup::booster, TrackGroup::diagBooster, 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 index 75c8103dbe..50ca3f39bf 100644 --- a/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h +++ b/src/openrct2/ride/rtd/coaster/LSMLaunchedRollerCoaster.h @@ -22,7 +22,7 @@ constexpr RideTypeDescriptor LSMLaunchedRollerCoasterRTD = .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 }, + .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::diagBooster, 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 = {}, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index f1c63a15dc..98a16a7a99 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1247,7 +1247,13 @@ enum : ImageIndex 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_DRIVE_TYRE_NE_SW = SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BRAKES + 6, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_1 = SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BRAKES + 6, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_2, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_1, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_2, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_3, + SPR_G2_LATTICE_TRIANGLE_TRACK_DIAG_BOOSTER_ALT_4, + SPR_G2_LATTICE_TRIANGLE_TRACK_DRIVE_TYRE_NE_SW, 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, From f90954b1a450f8c434dcae6cfe36e4bfd603af8a Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Mon, 25 Nov 2024 23:32:16 +0900 Subject: [PATCH 092/139] Reduce dependencies for Research.h (#23268) --- src/openrct2-ui/windows/EditorParkEntrance.cpp | 1 + src/openrct2-ui/windows/Ride.cpp | 1 + src/openrct2-ui/windows/Scenery.cpp | 1 + src/openrct2/actions/RideCreateAction.cpp | 1 + src/openrct2/entity/Staff.cpp | 1 + src/openrct2/management/Research.cpp | 1 + src/openrct2/management/Research.h | 2 -- src/openrct2/park/ParkFile.cpp | 1 + src/openrct2/rct1/S4Importer.cpp | 1 + src/openrct2/rct12/RCT12.h | 1 + src/openrct2/ride/TrackDesign.cpp | 1 + src/openrct2/ride/TrackDesign.h | 1 + src/openrct2/scenario/Scenario.cpp | 1 + src/openrct2/world/Footpath.cpp | 1 + src/openrct2/world/Park.h | 2 ++ src/openrct2/world/Scenery.cpp | 1 + 16 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/windows/EditorParkEntrance.cpp b/src/openrct2-ui/windows/EditorParkEntrance.cpp index 05108e445e..5a74703035 100644 --- a/src/openrct2-ui/windows/EditorParkEntrance.cpp +++ b/src/openrct2-ui/windows/EditorParkEntrance.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 7825032de6..da4c587cb3 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index b20d1d2c49..72a51fcb32 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 04435ae9c8..1ad1a70538 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -18,6 +18,7 @@ #include "../interface/Window.h" #include "../localisation/Localisation.Date.h" #include "../localisation/StringIds.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectManager.h" #include "../rct1/RCT1.h" #include "../ride/Ride.h" diff --git a/src/openrct2/entity/Staff.cpp b/src/openrct2/entity/Staff.cpp index 5e5a6f82fb..89069e04f1 100644 --- a/src/openrct2/entity/Staff.cpp +++ b/src/openrct2/entity/Staff.cpp @@ -24,6 +24,7 @@ #include "../management/Finance.h" #include "../network/network.h" #include "../object/ObjectEntryManager.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" #include "../object/PathAdditionEntry.h" diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index fc15197db2..c213f7e5f9 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -25,6 +25,7 @@ #include "../localisation/Localisation.Date.h" #include "../localisation/StringIds.h" #include "../object/ObjectEntryManager.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectList.h" #include "../object/RideObject.h" #include "../object/SceneryGroupEntry.h" diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index f956581365..aeca6429e8 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -10,10 +10,8 @@ #pragma once #include "../localisation/StringIdType.h" -#include "../object/ObjectLimits.h" #include "../object/ObjectTypes.h" #include "../ride/RideTypes.h" -#include "../util/Util.h" #include diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index cf2c503ec6..716621e741 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -42,6 +42,7 @@ #include "../management/Finance.h" #include "../management/NewsItem.h" #include "../object/Object.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectManager.h" #include "../object/ObjectRepository.h" #include "../peep/RideUseSystem.h" diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index c7058a5277..160c0500d6 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -45,6 +45,7 @@ #include "../management/Marketing.h" #include "../management/NewsItem.h" #include "../object/Object.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" #include "../object/ObjectRepository.h" diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 98d169f7f4..ca764e632d 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -14,6 +14,7 @@ #include "../management/Research.h" #include "../object/Object.h" #include "../ride/RideTypes.h" +#include "../util/Util.h" #include "../world/tile_element/TileElementType.h" #include "Limits.h" diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 817a86ec89..c510bdcd72 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -46,6 +46,7 @@ #include "../object/FootpathSurfaceObject.h" #include "../object/LargeSceneryEntry.h" #include "../object/ObjectEntryManager.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" #include "../object/ObjectRepository.h" diff --git a/src/openrct2/ride/TrackDesign.h b/src/openrct2/ride/TrackDesign.h index e51b4c4d57..a754801c61 100644 --- a/src/openrct2/ride/TrackDesign.h +++ b/src/openrct2/ride/TrackDesign.h @@ -14,6 +14,7 @@ #include "../object/Object.h" #include "../ride/RideColour.h" #include "../ride/Track.h" +#include "../util/Util.h" #include "../world/Map.h" #include "RideRatings.h" #include "VehicleColour.h" diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 575811d918..edce19bcca 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -39,6 +39,7 @@ #include "../network/network.h" #include "../object/Object.h" #include "../object/ObjectEntryManager.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" #include "../object/ScenarioTextObject.h" diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index a3f8a5ea6d..347aa277ac 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -26,6 +26,7 @@ #include "../object/FootpathRailingsObject.h" #include "../object/FootpathSurfaceObject.h" #include "../object/ObjectEntryManager.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectManager.h" #include "../object/PathAdditionEntry.h" #include "../paint/VirtualFloor.h" diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index 023c7e9fb9..b3d2e21673 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -12,6 +12,8 @@ #include "../management/Finance.h" #include "Map.h" +#include + constexpr auto MAX_ENTRANCE_FEE = 999.00_GBP; constexpr uint16_t kParkRatingHistoryUndefined = std::numeric_limits::max(); diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index 33caedd22b..e25c3ebf47 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -25,6 +25,7 @@ #include "../object/BannerSceneryEntry.h" #include "../object/LargeSceneryEntry.h" #include "../object/ObjectEntryManager.h" +#include "../object/ObjectLimits.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" #include "../object/PathAdditionEntry.h" From 97efc0dd0c22f694fd013a1eb785534abe9f8051 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Tue, 26 Nov 2024 04:02:11 +0000 Subject: [PATCH 093/139] Merge Localisation/master into OpenRCT2/develop --- data/language/es-ES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/language/es-ES.txt b/data/language/es-ES.txt index e9a814ebf3..5774693e4f 100644 --- a/data/language/es-ES.txt +++ b/data/language/es-ES.txt @@ -3747,3 +3747,5 @@ STR_6671 :Mostrar nombres ‘reales’ de empleados STR_6672 :Alternar entre mostrar nombres ‘reales’ y números de empleados STR_6673 :Translúcido STR_6674 :{MONTH}, Año {COMMA16} +STR_6675 :Nombres de Personitas +STR_6676 :Se debe seleccionar al menos un objeto de nombre de personita From ac775ae98453fd0079ee4fb650989bc62e1e7a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Wed, 27 Nov 2024 01:42:07 +0100 Subject: [PATCH 094/139] Update numeric typo in readme.md (#23281) --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index c0cd414f12..3ccb38dea8 100644 --- a/readme.md +++ b/readme.md @@ -56,9 +56,9 @@ If you want to help translate the game to your language, please stop by the Loca - 5.1 - [Code of conduct](#51-code-of-conduct) - 5.2 - [Code signing policy](#52-code-signing-policy) - 5.3 - [Privacy policy](#53-privacy-policy) -- 5 - [Licence](#6-licence) -- 6 - [More information](#7-more-information) -- 7 - [Sponsors](#8-sponsors) +- 6 - [Licence](#6-licence) +- 7 - [More information](#7-more-information) +- 8 - [Sponsors](#8-sponsors) --- From 32b164484a8029dd5e1402f1921cabbe97c0ed78 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Thu, 28 Nov 2024 04:02:21 +0000 Subject: [PATCH 095/139] Merge Localisation/master into OpenRCT2/develop --- data/language/da-DK.txt | 67 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/data/language/da-DK.txt b/data/language/da-DK.txt index d973c7b94a..7e6c94baf3 100644 --- a/data/language/da-DK.txt +++ b/data/language/da-DK.txt @@ -99,6 +99,7 @@ STR_0094 :Enkelt skinde rutchebane STR_0095 :Alpin rutchebane STR_0096 :Klassisk træ rutsjebane STR_0097 :Klassisk Stå-op Rutschebane +STR_0098 :LSM Accelereret Rutschebane STR_0512 :En kompakt rutschebane med en spiral stigning og bløde, snoede fald. STR_0513 :En loopende rutschebane hvor passagerne er i en stående position STR_0514 :Vogne suspenderet under rutschebane sporet, svinger ud til siden i svingene @@ -183,6 +184,7 @@ STR_0604 :Gæster sider i en enkelt række, på et smalt monorail spor, imens STR_0605 :Ryttere kælker ned ad en bugtende stålbane og bremser for at kontrollere deres hastighed STR_0606 :En ældre stils trærutsjebane med en hurtig og ujævn tur med masser af luft tid, laterale G'er, og designet til at føles som ‘ude-af-kontrol’ STR_0607 :En intens, Klassisk stål-stil, loopende rutschebane hvor passagerne er i en stående position +STR_0608 :Rutsjebanetog accelereres ud af stationen af lineære synkronmotorer, for at suse gennem snoede inversioner og sving STR_0767 :Gæst {INT32} STR_0768 :Handymand {INT32} STR_0769 :Mekaniker {INT32} @@ -3609,7 +3611,7 @@ STR_6537 :Tillad almindelige stier som køområde STR_6538 :Viser almindelige gangstier i rullemenuen Køer i sti vinduet. STR_6539 :Bremser lukket STR_6540 :{WINDOW_COLOUR_2}Særlig tak til følgende virksomheder for at tillade deres lighed: -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 :Bidragydere STR_6543 :Bidragydere… STR_6544 :Lån kan ikke være negativ! @@ -3717,3 +3719,66 @@ STR_6644 :Touch-forbedringer STR_6645 :Gør nogle UI-elementer større, så de er nemmere at klikke eller trykke på. STR_6646 :Forfatter: {STRING} STR_6647 :Forfattere: {STRING} +STR_6648 :Indlæser udvidelsesmodul… +STR_6649 :Indlæser scenarie… +STR_6650 :Indlæser gemt spil… +STR_6651 :{STRING} ({COMMA32}%) +STR_6652 :Fejlvindue +STR_6653 :Alle kilder vist +STR_6654 :Viser {POP16}{UINT16} kilder +STR_6655 :Kun ‘{POP16}{STRINGID}’ +STR_6656 :Fjern alle hegn fra parken +STR_6657 :Land Ikke Ejet +STR_6658 :Sæt land til at ikke være ejet af parken, heller ikke muligt at købe land +STR_6659 :Gæster ignorerer priser +STR_6660 :Gæsterne vil ignorere priserne for forlystelser og stande. +STR_6661 :Alt tilfældigt +STR_6662 :Gør farverne tilfældige for hver Randomise colours for every train or vehicle. +STR_6663 :Dato snyd +STR_6664 :Vis dato snyd +STR_6665 :Natur/vejr Snyd +STR_6666 :Vis natur/vejr snyd +STR_6667 :Fauna +STR_6668 :Ansatte snyd +STR_6669 :Vis snyd med ansatte +STR_6670 :Gæste opførsel +STR_6671 :Vis ‘rigtige’ navne på ansatte +STR_6672 :Skift imellem at vise ‘rigtige’ navne på ansatte og ansatte numre +STR_6673 :Gennemsigtig +# Used as part of a sentence (see https://github.com/OpenRCT2/OpenRCT2/issues/22072). +STR_6674 :{MONTH}, År {COMMA16} +STR_6675 :Peep Navne +STR_6676 :Mindst et peep navne objekt skal være valgt +STR_6677 :Tilføj strand omkring vandområder +STR_6678 :Højdekort kilde: +STR_6679 :Fladland +STR_6680 :Simpeleks støj +STR_6681 :Højdekort fil +STR_6682 :Kort Generator - Generator +STR_6683 :Kort Generator - Terræn +STR_6684 :Kort Generator - Vand +STR_6685 :Kort Generator - Skove +STR_6686 :Træ til land rate: +STR_6687 :Min. trægrænse: +STR_6688 :Maks. trægrænse: +STR_6689 :{UINT16}% +STR_6690 :Minimum landskabshøjde +STR_6691 :Angiv min. landskabshøjde imellem {COMMA16} og {COMMA16} +STR_6692 :Maksimum landskabshøjde +STR_6693 :Angiv maks. landskabshøjde imellem {COMMA16} og {COMMA16} +STR_6694 :Minimum trægrænse +STR_6695 :Angiv min. trægrænse imellem {COMMA16} og {COMMA16} +STR_6696 :Maksimum trægrænse +STR_6697 :Angiv maks. trægrænse imellem {COMMA16} og {COMMA16} +STR_6698 :Træ til land rate +STR_6699 :Angiv træ til land rate imellem {COMMA16} og {COMMA16} +STR_6700 :Simpleks Base Frekvens +STR_6701 :Angiv Base Frekvens imellem {COMMA2DP32} og {COMMA2DP32} +STR_6702 :Simpleks oktaver +STR_6703 :Angiv Oktaver imellem {COMMA16} og {COMMA16} +STR_6704 :{COMMA2DP32} +STR_6705 :Gennemse... +STR_6706 :{WINDOW_COLOUR_2}Nuværende billedfil: {BLACK}{STRING} +STR_6707 :(Ingen valgt) +STR_6708 :Udglatnings Styrke +STR_6709 :Angiv udglatnings styrke imellem {COMMA16} og {COMMA16} From 3685d1a24b17c0453b2a33020db62edf768e4cb4 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 29 Nov 2024 12:04:56 +0900 Subject: [PATCH 096/139] clang-format: change IndentPPDirectives to BeforeHash (#23287) --- .clang-format | 2 +- src/openrct2-ui/TextComposition.cpp | 6 +- src/openrct2-ui/UiContext.Android.cpp | 20 +-- src/openrct2-ui/UiContext.Linux.cpp | 36 +++--- src/openrct2-ui/UiContext.Win32.cpp | 38 +++--- src/openrct2-ui/UiContext.cpp | 6 +- src/openrct2-ui/audio/FlacAudioSource.cpp | 8 +- src/openrct2-ui/audio/OggAudioSource.cpp | 8 +- src/openrct2-ui/audio/SDLAudioSource.h | 8 +- .../engines/opengl/ApplyPaletteShader.cpp | 2 +- .../opengl/ApplyTransparencyShader.cpp | 2 +- .../drawing/engines/opengl/DrawLineShader.cpp | 4 +- .../drawing/engines/opengl/DrawRectShader.cpp | 2 +- .../drawing/engines/opengl/OpenGLAPI.cpp | 26 ++-- .../drawing/engines/opengl/OpenGLAPI.h | 106 +++++++-------- .../drawing/engines/opengl/OpenGLAPIProc.h | 2 +- .../engines/opengl/OpenGLDrawingEngine.cpp | 62 ++++----- .../engines/opengl/OpenGLFramebuffer.cpp | 10 +- .../engines/opengl/OpenGLShaderProgram.cpp | 14 +- .../engines/opengl/SwapFramebuffer.cpp | 4 +- .../drawing/engines/opengl/TextureCache.cpp | 22 ++-- .../engines/opengl/TransparencyDepth.cpp | 10 +- src/openrct2-ui/scripting/CustomImages.cpp | 14 +- src/openrct2-ui/scripting/CustomImages.h | 12 +- src/openrct2-ui/scripting/CustomListView.cpp | 18 +-- src/openrct2-ui/scripting/CustomListView.h | 16 +-- src/openrct2-ui/scripting/CustomMenu.cpp | 12 +- src/openrct2-ui/scripting/CustomMenu.h | 14 +- src/openrct2-ui/scripting/CustomWindow.cpp | 42 +++--- src/openrct2-ui/scripting/CustomWindow.h | 8 +- .../scripting/ScGraphicsContext.hpp | 6 +- src/openrct2-ui/scripting/ScImageManager.hpp | 10 +- src/openrct2-ui/scripting/ScTileSelection.hpp | 4 +- src/openrct2-ui/scripting/ScTitleSequence.hpp | 34 ++--- src/openrct2-ui/scripting/ScUi.hpp | 26 ++-- src/openrct2-ui/scripting/ScViewport.hpp | 14 +- src/openrct2-ui/scripting/ScWidget.hpp | 20 +-- src/openrct2-ui/scripting/ScWindow.hpp | 10 +- src/openrct2-ui/scripting/UiExtensions.cpp | 22 ++-- src/openrct2-ui/windows/ServerList.cpp | 50 +++---- src/openrct2-ui/windows/ServerStart.cpp | 20 +-- src/openrct2/Context.cpp | 4 +- src/openrct2/Diagnostic.cpp | 2 +- src/openrct2/Diagnostic.h | 46 +++---- src/openrct2/Version.cpp | 14 +- src/openrct2/Version.h | 46 +++---- src/openrct2/actions/CustomAction.cpp | 6 +- src/openrct2/actions/CustomAction.h | 2 +- src/openrct2/actions/GameAction.h | 8 +- src/openrct2/command_line/RootCommands.cpp | 4 +- src/openrct2/config/Config.h | 2 +- src/openrct2/core/CallingConventions.h | 36 +++--- src/openrct2/core/ChecksumStream.cpp | 4 +- src/openrct2/core/Crypt.CNG.cpp | 22 ++-- src/openrct2/core/Crypt.OpenSSL.cpp | 18 +-- src/openrct2/core/DateTime.h | 2 +- src/openrct2/core/Diagnostics.cpp | 6 +- src/openrct2/core/File.cpp | 4 +- src/openrct2/core/FileScanner.cpp | 14 +- src/openrct2/core/FileStream.cpp | 8 +- src/openrct2/core/FileSystem.hpp | 56 ++++---- src/openrct2/core/FileWatcher.cpp | 12 +- src/openrct2/core/FileWatcher.h | 4 +- src/openrct2/core/Guard.cpp | 10 +- src/openrct2/core/Http.Android.cpp | 14 +- src/openrct2/core/Http.WinHttp.cpp | 20 +-- src/openrct2/core/Http.cURL.cpp | 26 ++-- src/openrct2/core/Http.h | 8 +- src/openrct2/core/IStream.hpp | 8 +- src/openrct2/core/Json.hpp | 2 +- src/openrct2/core/Numerics.hpp | 6 +- src/openrct2/core/RTL.FriBidi.cpp | 20 +-- src/openrct2/core/RTL.ICU.cpp | 18 +-- src/openrct2/core/String.cpp | 50 +++---- src/openrct2/core/Zip.cpp | 2 +- src/openrct2/core/ZipAndroid.cpp | 18 +-- src/openrct2/drawing/AVX2Drawing.cpp | 8 +- src/openrct2/drawing/Drawing.String.cpp | 14 +- src/openrct2/drawing/Image.cpp | 12 +- src/openrct2/drawing/SSE41Drawing.cpp | 8 +- src/openrct2/drawing/TTF.cpp | 34 ++--- src/openrct2/drawing/X8DrawingEngine.cpp | 6 +- src/openrct2/drawing/X8DrawingEngine.h | 14 +- src/openrct2/interface/FontFamilies.h | 6 +- src/openrct2/interface/InteractiveConsole.cpp | 2 +- src/openrct2/interface/StdInOutConsole.cpp | 2 +- src/openrct2/interface/Window_internal.h | 8 +- src/openrct2/network/DiscordService.cpp | 26 ++-- src/openrct2/network/DiscordService.h | 4 +- src/openrct2/network/NetworkAction.cpp | 8 +- src/openrct2/network/NetworkBase.cpp | 118 ++++++++--------- src/openrct2/network/NetworkConnection.cpp | 20 +-- src/openrct2/network/NetworkConnection.h | 16 +-- src/openrct2/network/NetworkGroup.cpp | 8 +- src/openrct2/network/NetworkKey.cpp | 14 +- src/openrct2/network/NetworkKey.h | 6 +- src/openrct2/network/NetworkPacket.cpp | 6 +- src/openrct2/network/NetworkPlayer.cpp | 8 +- .../network/NetworkServerAdvertiser.cpp | 64 ++++----- src/openrct2/network/NetworkUser.cpp | 20 +-- src/openrct2/network/ServerList.cpp | 44 +++---- src/openrct2/network/Socket.cpp | 56 ++++---- src/openrct2/object/Object.cpp | 6 +- src/openrct2/object/Object.h | 8 +- src/openrct2/platform/Crash.cpp | 74 +++++------ src/openrct2/platform/Platform.Android.cpp | 18 +-- src/openrct2/platform/Platform.Common.cpp | 32 ++--- src/openrct2/platform/Platform.Linux.cpp | 80 ++++++------ src/openrct2/platform/Platform.Posix.cpp | 58 ++++----- src/openrct2/platform/Platform.Win32.cpp | 74 +++++------ src/openrct2/platform/Platform.h | 12 +- src/openrct2/profiling/ProfilingMacros.hpp | 10 +- src/openrct2/rct12/ScenarioPatcher.cpp | 4 +- src/openrct2/scripting/Duktape.hpp | 18 +-- src/openrct2/scripting/HookEngine.cpp | 8 +- src/openrct2/scripting/HookEngine.h | 12 +- src/openrct2/scripting/Plugin.cpp | 32 ++--- src/openrct2/scripting/Plugin.h | 10 +- src/openrct2/scripting/ScriptEngine.cpp | 122 +++++++++--------- src/openrct2/scripting/ScriptEngine.h | 42 +++--- .../scripting/bindings/entity/ScEntity.hpp | 18 +-- .../scripting/bindings/entity/ScGuest.cpp | 12 +- .../scripting/bindings/entity/ScGuest.hpp | 6 +- .../scripting/bindings/entity/ScLitter.cpp | 4 +- .../scripting/bindings/entity/ScLitter.hpp | 2 +- .../scripting/bindings/entity/ScParticle.hpp | 8 +- .../scripting/bindings/entity/ScPeep.hpp | 2 +- .../scripting/bindings/entity/ScStaff.cpp | 8 +- .../scripting/bindings/entity/ScStaff.hpp | 4 +- .../scripting/bindings/entity/ScVehicle.hpp | 6 +- .../scripting/bindings/game/ScCheats.hpp | 8 +- .../bindings/game/ScConfiguration.hpp | 10 +- .../scripting/bindings/game/ScConsole.hpp | 6 +- .../scripting/bindings/game/ScContext.hpp | 36 +++--- .../scripting/bindings/game/ScDisposable.hpp | 4 +- .../scripting/bindings/game/ScPlugin.hpp | 6 +- .../scripting/bindings/game/ScProfiler.hpp | 4 +- .../scripting/bindings/network/ScNetwork.cpp | 92 ++++++------- .../scripting/bindings/network/ScNetwork.hpp | 26 ++-- .../scripting/bindings/network/ScPlayer.cpp | 44 +++---- .../scripting/bindings/network/ScPlayer.hpp | 4 +- .../bindings/network/ScPlayerGroup.cpp | 40 +++--- .../bindings/network/ScPlayerGroup.hpp | 6 +- .../scripting/bindings/network/ScSocket.hpp | 18 +-- .../bindings/object/ScInstalledObject.hpp | 10 +- .../scripting/bindings/object/ScObject.hpp | 22 ++-- .../bindings/object/ScObjectManager.cpp | 10 +- .../bindings/object/ScObjectManager.h | 10 +- .../scripting/bindings/ride/ScRide.cpp | 16 +-- .../scripting/bindings/ride/ScRide.hpp | 12 +- .../scripting/bindings/ride/ScRideStation.cpp | 12 +- .../scripting/bindings/ride/ScRideStation.hpp | 6 +- .../bindings/ride/ScTrackIterator.cpp | 14 +- .../scripting/bindings/ride/ScTrackIterator.h | 8 +- .../bindings/ride/ScTrackSegment.cpp | 10 +- .../scripting/bindings/ride/ScTrackSegment.h | 6 +- .../scripting/bindings/world/ScClimate.hpp | 12 +- .../scripting/bindings/world/ScDate.hpp | 14 +- .../scripting/bindings/world/ScMap.cpp | 48 +++---- .../scripting/bindings/world/ScMap.hpp | 8 +- .../scripting/bindings/world/ScPark.cpp | 28 ++-- .../scripting/bindings/world/ScPark.hpp | 10 +- .../bindings/world/ScParkMessage.cpp | 22 ++-- .../bindings/world/ScParkMessage.hpp | 10 +- .../scripting/bindings/world/ScResearch.cpp | 18 +-- .../scripting/bindings/world/ScResearch.hpp | 2 +- .../scripting/bindings/world/ScScenario.hpp | 14 +- .../scripting/bindings/world/ScTile.cpp | 30 ++--- .../scripting/bindings/world/ScTile.hpp | 14 +- .../bindings/world/ScTileElement.cpp | 48 +++---- .../bindings/world/ScTileElement.hpp | 22 ++-- src/openrct2/util/Prefetch.h | 34 ++--- test/tests/tests.cpp | 4 +- 173 files changed, 1636 insertions(+), 1636 deletions(-) diff --git a/.clang-format b/.clang-format index 6ca231784a..1f105b47b9 100644 --- a/.clang-format +++ b/.clang-format @@ -62,7 +62,7 @@ IncludeCategories: - Regex: '^<' Priority: 2 IndentCaseLabels: true -IndentPPDirectives: AfterHash +IndentPPDirectives: BeforeHash IndentWidth: 4 IndentWrappedFunctionNames: true KeepEmptyLinesAtTheStartOfBlocks: false diff --git a/src/openrct2-ui/TextComposition.cpp b/src/openrct2-ui/TextComposition.cpp index da08505389..282b4c5f8f 100644 --- a/src/openrct2-ui/TextComposition.cpp +++ b/src/openrct2-ui/TextComposition.cpp @@ -20,10 +20,10 @@ #include #ifdef __MACOSX__ -// macOS uses COMMAND rather than CTRL for many keyboard shortcuts -# define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI + // macOS uses COMMAND rather than CTRL for many keyboard shortcuts + #define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI #else -# define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL + #define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL #endif using namespace OpenRCT2; diff --git a/src/openrct2-ui/UiContext.Android.cpp b/src/openrct2-ui/UiContext.Android.cpp index 0293c151a0..7ba0237ace 100644 --- a/src/openrct2-ui/UiContext.Android.cpp +++ b/src/openrct2-ui/UiContext.Android.cpp @@ -9,17 +9,17 @@ #ifdef __ANDROID__ -# include "UiContext.h" + #include "UiContext.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Ui { diff --git a/src/openrct2-ui/UiContext.Linux.cpp b/src/openrct2-ui/UiContext.Linux.cpp index bf5f0158e3..9f943e7412 100644 --- a/src/openrct2-ui/UiContext.Linux.cpp +++ b/src/openrct2-ui/UiContext.Linux.cpp @@ -9,23 +9,23 @@ #if (defined(__unix__) || defined(__EMSCRIPTEN__)) && !defined(__ANDROID__) && !defined(__APPLE__) -# include "UiContext.h" + #include "UiContext.h" -# include "UiStringIds.h" + #include "UiStringIds.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Ui { @@ -52,7 +52,7 @@ namespace OpenRCT2::Ui bool IsSteamOverlayAttached() override { -# ifdef __linux__ + #ifdef __linux__ // See http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html struct lmap { @@ -87,9 +87,9 @@ namespace OpenRCT2::Ui dlclose(processHandle); } return result; -# else + #else return false; // Needed for OpenBSD, likely all other Unixes. -# endif + #endif } void ShowMessageBox(SDL_Window* window, const std::string& message) override diff --git a/src/openrct2-ui/UiContext.Win32.cpp b/src/openrct2-ui/UiContext.Win32.cpp index 317c96a200..db7379e452 100644 --- a/src/openrct2-ui/UiContext.Win32.cpp +++ b/src/openrct2-ui/UiContext.Win32.cpp @@ -9,30 +9,30 @@ #ifdef _WIN32 -// Windows.h needs to be included first // clang-format off -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include -# include + // windows.h needs to be included first + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include + #include + #undef CreateWindow // clang-format on -# undef CreateWindow -// Then the rest -# include "UiContext.h" + // Then the rest + #include "UiContext.h" -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include -// Native resource IDs -# include "../../resources/resource.h" + // Native resource IDs + #include "../../resources/resource.h" using namespace Microsoft::WRL; diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 885463cc1f..cb8d98b072 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -55,10 +55,10 @@ using namespace OpenRCT2::Scripting; using namespace OpenRCT2::Ui; #ifdef __MACOSX__ -// macOS uses COMMAND rather than CTRL for many keyboard shortcuts -# define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI + // macOS uses COMMAND rather than CTRL for many keyboard shortcuts + #define KEYBOARD_PRIMARY_MODIFIER KMOD_GUI #else -# define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL + #define KEYBOARD_PRIMARY_MODIFIER KMOD_CTRL #endif class UiContext final : public IUiContext diff --git a/src/openrct2-ui/audio/FlacAudioSource.cpp b/src/openrct2-ui/audio/FlacAudioSource.cpp index 7b76758fcb..757e9487ad 100644 --- a/src/openrct2-ui/audio/FlacAudioSource.cpp +++ b/src/openrct2-ui/audio/FlacAudioSource.cpp @@ -13,10 +13,10 @@ #include #ifndef DISABLE_FLAC -# include -# include -# include -# include + #include + #include + #include + #include #endif namespace OpenRCT2::Audio diff --git a/src/openrct2-ui/audio/OggAudioSource.cpp b/src/openrct2-ui/audio/OggAudioSource.cpp index 214767dd04..803253fc2c 100644 --- a/src/openrct2-ui/audio/OggAudioSource.cpp +++ b/src/openrct2-ui/audio/OggAudioSource.cpp @@ -14,10 +14,10 @@ #include #ifndef DISABLE_VORBIS -# include -# include -# include -# include + #include + #include + #include + #include #endif namespace OpenRCT2::Audio diff --git a/src/openrct2-ui/audio/SDLAudioSource.h b/src/openrct2-ui/audio/SDLAudioSource.h index 5a5533cef8..37afb7d377 100644 --- a/src/openrct2-ui/audio/SDLAudioSource.h +++ b/src/openrct2-ui/audio/SDLAudioSource.h @@ -22,9 +22,9 @@ namespace OpenRCT2::Audio struct IAudioMixer; #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" -# pragma GCC diagnostic ignored "-Wsuggest-final-types" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic ignored "-Wsuggest-final-types" #endif class SDLAudioSource : public IAudioSource { @@ -46,7 +46,7 @@ namespace OpenRCT2::Audio IAudioMixer* GetMixer(); }; #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif std::unique_ptr CreateAudioSource(SDL_RWops* rw); diff --git a/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp b/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp index bcd74090c7..5fa541f612 100644 --- a/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/ApplyPaletteShader.cpp @@ -9,7 +9,7 @@ #ifndef DISABLE_OPENGL -# include "ApplyPaletteShader.h" + #include "ApplyPaletteShader.h" using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp b/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp index 7bbb1f2f4b..0f35d335a8 100644 --- a/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/ApplyTransparencyShader.cpp @@ -9,7 +9,7 @@ #ifndef DISABLE_OPENGL -# include "ApplyTransparencyShader.h" + #include "ApplyTransparencyShader.h" using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp index 5b0ed0df48..06ebe29e16 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/DrawLineShader.cpp @@ -9,9 +9,9 @@ #ifndef DISABLE_OPENGL -# include "DrawLineShader.h" + #include "DrawLineShader.h" -# include "OpenGLFramebuffer.h" + #include "OpenGLFramebuffer.h" using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp index ed43dddb34..f473806d53 100644 --- a/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/DrawRectShader.cpp @@ -9,7 +9,7 @@ #ifndef DISABLE_OPENGL -# include "DrawRectShader.h" + #include "DrawRectShader.h" using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp index d54f1c70cc..31347ad169 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.cpp @@ -9,20 +9,20 @@ #ifndef DISABLE_OPENGL -# include "OpenGLAPI.h" + #include "OpenGLAPI.h" -# if OPENGL_NO_LINK + #if OPENGL_NO_LINK -# define OPENGL_PROC(TYPE, PROC) TYPE PROC = nullptr; -# include "OpenGLAPIProc.h" -# undef OPENGL_PROC + #define OPENGL_PROC(TYPE, PROC) TYPE PROC = nullptr; + #include "OpenGLAPIProc.h" + #undef OPENGL_PROC -# include -# include + #include + #include static const char* TryLoadAllProcAddresses() { -# define OPENGL_PROC(TYPE, PROC) \ + #define OPENGL_PROC(TYPE, PROC) \ { \ PROC = reinterpret_cast(SDL_GL_GetProcAddress(#PROC)); \ if (PROC == nullptr) \ @@ -30,13 +30,13 @@ static const char* TryLoadAllProcAddresses() return #PROC; \ } \ } -# include "OpenGLAPIProc.h" -# undef OPENGL_PROC + #include "OpenGLAPIProc.h" + #undef OPENGL_PROC return nullptr; } -# endif /* #if OPENGL_NO_LINK */ + #endif /* #if OPENGL_NO_LINK */ using namespace OpenRCT2::Ui; @@ -65,14 +65,14 @@ bool OpenGLAPI::Initialise() { OpenGLState::Reset(); -# ifdef OPENGL_NO_LINK + #ifdef OPENGL_NO_LINK const char* failedProcName = TryLoadAllProcAddresses(); if (failedProcName != nullptr) { Console::Error::WriteLine("Failed to load %s.", failedProcName); return false; } -# endif + #endif return true; } diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h index 185a81463d..4c0302d555 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPI.h @@ -13,31 +13,31 @@ #ifdef OPENGL_NO_LINK -// BEGIN [Do not define 1.1 function signatures] -# define glActiveTexture __static__glActiveTexture -# define glBegin __static__glBegin -# define glBindTexture __static__glBindTexture -# define glBlendFunc __static__glBlendFunc -# define glClear __static__glClear -# define glClearColor __static__glClearColor -# define glCullFace __static__glCullFace -# define glDeleteTextures __static__glDeleteTextures -# define glDepthFunc __static__glDepthFunc -# define glDisable __static__glDisable -# define glDrawArrays __static__glDrawArrays -# define glEnable __static__glEnable -# define glEnd __static__glEnd -# define glGenTextures __static__glGenTextures -# define glGetError __static__glGetError -# define glPixelStorei __static__glPixelStorei -# define glReadPixels __static__glReadPixels -# define glTexImage2D __static__glTexImage2D -# define glTexParameteri __static__glTexParameteri -# define glViewport __static__glViewport -# define glTexSubImage3D __static__glTexSubImage3D -# define glTexImage3D __static__glTexImage3D -# define glGetIntegerv __static__glGetIntegerv -# define glGetTexImage __static__glGetTexImage + // BEGIN [Do not define 1.1 function signatures] + #define glActiveTexture __static__glActiveTexture + #define glBegin __static__glBegin + #define glBindTexture __static__glBindTexture + #define glBlendFunc __static__glBlendFunc + #define glClear __static__glClear + #define glClearColor __static__glClearColor + #define glCullFace __static__glCullFace + #define glDeleteTextures __static__glDeleteTextures + #define glDepthFunc __static__glDepthFunc + #define glDisable __static__glDisable + #define glDrawArrays __static__glDrawArrays + #define glEnable __static__glEnable + #define glEnd __static__glEnd + #define glGenTextures __static__glGenTextures + #define glGetError __static__glGetError + #define glPixelStorei __static__glPixelStorei + #define glReadPixels __static__glReadPixels + #define glTexImage2D __static__glTexImage2D + #define glTexParameteri __static__glTexParameteri + #define glViewport __static__glViewport + #define glTexSubImage3D __static__glTexSubImage3D + #define glTexImage3D __static__glTexImage3D + #define glGetIntegerv __static__glGetIntegerv + #define glGetTexImage __static__glGetTexImage #endif @@ -49,31 +49,31 @@ #ifdef OPENGL_NO_LINK -// END [Do not define 1.1 function signatures] -# undef glActiveTexture -# undef glBegin -# undef glBindTexture -# undef glBlendFunc -# undef glClear -# undef glClearColor -# undef glCullFace -# undef glDeleteTextures -# undef glDepthFunc -# undef glDisable -# undef glDrawArrays -# undef glEnable -# undef glEnd -# undef glGenTextures -# undef glGetError -# undef glPixelStorei -# undef glReadPixels -# undef glTexImage2D -# undef glTexParameteri -# undef glViewport -# undef glTexSubImage3D -# undef glTexImage3D -# undef glGetIntegerv -# undef glGetTexImage + // END [Do not define 1.1 function signatures] + #undef glActiveTexture + #undef glBegin + #undef glBindTexture + #undef glBlendFunc + #undef glClear + #undef glClearColor + #undef glCullFace + #undef glDeleteTextures + #undef glDepthFunc + #undef glDisable + #undef glDrawArrays + #undef glEnable + #undef glEnd + #undef glGenTextures + #undef glGetError + #undef glPixelStorei + #undef glReadPixels + #undef glTexImage2D + #undef glTexParameteri + #undef glViewport + #undef glTexSubImage3D + #undef glTexImage3D + #undef glGetIntegerv + #undef glGetTexImage // 1.1 function signatures using PFNGLBEGINPROC = void(APIENTRYP)(GLenum mode); @@ -107,9 +107,9 @@ using PFNGLTEXIMAGE3DPROC = void(APIENTRYP)( using PFNGLGETINTERGERVPROC = void(APIENTRYP)(GLenum pname, GLint* data); using PFNGLGETTEXIMAGEPROC = void(APIENTRYP)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid* img); -# define OPENGL_PROC(TYPE, PROC) extern TYPE PROC; -# include "OpenGLAPIProc.h" -# undef OPENGL_PROC + #define OPENGL_PROC(TYPE, PROC) extern TYPE PROC; + #include "OpenGLAPIProc.h" + #undef OPENGL_PROC #endif /* OPENGL_NO_LINK */ diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h index 1597d1c7c3..0245978654 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLAPIProc.h @@ -8,7 +8,7 @@ *****************************************************************************/ #ifndef OPENGL_PROC -# error "Do not include OpenGLAPIProc.h directly. Include OpenGLAPI.h instead." + #error "Do not include OpenGLAPIProc.h directly. Include OpenGLAPI.h instead." #endif // 1.1 function pointers diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 00f987d5c8..c7790b0bc8 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -9,34 +9,34 @@ #ifndef DISABLE_OPENGL -# include "../DrawingEngineFactory.hpp" -# include "ApplyPaletteShader.h" -# include "DrawCommands.h" -# include "DrawLineShader.h" -# include "DrawRectShader.h" -# include "GLSLTypes.h" -# include "OpenGLAPI.h" -# include "OpenGLFramebuffer.h" -# include "SwapFramebuffer.h" -# include "TextureCache.h" -# include "TransparencyDepth.h" + #include "../DrawingEngineFactory.hpp" + #include "ApplyPaletteShader.h" + #include "DrawCommands.h" + #include "DrawLineShader.h" + #include "DrawRectShader.h" + #include "GLSLTypes.h" + #include "OpenGLAPI.h" + #include "OpenGLFramebuffer.h" + #include "SwapFramebuffer.h" + #include "TextureCache.h" + #include "TransparencyDepth.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include using namespace OpenRCT2; using namespace OpenRCT2::Drawing; @@ -977,7 +977,7 @@ void OpenGLDrawingContext::DrawGlyph(DrawPixelInfo& dpi, const ImageId image, in void OpenGLDrawingContext::DrawTTFBitmap( DrawPixelInfo& dpi, TextDrawInfo* info, TTFSurface* surface, int32_t x, int32_t y, uint8_t hintingThreshold) { -# ifndef NO_TTF + #ifndef NO_TTF auto baseId = static_cast(0x7FFFF) - 1024; auto imageId = baseId + _ttfGlId; _engine.InvalidateImage(imageId); @@ -1062,7 +1062,7 @@ void OpenGLDrawingContext::DrawTTFBitmap( command.colour = info->palette[1]; command.bounds = { left, top, right, bottom }; command.depth = _drawCount++; -# endif // NO_TTF + #endif // NO_TTF } void OpenGLDrawingContext::FlushCommandBuffers() @@ -1149,10 +1149,10 @@ ScreenRect OpenGLDrawingContext::CalculateClipping(const DrawPixelInfo& dpi) con const DrawPixelInfo* screenDPI = _engine.GetDPI(); const int32_t bytesPerRow = screenDPI->LineStride(); const int32_t bitsOffset = static_cast(dpi.bits - screenDPI->bits); -# ifndef NDEBUG + #ifndef NDEBUG const ptrdiff_t bitsSize = static_cast(screenDPI->height) * static_cast(bytesPerRow); assert(static_cast(bitsOffset) < bitsSize && static_cast(bitsOffset) >= 0); -# endif + #endif const int32_t left = bitsOffset % bytesPerRow; const int32_t top = bitsOffset / bytesPerRow; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp index f636647799..0a4c6751ee 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLFramebuffer.cpp @@ -9,12 +9,12 @@ #ifndef DISABLE_OPENGL -# include "OpenGLFramebuffer.h" + #include "OpenGLFramebuffer.h" -# include -# include -# include -# include + #include + #include + #include + #include using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp index 7e9278087d..f30420086f 100644 --- a/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/OpenGLShaderProgram.cpp @@ -9,14 +9,14 @@ #ifndef DISABLE_OPENGL -# include "OpenGLShaderProgram.h" + #include "OpenGLShaderProgram.h" -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp index cf44c003b5..e143365714 100644 --- a/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/SwapFramebuffer.cpp @@ -9,9 +9,9 @@ #ifndef DISABLE_OPENGL -# include "SwapFramebuffer.h" + #include "SwapFramebuffer.h" -# include "OpenGLFramebuffer.h" + #include "OpenGLFramebuffer.h" using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp index 414e39b3b3..57c220001b 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TextureCache.cpp @@ -9,16 +9,16 @@ #ifndef DISABLE_OPENGL -# include "TextureCache.h" + #include "TextureCache.h" -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include using namespace OpenRCT2::Ui; @@ -352,9 +352,9 @@ AtlasTextureInfo TextureCache::AllocateImage(int32_t imageWidth, int32_t imageHe auto atlasIndex = static_cast(_atlases.size()); int32_t atlasSize = powf(2, static_cast(Atlas::CalculateImageSizeOrder(imageWidth, imageHeight))); -# ifdef DEBUG + #ifdef DEBUG LOG_VERBOSE("new texture atlas #%d (size %d) allocated", atlasIndex, atlasSize); -# endif + #endif _atlases.emplace_back(atlasIndex, atlasSize); _atlases.back().Initialise(_atlasesTextureDimensions, _atlasesTextureDimensions); diff --git a/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp b/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp index 04b40f59d3..a703f57961 100644 --- a/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp +++ b/src/openrct2-ui/drawing/engines/opengl/TransparencyDepth.cpp @@ -9,12 +9,12 @@ #ifndef DISABLE_OPENGL -# include "TransparencyDepth.h" + #include "TransparencyDepth.h" -# include -# include -# include -# include + #include + #include + #include + #include namespace OpenRCT2::Ui { diff --git a/src/openrct2-ui/scripting/CustomImages.cpp b/src/openrct2-ui/scripting/CustomImages.cpp index 76b5ac3acd..3e06b01f1c 100644 --- a/src/openrct2-ui/scripting/CustomImages.cpp +++ b/src/openrct2-ui/scripting/CustomImages.cpp @@ -9,15 +9,15 @@ #ifdef ENABLE_SCRIPTING -# include "CustomImages.h" + #include "CustomImages.h" -# include "ScGraphicsContext.hpp" + #include "ScGraphicsContext.hpp" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include using namespace OpenRCT2::Drawing; diff --git a/src/openrct2-ui/scripting/CustomImages.h b/src/openrct2-ui/scripting/CustomImages.h index e78e8256af..1e9ed79cc6 100644 --- a/src/openrct2-ui/scripting/CustomImages.h +++ b/src/openrct2-ui/scripting/CustomImages.h @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/CustomListView.cpp b/src/openrct2-ui/scripting/CustomListView.cpp index 8550a34709..332d028b39 100644 --- a/src/openrct2-ui/scripting/CustomListView.cpp +++ b/src/openrct2-ui/scripting/CustomListView.cpp @@ -9,17 +9,17 @@ #ifdef ENABLE_SCRIPTING -# include "CustomListView.h" + #include "CustomListView.h" -# include "../interface/Viewport.h" -# include "../interface/Widget.h" -# include "../interface/Window.h" + #include "../interface/Viewport.h" + #include "../interface/Widget.h" + #include "../interface/Window.h" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include using namespace OpenRCT2::Scripting; using namespace OpenRCT2::Ui::Windows; diff --git a/src/openrct2-ui/scripting/CustomListView.h b/src/openrct2-ui/scripting/CustomListView.h index 3a473e723f..8eca117a46 100644 --- a/src/openrct2-ui/scripting/CustomListView.h +++ b/src/openrct2-ui/scripting/CustomListView.h @@ -11,15 +11,15 @@ #ifdef ENABLE_SCRIPTING -# include "../interface/Window.h" + #include "../interface/Window.h" -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Ui::Windows { diff --git a/src/openrct2-ui/scripting/CustomMenu.cpp b/src/openrct2-ui/scripting/CustomMenu.cpp index 898d600e9e..ad73c492d5 100644 --- a/src/openrct2-ui/scripting/CustomMenu.cpp +++ b/src/openrct2-ui/scripting/CustomMenu.cpp @@ -9,14 +9,14 @@ #ifdef ENABLE_SCRIPTING -# include "CustomMenu.h" + #include "CustomMenu.h" -# include "../interface/Viewport.h" + #include "../interface/Viewport.h" -# include -# include -# include -# include + #include + #include + #include + #include using namespace OpenRCT2; using namespace OpenRCT2::Ui; diff --git a/src/openrct2-ui/scripting/CustomMenu.h b/src/openrct2-ui/scripting/CustomMenu.h index 7a30868b4b..6ac95b55f2 100644 --- a/src/openrct2-ui/scripting/CustomMenu.h +++ b/src/openrct2-ui/scripting/CustomMenu.h @@ -11,13 +11,13 @@ #ifdef ENABLE_SCRIPTING -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include enum class CursorID : uint8_t; diff --git a/src/openrct2-ui/scripting/CustomWindow.cpp b/src/openrct2-ui/scripting/CustomWindow.cpp index 4924c089c3..0059c3d2bf 100644 --- a/src/openrct2-ui/scripting/CustomWindow.cpp +++ b/src/openrct2-ui/scripting/CustomWindow.cpp @@ -9,28 +9,28 @@ #ifdef ENABLE_SCRIPTING -# include "../UiContext.h" -# include "../UiStringIds.h" -# include "../interface/Dropdown.h" -# include "../interface/Widget.h" -# include "../scripting/ScGraphicsContext.hpp" -# include "../scripting/ScWidget.hpp" -# include "../windows/Window.h" -# include "CustomListView.h" -# include "ScUi.hpp" -# include "ScWindow.hpp" + #include "../UiContext.h" + #include "../UiStringIds.h" + #include "../interface/Dropdown.h" + #include "../interface/Widget.h" + #include "../scripting/ScGraphicsContext.hpp" + #include "../scripting/ScWidget.hpp" + #include "../windows/Window.h" + #include "CustomListView.h" + #include "ScUi.hpp" + #include "ScWindow.hpp" -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include using namespace OpenRCT2; using namespace OpenRCT2::Scripting; diff --git a/src/openrct2-ui/scripting/CustomWindow.h b/src/openrct2-ui/scripting/CustomWindow.h index 13f8a81410..17fe8de3f7 100644 --- a/src/openrct2-ui/scripting/CustomWindow.h +++ b/src/openrct2-ui/scripting/CustomWindow.h @@ -11,11 +11,11 @@ #ifdef ENABLE_SCRIPTING -# include "../interface/Window.h" + #include "../interface/Window.h" -# include -# include -# include + #include + #include + #include namespace OpenRCT2::Ui::Windows { diff --git a/src/openrct2-ui/scripting/ScGraphicsContext.hpp b/src/openrct2-ui/scripting/ScGraphicsContext.hpp index ad1ec00091..98ba930e22 100644 --- a/src/openrct2-ui/scripting/ScGraphicsContext.hpp +++ b/src/openrct2-ui/scripting/ScGraphicsContext.hpp @@ -11,10 +11,10 @@ #ifdef ENABLE_SCRIPTING -# include "CustomImages.h" + #include "CustomImages.h" -# include -# include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/ScImageManager.hpp b/src/openrct2-ui/scripting/ScImageManager.hpp index 296c47dc6c..c6cdf9e75f 100644 --- a/src/openrct2-ui/scripting/ScImageManager.hpp +++ b/src/openrct2-ui/scripting/ScImageManager.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "CustomImages.h" + #include "CustomImages.h" -# include -# include -# include -# include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/ScTileSelection.hpp b/src/openrct2-ui/scripting/ScTileSelection.hpp index 9be4723d6e..e19920979f 100644 --- a/src/openrct2-ui/scripting/ScTileSelection.hpp +++ b/src/openrct2-ui/scripting/ScTileSelection.hpp @@ -11,8 +11,8 @@ #ifdef ENABLE_SCRIPTING -# include -# include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/ScTitleSequence.hpp b/src/openrct2-ui/scripting/ScTitleSequence.hpp index 5d179018ef..434fef4664 100644 --- a/src/openrct2-ui/scripting/ScTitleSequence.hpp +++ b/src/openrct2-ui/scripting/ScTitleSequence.hpp @@ -11,23 +11,23 @@ #ifdef ENABLE_SCRIPTING -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/ScUi.hpp b/src/openrct2-ui/scripting/ScUi.hpp index c1b8a3d4ae..140a5ca658 100644 --- a/src/openrct2-ui/scripting/ScUi.hpp +++ b/src/openrct2-ui/scripting/ScUi.hpp @@ -11,20 +11,20 @@ #ifdef ENABLE_SCRIPTING -# include "../windows/Window.h" -# include "CustomMenu.h" -# include "ScImageManager.hpp" -# include "ScTileSelection.hpp" -# include "ScViewport.hpp" -# include "ScWindow.hpp" + #include "../windows/Window.h" + #include "CustomMenu.h" + #include "ScImageManager.hpp" + #include "ScTileSelection.hpp" + #include "ScViewport.hpp" + #include "ScWindow.hpp" -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/ScViewport.hpp b/src/openrct2-ui/scripting/ScViewport.hpp index 5315050b53..49410bcc9d 100644 --- a/src/openrct2-ui/scripting/ScViewport.hpp +++ b/src/openrct2-ui/scripting/ScViewport.hpp @@ -11,14 +11,14 @@ #ifdef ENABLE_SCRIPTING -# include "../interface/Window.h" + #include "../interface/Window.h" -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/ScWidget.hpp b/src/openrct2-ui/scripting/ScWidget.hpp index 5bb00ccd7f..7324a435b1 100644 --- a/src/openrct2-ui/scripting/ScWidget.hpp +++ b/src/openrct2-ui/scripting/ScWidget.hpp @@ -11,17 +11,17 @@ #ifdef ENABLE_SCRIPTING -# include "../interface/Widget.h" -# include "../interface/Window.h" -# include "CustomListView.h" -# include "CustomWindow.h" -# include "ScViewport.hpp" + #include "../interface/Widget.h" + #include "../interface/Window.h" + #include "CustomListView.h" + #include "CustomWindow.h" + #include "ScViewport.hpp" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/ScWindow.hpp b/src/openrct2-ui/scripting/ScWindow.hpp index 6289386ad9..b07da7d872 100644 --- a/src/openrct2-ui/scripting/ScWindow.hpp +++ b/src/openrct2-ui/scripting/ScWindow.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "ScWidget.hpp" + #include "ScWidget.hpp" -# include -# include -# include -# include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2-ui/scripting/UiExtensions.cpp b/src/openrct2-ui/scripting/UiExtensions.cpp index 05a27456f8..eb8a963f6c 100644 --- a/src/openrct2-ui/scripting/UiExtensions.cpp +++ b/src/openrct2-ui/scripting/UiExtensions.cpp @@ -9,19 +9,19 @@ #ifdef ENABLE_SCRIPTING -# include "UiExtensions.h" + #include "UiExtensions.h" -# include "CustomImages.h" -# include "CustomMenu.h" -# include "ScGraphicsContext.hpp" -# include "ScImageManager.hpp" -# include "ScTileSelection.hpp" -# include "ScTitleSequence.hpp" -# include "ScUi.hpp" -# include "ScWidget.hpp" -# include "ScWindow.hpp" + #include "CustomImages.h" + #include "CustomMenu.h" + #include "ScGraphicsContext.hpp" + #include "ScImageManager.hpp" + #include "ScTileSelection.hpp" + #include "ScTitleSequence.hpp" + #include "ScUi.hpp" + #include "ScWidget.hpp" + #include "ScWindow.hpp" -# include + #include using namespace OpenRCT2::Scripting; diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index 3b7e3e9c4d..196d48728d 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -9,32 +9,32 @@ #ifndef DISABLE_NETWORK -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Ui::Windows { -# define WWIDTH_MIN 500 -# define WHEIGHT_MIN 300 -# define WWIDTH_MAX 1200 -# define WHEIGHT_MAX 800 -# define ITEM_HEIGHT (3 + 9 + 3) + #define WWIDTH_MIN 500 + #define WHEIGHT_MIN 300 + #define WWIDTH_MAX 1200 + #define WHEIGHT_MAX 800 + #define ITEM_HEIGHT (3 + 9 + 3) constexpr size_t MaxPlayerNameLength = 32; @@ -91,7 +91,7 @@ namespace OpenRCT2::Ui::Windows std::string _version; public: -# pragma region Window Override Events + #pragma region Window Override Events void OnOpen() override { @@ -433,7 +433,7 @@ namespace OpenRCT2::Ui::Windows } } -# pragma endregion + #pragma endregion private: void ServerListFetchServersBegin() diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index f24b12d24d..93988b3710 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -9,17 +9,17 @@ #ifndef DISABLE_NETWORK -# include "../interface/Theme.h" + #include "../interface/Theme.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include namespace OpenRCT2::Ui::Windows { diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 4f2684257b..7ba3a94b47 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -8,8 +8,8 @@ *****************************************************************************/ #ifdef __EMSCRIPTEN__ -# include -# include + #include + #include #endif // __EMSCRIPTEN__ #include "AssetPackManager.h" diff --git a/src/openrct2/Diagnostic.cpp b/src/openrct2/Diagnostic.cpp index 93f757e018..33666bf974 100644 --- a/src/openrct2/Diagnostic.cpp +++ b/src/openrct2/Diagnostic.cpp @@ -17,7 +17,7 @@ #include #ifdef __ANDROID__ -# include + #include #endif using namespace OpenRCT2; diff --git a/src/openrct2/Diagnostic.h b/src/openrct2/Diagnostic.h index 1181d00b06..734085874f 100644 --- a/src/openrct2/Diagnostic.h +++ b/src/openrct2/Diagnostic.h @@ -44,28 +44,28 @@ enum class DiagnosticLevel */ #if defined(DEBUG) -# if DEBUG > 0 -# define DEBUG_LEVEL_1 1 -# if DEBUG > 1 -# define DEBUG_LEVEL_2 1 -# if DEBUG > 2 -# define DEBUG_LEVEL_3 1 -# else -# define DEBUG_LEVEL_3 0 -# endif // DEBUG > 2 -# else -# define DEBUG_LEVEL_3 0 -# define DEBUG_LEVEL_2 0 -# endif // DEBUG > 1 -# else -# define DEBUG_LEVEL_1 0 -# define DEBUG_LEVEL_2 0 -# define DEBUG_LEVEL_3 0 -# endif // DEBUG > 0 + #if DEBUG > 0 + #define DEBUG_LEVEL_1 1 + #if DEBUG > 1 + #define DEBUG_LEVEL_2 1 + #if DEBUG > 2 + #define DEBUG_LEVEL_3 1 + #else + #define DEBUG_LEVEL_3 0 + #endif // DEBUG > 2 + #else + #define DEBUG_LEVEL_3 0 + #define DEBUG_LEVEL_2 0 + #endif // DEBUG > 1 + #else + #define DEBUG_LEVEL_1 0 + #define DEBUG_LEVEL_2 0 + #define DEBUG_LEVEL_3 0 + #endif // DEBUG > 0 #else -# define DEBUG_LEVEL_3 0 -# define DEBUG_LEVEL_2 0 -# define DEBUG_LEVEL_1 0 + #define DEBUG_LEVEL_3 0 + #define DEBUG_LEVEL_2 0 + #define DEBUG_LEVEL_1 0 #endif // defined(DEBUG) extern bool _log_levels[static_cast(DiagnosticLevel::Count)]; @@ -75,10 +75,10 @@ void DiagnosticLogWithLocation( DiagnosticLevel diagnosticLevel, const char* file, const char* function, int32_t line, const char* format, ...); #ifdef _MSC_VER -# define DIAGNOSTIC_LOG_MACRO(level, format, ...) \ + #define DIAGNOSTIC_LOG_MACRO(level, format, ...) \ DiagnosticLogWithLocation(level, __FILE__, __FUNCTION__, __LINE__, format, ##__VA_ARGS__) #else -# define DIAGNOSTIC_LOG_MACRO(level, format, ...) \ + #define DIAGNOSTIC_LOG_MACRO(level, format, ...) \ DiagnosticLogWithLocation(level, __FILE__, __func__, __LINE__, format, ##__VA_ARGS__) #endif // _MSC_VER diff --git a/src/openrct2/Version.cpp b/src/openrct2/Version.cpp index 0b1863e608..ee76fdd1ea 100644 --- a/src/openrct2/Version.cpp +++ b/src/openrct2/Version.cpp @@ -19,7 +19,7 @@ using namespace OpenRCT2; #ifdef OPENRCT2_BUILD_INFO_HEADER -# include OPENRCT2_BUILD_INFO_HEADER + #include OPENRCT2_BUILD_INFO_HEADER #endif const char gVersionInfoTag[] = @@ -38,16 +38,16 @@ const char gVersionInfoFull[] = OPENRCT2_NAME ", " #endif #if defined(OPENRCT2_BRANCH) || defined(OPENRCT2_COMMIT_SHA1_SHORT) || !defined(NDEBUG) " (" -# if defined(OPENRCT2_BRANCH) && defined(OPENRCT2_COMMIT_SHA1_SHORT) + #if defined(OPENRCT2_BRANCH) && defined(OPENRCT2_COMMIT_SHA1_SHORT) OPENRCT2_COMMIT_SHA1_SHORT " on " OPENRCT2_BRANCH -# elif defined(OPENRCT2_COMMIT_SHA1_SHORT) + #elif defined(OPENRCT2_COMMIT_SHA1_SHORT) OPENRCT2_COMMIT_SHA1_SHORT -# elif defined(OPENRCT2_BRANCH) + #elif defined(OPENRCT2_BRANCH) OPENRCT2_BRANCH -# endif -# ifndef NDEBUG + #endif + #ifndef NDEBUG ", DEBUG" -# endif + #endif ")" #endif #ifdef OPENRCT2_BUILD_SERVER diff --git a/src/openrct2/Version.h b/src/openrct2/Version.h index f9da61cfb7..a44b865e70 100644 --- a/src/openrct2/Version.h +++ b/src/openrct2/Version.h @@ -15,61 +15,61 @@ #define OPENRCT2_VERSION "0.4.16" #if defined(__amd64__) || defined(_M_AMD64) -# define OPENRCT2_ARCHITECTURE "x86-64" + #define OPENRCT2_ARCHITECTURE "x86-64" #elif defined(__i386__) || defined(_M_IX86) -# define OPENRCT2_ARCHITECTURE "x86" + #define OPENRCT2_ARCHITECTURE "x86" #elif defined(__aarch64__) || defined(_M_ARM64) -# define OPENRCT2_ARCHITECTURE "AArch64" + #define OPENRCT2_ARCHITECTURE "AArch64" #elif defined(__arm__) || defined(_M_ARM) -# if defined(__ARM_ARCH_7A__) -# define OPENRCT2_ARCHITECTURE "arm-v7a" -# else -# define OPENRCT2_ARCHITECTURE "arm" -# endif + #if defined(__ARM_ARCH_7A__) + #define OPENRCT2_ARCHITECTURE "arm-v7a" + #else + #define OPENRCT2_ARCHITECTURE "arm" + #endif #elif defined(__powerpc__) || defined(_M_PPC) -# define OPENRCT2_ARCHITECTURE "PowerPC" + #define OPENRCT2_ARCHITECTURE "PowerPC" #elif defined(__mips64) -# define OPENRCT2_ARCHITECTURE "mips64" + #define OPENRCT2_ARCHITECTURE "mips64" #elif defined(__mips__) -# define OPENRCT2_ARCHITECTURE "mips" + #define OPENRCT2_ARCHITECTURE "mips" #elif defined(__riscv) -# define OPENRCT2_ARCHITECTURE "RISC-V" + #define OPENRCT2_ARCHITECTURE "RISC-V" #endif #ifdef __EMSCRIPTEN__ -# define OPENRCT2_ARCHITECTURE "Emscripten" + #define OPENRCT2_ARCHITECTURE "Emscripten" #endif #ifndef OPENRCT2_ARCHITECTURE -# error "OPENRCT2_ARCHITECTURE is undefined. Please add identification." + #error "OPENRCT2_ARCHITECTURE is undefined. Please add identification." #endif // Platform #ifdef _WIN32 -# define OPENRCT2_PLATFORM "Windows" + #define OPENRCT2_PLATFORM "Windows" #endif #if defined(__linux__) && !defined(__ANDROID__) -# define OPENRCT2_PLATFORM "Linux" + #define OPENRCT2_PLATFORM "Linux" #endif #if (defined(__APPLE__) && defined(__MACH__)) -# define OPENRCT2_PLATFORM "macOS" + #define OPENRCT2_PLATFORM "macOS" #endif #ifdef __FreeBSD__ -# define OPENRCT2_PLATFORM "FreeBSD" + #define OPENRCT2_PLATFORM "FreeBSD" #endif #ifdef __NetBSD__ -# define OPENRCT2_PLATFORM "NetBSD" + #define OPENRCT2_PLATFORM "NetBSD" #endif #ifdef __ANDROID__ -# define OPENRCT2_PLATFORM "Android" + #define OPENRCT2_PLATFORM "Android" #endif #ifdef __OpenBSD__ -# define OPENRCT2_PLATFORM "OpenBSD" + #define OPENRCT2_PLATFORM "OpenBSD" #endif #ifdef __EMSCRIPTEN__ -# define OPENRCT2_PLATFORM "Emscripten" + #define OPENRCT2_PLATFORM "Emscripten" #endif #ifndef OPENRCT2_PLATFORM -# error Unknown platform! + #error Unknown platform! #endif extern const char gVersionInfoFull[]; diff --git a/src/openrct2/actions/CustomAction.cpp b/src/openrct2/actions/CustomAction.cpp index 922bf8ab67..d6eaaea72b 100644 --- a/src/openrct2/actions/CustomAction.cpp +++ b/src/openrct2/actions/CustomAction.cpp @@ -8,10 +8,10 @@ *****************************************************************************/ #ifdef ENABLE_SCRIPTING -# include "CustomAction.h" + #include "CustomAction.h" -# include "../Context.h" -# include "../scripting/ScriptEngine.h" + #include "../Context.h" + #include "../scripting/ScriptEngine.h" using namespace OpenRCT2; diff --git a/src/openrct2/actions/CustomAction.h b/src/openrct2/actions/CustomAction.h index eb44d92d5e..8011b1d333 100644 --- a/src/openrct2/actions/CustomAction.h +++ b/src/openrct2/actions/CustomAction.h @@ -11,7 +11,7 @@ #ifdef ENABLE_SCRIPTING -# include "GameAction.h" + #include "GameAction.h" class CustomAction final : public GameActionBase { diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index 753f0e9220..4e827c2e42 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -33,9 +33,9 @@ namespace OpenRCT2::GameActions } // namespace OpenRCT2::GameActions #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" -# pragma GCC diagnostic ignored "-Wsuggest-final-types" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic ignored "-Wsuggest-final-types" #endif /** @@ -247,7 +247,7 @@ public: }; #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif template diff --git a/src/openrct2/command_line/RootCommands.cpp b/src/openrct2/command_line/RootCommands.cpp index 3fe044d43d..4902c2bae6 100644 --- a/src/openrct2/command_line/RootCommands.cpp +++ b/src/openrct2/command_line/RootCommands.cpp @@ -34,9 +34,9 @@ using namespace OpenRCT2; #ifdef USE_BREAKPAD -# define IMPLIES_SILENT_BREAKPAD ", implies --silent-breakpad" + #define IMPLIES_SILENT_BREAKPAD ", implies --silent-breakpad" #else -# define IMPLIES_SILENT_BREAKPAD + #define IMPLIES_SILENT_BREAKPAD #endif // USE_BREAKPAD #ifndef DISABLE_NETWORK diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 679dc1d179..cd73947db1 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -17,7 +17,7 @@ // windows.h defines an interface keyword #ifdef interface -# undef interface + #undef interface #endif namespace OpenRCT2::Config diff --git a/src/openrct2/core/CallingConventions.h b/src/openrct2/core/CallingConventions.h index 5d0646b087..65247d5f7e 100644 --- a/src/openrct2/core/CallingConventions.h +++ b/src/openrct2/core/CallingConventions.h @@ -10,19 +10,19 @@ #pragma once #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) -# define OPENRCT2_X86 + #define OPENRCT2_X86 #elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_X64) || defined(_M_IX86)) // VS2008 -# define OPENRCT2_X86 + #define OPENRCT2_X86 #endif #if defined(__i386__) || defined(_M_IX86) -# define PLATFORM_X86 + #define PLATFORM_X86 #endif #if defined(__LP64__) || defined(_WIN64) -# define PLATFORM_64BIT + #define PLATFORM_64BIT #else -# define PLATFORM_32BIT + #define PLATFORM_32BIT #endif // C99's restrict keywords guarantees the pointer in question, for the whole of its lifetime, @@ -30,22 +30,22 @@ // aliasing the same memory area. Using it lets compiler generate better code. If your compiler // does not support it, feel free to drop it, at some performance hit. #ifdef _MSC_VER -# define RESTRICT __restrict + #define RESTRICT __restrict #else -# define RESTRICT __restrict__ + #define RESTRICT __restrict__ #endif #ifdef PLATFORM_X86 -# ifndef FASTCALL -# ifdef __GNUC__ -# define FASTCALL __attribute__((fastcall)) -# elif defined(_MSC_VER) -# define FASTCALL __fastcall -# else -# pragma message "Not using fastcall calling convention, please check your compiler support" -# define FASTCALL -# endif -# endif // FASTCALL + #ifndef FASTCALL + #ifdef __GNUC__ + #define FASTCALL __attribute__((fastcall)) + #elif defined(_MSC_VER) + #define FASTCALL __fastcall + #else + #pragma message "Not using fastcall calling convention, please check your compiler support" + #define FASTCALL + #endif + #endif // FASTCALL #else // PLATFORM_X86 -# define FASTCALL + #define FASTCALL #endif // PLATFORM_X86 diff --git a/src/openrct2/core/ChecksumStream.cpp b/src/openrct2/core/ChecksumStream.cpp index 2017b11e89..5944b6b019 100644 --- a/src/openrct2/core/ChecksumStream.cpp +++ b/src/openrct2/core/ChecksumStream.cpp @@ -34,9 +34,9 @@ namespace OpenRCT2 std::memcpy(&temp, reinterpret_cast(buffer) + i, maxLen); // Always use value as little endian, most common systems are little. -# if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) temp = ByteSwapBE(temp); -# endif + #endif *hash ^= temp; *hash *= Prime; diff --git a/src/openrct2/core/Crypt.CNG.cpp b/src/openrct2/core/Crypt.CNG.cpp index 7622668364..e874476889 100644 --- a/src/openrct2/core/Crypt.CNG.cpp +++ b/src/openrct2/core/Crypt.CNG.cpp @@ -9,19 +9,19 @@ #if !defined(DISABLE_NETWORK) && defined(_WIN32) -# include "Crypt.h" + #include "Crypt.h" -# include "../platform/Platform.h" -# include "IStream.hpp" + #include "../platform/Platform.h" + #include "IStream.hpp" -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include // clang-format off // CNG: Cryptography API: Next Generation (CNG) diff --git a/src/openrct2/core/Crypt.OpenSSL.cpp b/src/openrct2/core/Crypt.OpenSSL.cpp index 08821c9137..12834a889e 100644 --- a/src/openrct2/core/Crypt.OpenSSL.cpp +++ b/src/openrct2/core/Crypt.OpenSSL.cpp @@ -9,16 +9,16 @@ #if !defined(DISABLE_NETWORK) && !defined(_WIN32) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -# include "Crypt.h" + #include "Crypt.h" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include using namespace OpenRCT2::Crypt; @@ -354,6 +354,6 @@ namespace OpenRCT2::Crypt } } // namespace OpenRCT2::Crypt -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif // DISABLE_NETWORK diff --git a/src/openrct2/core/DateTime.h b/src/openrct2/core/DateTime.h index 287c1c4a91..a5ff640a79 100644 --- a/src/openrct2/core/DateTime.h +++ b/src/openrct2/core/DateTime.h @@ -10,7 +10,7 @@ #pragma once #ifdef _MSC_VER -# include + #include #endif #include diff --git a/src/openrct2/core/Diagnostics.cpp b/src/openrct2/core/Diagnostics.cpp index 91a8e1f1af..74691744b7 100644 --- a/src/openrct2/core/Diagnostics.cpp +++ b/src/openrct2/core/Diagnostics.cpp @@ -8,7 +8,7 @@ *****************************************************************************/ #if defined(DEBUG) && defined(_WIN32) -# include + #include #endif #include "Diagnostics.hpp" @@ -18,12 +18,12 @@ namespace OpenRCT2::Debug void Break() { #if defined(DEBUG) -# if defined(_WIN32) + #if defined(_WIN32) if (IsDebuggerPresent()) { DebugBreak(); } -# endif + #endif #endif } } // namespace OpenRCT2::Debug diff --git a/src/openrct2/core/File.cpp b/src/openrct2/core/File.cpp index 11c9705284..dcd5fb4a30 100644 --- a/src/openrct2/core/File.cpp +++ b/src/openrct2/core/File.cpp @@ -8,9 +8,9 @@ *****************************************************************************/ #ifdef _WIN32 -# include + #include #else -# include + #include #endif #include "../Diagnostic.h" diff --git a/src/openrct2/core/FileScanner.cpp b/src/openrct2/core/FileScanner.cpp index 84c83253a7..321babd957 100644 --- a/src/openrct2/core/FileScanner.cpp +++ b/src/openrct2/core/FileScanner.cpp @@ -8,17 +8,17 @@ *****************************************************************************/ #ifdef _WIN32 -# include + #include #endif #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -# include -# include -# include -# include + #include + #include + #include + #include #elif defined(_WIN32) -// Windows needs this for widechar <-> utf8 conversion utils -# include "../localisation/Language.h" + // Windows needs this for widechar <-> utf8 conversion utils + #include "../localisation/Language.h" #endif #include "FileScanner.h" diff --git a/src/openrct2/core/FileStream.cpp b/src/openrct2/core/FileStream.cpp index ea82218932..25eb5a5793 100644 --- a/src/openrct2/core/FileStream.cpp +++ b/src/openrct2/core/FileStream.cpp @@ -15,14 +15,14 @@ #include #ifndef _WIN32 -# include + #include #else -# include + #include #endif #ifdef _MSC_VER -# define ftello _ftelli64 -# define fseeko _fseeki64 + #define ftello _ftelli64 + #define fseeko _fseeki64 #endif namespace OpenRCT2 diff --git a/src/openrct2/core/FileSystem.hpp b/src/openrct2/core/FileSystem.hpp index 5c750ab6be..2e1bd7571f 100644 --- a/src/openrct2/core/FileSystem.hpp +++ b/src/openrct2/core/FileSystem.hpp @@ -16,43 +16,43 @@ // Find out if std::filesystem is available: #if defined(_MSC_VER) // Visual Studio supports -# define HAVE_STD_FILESYSTEM 1 + #define HAVE_STD_FILESYSTEM 1 #elif defined(__APPLE__) // XCode has the header, but reports error when included. -# define HAVE_STD_FILESYSTEM 0 + #define HAVE_STD_FILESYSTEM 0 #elif defined(__ANDROID__) -# define HAVE_STD_FILESYSTEM 1 + #define HAVE_STD_FILESYSTEM 1 #elif defined(__has_include) // For GCC/Clang check if the header exists. -# if __has_include() -# define HAVE_STD_FILESYSTEM 1 -# else -# define HAVE_STD_FILESYSTEM 0 -# endif + #if __has_include() + #define HAVE_STD_FILESYSTEM 1 + #else + #define HAVE_STD_FILESYSTEM 0 + #endif #else // By default assume not supported. -# define HAVE_STD_FILESYSTEM 0 + #define HAVE_STD_FILESYSTEM 0 #endif #if HAVE_STD_FILESYSTEM -# include + #include namespace fs = std::filesystem; #else -# ifdef _WIN32 -# ifndef NOMINMAX -# define NOMINMAX -# endif -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# define BITMAP WIN32_BITMAP -# define PATTERN WIN32_PATTERN -# endif -# include -# ifdef _WIN32 -# undef CreateDirectory -# undef CreateWindow -# undef GetMessage -# undef BITMAP -# undef PATTERN -# endif + #ifdef _WIN32 + #ifndef NOMINMAX + #define NOMINMAX + #endif + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #define BITMAP WIN32_BITMAP + #define PATTERN WIN32_PATTERN + #endif + #include + #ifdef _WIN32 + #undef CreateDirectory + #undef CreateWindow + #undef GetMessage + #undef BITMAP + #undef PATTERN + #endif namespace fs = ghc::filesystem; #endif diff --git a/src/openrct2/core/FileWatcher.cpp b/src/openrct2/core/FileWatcher.cpp index 42b5c7e47e..f1de739d8c 100644 --- a/src/openrct2/core/FileWatcher.cpp +++ b/src/openrct2/core/FileWatcher.cpp @@ -15,14 +15,14 @@ #include #ifdef _WIN32 -# include + #include #elif defined(__linux__) -# include -# include -# include -# include + #include + #include + #include + #include #elif defined(__APPLE__) -# include + #include #endif #include "../core/Guard.hpp" diff --git a/src/openrct2/core/FileWatcher.h b/src/openrct2/core/FileWatcher.h index a5539d3fcf..9c5848211e 100644 --- a/src/openrct2/core/FileWatcher.h +++ b/src/openrct2/core/FileWatcher.h @@ -17,11 +17,11 @@ #include #ifdef _WIN32 -# include "FileSystem.hpp" + #include "FileSystem.hpp" typedef void* HANDLE; #elif defined(__APPLE__) -# include + #include #endif /** diff --git a/src/openrct2/core/Guard.cpp b/src/openrct2/core/Guard.cpp index f17037c4e8..d50358c20b 100644 --- a/src/openrct2/core/Guard.cpp +++ b/src/openrct2/core/Guard.cpp @@ -8,8 +8,8 @@ *****************************************************************************/ #ifdef _WIN32 -# include -# include + #include + #include #endif #include "../Version.h" @@ -144,12 +144,12 @@ namespace OpenRCT2::Guard static void ForceCrash() { -# ifdef USE_BREAKPAD + #ifdef USE_BREAKPAD // Force a crash that breakpad will handle allowing us to get a dump *((void**)0) = 0; -# else + #else assert(false); -# endif + #endif } #endif } // namespace OpenRCT2::Guard diff --git a/src/openrct2/core/Http.Android.cpp b/src/openrct2/core/Http.Android.cpp index 3f4a478819..73277f64f7 100644 --- a/src/openrct2/core/Http.Android.cpp +++ b/src/openrct2/core/Http.Android.cpp @@ -9,16 +9,16 @@ #if !defined(DISABLE_HTTP) && defined(__ANDROID__) -# include "Http.h" + #include "Http.h" -# include "../Version.h" -# include "../platform/Platform.h" + #include "../Version.h" + #include "../platform/Platform.h" -# include -# include -# include + #include + #include + #include -# define OPENRCT2_USER_AGENT "OpenRCT2/" OPENRCT2_VERSION + #define OPENRCT2_USER_AGENT "OpenRCT2/" OPENRCT2_VERSION namespace OpenRCT2::Http { diff --git a/src/openrct2/core/Http.WinHttp.cpp b/src/openrct2/core/Http.WinHttp.cpp index b75c3ce2cd..b2a7c37d35 100644 --- a/src/openrct2/core/Http.WinHttp.cpp +++ b/src/openrct2/core/Http.WinHttp.cpp @@ -9,16 +9,16 @@ #if !defined(DISABLE_HTTP) && defined(_WIN32) -# include "Http.h" + #include "Http.h" -# include "../Version.h" -# include "../core/Console.hpp" -# include "String.hpp" + #include "../Version.h" + #include "../core/Console.hpp" + #include "String.hpp" -# include -# include -# include -# include + #include + #include + #include + #include namespace OpenRCT2::Http { @@ -226,9 +226,9 @@ namespace OpenRCT2::Http } catch ([[maybe_unused]] const std::exception& e) { -# ifdef DEBUG + #ifdef DEBUG Console::Error::WriteLine("HTTP request failed: %s", e.what()); -# endif + #endif WinHttpCloseHandle(hSession); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hRequest); diff --git a/src/openrct2/core/Http.cURL.cpp b/src/openrct2/core/Http.cURL.cpp index 11cf9e5f8b..207edefce0 100644 --- a/src/openrct2/core/Http.cURL.cpp +++ b/src/openrct2/core/Http.cURL.cpp @@ -9,23 +9,23 @@ #if !defined(DISABLE_HTTP) && !defined(_WIN32) && !defined(__ANDROID__) -# include "Http.h" + #include "Http.h" -# include "../Version.h" -# include "../core/Console.hpp" + #include "../Version.h" + #include "../core/Console.hpp" -# include -# include -# include -# include + #include + #include + #include + #include -# if defined(_WIN32) && !defined(WIN32_LEAN_AND_MEAN) -// cURL includes windows.h, but we don't need all of it. -# define WIN32_LEAN_AND_MEAN -# endif -# include + #if defined(_WIN32) && !defined(WIN32_LEAN_AND_MEAN) + // cURL includes windows.h, but we don't need all of it. + #define WIN32_LEAN_AND_MEAN + #endif + #include -# define OPENRCT2_USER_AGENT "OpenRCT2/" OPENRCT2_VERSION + #define OPENRCT2_USER_AGENT "OpenRCT2/" OPENRCT2_VERSION namespace OpenRCT2::Http { diff --git a/src/openrct2/core/Http.h b/src/openrct2/core/Http.h index 7c03f88bdf..c53987897e 100644 --- a/src/openrct2/core/Http.h +++ b/src/openrct2/core/Http.h @@ -11,10 +11,10 @@ #ifndef DISABLE_HTTP -# include -# include -# include -# include + #include + #include + #include + #include namespace OpenRCT2::Http { diff --git a/src/openrct2/core/IStream.hpp b/src/openrct2/core/IStream.hpp index 9d08e2afe8..263676f8ba 100644 --- a/src/openrct2/core/IStream.hpp +++ b/src/openrct2/core/IStream.hpp @@ -19,9 +19,9 @@ #include #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" -# pragma GCC diagnostic ignored "-Wsuggest-final-types" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic ignored "-Wsuggest-final-types" #endif namespace OpenRCT2 @@ -218,7 +218,7 @@ namespace OpenRCT2 } // namespace OpenRCT2 #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif class IOException : public std::runtime_error diff --git a/src/openrct2/core/Json.hpp b/src/openrct2/core/Json.hpp index 43490d1c1c..5d205ba980 100644 --- a/src/openrct2/core/Json.hpp +++ b/src/openrct2/core/Json.hpp @@ -16,7 +16,7 @@ #include #if NLOHMANN_JSON_VERSION_MAJOR < 3 || (NLOHMANN_JSON_VERSION_MAJOR == 3 && NLOHMANN_JSON_VERSION_MINOR < 9) -# error "Unsupported version of nlohmann json library, must be >= 3.9" + #error "Unsupported version of nlohmann json library, must be >= 3.9" #endif // NLOHMANN_JSON_VERSION_MAJOR < 3 || (NLOHMANN_JSON_VERSION_MAJOR == 3 && NLOHMANN_JSON_VERSION_MINOR < 9) using json_t = nlohmann::json; diff --git a/src/openrct2/core/Numerics.hpp b/src/openrct2/core/Numerics.hpp index 23ac49ef68..6eac9b37b6 100644 --- a/src/openrct2/core/Numerics.hpp +++ b/src/openrct2/core/Numerics.hpp @@ -15,7 +15,7 @@ #include #ifdef _MSC_VER -# include + #include #endif namespace OpenRCT2::Numerics @@ -30,7 +30,7 @@ namespace OpenRCT2::Numerics int32_t success = __builtin_ffs(source); return success - 1; #else -# pragma message("Falling back to iterative bitscan32 forward, consider using intrinsics") + #pragma message("Falling back to iterative bitscan32 forward, consider using intrinsics") // This is a low-hanging optimisation boost, check if your compiler offers // any intrinsic. // cf. https://github.com/OpenRCT2/OpenRCT2/pull/2093 @@ -52,7 +52,7 @@ namespace OpenRCT2::Numerics int32_t success = __builtin_ffsll(source); return success - 1; #else -# pragma message("Falling back to iterative bitscan64 forward, consider using intrinsics") + #pragma message("Falling back to iterative bitscan64 forward, consider using intrinsics") // This is a low-hanging optimisation boost, check if your compiler offers // any intrinsic. // cf. https://github.com/OpenRCT2/OpenRCT2/pull/2093 diff --git a/src/openrct2/core/RTL.FriBidi.cpp b/src/openrct2/core/RTL.FriBidi.cpp index 44b83b5b8a..614af97595 100644 --- a/src/openrct2/core/RTL.FriBidi.cpp +++ b/src/openrct2/core/RTL.FriBidi.cpp @@ -8,17 +8,17 @@ *****************************************************************************/ #if defined(_WIN32) && defined(USE_FRIBIDI) -# include "RTL.h" + #include "RTL.h" -# include "../Diagnostic.h" + #include "../Diagnostic.h" -# include + #include extern "C" { -# include -# include -# include -# include + #include + #include + #include + #include } static constexpr uint16_t BufferLength = 1024; @@ -50,10 +50,10 @@ std::string FixRTL(std::string& input) return std::string(outputString); } #elif defined(_WIN32) -# include "../Diagnostic.h" -# include "RTL.h" + #include "../Diagnostic.h" + #include "RTL.h" -# include + #include static bool hasWarned = false; diff --git a/src/openrct2/core/RTL.ICU.cpp b/src/openrct2/core/RTL.ICU.cpp index 1c817d0216..03e69519cf 100644 --- a/src/openrct2/core/RTL.ICU.cpp +++ b/src/openrct2/core/RTL.ICU.cpp @@ -8,16 +8,16 @@ *****************************************************************************/ #ifndef _WIN32 -# include "RTL.h" + #include "RTL.h" -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include std::string FixRTL(std::string& input) { diff --git a/src/openrct2/core/String.cpp b/src/openrct2/core/String.cpp index b0b09dca5b..d0a57c094f 100644 --- a/src/openrct2/core/String.cpp +++ b/src/openrct2/core/String.cpp @@ -17,14 +17,14 @@ #include #ifndef _WIN32 -# if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) -# include -# endif -# include -# include -# include + #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) + #include + #endif + #include + #include + #include #else -# include + #include #endif #include "../util/Util.h" @@ -34,8 +34,8 @@ #include "UTF8.h" #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -# include -# define _stricmp(x, y) strcasecmp((x), (y)) + #include + #define _stricmp(x, y) strcasecmp((x), (y)) #endif namespace OpenRCT2::String @@ -57,17 +57,17 @@ namespace OpenRCT2::String WideCharToMultiByte(OpenRCT2::CodePage::UTF8, 0, src.data(), srcLen, result.data(), sizeReq, nullptr, nullptr); return result; #else -// Which constructor to use depends on the size of wchar_t... -// UTF-32 is the default on most POSIX systems; Windows uses UTF-16. -// Unfortunately, we'll have to help the compiler here. -# if U_SIZEOF_WCHAR_T == 4 + // Which constructor to use depends on the size of wchar_t... + // UTF-32 is the default on most POSIX systems; Windows uses UTF-16. + // Unfortunately, we'll have to help the compiler here. + #if U_SIZEOF_WCHAR_T == 4 icu::UnicodeString str = icu::UnicodeString::fromUTF32(reinterpret_cast(src.data()), src.length()); -# elif U_SIZEOF_WCHAR_T == 2 + #elif U_SIZEOF_WCHAR_T == 2 std::wstring wstr = std::wstring(src); icu::UnicodeString str = icu::UnicodeString(static_cast(wstr.c_str())); -# else -# error Unsupported U_SIZEOF_WCHAR_T size -# endif + #else + #error Unsupported U_SIZEOF_WCHAR_T size + #endif std::string result; str.toUTF8String(result); @@ -87,23 +87,23 @@ namespace OpenRCT2::String #else icu::UnicodeString str = icu::UnicodeString::fromUTF8(std::string(src)); -// Which constructor to use depends on the size of wchar_t... -// UTF-32 is the default on most POSIX systems; Windows uses UTF-16. -// Unfortunately, we'll have to help the compiler here. -# if U_SIZEOF_WCHAR_T == 4 + // Which constructor to use depends on the size of wchar_t... + // UTF-32 is the default on most POSIX systems; Windows uses UTF-16. + // Unfortunately, we'll have to help the compiler here. + #if U_SIZEOF_WCHAR_T == 4 size_t length = static_cast(str.length()); std::wstring result(length, '\0'); UErrorCode status = U_ZERO_ERROR; str.toUTF32(reinterpret_cast(&result[0]), str.length(), status); -# elif U_SIZEOF_WCHAR_T == 2 + #elif U_SIZEOF_WCHAR_T == 2 const char16_t* buffer = str.getBuffer(); std::wstring result = static_cast(buffer); -# else -# error Unsupported U_SIZEOF_WCHAR_T size -# endif + #else + #error Unsupported U_SIZEOF_WCHAR_T size + #endif return result; #endif diff --git a/src/openrct2/core/Zip.cpp b/src/openrct2/core/Zip.cpp index c2b930b2ae..3e00d342fc 100644 --- a/src/openrct2/core/Zip.cpp +++ b/src/openrct2/core/Zip.cpp @@ -12,7 +12,7 @@ #include "IStream.hpp" #ifndef __ANDROID__ -# include + #include #endif using namespace OpenRCT2; diff --git a/src/openrct2/core/ZipAndroid.cpp b/src/openrct2/core/ZipAndroid.cpp index a57d34293d..5d669f7dbf 100644 --- a/src/openrct2/core/ZipAndroid.cpp +++ b/src/openrct2/core/ZipAndroid.cpp @@ -9,16 +9,16 @@ #ifdef __ANDROID__ -# include "../Diagnostic.h" -# include "../platform/Platform.h" -# include "IStream.hpp" -# include "Memory.hpp" -# include "MemoryStream.h" -# include "Zip.h" + #include "../Diagnostic.h" + #include "../platform/Platform.h" + #include "IStream.hpp" + #include "Memory.hpp" + #include "MemoryStream.h" + #include "Zip.h" -# include -# include -# include + #include + #include + #include using namespace OpenRCT2; diff --git a/src/openrct2/drawing/AVX2Drawing.cpp b/src/openrct2/drawing/AVX2Drawing.cpp index aea86a804b..70f7a6dd6f 100644 --- a/src/openrct2/drawing/AVX2Drawing.cpp +++ b/src/openrct2/drawing/AVX2Drawing.cpp @@ -12,7 +12,7 @@ #ifdef __AVX2__ -# include + #include void MaskAvx2( int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst, @@ -43,9 +43,9 @@ void MaskAvx2( #else -# ifdef OPENRCT2_X86 -# error You have to compile this file with AVX2 enabled, when targeting x86! -# endif + #ifdef OPENRCT2_X86 + #error You have to compile this file with AVX2 enabled, when targeting x86! + #endif void MaskAvx2( int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst, diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index 74db073471..d8a5616aad 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -674,15 +674,15 @@ static void TTFProcessStringLiteral(DrawPixelInfo& dpi, std::string_view text, T // This error suppression abomination is here to suppress https://github.com/OpenRCT2/OpenRCT2/issues/17371. // Additionally, we have to suppress the error for the error suppression... :'-( // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105937 is fixed in GCC13 -# if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -# endif + #if defined(__GNUC__) && !defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + #endif auto len = it.GetIndex() - ttfRunIndex.value(); TTFDrawStringRawTTF(dpi, text.substr(ttfRunIndex.value(), len), info); -# if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic pop -# endif + #if defined(__GNUC__) && !defined(__clang__) + #pragma GCC diagnostic pop + #endif ttfRunIndex = std::nullopt; } diff --git a/src/openrct2/drawing/Image.cpp b/src/openrct2/drawing/Image.cpp index dab2c01e27..0044c0357f 100644 --- a/src/openrct2/drawing/Image.cpp +++ b/src/openrct2/drawing/Image.cpp @@ -31,11 +31,11 @@ static uint32_t _allocatedImageCount; #ifdef DEBUG_LEVEL_1 static std::list _allocatedLists; -// MSVC's compiler doesn't support the [[maybe_unused]] attribute for unused static functions. Until this has been resolved, we -// need to explicitly tell the compiler to temporarily disable the warning. -// See discussion at https://github.com/OpenRCT2/OpenRCT2/pull/7617 -# pragma warning(push) -# pragma warning(disable : 4505) // unreferenced local function has been removed + // MSVC's compiler doesn't support the [[maybe_unused]] attribute for unused static functions. Until this has been resolved, + // we need to explicitly tell the compiler to temporarily disable the warning. See discussion at + // https://github.com/OpenRCT2/OpenRCT2/pull/7617 + #pragma warning(push) + #pragma warning(disable : 4505) // unreferenced local function has been removed [[maybe_unused]] static bool AllocatedListContains(uint32_t baseImageId, uint32_t count) { @@ -46,7 +46,7 @@ static std::list _allocatedLists; return contains; } -# pragma warning(pop) + #pragma warning(pop) static bool AllocatedListRemove(uint32_t baseImageId, uint32_t count) { diff --git a/src/openrct2/drawing/SSE41Drawing.cpp b/src/openrct2/drawing/SSE41Drawing.cpp index 3177f81919..732506eb61 100644 --- a/src/openrct2/drawing/SSE41Drawing.cpp +++ b/src/openrct2/drawing/SSE41Drawing.cpp @@ -12,7 +12,7 @@ #ifdef __SSE4_1__ -# include + #include void MaskSse4_1( int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst, @@ -57,9 +57,9 @@ void MaskSse4_1( #else -# ifdef OPENRCT2_X86 -# error You have to compile this file with SSE4.1 enabled, when targeting x86! -# endif + #ifdef OPENRCT2_X86 + #error You have to compile this file with SSE4.1 enabled, when targeting x86! + #endif void MaskSse4_1( int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst, diff --git a/src/openrct2/drawing/TTF.cpp b/src/openrct2/drawing/TTF.cpp index 6b35dcd8e4..9e81a40d0f 100644 --- a/src/openrct2/drawing/TTF.cpp +++ b/src/openrct2/drawing/TTF.cpp @@ -9,24 +9,24 @@ #ifndef NO_TTF -# include "../Diagnostic.h" + #include "../Diagnostic.h" -# include -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdocumentation" -# include -# include FT_FREETYPE_H -# pragma clang diagnostic pop + #include + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdocumentation" + #include + #include FT_FREETYPE_H + #pragma clang diagnostic pop -# include "../OpenRCT2.h" -# include "../core/Numerics.hpp" -# include "../core/String.hpp" -# include "../drawing/Font.h" -# include "../localisation/LocalisationService.h" -# include "../platform/Platform.h" -# include "../util/Util.h" -# include "DrawingLock.hpp" -# include "TTF.h" + #include "../OpenRCT2.h" + #include "../core/Numerics.hpp" + #include "../core/String.hpp" + #include "../drawing/Font.h" + #include "../localisation/LocalisationService.h" + #include "../platform/Platform.h" + #include "../util/Util.h" + #include "DrawingLock.hpp" + #include "TTF.h" using namespace OpenRCT2; @@ -360,7 +360,7 @@ void TTFFreeSurface(TTFSurface* surface) #else -# include "TTF.h" + #include "TTF.h" bool TTFInitialise() { diff --git a/src/openrct2/drawing/X8DrawingEngine.cpp b/src/openrct2/drawing/X8DrawingEngine.cpp index 57d7e6fc26..0e27671018 100644 --- a/src/openrct2/drawing/X8DrawingEngine.cpp +++ b/src/openrct2/drawing/X8DrawingEngine.cpp @@ -112,8 +112,8 @@ void X8WeatherDrawer::Restore(DrawPixelInfo& dpi) } #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" #endif X8DrawingEngine::X8DrawingEngine([[maybe_unused]] const std::shared_ptr& uiContext) @@ -453,7 +453,7 @@ void X8DrawingEngine::DrawDirtyBlocks(uint32_t x, uint32_t y, uint32_t columns, } #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif X8DrawingContext::X8DrawingContext(X8DrawingEngine* engine) diff --git a/src/openrct2/drawing/X8DrawingEngine.h b/src/openrct2/drawing/X8DrawingEngine.h index 4a3ea69ee3..f8fb04d495 100644 --- a/src/openrct2/drawing/X8DrawingEngine.h +++ b/src/openrct2/drawing/X8DrawingEngine.h @@ -61,8 +61,8 @@ namespace OpenRCT2 }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-types" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-types" #endif class X8DrawingEngine : public IDrawingEngine { @@ -86,13 +86,13 @@ namespace OpenRCT2 explicit X8DrawingEngine(const std::shared_ptr& uiContext); #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" -# pragma GCC diagnostic ignored "-Wsuggest-final-types" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic ignored "-Wsuggest-final-types" #endif ~X8DrawingEngine() override; #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif void Initialise() override; @@ -124,7 +124,7 @@ namespace OpenRCT2 void DrawDirtyBlocks(uint32_t x, uint32_t y, uint32_t columns, uint32_t rows); }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif class X8DrawingContext final : public IDrawingContext diff --git a/src/openrct2/interface/FontFamilies.h b/src/openrct2/interface/FontFamilies.h index cf22871f51..3932f9999f 100644 --- a/src/openrct2/interface/FontFamilies.h +++ b/src/openrct2/interface/FontFamilies.h @@ -15,7 +15,7 @@ constexpr std::nullptr_t kFamilyOpenRCT2Sprite = nullptr; #ifndef NO_TTF -# include + #include struct TTFFontSetDescriptor; @@ -27,10 +27,10 @@ extern TTFontFamily const TTFFamilyJapanese; extern TTFontFamily const TTFFamilyKorean; extern TTFontFamily const TTFFamilySansSerif; -# define FAMILY(x) x + #define FAMILY(x) x #else // NO_TTF -# define FAMILY(x) kFamilyOpenRCT2Sprite + #define FAMILY(x) kFamilyOpenRCT2Sprite #endif // NO_TTF diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 67b5ed1930..1b4d2a787a 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -74,7 +74,7 @@ #include #ifndef NO_TTF -# include "../drawing/TTF.h" + #include "../drawing/TTF.h" #endif using namespace OpenRCT2; diff --git a/src/openrct2/interface/StdInOutConsole.cpp b/src/openrct2/interface/StdInOutConsole.cpp index 2909940bad..5db10847d3 100644 --- a/src/openrct2/interface/StdInOutConsole.cpp +++ b/src/openrct2/interface/StdInOutConsole.cpp @@ -19,7 +19,7 @@ // Ignore isatty warning on WIN32 #ifdef _MSC_VER -# pragma warning(disable : 4996) + #pragma warning(disable : 4996) #endif void StdInOutConsole::Start() diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index 7c204501ad..85db10a6bf 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -22,9 +22,9 @@ struct ResearchItem; struct RCTObjectEntry; #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" -# pragma GCC diagnostic ignored "-Wsuggest-final-types" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic ignored "-Wsuggest-final-types" #endif /** @@ -169,7 +169,7 @@ struct WindowBase }; #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif // rct2: 0x01420078 diff --git a/src/openrct2/network/DiscordService.cpp b/src/openrct2/network/DiscordService.cpp index 9599712e50..9699710362 100644 --- a/src/openrct2/network/DiscordService.cpp +++ b/src/openrct2/network/DiscordService.cpp @@ -8,21 +8,21 @@ *****************************************************************************/ #ifdef __ENABLE_DISCORD__ -# include "DiscordService.h" + #include "DiscordService.h" -# include "../Context.h" -# include "../Diagnostic.h" -# include "../GameState.h" -# include "../OpenRCT2.h" -# include "../core/Console.hpp" -# include "../core/String.hpp" -# include "../core/UTF8.h" -# include "../localisation/Formatting.h" -# include "../world/Park.h" -# include "network.h" + #include "../Context.h" + #include "../Diagnostic.h" + #include "../GameState.h" + #include "../OpenRCT2.h" + #include "../core/Console.hpp" + #include "../core/String.hpp" + #include "../core/UTF8.h" + #include "../localisation/Formatting.h" + #include "../world/Park.h" + #include "network.h" -# include -# include + #include + #include using namespace OpenRCT2; diff --git a/src/openrct2/network/DiscordService.h b/src/openrct2/network/DiscordService.h index ab496b4055..7ba3ab9e0d 100644 --- a/src/openrct2/network/DiscordService.h +++ b/src/openrct2/network/DiscordService.h @@ -11,9 +11,9 @@ #ifdef __ENABLE_DISCORD__ -# include "../core/Timer.hpp" + #include "../core/Timer.hpp" -# include + #include class DiscordService final { diff --git a/src/openrct2/network/NetworkAction.cpp b/src/openrct2/network/NetworkAction.cpp index 10142a6cad..5d9c8f2093 100644 --- a/src/openrct2/network/NetworkAction.cpp +++ b/src/openrct2/network/NetworkAction.cpp @@ -9,12 +9,12 @@ #ifndef DISABLE_NETWORK -# include "NetworkAction.h" + #include "NetworkAction.h" -# include "../Game.h" -# include "../localisation/StringIds.h" + #include "../Game.h" + #include "../localisation/StringIds.h" -# include + #include NetworkPermission NetworkActions::FindCommand(GameCommand command) { diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 1ec9033c2f..48ac7304ca 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -66,45 +66,45 @@ static constexpr uint32_t kChunkSize = 1024 * 63; // This limit is per connection, the current value was determined by tests with fuzzing. static constexpr uint32_t kMaxPacketsPerUpdate = 100; -# include "../Cheats.h" -# include "../ParkImporter.h" -# include "../Version.h" -# include "../actions/GameAction.h" -# include "../config/Config.h" -# include "../core/Console.hpp" -# include "../core/FileStream.h" -# include "../core/MemoryStream.h" -# include "../core/Path.hpp" -# include "../core/String.hpp" -# include "../interface/Chat.h" -# include "../interface/Window.h" -# include "../localisation/Localisation.Date.h" -# include "../object/ObjectManager.h" -# include "../object/ObjectRepository.h" -# include "../scenario/Scenario.h" -# include "../util/Util.h" -# include "../world/Park.h" -# include "NetworkAction.h" -# include "NetworkConnection.h" -# include "NetworkGroup.h" -# include "NetworkKey.h" -# include "NetworkPacket.h" -# include "NetworkPlayer.h" -# include "NetworkServerAdvertiser.h" -# include "NetworkUser.h" -# include "Socket.h" + #include "../Cheats.h" + #include "../ParkImporter.h" + #include "../Version.h" + #include "../actions/GameAction.h" + #include "../config/Config.h" + #include "../core/Console.hpp" + #include "../core/FileStream.h" + #include "../core/MemoryStream.h" + #include "../core/Path.hpp" + #include "../core/String.hpp" + #include "../interface/Chat.h" + #include "../interface/Window.h" + #include "../localisation/Localisation.Date.h" + #include "../object/ObjectManager.h" + #include "../object/ObjectRepository.h" + #include "../scenario/Scenario.h" + #include "../util/Util.h" + #include "../world/Park.h" + #include "NetworkAction.h" + #include "NetworkConnection.h" + #include "NetworkGroup.h" + #include "NetworkKey.h" + #include "NetworkPacket.h" + #include "NetworkPlayer.h" + #include "NetworkServerAdvertiser.h" + #include "NetworkUser.h" + #include "Socket.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include using namespace OpenRCT2; @@ -209,10 +209,10 @@ void NetworkBase::Close() _pendingPlayerLists.clear(); _pendingPlayerInfo.clear(); -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING auto& scriptEngine = GetContext().GetScriptEngine(); scriptEngine.RemoveNetworkPlugins(); -# endif + #endif GfxInvalidateScreen(); @@ -1350,7 +1350,7 @@ void NetworkBase::ServerSendObjectsList( void NetworkBase::ServerSendScripts(NetworkConnection& connection) { -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING using namespace OpenRCT2::Scripting; auto& scriptEngine = GetContext().GetScriptEngine(); @@ -1393,11 +1393,11 @@ void NetworkBase::ServerSendScripts(NetworkConnection& connection) } Guard::Assert(dataOffset == pluginData.GetLength()); -# else + #else NetworkPacket packetScriptHeader(NetworkCommand::ScriptsHeader); packetScriptHeader << static_cast(0u); packetScriptHeader << static_cast(0u); -# endif + #endif } void NetworkBase::Client_Send_HEARTBEAT(NetworkConnection& connection) const @@ -1676,7 +1676,7 @@ json_t NetworkBase::GetServerInfoAsJson() const void NetworkBase::ServerSendGameInfo(NetworkConnection& connection) { NetworkPacket packet(NetworkCommand::GameInfo); -# ifndef DISABLE_HTTP + #ifndef DISABLE_HTTP json_t jsonObj = GetServerInfoAsJson(); // Provider details @@ -1692,7 +1692,7 @@ void NetworkBase::ServerSendGameInfo(NetworkConnection& connection) packet << _serverState.gamestateSnapshotsEnabled; packet << IsServerPlayerInvisible; -# endif + #endif connection.QueuePacket(std::move(packet)); } @@ -1819,7 +1819,7 @@ void NetworkBase::ProcessPending() static bool ProcessPlayerAuthenticatePluginHooks( const NetworkConnection& connection, std::string_view name, std::string_view publicKeyHash) { -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING using namespace OpenRCT2::Scripting; auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine(); @@ -1844,13 +1844,13 @@ static bool ProcessPlayerAuthenticatePluginHooks( return false; } } -# endif + #endif return true; } static void ProcessPlayerJoinedPluginHooks(uint8_t playerId) { -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING using namespace OpenRCT2::Scripting; auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine(); @@ -1866,12 +1866,12 @@ static void ProcessPlayerJoinedPluginHooks(uint8_t playerId) // Call the subscriptions hookEngine.Call(OpenRCT2::Scripting::HOOK_TYPE::NETWORK_JOIN, e, false); } -# endif + #endif } static void ProcessPlayerLeftPluginHooks(uint8_t playerId) { -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING using namespace OpenRCT2::Scripting; auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine(); @@ -1887,7 +1887,7 @@ static void ProcessPlayerLeftPluginHooks(uint8_t playerId) // Call the subscriptions hookEngine.Call(OpenRCT2::Scripting::HOOK_TYPE::NETWORK_LEAVE, e, false); } -# endif + #endif } void NetworkBase::ProcessPlayerList() @@ -2467,22 +2467,22 @@ void NetworkBase::Client_Handle_SCRIPTS_HEADER(NetworkConnection& connection, Ne uint32_t dataSize{}; packet >> numScripts >> dataSize; -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING _serverScriptsData.data.Clear(); _serverScriptsData.pluginCount = numScripts; _serverScriptsData.dataSize = dataSize; -# else + #else if (numScripts > 0) { connection.SetLastDisconnectReason("The client requires plugin support."); Close(); } -# endif + #endif } void NetworkBase::Client_Handle_SCRIPTS_DATA(NetworkConnection& connection, NetworkPacket& packet) { -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING uint32_t dataSize{}; packet >> dataSize; Guard::Assert(dataSize > 0); @@ -2511,10 +2511,10 @@ void NetworkBase::Client_Handle_SCRIPTS_DATA(NetworkConnection& connection, Netw // Empty the current buffer. _serverScriptsData = {}; } -# else + #else connection.SetLastDisconnectReason("The client requires plugin support."); Close(); -# endif + #endif } void NetworkBase::Client_Handle_GAMESTATE(NetworkConnection& connection, NetworkPacket& packet) @@ -2896,7 +2896,7 @@ void NetworkBase::Client_Handle_CHAT([[maybe_unused]] NetworkConnection& connect static bool ProcessChatMessagePluginHooks(uint8_t playerId, std::string& text) { -# ifdef ENABLE_SCRIPTING + #ifdef ENABLE_SCRIPTING auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine(); if (hookEngine.HasSubscriptions(OpenRCT2::Scripting::HOOK_TYPE::NETWORK_CHAT)) { @@ -2926,7 +2926,7 @@ static bool ProcessChatMessagePluginHooks(uint8_t playerId, std::string& text) return false; } } -# endif + #endif return true; } diff --git a/src/openrct2/network/NetworkConnection.cpp b/src/openrct2/network/NetworkConnection.cpp index d1cbd98f6f..a2fc31fed8 100644 --- a/src/openrct2/network/NetworkConnection.cpp +++ b/src/openrct2/network/NetworkConnection.cpp @@ -9,21 +9,21 @@ #ifndef DISABLE_NETWORK -# include "NetworkConnection.h" + #include "NetworkConnection.h" -# include "../core/String.hpp" -# include "../localisation/Formatting.h" -# include "../platform/Platform.h" -# include "Socket.h" -# include "network.h" + #include "../core/String.hpp" + #include "../localisation/Formatting.h" + #include "../platform/Platform.h" + #include "Socket.h" + #include "network.h" using namespace OpenRCT2; static constexpr size_t kNetworkDisconnectReasonBufSize = 256; static constexpr size_t kNetworkBufferSize = 1024 * 64; // 64 KiB, maximum packet size. -# ifndef DEBUG + #ifndef DEBUG static constexpr size_t kNetworkNoDataTimeout = 20; // Seconds. -# endif + #endif NetworkConnection::NetworkConnection() noexcept { @@ -181,13 +181,13 @@ void NetworkConnection::ResetLastPacketTime() noexcept bool NetworkConnection::ReceivedPacketRecently() const noexcept { -# ifndef DEBUG + #ifndef DEBUG constexpr auto kTimeoutMs = kNetworkNoDataTimeout * 1000; if (Platform::GetTicks() > _lastPacketTime + kTimeoutMs) { return false; } -# endif + #endif return true; } diff --git a/src/openrct2/network/NetworkConnection.h b/src/openrct2/network/NetworkConnection.h index ad65de39af..c5fb549b53 100644 --- a/src/openrct2/network/NetworkConnection.h +++ b/src/openrct2/network/NetworkConnection.h @@ -11,15 +11,15 @@ #ifndef DISABLE_NETWORK -# include "NetworkKey.h" -# include "NetworkPacket.h" -# include "NetworkTypes.h" -# include "Socket.h" + #include "NetworkKey.h" + #include "NetworkPacket.h" + #include "NetworkTypes.h" + #include "Socket.h" -# include -# include -# include -# include + #include + #include + #include + #include class NetworkPlayer; struct ObjectRepositoryItem; diff --git a/src/openrct2/network/NetworkGroup.cpp b/src/openrct2/network/NetworkGroup.cpp index ed6ec8fde9..3d579431f1 100644 --- a/src/openrct2/network/NetworkGroup.cpp +++ b/src/openrct2/network/NetworkGroup.cpp @@ -9,11 +9,11 @@ #ifndef DISABLE_NETWORK -# include "NetworkGroup.h" + #include "NetworkGroup.h" -# include "../openrct2/core/Json.hpp" -# include "NetworkAction.h" -# include "NetworkTypes.h" + #include "../openrct2/core/Json.hpp" + #include "NetworkAction.h" + #include "NetworkTypes.h" using namespace OpenRCT2; diff --git a/src/openrct2/network/NetworkKey.cpp b/src/openrct2/network/NetworkKey.cpp index 2ead9e479d..ce83211dcc 100644 --- a/src/openrct2/network/NetworkKey.cpp +++ b/src/openrct2/network/NetworkKey.cpp @@ -9,15 +9,15 @@ #ifndef DISABLE_NETWORK -# include "NetworkKey.h" + #include "NetworkKey.h" -# include "../Diagnostic.h" -# include "../core/Crypt.h" -# include "../core/Guard.hpp" -# include "../core/IStream.hpp" -# include "../core/String.hpp" + #include "../Diagnostic.h" + #include "../core/Crypt.h" + #include "../core/Guard.hpp" + #include "../core/IStream.hpp" + #include "../core/String.hpp" -# include + #include using namespace OpenRCT2; diff --git a/src/openrct2/network/NetworkKey.h b/src/openrct2/network/NetworkKey.h index 36e8507ec8..f59d01fc52 100644 --- a/src/openrct2/network/NetworkKey.h +++ b/src/openrct2/network/NetworkKey.h @@ -11,9 +11,9 @@ #ifndef DISABLE_NETWORK -# include -# include -# include + #include + #include + #include namespace OpenRCT2 { diff --git a/src/openrct2/network/NetworkPacket.cpp b/src/openrct2/network/NetworkPacket.cpp index 580f8c328c..45c901ffc0 100644 --- a/src/openrct2/network/NetworkPacket.cpp +++ b/src/openrct2/network/NetworkPacket.cpp @@ -9,11 +9,11 @@ #ifndef DISABLE_NETWORK -# include "NetworkPacket.h" + #include "NetworkPacket.h" -# include "NetworkTypes.h" + #include "NetworkTypes.h" -# include + #include NetworkPacket::NetworkPacket(NetworkCommand id) noexcept : Header{ 0, id } diff --git a/src/openrct2/network/NetworkPlayer.cpp b/src/openrct2/network/NetworkPlayer.cpp index 9bc4915d75..61ebe7e876 100644 --- a/src/openrct2/network/NetworkPlayer.cpp +++ b/src/openrct2/network/NetworkPlayer.cpp @@ -9,11 +9,11 @@ #ifndef DISABLE_NETWORK -# include "NetworkPlayer.h" + #include "NetworkPlayer.h" -# include "../core/Money.hpp" -# include "../interface/Window.h" -# include "NetworkPacket.h" + #include "../core/Money.hpp" + #include "../interface/Window.h" + #include "NetworkPacket.h" void NetworkPlayer::SetName(std::string_view name) { diff --git a/src/openrct2/network/NetworkServerAdvertiser.cpp b/src/openrct2/network/NetworkServerAdvertiser.cpp index e45bfa333f..d04ade1c52 100644 --- a/src/openrct2/network/NetworkServerAdvertiser.cpp +++ b/src/openrct2/network/NetworkServerAdvertiser.cpp @@ -9,30 +9,30 @@ #ifndef DISABLE_NETWORK -# include "NetworkServerAdvertiser.h" + #include "NetworkServerAdvertiser.h" -# include "../Diagnostic.h" -# include "../GameState.h" -# include "../config/Config.h" -# include "../core/Console.hpp" -# include "../core/Guard.hpp" -# include "../core/Http.h" -# include "../core/Json.hpp" -# include "../core/String.hpp" -# include "../entity/Guest.h" -# include "../localisation/Localisation.Date.h" -# include "../management/Finance.h" -# include "../platform/Platform.h" -# include "../world/Map.h" -# include "../world/Park.h" -# include "Socket.h" -# include "network.h" + #include "../Diagnostic.h" + #include "../GameState.h" + #include "../config/Config.h" + #include "../core/Console.hpp" + #include "../core/Guard.hpp" + #include "../core/Http.h" + #include "../core/Json.hpp" + #include "../core/String.hpp" + #include "../entity/Guest.h" + #include "../localisation/Localisation.Date.h" + #include "../management/Finance.h" + #include "../platform/Platform.h" + #include "../world/Map.h" + #include "../world/Park.h" + #include "Socket.h" + #include "network.h" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include using namespace OpenRCT2; @@ -44,10 +44,10 @@ enum class MasterServerStatus InternalError = 500 }; -# ifndef DISABLE_HTTP + #ifndef DISABLE_HTTP constexpr int32_t kMasterServerRegisterTime = 120 * 1000; // 2 minutes constexpr int32_t kMasterServerHeartbeatTime = 60 * 1000; // 1 minute -# endif + #endif class NetworkServerAdvertiser final : public INetworkServerAdvertiser { @@ -59,7 +59,7 @@ private: ADVERTISE_STATUS _status = ADVERTISE_STATUS::UNREGISTERED; -# ifndef DISABLE_HTTP + #ifndef DISABLE_HTTP uint32_t _lastAdvertiseTime = 0; uint32_t _lastHeartbeatTime = 0; @@ -71,16 +71,16 @@ private: // See https://github.com/OpenRCT2/OpenRCT2/issues/6277 and 4953 bool _forceIPv4 = false; -# endif + #endif public: explicit NetworkServerAdvertiser(uint16_t port) { _port = port; _lanListener = CreateUdpSocket(); -# ifndef DISABLE_HTTP + #ifndef DISABLE_HTTP _key = GenerateAdvertiseKey(); -# endif + #endif } ADVERTISE_STATUS GetStatus() const override @@ -91,12 +91,12 @@ public: void Update() override { UpdateLAN(); -# ifndef DISABLE_HTTP + #ifndef DISABLE_HTTP if (Config::Get().network.Advertise) { UpdateWAN(); } -# endif + #endif } private: @@ -140,7 +140,7 @@ private: return root; } -# ifndef DISABLE_HTTP + #ifndef DISABLE_HTTP void UpdateWAN() { switch (_status) @@ -351,7 +351,7 @@ private: } return result; } -# endif + #endif }; std::unique_ptr CreateServerAdvertiser(uint16_t port) diff --git a/src/openrct2/network/NetworkUser.cpp b/src/openrct2/network/NetworkUser.cpp index e769f94f52..a2ad556f39 100644 --- a/src/openrct2/network/NetworkUser.cpp +++ b/src/openrct2/network/NetworkUser.cpp @@ -9,18 +9,18 @@ #ifndef DISABLE_NETWORK -# include "NetworkUser.h" + #include "NetworkUser.h" -# include "../Context.h" -# include "../PlatformEnvironment.h" -# include "../core/Console.hpp" -# include "../core/File.h" -# include "../core/Guard.hpp" -# include "../core/Json.hpp" -# include "../core/Path.hpp" -# include "../core/String.hpp" + #include "../Context.h" + #include "../PlatformEnvironment.h" + #include "../core/Console.hpp" + #include "../core/File.h" + #include "../core/Guard.hpp" + #include "../core/Json.hpp" + #include "../core/Path.hpp" + #include "../core/String.hpp" -# include + #include using namespace OpenRCT2; diff --git a/src/openrct2/network/ServerList.cpp b/src/openrct2/network/ServerList.cpp index 5ee748bad0..5d35cfba2a 100644 --- a/src/openrct2/network/ServerList.cpp +++ b/src/openrct2/network/ServerList.cpp @@ -9,27 +9,27 @@ #ifndef DISABLE_NETWORK -# include "ServerList.h" + #include "ServerList.h" -# include "../Context.h" -# include "../Diagnostic.h" -# include "../PlatformEnvironment.h" -# include "../config/Config.h" -# include "../core/File.h" -# include "../core/FileStream.h" -# include "../core/Guard.hpp" -# include "../core/Http.h" -# include "../core/Json.hpp" -# include "../core/Memory.hpp" -# include "../core/Path.hpp" -# include "../core/String.hpp" -# include "../localisation/Language.h" -# include "../platform/Platform.h" -# include "Socket.h" -# include "network.h" + #include "../Context.h" + #include "../Diagnostic.h" + #include "../PlatformEnvironment.h" + #include "../config/Config.h" + #include "../core/File.h" + #include "../core/FileStream.h" + #include "../core/Guard.hpp" + #include "../core/Http.h" + #include "../core/Json.hpp" + #include "../core/Memory.hpp" + #include "../core/Path.hpp" + #include "../core/String.hpp" + #include "../localisation/Language.h" + #include "../platform/Platform.h" + #include "Socket.h" + #include "network.h" -# include -# include + #include + #include using namespace OpenRCT2; @@ -354,9 +354,9 @@ std::future> ServerList::FetchLocalServerListAsync( std::future> ServerList::FetchOnlineServerListAsync() const { -# ifdef DISABLE_HTTP + #ifdef DISABLE_HTTP return {}; -# else + #else auto p = std::make_shared>>(); auto f = p->get_future(); @@ -423,7 +423,7 @@ std::future> ServerList::FetchOnlineServerListAsync } }); return f; -# endif + #endif } uint32_t ServerList::GetTotalPlayerCount() const diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index 56a1f7db1b..68567f6c71 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -9,15 +9,15 @@ #ifndef DISABLE_NETWORK -# include "../Diagnostic.h" + #include "../Diagnostic.h" -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include // clang-format off // MSVC: include here otherwise PI gets defined twice @@ -71,12 +71,12 @@ #endif // _WIN32 // clang-format on -# include "Socket.h" + #include "Socket.h" constexpr auto kConnectTimeout = std::chrono::milliseconds(3000); -// RAII WSA initialisation needed for Windows -# ifdef _WIN32 + // RAII WSA initialisation needed for Windows + #ifdef _WIN32 class WSA { private: @@ -120,12 +120,12 @@ static bool InitialiseWSA() static WSA wsa; return wsa.Initialise(); } -# else + #else static bool InitialiseWSA() { return true; } -# endif + #endif class SocketException : public std::runtime_error { @@ -198,13 +198,13 @@ protected: static bool SetNonBlocking(SOCKET socket, bool on) { -# ifdef _WIN32 + #ifdef _WIN32 u_long nonBlocking = on; return ioctlsocket(socket, FIONBIO, &nonBlocking) == 0; -# else + #else int32_t flags = fcntl(socket, F_GETFL, 0); return fcntl(socket, F_SETFL, on ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK)) == 0; -# endif + #endif } static bool SetOption(SOCKET socket, int32_t a, int32_t b, bool value) @@ -471,10 +471,10 @@ public: fd_set writeFD; FD_ZERO(&writeFD); -# pragma warning(push) -# pragma warning(disable : 4548) // expression before comma has no effect; expected expression with side-effect + #pragma warning(push) + #pragma warning(disable : 4548) // expression before comma has no effect; expected expression with side-effect FD_SET(_socket, &writeFD); -# pragma warning(pop) + #pragma warning(pop) timeval timeout{}; timeout.tv_sec = 0; timeout.tv_usec = 0; @@ -591,7 +591,7 @@ public: if (readBytes == SOCKET_ERROR) { *sizeReceived = 0; -# ifndef _WIN32 + #ifndef _WIN32 // Removing the check for EAGAIN and instead relying on the values being the same allows turning on of // -Wlogical-op warning. // This is not true on Windows, see: @@ -602,7 +602,7 @@ public: EWOULDBLOCK == EAGAIN, "Portability note: your system has different values for EWOULDBLOCK " "and EAGAIN, please extend the condition below"); -# endif // _WIN32 + #endif // _WIN32 if (LAST_SOCKET_ERROR() != EWOULDBLOCK) { return NetworkReadPacket::Disconnected; @@ -876,7 +876,7 @@ std::unique_ptr CreateUdpSocket() return std::make_unique(); } -# ifdef _WIN32 + #ifdef _WIN32 static std::vector GetNetworkInterfaces() { InitialiseWSA(); @@ -913,12 +913,12 @@ static std::vector GetNetworkInterfaces() interfaces.shrink_to_fit(); return interfaces; } -# endif + #endif std::vector> GetBroadcastAddresses() { std::vector> baddresses; -# ifdef _WIN32 + #ifdef _WIN32 auto interfaces = GetNetworkInterfaces(); for (const auto& ifo : interfaces) { @@ -935,7 +935,7 @@ std::vector> GetBroadcastAddresses() baddresses.push_back(std::make_unique( reinterpret_cast(&address), static_cast(sizeof(sockaddr)))); } -# else + #else int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { @@ -966,12 +966,12 @@ std::vector> GetBroadcastAddresses() } } p += sizeof(ifreq); -# if defined(AF_LINK) && !defined(SUNOS) + #if defined(AF_LINK) && !defined(SUNOS) p += req->ifr_addr.sa_len - sizeof(struct sockaddr); -# endif + #endif } close(sock); -# endif + #endif return baddresses; } diff --git a/src/openrct2/object/Object.cpp b/src/openrct2/object/Object.cpp index d3b0be75d9..f453a144af 100644 --- a/src/openrct2/object/Object.cpp +++ b/src/openrct2/object/Object.cpp @@ -193,8 +193,8 @@ void Object::SetSourceGames(const std::vector& sourceGames) } #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" #endif std::string Object::GetName() const @@ -426,5 +426,5 @@ ObjectVersion VersionTuple(std::string_view version) } #ifdef __WARN_SUGGEST_FINAL_METHODS__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif diff --git a/src/openrct2/object/Object.h b/src/openrct2/object/Object.h index ed2005bac9..9049357407 100644 --- a/src/openrct2/object/Object.h +++ b/src/openrct2/object/Object.h @@ -179,9 +179,9 @@ struct IReadObjectContext }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wsuggest-final-types" -# pragma GCC diagnostic ignored "-Wsuggest-final-methods" + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wsuggest-final-types" + #pragma GCC diagnostic ignored "-Wsuggest-final-methods" #endif class Object { @@ -336,7 +336,7 @@ public: void UnloadImages(); }; #ifdef __WARN_SUGGEST_FINAL_TYPES__ -# pragma GCC diagnostic pop + #pragma GCC diagnostic pop #endif int32_t ObjectCalculateChecksum(const RCTObjectEntry* entry, const void* data, size_t dataLength); diff --git a/src/openrct2/platform/Crash.cpp b/src/openrct2/platform/Crash.cpp index 5e64f16e56..de7a7adf5e 100644 --- a/src/openrct2/platform/Crash.cpp +++ b/src/openrct2/platform/Crash.cpp @@ -10,54 +10,54 @@ #include "Crash.h" #ifdef USE_BREAKPAD -# include -# include -# include -# include + #include + #include + #include + #include -# if defined(_WIN32) -# include -# include -# include -# include -# else -# error Breakpad support not implemented yet for this platform -# endif + #if defined(_WIN32) + #include + #include + #include + #include + #else + #error Breakpad support not implemented yet for this platform + #endif -# include "../Context.h" -# include "../Game.h" -# include "../GameState.h" -# include "../OpenRCT2.h" -# include "../PlatformEnvironment.h" -# include "../Version.h" -# include "../config/Config.h" -# include "../core/Compression.h" -# include "../core/Console.hpp" -# include "../core/Guard.hpp" -# include "../core/Path.hpp" -# include "../core/SawyerCoding.h" -# include "../core/String.hpp" -# include "../drawing/IDrawingEngine.h" -# include "../interface/Screenshot.h" -# include "../localisation/Language.h" -# include "../object/ObjectManager.h" -# include "../park/ParkFile.h" -# include "../scenario/Scenario.h" -# include "Platform.h" + #include "../Context.h" + #include "../Game.h" + #include "../GameState.h" + #include "../OpenRCT2.h" + #include "../PlatformEnvironment.h" + #include "../Version.h" + #include "../config/Config.h" + #include "../core/Compression.h" + #include "../core/Console.hpp" + #include "../core/Guard.hpp" + #include "../core/Path.hpp" + #include "../core/SawyerCoding.h" + #include "../core/String.hpp" + #include "../drawing/IDrawingEngine.h" + #include "../interface/Screenshot.h" + #include "../localisation/Language.h" + #include "../object/ObjectManager.h" + #include "../park/ParkFile.h" + #include "../scenario/Scenario.h" + #include "Platform.h" -# define WSZ(x) L"" x + #define WSZ(x) L"" x -# ifdef OPENRCT2_COMMIT_SHA1_SHORT + #ifdef OPENRCT2_COMMIT_SHA1_SHORT static const wchar_t* _wszCommitSha1Short = WSZ(OPENRCT2_COMMIT_SHA1_SHORT); -# else + #else static const wchar_t* _wszCommitSha1Short = WSZ(""); -# endif + #endif // OPENRCT2_ARCHITECTURE is required to be defined in version.h static const wchar_t* _wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE); static std::map _uploadFiles; -# define BACKTRACE_TOKEN "1a9becc5de031b0a24ecad5222d2b42820c3710863a0f1dba6ab378b02ca659a" + #define BACKTRACE_TOKEN "1a9becc5de031b0a24ecad5222d2b42820c3710863a0f1dba6ab378b02ca659a" using namespace OpenRCT2; diff --git a/src/openrct2/platform/Platform.Android.cpp b/src/openrct2/platform/Platform.Android.cpp index b011e4db98..9a48128ff1 100644 --- a/src/openrct2/platform/Platform.Android.cpp +++ b/src/openrct2/platform/Platform.Android.cpp @@ -9,15 +9,15 @@ #ifdef __ANDROID__ -# include "Platform.h" + #include "Platform.h" -# include "../Diagnostic.h" -# include "../core/Guard.hpp" -# include "../localisation/Language.h" + #include "../Diagnostic.h" + #include "../core/Guard.hpp" + #include "../localisation/Language.h" -# include -# include -# include + #include + #include + #include AndroidClassLoader::~AndroidClassLoader() { @@ -162,13 +162,13 @@ namespace OpenRCT2::Platform return {}; } -# ifndef NO_TTF + #ifndef NO_TTF std::string GetFontPath(const TTFFontDescriptor& font) { STUB(); return {}; } -# endif + #endif float GetDefaultScale() { diff --git a/src/openrct2/platform/Platform.Common.cpp b/src/openrct2/platform/Platform.Common.cpp index 02e7f389da..42d00311fc 100644 --- a/src/openrct2/platform/Platform.Common.cpp +++ b/src/openrct2/platform/Platform.Common.cpp @@ -10,19 +10,19 @@ #include "../Date.h" #ifdef _WIN32 -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include #endif #if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) -# include -# define OpenRCT2_CPUID_GNUC_X86 + #include + #define OpenRCT2_CPUID_GNUC_X86 #elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_X64) || defined(_M_IX86)) // VS2008 -# include -# include -# define OpenRCT2_CPUID_MSVC_X86 + #include + #include + #define OpenRCT2_CPUID_MSVC_X86 #endif #include "../Context.h" @@ -149,15 +149,15 @@ namespace OpenRCT2::Platform #ifdef OPENRCT2_X86 static bool CPUIDX86(uint32_t* cpuid_outdata, int32_t eax) { -# if defined(OpenRCT2_CPUID_GNUC_X86) + #if defined(OpenRCT2_CPUID_GNUC_X86) int ret = __get_cpuid(eax, &cpuid_outdata[0], &cpuid_outdata[1], &cpuid_outdata[2], &cpuid_outdata[3]); return ret == 1; -# elif defined(OpenRCT2_CPUID_MSVC_X86) + #elif defined(OpenRCT2_CPUID_MSVC_X86) __cpuid(reinterpret_cast(cpuid_outdata), static_cast(eax)); return true; -# else + #else return false; -# endif + #endif } #endif // OPENRCT2_X86 @@ -181,9 +181,9 @@ namespace OpenRCT2::Platform // https://github.com/gcc-mirror/gcc/commit/132fa33ce998df69a9f793d63785785f4b93e6f1 // which causes it to ignore subleafs, but the new function is unavailable on // Ubuntu 18.04's toolchains. -# if defined(OpenRCT2_CPUID_GNUC_X86) && (!defined(__FreeBSD__) || (__FreeBSD__ > 10)) + #if defined(OpenRCT2_CPUID_GNUC_X86) && (!defined(__FreeBSD__) || (__FreeBSD__ > 10)) return __builtin_cpu_supports("avx2"); -# else + #else // AVX2 support is declared as the 5th bit of EBX with CPUID(EAX = 7, ECX = 0). uint32_t regs[4] = { 0 }; if (CPUIDX86(regs, 7)) @@ -198,7 +198,7 @@ namespace OpenRCT2::Platform } return avxCPUSupport; } -# endif + #endif #endif return false; } diff --git a/src/openrct2/platform/Platform.Linux.cpp b/src/openrct2/platform/Platform.Linux.cpp index 1cfcaf45d6..f58fa97a46 100644 --- a/src/openrct2/platform/Platform.Linux.cpp +++ b/src/openrct2/platform/Platform.Linux.cpp @@ -9,33 +9,33 @@ #if defined(__unix__) && !defined(__ANDROID__) && !defined(__APPLE__) -# include "../Diagnostic.h" + #include "../Diagnostic.h" -# include -# include -# include -# include -# include -# include -# include -# if defined(__FreeBSD__) || defined(__NetBSD__) -# include -# include -# include -# endif // __FreeBSD__ || __NetBSD__ -# if defined(__linux__) -// for PATH_MAX -# include -# endif // __linux__ -# ifndef NO_TTF -# include -# endif // NO_TTF + #include + #include + #include + #include + #include + #include + #include + #if defined(__FreeBSD__) || defined(__NetBSD__) + #include + #include + #include + #endif // __FreeBSD__ || __NetBSD__ + #if defined(__linux__) + // for PATH_MAX + #include + #endif // __linux__ + #ifndef NO_TTF + #include + #endif // NO_TTF -# include "../Date.h" -# include "../OpenRCT2.h" -# include "../core/Path.hpp" -# include "../localisation/Language.h" -# include "Platform.h" + #include "../Date.h" + #include "../OpenRCT2.h" + #include "../core/Path.hpp" + #include "../localisation/Language.h" + #include "Platform.h" namespace OpenRCT2::Platform { @@ -131,40 +131,40 @@ namespace OpenRCT2::Platform std::string GetCurrentExecutablePath() { char exePath[PATH_MAX] = { 0 }; -# ifdef __linux__ + #ifdef __linux__ auto bytesRead = readlink("/proc/self/exe", exePath, sizeof(exePath)); if (bytesRead == -1) { LOG_FATAL("failed to read /proc/self/exe"); } -# elif defined(__FreeBSD__) || defined(__NetBSD__) -# if defined(__FreeBSD__) + #elif defined(__FreeBSD__) || defined(__NetBSD__) + #if defined(__FreeBSD__) const int32_t mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1, }; -# else + #else const int32_t mib[] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME, }; -# endif + #endif auto exeLen = sizeof(exePath); if (sysctl(mib, 4, exePath, &exeLen, nullptr, 0) == -1) { LOG_FATAL("failed to get process path"); } -# elif defined(__OpenBSD__) + #elif defined(__OpenBSD__) // There is no way to get the path name of a running executable. // If you are not using the port or package, you may have to change this line! strlcpy(exePath, "/usr/local/bin/", sizeof(exePath)); -# else -# error "Platform does not support full path exe retrieval" -# endif + #else + #error "Platform does not support full path exe retrieval" + #endif return exePath; } @@ -259,12 +259,12 @@ namespace OpenRCT2::Platform MeasurementFormat GetLocaleMeasurementFormat() { -// LC_MEASUREMENT is GNU specific. -# ifdef LC_MEASUREMENT + // LC_MEASUREMENT is GNU specific. + #ifdef LC_MEASUREMENT const char* langstring = setlocale(LC_MEASUREMENT, ""); -# else + #else const char* langstring = setlocale(LC_ALL, ""); -# endif + #endif if (langstring != nullptr) { @@ -349,7 +349,7 @@ namespace OpenRCT2::Platform }; } -# ifndef NO_TTF + #ifndef NO_TTF std::string GetFontPath(const TTFFontDescriptor& font) { LOG_VERBOSE("Looking for font %s with FontConfig.", font.font_name); @@ -406,7 +406,7 @@ namespace OpenRCT2::Platform FcFini(); return path; } -# endif // NO_TTF + #endif // NO_TTF } // namespace OpenRCT2::Platform #endif diff --git a/src/openrct2/platform/Platform.Posix.cpp b/src/openrct2/platform/Platform.Posix.cpp index f56fc144bd..55a91fd8af 100644 --- a/src/openrct2/platform/Platform.Posix.cpp +++ b/src/openrct2/platform/Platform.Posix.cpp @@ -9,27 +9,27 @@ #if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) -# include "Platform.h" + #include "Platform.h" -# include "../Date.h" -# include "../Diagnostic.h" -# include "../core/Memory.hpp" -# include "../core/Path.hpp" -# include "../core/String.hpp" + #include "../Date.h" + #include "../Diagnostic.h" + #include "../core/Memory.hpp" + #include "../core/Path.hpp" + #include "../core/String.hpp" -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include // The name of the mutex used to prevent multiple instances of the game from running static constexpr const utf8* SINGLE_INSTANCE_MUTEX_NAME = u8"openrct2.lock"; @@ -118,7 +118,7 @@ namespace OpenRCT2::Platform int32_t Execute(std::string_view command, std::string* output) { -# ifndef __EMSCRIPTEN__ + #ifndef __EMSCRIPTEN__ LOG_VERBOSE("executing \"%s\"...", std::string(command).c_str()); FILE* fpipe = popen(std::string(command).c_str(), "r"); if (fpipe == nullptr) @@ -160,10 +160,10 @@ namespace OpenRCT2::Platform // Return exit code return pclose(fpipe); -# else + #else LOG_WARNING("Emscripten cannot execute processes. The commandline was '%s'.", command.c_str()); return -1; -# endif // __EMSCRIPTEN__ + #endif // __EMSCRIPTEN__ } uint64_t GetLastModified(std::string_view path) @@ -279,12 +279,12 @@ namespace OpenRCT2::Platform TemperatureUnit GetLocaleTemperatureFormat() { -// LC_MEASUREMENT is GNU specific. -# ifdef LC_MEASUREMENT + // LC_MEASUREMENT is GNU specific. + #ifdef LC_MEASUREMENT const char* langstring = setlocale(LC_MEASUREMENT, ""); -# else + #else const char* langstring = setlocale(LC_ALL, ""); -# endif + #endif if (langstring != nullptr) { @@ -299,11 +299,11 @@ namespace OpenRCT2::Platform bool ProcessIsElevated() { -# ifndef __EMSCRIPTEN__ + #ifndef __EMSCRIPTEN__ return (geteuid() == 0); -# else + #else return false; -# endif // __EMSCRIPTEN__ + #endif // __EMSCRIPTEN__ } bool LockSingleInstance() diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index 905d21cf7a..859ebfc669 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -9,48 +9,48 @@ #ifdef _WIN32 -// Windows.h needs to be included first -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include "../Diagnostic.h" + // Windows.h needs to be included first + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include "../Diagnostic.h" -# include -# include + #include + #include -// Then the rest -# include "../Version.h" + // Then the rest + #include "../Version.h" -# include -# include -# include -# include -# undef GetEnvironmentVariable + #include + #include + #include + #include + #undef GetEnvironmentVariable -# include "../Date.h" -# include "../OpenRCT2.h" -# include "../core/Path.hpp" -# include "../core/String.hpp" -# include "../localisation/Language.h" -# include "../localisation/Localisation.Date.h" -# include "Platform.h" + #include "../Date.h" + #include "../OpenRCT2.h" + #include "../core/Path.hpp" + #include "../core/String.hpp" + #include "../localisation/Language.h" + #include "../localisation/Localisation.Date.h" + #include "Platform.h" -# include -# include -# include + #include + #include + #include -// Native resource IDs -# include "../../../resources/resource.h" + // Native resource IDs + #include "../../../resources/resource.h" -// Enable visual styles -# pragma comment( \ + // Enable visual styles + #pragma comment( \ linker, \ "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") // The name of the mutex used to prevent multiple instances of the game from running static constexpr wchar_t SINGLE_INSTANCE_MUTEX_NAME[] = L"RollerCoaster Tycoon 2_GSKMUTEX"; -# define SOFTWARE_CLASSES L"Software\\Classes" -# define MUI_CACHE L"Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache" + #define SOFTWARE_CLASSES L"Software\\Classes" + #define MUI_CACHE L"Local Settings\\Software\\Microsoft\\Windows\\Shell\\MuiCache" namespace OpenRCT2::Platform { @@ -215,14 +215,14 @@ namespace OpenRCT2::Platform if (hModule != nullptr) { using RtlGetVersionPtr = long(WINAPI*)(PRTL_OSVERSIONINFOW); -# if defined(__GNUC__) && __GNUC__ >= 8 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wcast-function-type" -# endif + #if defined(__GNUC__) && __GNUC__ >= 8 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-function-type" + #endif auto fn = reinterpret_cast(GetProcAddress(hModule, "RtlGetVersion")); -# if defined(__GNUC__) && __GNUC__ >= 8 -# pragma GCC diagnostic pop -# endif + #if defined(__GNUC__) && __GNUC__ >= 8 + #pragma GCC diagnostic pop + #endif if (fn != nullptr) { RTL_OSVERSIONINFOW rovi{}; diff --git a/src/openrct2/platform/Platform.h b/src/openrct2/platform/Platform.h index 5530eda866..dde5053f9b 100644 --- a/src/openrct2/platform/Platform.h +++ b/src/openrct2/platform/Platform.h @@ -17,18 +17,18 @@ #include #ifdef _WIN32 -# define PATH_SEPARATOR u8"\\" -# define PLATFORM_NEWLINE u8"\r\n" + #define PATH_SEPARATOR u8"\\" + #define PLATFORM_NEWLINE u8"\r\n" #else -# define PATH_SEPARATOR u8"/" -# define PLATFORM_NEWLINE u8"\n" + #define PATH_SEPARATOR u8"/" + #define PLATFORM_NEWLINE u8"\n" #endif #ifdef __ANDROID__ -# include + #include #endif // __ANDROID__ #ifndef MAX_PATH -# define MAX_PATH 260 + #define MAX_PATH 260 #endif enum class SPECIAL_FOLDER diff --git a/src/openrct2/profiling/ProfilingMacros.hpp b/src/openrct2/profiling/ProfilingMacros.hpp index de06c28045..3712be0e46 100644 --- a/src/openrct2/profiling/ProfilingMacros.hpp +++ b/src/openrct2/profiling/ProfilingMacros.hpp @@ -11,11 +11,11 @@ namespace OpenRCT2::Profiling { #if defined(__clang__) || defined(__GNUC__) -# define PROFILING_FUNC_NAME __PRETTY_FUNCTION__ + #define PROFILING_FUNC_NAME __PRETTY_FUNCTION__ #elif defined(_MSC_VER) -# define PROFILING_FUNC_NAME __FUNCSIG__ + #define PROFILING_FUNC_NAME __FUNCSIG__ #else -# error "Unsupported compiler" + #error "Unsupported compiler" #endif #define PROFILED_FUNCTION_NAME(func) \ @@ -30,10 +30,10 @@ namespace OpenRCT2::Profiling #if defined(__clang_major__) && __clang_major__ <= 5 // Clang 5 crashes using the profiler, we need to disable it. -# define PROFILED_FUNCTION() + #define PROFILED_FUNCTION() #else -# define PROFILED_FUNCTION() \ + #define PROFILED_FUNCTION() \ PROFILED_FUNCTION_NAME(PROFILING_FUNC_NAME) \ static auto& _profiling_func = ::OpenRCT2::Profiling::Detail::Storage::Data; \ ::OpenRCT2::Profiling::ScopedProfiling _profiling_scope(_profiling_func); diff --git a/src/openrct2/rct12/ScenarioPatcher.cpp b/src/openrct2/rct12/ScenarioPatcher.cpp index 0f05fdcc6c..359d6eba8b 100644 --- a/src/openrct2/rct12/ScenarioPatcher.cpp +++ b/src/openrct2/rct12/ScenarioPatcher.cpp @@ -33,9 +33,9 @@ #include "../world/tile_element/TrackElement.h" #ifdef DISABLE_NETWORK -# include + #include #else -# include "../core/Crypt.h" + #include "../core/Crypt.h" #endif #include diff --git a/src/openrct2/scripting/Duktape.hpp b/src/openrct2/scripting/Duktape.hpp index 8619683f80..dfcccfd85f 100644 --- a/src/openrct2/scripting/Duktape.hpp +++ b/src/openrct2/scripting/Duktape.hpp @@ -11,16 +11,16 @@ #ifdef ENABLE_SCRIPTING -# include "../core/Console.hpp" -# include "../core/EnumMap.hpp" -# include "../ride/Vehicle.h" -# include "../world/Map.h" + #include "../core/Console.hpp" + #include "../core/EnumMap.hpp" + #include "../ride/Vehicle.h" + #include "../world/Map.h" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/HookEngine.cpp b/src/openrct2/scripting/HookEngine.cpp index 77ead25f9b..0b6d74f3fd 100644 --- a/src/openrct2/scripting/HookEngine.cpp +++ b/src/openrct2/scripting/HookEngine.cpp @@ -9,12 +9,12 @@ #ifdef ENABLE_SCRIPTING -# include "HookEngine.h" + #include "HookEngine.h" -# include "../core/EnumMap.hpp" -# include "ScriptEngine.h" + #include "../core/EnumMap.hpp" + #include "ScriptEngine.h" -# include + #include using namespace OpenRCT2::Scripting; diff --git a/src/openrct2/scripting/HookEngine.h b/src/openrct2/scripting/HookEngine.h index 839691aedb..550af6e85a 100644 --- a/src/openrct2/scripting/HookEngine.h +++ b/src/openrct2/scripting/HookEngine.h @@ -11,13 +11,13 @@ #ifdef ENABLE_SCRIPTING -# include "Duktape.hpp" + #include "Duktape.hpp" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/Plugin.cpp b/src/openrct2/scripting/Plugin.cpp index 7a6d7efa69..a54e60ead2 100644 --- a/src/openrct2/scripting/Plugin.cpp +++ b/src/openrct2/scripting/Plugin.cpp @@ -9,16 +9,16 @@ #ifdef ENABLE_SCRIPTING -# include "Plugin.h" + #include "Plugin.h" -# include "../Diagnostic.h" -# include "../OpenRCT2.h" -# include "../core/File.h" -# include "Duktape.hpp" -# include "ScriptEngine.h" + #include "../Diagnostic.h" + #include "../OpenRCT2.h" + #include "../core/File.h" + #include "Duktape.hpp" + #include "ScriptEngine.h" -# include -# include + #include + #include using namespace OpenRCT2::Scripting; @@ -122,15 +122,15 @@ void Plugin::ThrowIfStopping() const void Plugin::Unload() { -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105937, fixed in GCC13 -# if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" -# endif + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105937, fixed in GCC13 + #if defined(__GNUC__) && !defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + #endif _metadata.Main = {}; -# if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic pop -# endif + #if defined(__GNUC__) && !defined(__clang__) + #pragma GCC diagnostic pop + #endif _hasLoaded = false; } diff --git a/src/openrct2/scripting/Plugin.h b/src/openrct2/scripting/Plugin.h index 2d6df869c6..8b91b08d82 100644 --- a/src/openrct2/scripting/Plugin.h +++ b/src/openrct2/scripting/Plugin.h @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "Duktape.hpp" + #include "Duktape.hpp" -# include -# include -# include -# include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index c73223c9a0..b678ee3ff2 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -9,61 +9,61 @@ #ifdef ENABLE_SCRIPTING -# include "ScriptEngine.h" + #include "ScriptEngine.h" -# include "../PlatformEnvironment.h" -# include "../actions/BannerPlaceAction.h" -# include "../actions/CustomAction.h" -# include "../actions/GameAction.h" -# include "../actions/LargeSceneryPlaceAction.h" -# include "../actions/RideCreateAction.h" -# include "../actions/StaffHireNewAction.h" -# include "../actions/WallPlaceAction.h" -# include "../config/Config.h" -# include "../core/EnumMap.hpp" -# include "../core/File.h" -# include "../core/FileScanner.h" -# include "../core/Path.hpp" -# include "../interface/InteractiveConsole.h" -# include "../platform/Platform.h" -# include "Duktape.hpp" -# include "bindings/entity/ScEntity.hpp" -# include "bindings/entity/ScGuest.hpp" -# include "bindings/entity/ScLitter.hpp" -# include "bindings/entity/ScParticle.hpp" -# include "bindings/entity/ScPeep.hpp" -# include "bindings/entity/ScStaff.hpp" -# include "bindings/entity/ScVehicle.hpp" -# include "bindings/game/ScCheats.hpp" -# include "bindings/game/ScConsole.hpp" -# include "bindings/game/ScContext.hpp" -# include "bindings/game/ScDisposable.hpp" -# include "bindings/game/ScPlugin.hpp" -# include "bindings/game/ScProfiler.hpp" -# include "bindings/network/ScNetwork.hpp" -# include "bindings/network/ScPlayer.hpp" -# include "bindings/network/ScPlayerGroup.hpp" -# include "bindings/network/ScSocket.hpp" -# include "bindings/object/ScInstalledObject.hpp" -# include "bindings/object/ScObject.hpp" -# include "bindings/object/ScObjectManager.h" -# include "bindings/ride/ScRide.hpp" -# include "bindings/ride/ScRideStation.hpp" -# include "bindings/world/ScClimate.hpp" -# include "bindings/world/ScDate.hpp" -# include "bindings/world/ScMap.hpp" -# include "bindings/world/ScPark.hpp" -# include "bindings/world/ScParkMessage.hpp" -# include "bindings/world/ScResearch.hpp" -# include "bindings/world/ScScenario.hpp" -# include "bindings/world/ScTile.hpp" -# include "bindings/world/ScTileElement.hpp" + #include "../PlatformEnvironment.h" + #include "../actions/BannerPlaceAction.h" + #include "../actions/CustomAction.h" + #include "../actions/GameAction.h" + #include "../actions/LargeSceneryPlaceAction.h" + #include "../actions/RideCreateAction.h" + #include "../actions/StaffHireNewAction.h" + #include "../actions/WallPlaceAction.h" + #include "../config/Config.h" + #include "../core/EnumMap.hpp" + #include "../core/File.h" + #include "../core/FileScanner.h" + #include "../core/Path.hpp" + #include "../interface/InteractiveConsole.h" + #include "../platform/Platform.h" + #include "Duktape.hpp" + #include "bindings/entity/ScEntity.hpp" + #include "bindings/entity/ScGuest.hpp" + #include "bindings/entity/ScLitter.hpp" + #include "bindings/entity/ScParticle.hpp" + #include "bindings/entity/ScPeep.hpp" + #include "bindings/entity/ScStaff.hpp" + #include "bindings/entity/ScVehicle.hpp" + #include "bindings/game/ScCheats.hpp" + #include "bindings/game/ScConsole.hpp" + #include "bindings/game/ScContext.hpp" + #include "bindings/game/ScDisposable.hpp" + #include "bindings/game/ScPlugin.hpp" + #include "bindings/game/ScProfiler.hpp" + #include "bindings/network/ScNetwork.hpp" + #include "bindings/network/ScPlayer.hpp" + #include "bindings/network/ScPlayerGroup.hpp" + #include "bindings/network/ScSocket.hpp" + #include "bindings/object/ScInstalledObject.hpp" + #include "bindings/object/ScObject.hpp" + #include "bindings/object/ScObjectManager.h" + #include "bindings/ride/ScRide.hpp" + #include "bindings/ride/ScRideStation.hpp" + #include "bindings/world/ScClimate.hpp" + #include "bindings/world/ScDate.hpp" + #include "bindings/world/ScMap.hpp" + #include "bindings/world/ScPark.hpp" + #include "bindings/world/ScParkMessage.hpp" + #include "bindings/world/ScResearch.hpp" + #include "bindings/world/ScScenario.hpp" + #include "bindings/world/ScTile.hpp" + #include "bindings/world/ScTileElement.hpp" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include using namespace OpenRCT2; using namespace OpenRCT2::Scripting; @@ -443,10 +443,10 @@ void ScriptEngine::Initialise() ScPeep::Register(ctx); ScGuest::Register(ctx); ScThought::Register(ctx); -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK ScSocket::Register(ctx); ScListener::Register(ctx); -# endif + #endif ScScenario::Register(ctx); ScScenarioObjective::Register(ctx); ScPatrolArea::Register(ctx); @@ -1749,16 +1749,16 @@ void ScriptEngine::RemoveIntervals(const std::shared_ptr& plugin) } } -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK void ScriptEngine::AddSocket(const std::shared_ptr& socket) { _sockets.push_back(socket); } -# endif + #endif void ScriptEngine::UpdateSockets() { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK // Use simple for i loop as Update calls can modify the list auto it = _sockets.begin(); while (it != _sockets.end()) @@ -1774,12 +1774,12 @@ void ScriptEngine::UpdateSockets() it++; } } -# endif + #endif } void ScriptEngine::RemoveSockets(const std::shared_ptr& plugin) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto it = _sockets.begin(); while (it != _sockets.end()) { @@ -1794,7 +1794,7 @@ void ScriptEngine::RemoveSockets(const std::shared_ptr& plugin) it++; } } -# endif + #endif } std::string OpenRCT2::Scripting::Stringify(const DukValue& val) diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index 9993840364..e05f1c2fa5 100644 --- a/src/openrct2/scripting/ScriptEngine.h +++ b/src/openrct2/scripting/ScriptEngine.h @@ -11,22 +11,22 @@ #ifdef ENABLE_SCRIPTING -# include "../actions/CustomAction.h" -# include "../core/FileWatcher.h" -# include "../management/Finance.h" -# include "../world/Location.hpp" -# include "HookEngine.h" -# include "Plugin.h" + #include "../actions/CustomAction.h" + #include "../core/FileWatcher.h" + #include "../management/Finance.h" + #include "../world/Location.hpp" + #include "HookEngine.h" + #include "Plugin.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include + #include + #include + #include + #include struct duk_hthread; typedef struct duk_hthread duk_context; @@ -54,9 +54,9 @@ namespace OpenRCT2::Scripting static constexpr int32_t API_VERSION_68_CUSTOM_ACTION_ARGS = 68; static constexpr int32_t API_VERSION_77_NETWORK_IDS = 77; -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK class ScSocketBase; -# endif + #endif class ScriptExecutionInfo { @@ -173,9 +173,9 @@ namespace OpenRCT2::Scripting }; std::unordered_map _customActions; -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK std::list> _sockets; -# endif + #endif public: ScriptEngine(InteractiveConsole& console, IPlatformEnvironment& env); @@ -264,9 +264,9 @@ namespace OpenRCT2::Scripting static std::string_view ExpenditureTypeToString(ExpenditureType expenditureType); static ExpenditureType StringToExpenditureType(std::string_view expenditureType); -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK void AddSocket(const std::shared_ptr& socket); -# endif + #endif private: void RegisterConstants(); diff --git a/src/openrct2/scripting/bindings/entity/ScEntity.hpp b/src/openrct2/scripting/bindings/entity/ScEntity.hpp index 1f5010d436..2126a52842 100644 --- a/src/openrct2/scripting/bindings/entity/ScEntity.hpp +++ b/src/openrct2/scripting/bindings/entity/ScEntity.hpp @@ -11,16 +11,16 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../entity/EntityList.h" -# include "../../../entity/EntityRegistry.h" -# include "../../../entity/Peep.h" -# include "../../../util/Util.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../entity/EntityList.h" + #include "../../../entity/EntityRegistry.h" + #include "../../../entity/Peep.h" + #include "../../../util/Util.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" -# include -# include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/entity/ScGuest.cpp b/src/openrct2/scripting/bindings/entity/ScGuest.cpp index adffa367b3..fec22eebc9 100644 --- a/src/openrct2/scripting/bindings/entity/ScGuest.cpp +++ b/src/openrct2/scripting/bindings/entity/ScGuest.cpp @@ -9,13 +9,13 @@ #ifdef ENABLE_SCRIPTING -# include "ScGuest.hpp" + #include "ScGuest.hpp" -# include "../../../GameState.h" -# include "../../../entity/Guest.h" -# include "../../../localisation/Formatting.h" -# include "../../../peep/PeepAnimationData.h" -# include "../../../ride/RideEntry.h" + #include "../../../GameState.h" + #include "../../../entity/Guest.h" + #include "../../../localisation/Formatting.h" + #include "../../../peep/PeepAnimationData.h" + #include "../../../ride/RideEntry.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/entity/ScGuest.hpp b/src/openrct2/scripting/bindings/entity/ScGuest.hpp index 02947955b1..69d36bcaf3 100644 --- a/src/openrct2/scripting/bindings/entity/ScGuest.hpp +++ b/src/openrct2/scripting/bindings/entity/ScGuest.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../../../entity/Guest.h" -# include "../../../management/Marketing.h" -# include "ScPeep.hpp" + #include "../../../entity/Guest.h" + #include "../../../management/Marketing.h" + #include "ScPeep.hpp" enum class PeepAnimationType : uint8_t; diff --git a/src/openrct2/scripting/bindings/entity/ScLitter.cpp b/src/openrct2/scripting/bindings/entity/ScLitter.cpp index 67177cdef5..d6cef1eecc 100644 --- a/src/openrct2/scripting/bindings/entity/ScLitter.cpp +++ b/src/openrct2/scripting/bindings/entity/ScLitter.cpp @@ -9,9 +9,9 @@ #ifdef ENABLE_SCRIPTING -# include "ScLitter.hpp" + #include "ScLitter.hpp" -# include "../../../entity/Litter.h" + #include "../../../entity/Litter.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/entity/ScLitter.hpp b/src/openrct2/scripting/bindings/entity/ScLitter.hpp index 6f83ae3d09..4cd837cf08 100644 --- a/src/openrct2/scripting/bindings/entity/ScLitter.hpp +++ b/src/openrct2/scripting/bindings/entity/ScLitter.hpp @@ -11,7 +11,7 @@ #ifdef ENABLE_SCRIPTING -# include "ScEntity.hpp" + #include "ScEntity.hpp" struct Litter; diff --git a/src/openrct2/scripting/bindings/entity/ScParticle.hpp b/src/openrct2/scripting/bindings/entity/ScParticle.hpp index 1dbdec41dc..2798e281d6 100644 --- a/src/openrct2/scripting/bindings/entity/ScParticle.hpp +++ b/src/openrct2/scripting/bindings/entity/ScParticle.hpp @@ -11,11 +11,11 @@ #ifdef ENABLE_SCRIPTING -# include "../../../entity/Particle.h" -# include "../../../world/Location.hpp" -# include "ScEntity.hpp" + #include "../../../entity/Particle.h" + #include "../../../world/Location.hpp" + #include "ScEntity.hpp" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/entity/ScPeep.hpp b/src/openrct2/scripting/bindings/entity/ScPeep.hpp index 8cc4d4287a..9846349944 100644 --- a/src/openrct2/scripting/bindings/entity/ScPeep.hpp +++ b/src/openrct2/scripting/bindings/entity/ScPeep.hpp @@ -11,7 +11,7 @@ #ifdef ENABLE_SCRIPTING -# include "ScEntity.hpp" + #include "ScEntity.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/entity/ScStaff.cpp b/src/openrct2/scripting/bindings/entity/ScStaff.cpp index 3f6b993ad5..8123de9f37 100644 --- a/src/openrct2/scripting/bindings/entity/ScStaff.cpp +++ b/src/openrct2/scripting/bindings/entity/ScStaff.cpp @@ -9,11 +9,11 @@ #ifdef ENABLE_SCRIPTING -# include "ScStaff.hpp" + #include "ScStaff.hpp" -# include "../../../entity/PatrolArea.h" -# include "../../../entity/Staff.h" -# include "../../../peep/PeepAnimationData.h" + #include "../../../entity/PatrolArea.h" + #include "../../../entity/Staff.h" + #include "../../../peep/PeepAnimationData.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/entity/ScStaff.hpp b/src/openrct2/scripting/bindings/entity/ScStaff.hpp index 112431e4a0..12bb57819f 100644 --- a/src/openrct2/scripting/bindings/entity/ScStaff.hpp +++ b/src/openrct2/scripting/bindings/entity/ScStaff.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "ScPeep.hpp" + #include "ScPeep.hpp" -# include + #include enum class PeepAnimationType : uint8_t; enum class StaffType : uint8_t; diff --git a/src/openrct2/scripting/bindings/entity/ScVehicle.hpp b/src/openrct2/scripting/bindings/entity/ScVehicle.hpp index 4837bf6cbe..7955a162a7 100644 --- a/src/openrct2/scripting/bindings/entity/ScVehicle.hpp +++ b/src/openrct2/scripting/bindings/entity/ScVehicle.hpp @@ -11,10 +11,10 @@ #ifdef ENABLE_SCRIPTING -# include "../../../ride/Ride.h" -# include "ScEntity.hpp" + #include "../../../ride/Ride.h" + #include "ScEntity.hpp" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/game/ScCheats.hpp b/src/openrct2/scripting/bindings/game/ScCheats.hpp index 4ba6849a8b..c69a41cb1c 100644 --- a/src/openrct2/scripting/bindings/game/ScCheats.hpp +++ b/src/openrct2/scripting/bindings/game/ScCheats.hpp @@ -11,10 +11,10 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Cheats.h" -# include "../../../GameState.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Cheats.h" + #include "../../../GameState.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/game/ScConfiguration.hpp b/src/openrct2/scripting/bindings/game/ScConfiguration.hpp index 452aa69094..699714a8e9 100644 --- a/src/openrct2/scripting/bindings/game/ScConfiguration.hpp +++ b/src/openrct2/scripting/bindings/game/ScConfiguration.hpp @@ -11,11 +11,11 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../config/Config.h" -# include "../../../localisation/LocalisationService.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../config/Config.h" + #include "../../../localisation/LocalisationService.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/game/ScConsole.hpp b/src/openrct2/scripting/bindings/game/ScConsole.hpp index d5d13468a5..88d18d8ddc 100644 --- a/src/openrct2/scripting/bindings/game/ScConsole.hpp +++ b/src/openrct2/scripting/bindings/game/ScConsole.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../../../interface/InteractiveConsole.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../interface/InteractiveConsole.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/game/ScContext.hpp b/src/openrct2/scripting/bindings/game/ScContext.hpp index 8760ea6373..e1a28cbc92 100644 --- a/src/openrct2/scripting/bindings/game/ScContext.hpp +++ b/src/openrct2/scripting/bindings/game/ScContext.hpp @@ -11,23 +11,23 @@ #ifdef ENABLE_SCRIPTING -# include "../../../OpenRCT2.h" -# include "../../../actions/GameAction.h" -# include "../../../interface/Screenshot.h" -# include "../../../localisation/Formatting.h" -# include "../../../object/ObjectManager.h" -# include "../../../scenario/Scenario.h" -# include "../../Duktape.hpp" -# include "../../HookEngine.h" -# include "../../IconNames.hpp" -# include "../../ScriptEngine.h" -# include "../game/ScConfiguration.hpp" -# include "../game/ScDisposable.hpp" -# include "../object/ScObjectManager.h" -# include "../ride/ScTrackSegment.h" + #include "../../../OpenRCT2.h" + #include "../../../actions/GameAction.h" + #include "../../../interface/Screenshot.h" + #include "../../../localisation/Formatting.h" + #include "../../../object/ObjectManager.h" + #include "../../../scenario/Scenario.h" + #include "../../Duktape.hpp" + #include "../../HookEngine.h" + #include "../../IconNames.hpp" + #include "../../ScriptEngine.h" + #include "../game/ScConfiguration.hpp" + #include "../game/ScDisposable.hpp" + #include "../object/ScObjectManager.h" + #include "../ride/ScTrackSegment.h" -# include -# include + #include + #include namespace OpenRCT2::Scripting { @@ -267,12 +267,12 @@ namespace OpenRCT2::Scripting return 1; } -# ifdef _MSC_VER + #ifdef _MSC_VER // HACK workaround to resolve issue #14853 // The exception thrown in duk_error was causing a crash when RAII kicked in for this lambda. // Only ensuring it was not in the same generated method fixed it. __declspec(noinline) -# endif + #endif std::shared_ptr CreateSubscription(HOOK_TYPE hookType, const DukValue& callback) { diff --git a/src/openrct2/scripting/bindings/game/ScDisposable.hpp b/src/openrct2/scripting/bindings/game/ScDisposable.hpp index 761d7b204f..79e976afa7 100644 --- a/src/openrct2/scripting/bindings/game/ScDisposable.hpp +++ b/src/openrct2/scripting/bindings/game/ScDisposable.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" + #include "../../Duktape.hpp" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/game/ScPlugin.hpp b/src/openrct2/scripting/bindings/game/ScPlugin.hpp index 0253b08e56..834f02472c 100644 --- a/src/openrct2/scripting/bindings/game/ScPlugin.hpp +++ b/src/openrct2/scripting/bindings/game/ScPlugin.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "../game/ScContext.hpp" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "../game/ScContext.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/game/ScProfiler.hpp b/src/openrct2/scripting/bindings/game/ScProfiler.hpp index 27843c12b4..67ab448e15 100644 --- a/src/openrct2/scripting/bindings/game/ScProfiler.hpp +++ b/src/openrct2/scripting/bindings/game/ScProfiler.hpp @@ -11,8 +11,8 @@ #ifdef ENABLE_SCRIPTING -# include "../../../profiling/Profiling.h" -# include "../../Duktape.hpp" + #include "../../../profiling/Profiling.h" + #include "../../Duktape.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/network/ScNetwork.cpp b/src/openrct2/scripting/bindings/network/ScNetwork.cpp index a3b1f08f5c..bc3ac9b55e 100644 --- a/src/openrct2/scripting/bindings/network/ScNetwork.cpp +++ b/src/openrct2/scripting/bindings/network/ScNetwork.cpp @@ -9,13 +9,13 @@ #ifdef ENABLE_SCRIPTING -# include "ScNetwork.hpp" + #include "ScNetwork.hpp" -# include "../../../Context.h" -# include "../../../actions/NetworkModifyGroupAction.h" -# include "../../../actions/PlayerKickAction.h" -# include "../../../network/NetworkAction.h" -# include "../../../network/network.h" + #include "../../../Context.h" + #include "../../../actions/NetworkModifyGroupAction.h" + #include "../../../actions/PlayerKickAction.h" + #include "../../../network/NetworkAction.h" + #include "../../../network/network.h" namespace OpenRCT2::Scripting { @@ -26,7 +26,7 @@ namespace OpenRCT2::Scripting std::string ScNetwork::mode_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK switch (NetworkGetMode()) { case NETWORK_MODE_SERVER: @@ -34,86 +34,86 @@ namespace OpenRCT2::Scripting case NETWORK_MODE_CLIENT: return "client"; } -# endif + #endif return "none"; } int32_t ScNetwork::numPlayers_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK return NetworkGetNumPlayers(); -# else + #else return 0; -# endif + #endif } int32_t ScNetwork::numGroups_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK return NetworkGetNumGroups(); -# else + #else return 0; -# endif + #endif } int32_t ScNetwork::defaultGroup_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK return NetworkGetDefaultGroup(); -# else + #else return 0; -# endif + #endif } void ScNetwork::defaultGroup_set(int32_t value) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto action = NetworkModifyGroupAction(ModifyGroupType::SetDefault, value); GameActions::Execute(&action); -# endif + #endif } std::vector> ScNetwork::groups_get() const { std::vector> groups; -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto numGroups = NetworkGetNumGroups(); for (int32_t i = 0; i < numGroups; i++) { auto groupId = NetworkGetGroupID(i); groups.push_back(std::make_shared(groupId)); } -# endif + #endif return groups; } std::vector> ScNetwork::players_get() const { std::vector> players; -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto numPlayers = NetworkGetNumPlayers(); for (int32_t i = 0; i < numPlayers; i++) { auto playerId = NetworkGetPlayerID(i); players.push_back(std::make_shared(playerId)); } -# endif + #endif return players; } std::shared_ptr ScNetwork::currentPlayer_get() const { std::shared_ptr player; -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto playerId = NetworkGetCurrentPlayerId(); player = std::make_shared(playerId); -# endif + #endif return player; } std::shared_ptr ScNetwork::getPlayer(int32_t id) const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK if (GetTargetAPIVersion() < API_VERSION_77_NETWORK_IDS) { auto index = id; @@ -133,13 +133,13 @@ namespace OpenRCT2::Scripting } } -# endif + #endif return nullptr; } DukValue ScNetwork::stats_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto obj = OpenRCT2::Scripting::DukObject(_context); auto networkStats = NetworkGetStats(); { @@ -165,14 +165,14 @@ namespace OpenRCT2::Scripting obj.Set("bytesSent", DukValue::take_from_stack(_context)); } return obj.Take(); -# else + #else return ToDuk(_context, nullptr); -# endif + #endif } std::shared_ptr ScNetwork::getGroup(int32_t id) const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK if (GetTargetAPIVersion() < API_VERSION_77_NETWORK_IDS) { auto index = id; @@ -191,21 +191,21 @@ namespace OpenRCT2::Scripting return std::make_shared(id); } } -# endif + #endif return nullptr; } void ScNetwork::addGroup() { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto networkModifyGroup = NetworkModifyGroupAction(ModifyGroupType::AddGroup); GameActions::Execute(&networkModifyGroup); -# endif + #endif } void ScNetwork::removeGroup(int32_t id) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK if (GetTargetAPIVersion() < API_VERSION_77_NETWORK_IDS) { auto index = id; @@ -226,12 +226,12 @@ namespace OpenRCT2::Scripting GameActions::Execute(&networkAction); } } -# endif + #endif } void ScNetwork::kickPlayer(int32_t id) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK if (GetTargetAPIVersion() < API_VERSION_77_NETWORK_IDS) { auto index = id; @@ -252,12 +252,12 @@ namespace OpenRCT2::Scripting GameActions::Execute(&kickPlayerAction); } } -# endif + #endif } void ScNetwork::sendMessage(std::string message, DukValue players) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK if (players.is_array()) { if (NetworkGetMode() == NETWORK_MODE_SERVER) @@ -285,10 +285,10 @@ namespace OpenRCT2::Scripting { NetworkSendChat(message.c_str()); } -# endif + #endif } -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK std::shared_ptr ScNetwork::createListener() { auto& scriptEngine = GetContext()->GetScriptEngine(); @@ -297,14 +297,14 @@ namespace OpenRCT2::Scripting scriptEngine.AddSocket(socket); return socket; } -# else + #else void ScNetwork::createListener() { duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); } -# endif + #endif -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK std::shared_ptr ScNetwork::createSocket() { auto& scriptEngine = GetContext()->GetScriptEngine(); @@ -313,12 +313,12 @@ namespace OpenRCT2::Scripting scriptEngine.AddSocket(socket); return socket; } -# else + #else void ScNetwork::createSocket() { duk_error(_context, DUK_ERR_ERROR, "Networking has been disabled."); } -# endif + #endif void ScNetwork::Register(duk_context* ctx) { diff --git a/src/openrct2/scripting/bindings/network/ScNetwork.hpp b/src/openrct2/scripting/bindings/network/ScNetwork.hpp index d1b65c8db4..07b14a84d4 100644 --- a/src/openrct2/scripting/bindings/network/ScNetwork.hpp +++ b/src/openrct2/scripting/bindings/network/ScNetwork.hpp @@ -11,21 +11,21 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" -# include "ScPlayer.hpp" -# include "ScPlayerGroup.hpp" -# include "ScSocket.hpp" + #include "../../Duktape.hpp" + #include "ScPlayer.hpp" + #include "ScPlayerGroup.hpp" + #include "ScSocket.hpp" -# include + #include namespace OpenRCT2::Scripting { class ScNetwork { private: -# ifdef __clang__ + #ifdef __clang__ [[maybe_unused]] -# endif + #endif duk_context* _context; public: @@ -57,17 +57,17 @@ namespace OpenRCT2::Scripting void sendMessage(std::string message, DukValue players); -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK std::shared_ptr createListener(); -# else + #else void createListener(); -# endif + #endif -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK std::shared_ptr createSocket(); -# else + #else void createSocket(); -# endif + #endif static void Register(duk_context* ctx); }; diff --git a/src/openrct2/scripting/bindings/network/ScPlayer.cpp b/src/openrct2/scripting/bindings/network/ScPlayer.cpp index 2af77ef49d..56362bce3f 100644 --- a/src/openrct2/scripting/bindings/network/ScPlayer.cpp +++ b/src/openrct2/scripting/bindings/network/ScPlayer.cpp @@ -9,12 +9,12 @@ #ifdef ENABLE_SCRIPTING -# include "ScPlayer.hpp" + #include "ScPlayer.hpp" -# include "../../../Context.h" -# include "../../../actions/PlayerSetGroupAction.h" -# include "../../../network/NetworkAction.h" -# include "../../../network/network.h" + #include "../../../Context.h" + #include "../../../actions/PlayerSetGroupAction.h" + #include "../../../network/NetworkAction.h" + #include "../../../network/network.h" namespace OpenRCT2::Scripting { @@ -30,69 +30,69 @@ namespace OpenRCT2::Scripting std::string ScPlayer::name_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto index = NetworkGetPlayerIndex(_id); if (index == -1) return {}; return NetworkGetPlayerName(index); -# else + #else return {}; -# endif + #endif } int32_t ScPlayer::group_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto index = NetworkGetPlayerIndex(_id); if (index == -1) return {}; return NetworkGetPlayerGroup(index); -# else + #else return 0; -# endif + #endif } void ScPlayer::group_set(int32_t value) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto playerSetGroupAction = PlayerSetGroupAction(_id, value); GameActions::Execute(&playerSetGroupAction); -# endif + #endif } int32_t ScPlayer::ping_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto index = NetworkGetPlayerIndex(_id); if (index == -1) return {}; return NetworkGetPlayerPing(index); -# else + #else return 0; -# endif + #endif } int32_t ScPlayer::commandsRan_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto index = NetworkGetPlayerIndex(_id); if (index == -1) return {}; return NetworkGetPlayerCommandsRan(index); -# else + #else return 0; -# endif + #endif } int32_t ScPlayer::moneySpent_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto index = NetworkGetPlayerIndex(_id); if (index == -1) return {}; return NetworkGetPlayerMoneySpent(index); -# else + #else return 0; -# endif + #endif } std::string ScPlayer::ipAddress_get() const diff --git a/src/openrct2/scripting/bindings/network/ScPlayer.hpp b/src/openrct2/scripting/bindings/network/ScPlayer.hpp index 1826597953..056dea1205 100644 --- a/src/openrct2/scripting/bindings/network/ScPlayer.hpp +++ b/src/openrct2/scripting/bindings/network/ScPlayer.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" + #include "../../Duktape.hpp" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp b/src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp index 4ba8be2ebf..2bae124bdd 100644 --- a/src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp +++ b/src/openrct2/scripting/bindings/network/ScPlayerGroup.cpp @@ -9,15 +9,15 @@ #ifdef ENABLE_SCRIPTING -# include "ScPlayerGroup.hpp" + #include "ScPlayerGroup.hpp" -# include "../../../Context.h" -# include "../../../actions/NetworkModifyGroupAction.h" -# include "../../../actions/PlayerSetGroupAction.h" -# include "../../../core/String.hpp" -# include "../../../network/NetworkAction.h" -# include "../../../network/network.h" -# include "../../Duktape.hpp" + #include "../../../Context.h" + #include "../../../actions/NetworkModifyGroupAction.h" + #include "../../../actions/PlayerSetGroupAction.h" + #include "../../../core/String.hpp" + #include "../../../network/NetworkAction.h" + #include "../../../network/network.h" + #include "../../Duktape.hpp" namespace OpenRCT2::Scripting { @@ -33,25 +33,25 @@ namespace OpenRCT2::Scripting std::string ScPlayerGroup::name_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto index = NetworkGetGroupIndex(_id); if (index == -1) return {}; return NetworkGetGroupName(index); -# else + #else return {}; -# endif + #endif } void ScPlayerGroup::name_set(std::string value) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto action = NetworkModifyGroupAction(ModifyGroupType::SetName, _id, value); GameActions::Execute(&action); -# endif + #endif } -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK static std::string TransformPermissionKeyToJS(const std::string& s) { auto result = s.substr(sizeof("PERMISSION_") - 1); @@ -66,11 +66,11 @@ namespace OpenRCT2::Scripting { return "PERMISSION_" + String::ToUpper(s); } -# endif + #endif std::vector ScPlayerGroup::permissions_get() const { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto index = NetworkGetGroupIndex(_id); if (index == -1) return {}; @@ -87,14 +87,14 @@ namespace OpenRCT2::Scripting permissionIndex++; } return result; -# else + #else return {}; -# endif + #endif } void ScPlayerGroup::permissions_set(std::vector value) { -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK auto groupIndex = NetworkGetGroupIndex(_id); if (groupIndex == -1) return; @@ -131,7 +131,7 @@ namespace OpenRCT2::Scripting GameActions::Execute(&networkAction2); } } -# endif + #endif } void ScPlayerGroup::Register(duk_context* ctx) diff --git a/src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp b/src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp index f97a03bfc0..b2854ec0f3 100644 --- a/src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp +++ b/src/openrct2/scripting/bindings/network/ScPlayerGroup.hpp @@ -11,10 +11,10 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" + #include "../../Duktape.hpp" -# include -# include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/network/ScSocket.hpp b/src/openrct2/scripting/bindings/network/ScSocket.hpp index f5a6ab4e0d..1f9849993c 100644 --- a/src/openrct2/scripting/bindings/network/ScSocket.hpp +++ b/src/openrct2/scripting/bindings/network/ScSocket.hpp @@ -10,16 +10,16 @@ #pragma once #ifdef ENABLE_SCRIPTING -# ifndef DISABLE_NETWORK + #ifndef DISABLE_NETWORK -# include "../../../Context.h" -# include "../../../config/Config.h" -# include "../../../network/Socket.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../config/Config.h" + #include "../../../network/Socket.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" -# include -# include + #include + #include namespace OpenRCT2::Scripting { @@ -556,5 +556,5 @@ namespace OpenRCT2::Scripting }; } // namespace OpenRCT2::Scripting -# endif + #endif #endif diff --git a/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp b/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp index 7590eba2ee..57fc102304 100644 --- a/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp +++ b/src/openrct2/scripting/bindings/object/ScInstalledObject.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../object/ObjectRepository.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../object/ObjectRepository.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/object/ScObject.hpp b/src/openrct2/scripting/bindings/object/ScObject.hpp index 0f41cbc1b9..08c68c705c 100644 --- a/src/openrct2/scripting/bindings/object/ScObject.hpp +++ b/src/openrct2/scripting/bindings/object/ScObject.hpp @@ -11,18 +11,18 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../object/LargeSceneryObject.h" -# include "../../../object/ObjectManager.h" -# include "../../../object/RideObject.h" -# include "../../../object/SceneryGroupObject.h" -# include "../../../object/SmallSceneryObject.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "ScInstalledObject.hpp" + #include "../../../Context.h" + #include "../../../object/LargeSceneryObject.h" + #include "../../../object/ObjectManager.h" + #include "../../../object/RideObject.h" + #include "../../../object/SceneryGroupObject.h" + #include "../../../object/SmallSceneryObject.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "ScInstalledObject.hpp" -# include -# include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/object/ScObjectManager.cpp b/src/openrct2/scripting/bindings/object/ScObjectManager.cpp index 39742f16e4..b17ff1033d 100644 --- a/src/openrct2/scripting/bindings/object/ScObjectManager.cpp +++ b/src/openrct2/scripting/bindings/object/ScObjectManager.cpp @@ -9,12 +9,12 @@ #ifdef ENABLE_SCRIPTING -# include "ScObjectManager.h" + #include "ScObjectManager.h" -# include "../../../object/ObjectList.h" -# include "../../../ride/RideData.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../object/ObjectList.h" + #include "../../../ride/RideData.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" using namespace OpenRCT2; using namespace OpenRCT2::Scripting; diff --git a/src/openrct2/scripting/bindings/object/ScObjectManager.h b/src/openrct2/scripting/bindings/object/ScObjectManager.h index 4a440c019c..de3e3195e0 100644 --- a/src/openrct2/scripting/bindings/object/ScObjectManager.h +++ b/src/openrct2/scripting/bindings/object/ScObjectManager.h @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "ScInstalledObject.hpp" -# include "ScObject.hpp" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "ScInstalledObject.hpp" + #include "ScObject.hpp" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/ride/ScRide.cpp b/src/openrct2/scripting/bindings/ride/ScRide.cpp index 60566ead32..5698a6f805 100644 --- a/src/openrct2/scripting/bindings/ride/ScRide.cpp +++ b/src/openrct2/scripting/bindings/ride/ScRide.cpp @@ -9,15 +9,15 @@ #ifdef ENABLE_SCRIPTING -# include "ScRide.hpp" + #include "ScRide.hpp" -# include "../../../Context.h" -# include "../../../core/UnitConversion.h" -# include "../../../ride/Ride.h" -# include "../../../ride/RideData.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "../object/ScObject.hpp" + #include "../../../Context.h" + #include "../../../core/UnitConversion.h" + #include "../../../ride/Ride.h" + #include "../../../ride/RideData.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "../object/ScObject.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/ride/ScRide.hpp b/src/openrct2/scripting/bindings/ride/ScRide.hpp index a1f3165630..fcff9e1cdc 100644 --- a/src/openrct2/scripting/bindings/ride/ScRide.hpp +++ b/src/openrct2/scripting/bindings/ride/ScRide.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../ride/Ride.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "../object/ScObject.hpp" -# include "ScRideStation.hpp" + #include "../../../Context.h" + #include "../../../ride/Ride.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "../object/ScObject.hpp" + #include "ScRideStation.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/ride/ScRideStation.cpp b/src/openrct2/scripting/bindings/ride/ScRideStation.cpp index 18a4c9e8b4..c1363486fd 100644 --- a/src/openrct2/scripting/bindings/ride/ScRideStation.cpp +++ b/src/openrct2/scripting/bindings/ride/ScRideStation.cpp @@ -9,13 +9,13 @@ #ifdef ENABLE_SCRIPTING -# include "ScRideStation.hpp" + #include "ScRideStation.hpp" -# include "../../../Context.h" -# include "../../../ride/Ride.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "../object/ScObject.hpp" + #include "../../../Context.h" + #include "../../../ride/Ride.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "../object/ScObject.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/ride/ScRideStation.hpp b/src/openrct2/scripting/bindings/ride/ScRideStation.hpp index 9dd604290e..34c0207da9 100644 --- a/src/openrct2/scripting/bindings/ride/ScRideStation.hpp +++ b/src/openrct2/scripting/bindings/ride/ScRideStation.hpp @@ -11,9 +11,9 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../ride/Ride.h" -# include "../../Duktape.hpp" + #include "../../../Context.h" + #include "../../../ride/Ride.h" + #include "../../Duktape.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/ride/ScTrackIterator.cpp b/src/openrct2/scripting/bindings/ride/ScTrackIterator.cpp index a54e151b83..93283e907d 100644 --- a/src/openrct2/scripting/bindings/ride/ScTrackIterator.cpp +++ b/src/openrct2/scripting/bindings/ride/ScTrackIterator.cpp @@ -9,14 +9,14 @@ #ifdef ENABLE_SCRIPTING -# include "ScTrackIterator.h" + #include "ScTrackIterator.h" -# include "../../../Context.h" -# include "../../../ride/Ride.h" -# include "../../../ride/TrackData.h" -# include "../../../world/tile_element/TrackElement.h" -# include "../../ScriptEngine.h" -# include "ScTrackSegment.h" + #include "../../../Context.h" + #include "../../../ride/Ride.h" + #include "../../../ride/TrackData.h" + #include "../../../world/tile_element/TrackElement.h" + #include "../../ScriptEngine.h" + #include "ScTrackSegment.h" using namespace OpenRCT2::Scripting; using namespace OpenRCT2::TrackMetaData; diff --git a/src/openrct2/scripting/bindings/ride/ScTrackIterator.h b/src/openrct2/scripting/bindings/ride/ScTrackIterator.h index b3a977e957..6c5353afff 100644 --- a/src/openrct2/scripting/bindings/ride/ScTrackIterator.h +++ b/src/openrct2/scripting/bindings/ride/ScTrackIterator.h @@ -11,11 +11,11 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Identifiers.h" -# include "../../Duktape.hpp" + #include "../../../Identifiers.h" + #include "../../Duktape.hpp" -# include -# include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp b/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp index 4a3c469eac..27da8c20cc 100644 --- a/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp +++ b/src/openrct2/scripting/bindings/ride/ScTrackSegment.cpp @@ -9,12 +9,12 @@ #ifdef ENABLE_SCRIPTING -# include "ScTrackSegment.h" + #include "ScTrackSegment.h" -# include "../../../Context.h" -# include "../../../ride/TrackData.h" -# include "../../../ride/Vehicle.h" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../ride/TrackData.h" + #include "../../../ride/Vehicle.h" + #include "../../ScriptEngine.h" using namespace OpenRCT2::Scripting; using namespace OpenRCT2::TrackMetaData; diff --git a/src/openrct2/scripting/bindings/ride/ScTrackSegment.h b/src/openrct2/scripting/bindings/ride/ScTrackSegment.h index 92722711aa..3eee4d37af 100644 --- a/src/openrct2/scripting/bindings/ride/ScTrackSegment.h +++ b/src/openrct2/scripting/bindings/ride/ScTrackSegment.h @@ -11,10 +11,10 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" + #include "../../Duktape.hpp" -# include -# include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScClimate.hpp b/src/openrct2/scripting/bindings/world/ScClimate.hpp index 677e658464..91d8c3d5fc 100644 --- a/src/openrct2/scripting/bindings/world/ScClimate.hpp +++ b/src/openrct2/scripting/bindings/world/ScClimate.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../GameState.h" -# include "../../../core/StringTypes.h" -# include "../../../world/Climate.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../GameState.h" + #include "../../../core/StringTypes.h" + #include "../../../world/Climate.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScDate.hpp b/src/openrct2/scripting/bindings/world/ScDate.hpp index a04b0a201f..27bcafdc60 100644 --- a/src/openrct2/scripting/bindings/world/ScDate.hpp +++ b/src/openrct2/scripting/bindings/world/ScDate.hpp @@ -11,13 +11,13 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../Date.h" -# include "../../../Game.h" -# include "../../../GameState.h" -# include "../../../localisation/Localisation.Date.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../Date.h" + #include "../../../Game.h" + #include "../../../GameState.h" + #include "../../../localisation/Localisation.Date.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScMap.cpp b/src/openrct2/scripting/bindings/world/ScMap.cpp index de59a8c083..8269838f6b 100644 --- a/src/openrct2/scripting/bindings/world/ScMap.cpp +++ b/src/openrct2/scripting/bindings/world/ScMap.cpp @@ -9,31 +9,31 @@ #ifdef ENABLE_SCRIPTING -# include "ScMap.hpp" + #include "ScMap.hpp" -# include "../../../GameState.h" -# include "../../../entity/Balloon.h" -# include "../../../entity/Duck.h" -# include "../../../entity/EntityList.h" -# include "../../../entity/Fountain.h" -# include "../../../entity/Guest.h" -# include "../../../entity/Litter.h" -# include "../../../entity/MoneyEffect.h" -# include "../../../entity/Particle.h" -# include "../../../entity/Staff.h" -# include "../../../ride/Ride.h" -# include "../../../ride/TrainManager.h" -# include "../../../world/Map.h" -# include "../../Duktape.hpp" -# include "../entity/ScEntity.hpp" -# include "../entity/ScGuest.hpp" -# include "../entity/ScLitter.hpp" -# include "../entity/ScParticle.hpp" -# include "../entity/ScStaff.hpp" -# include "../entity/ScVehicle.hpp" -# include "../ride/ScRide.hpp" -# include "../ride/ScTrackIterator.h" -# include "../world/ScTile.hpp" + #include "../../../GameState.h" + #include "../../../entity/Balloon.h" + #include "../../../entity/Duck.h" + #include "../../../entity/EntityList.h" + #include "../../../entity/Fountain.h" + #include "../../../entity/Guest.h" + #include "../../../entity/Litter.h" + #include "../../../entity/MoneyEffect.h" + #include "../../../entity/Particle.h" + #include "../../../entity/Staff.h" + #include "../../../ride/Ride.h" + #include "../../../ride/TrainManager.h" + #include "../../../world/Map.h" + #include "../../Duktape.hpp" + #include "../entity/ScEntity.hpp" + #include "../entity/ScGuest.hpp" + #include "../entity/ScLitter.hpp" + #include "../entity/ScParticle.hpp" + #include "../entity/ScStaff.hpp" + #include "../entity/ScVehicle.hpp" + #include "../ride/ScRide.hpp" + #include "../ride/ScTrackIterator.h" + #include "../world/ScTile.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScMap.hpp b/src/openrct2/scripting/bindings/world/ScMap.hpp index dcae067c71..718f40115a 100644 --- a/src/openrct2/scripting/bindings/world/ScMap.hpp +++ b/src/openrct2/scripting/bindings/world/ScMap.hpp @@ -11,10 +11,10 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" -# include "../ride/ScRide.hpp" -# include "../ride/ScTrackIterator.h" -# include "../world/ScTile.hpp" + #include "../../Duktape.hpp" + #include "../ride/ScRide.hpp" + #include "../ride/ScTrackIterator.h" + #include "../world/ScTile.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScPark.cpp b/src/openrct2/scripting/bindings/world/ScPark.cpp index 91a497da87..a6a6af0d9d 100644 --- a/src/openrct2/scripting/bindings/world/ScPark.cpp +++ b/src/openrct2/scripting/bindings/world/ScPark.cpp @@ -9,21 +9,21 @@ #ifdef ENABLE_SCRIPTING -# include "ScPark.hpp" + #include "ScPark.hpp" -# include "../../../Context.h" -# include "../../../Date.h" -# include "../../../GameState.h" -# include "../../../core/String.hpp" -# include "../../../entity/Guest.h" -# include "../../../management/Finance.h" -# include "../../../management/NewsItem.h" -# include "../../../windows/Intent.h" -# include "../../../world/Park.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "../entity/ScGuest.hpp" -# include "ScParkMessage.hpp" + #include "../../../Context.h" + #include "../../../Date.h" + #include "../../../GameState.h" + #include "../../../core/String.hpp" + #include "../../../entity/Guest.h" + #include "../../../management/Finance.h" + #include "../../../management/NewsItem.h" + #include "../../../windows/Intent.h" + #include "../../../world/Park.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "../entity/ScGuest.hpp" + #include "ScParkMessage.hpp" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScPark.hpp b/src/openrct2/scripting/bindings/world/ScPark.hpp index bf590bdefe..250f50b6a4 100644 --- a/src/openrct2/scripting/bindings/world/ScPark.hpp +++ b/src/openrct2/scripting/bindings/world/ScPark.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../Duktape.hpp" -# include "ScParkMessage.hpp" -# include "ScResearch.hpp" + #include "../../../Context.h" + #include "../../Duktape.hpp" + #include "ScParkMessage.hpp" + #include "ScResearch.hpp" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScParkMessage.cpp b/src/openrct2/scripting/bindings/world/ScParkMessage.cpp index 1274b29721..0ccd024262 100644 --- a/src/openrct2/scripting/bindings/world/ScParkMessage.cpp +++ b/src/openrct2/scripting/bindings/world/ScParkMessage.cpp @@ -9,18 +9,18 @@ #ifdef ENABLE_SCRIPTING -# include "ScParkMessage.hpp" + #include "ScParkMessage.hpp" -# include "../../../Context.h" -# include "../../../GameState.h" -# include "../../../core/String.hpp" -# include "../../../entity/Peep.h" -# include "../../../management/Finance.h" -# include "../../../management/NewsItem.h" -# include "../../../windows/Intent.h" -# include "../../../world/Park.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../GameState.h" + #include "../../../core/String.hpp" + #include "../../../entity/Peep.h" + #include "../../../management/Finance.h" + #include "../../../management/NewsItem.h" + #include "../../../windows/Intent.h" + #include "../../../world/Park.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScParkMessage.hpp b/src/openrct2/scripting/bindings/world/ScParkMessage.hpp index 368311976c..acfb0972a3 100644 --- a/src/openrct2/scripting/bindings/world/ScParkMessage.hpp +++ b/src/openrct2/scripting/bindings/world/ScParkMessage.hpp @@ -11,12 +11,12 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../management/NewsItem.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../management/NewsItem.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" -# include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScResearch.cpp b/src/openrct2/scripting/bindings/world/ScResearch.cpp index e61eb5a4a8..72795f74ab 100644 --- a/src/openrct2/scripting/bindings/world/ScResearch.cpp +++ b/src/openrct2/scripting/bindings/world/ScResearch.cpp @@ -9,16 +9,16 @@ #ifdef ENABLE_SCRIPTING -# include "ScResearch.hpp" + #include "ScResearch.hpp" -# include "../../../Context.h" -# include "../../../GameState.h" -# include "../../../core/String.hpp" -# include "../../../management/Research.h" -# include "../../../ride/RideData.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "../object/ScObject.hpp" + #include "../../../Context.h" + #include "../../../GameState.h" + #include "../../../core/String.hpp" + #include "../../../management/Research.h" + #include "../../../ride/RideData.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "../object/ScObject.hpp" using namespace OpenRCT2; diff --git a/src/openrct2/scripting/bindings/world/ScResearch.hpp b/src/openrct2/scripting/bindings/world/ScResearch.hpp index e2f7577bb6..dfdff928e6 100644 --- a/src/openrct2/scripting/bindings/world/ScResearch.hpp +++ b/src/openrct2/scripting/bindings/world/ScResearch.hpp @@ -11,7 +11,7 @@ #ifdef ENABLE_SCRIPTING -# include "../../ScriptEngine.h" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScScenario.hpp b/src/openrct2/scripting/bindings/world/ScScenario.hpp index c321f100f1..39d5f73eda 100644 --- a/src/openrct2/scripting/bindings/world/ScScenario.hpp +++ b/src/openrct2/scripting/bindings/world/ScScenario.hpp @@ -11,13 +11,13 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../GameState.h" -# include "../../../core/StringTypes.h" -# include "../../../scenario/Scenario.h" -# include "../../../world/Park.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../GameState.h" + #include "../../../core/StringTypes.h" + #include "../../../scenario/Scenario.h" + #include "../../../world/Park.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScTile.cpp b/src/openrct2/scripting/bindings/world/ScTile.cpp index 795911e97c..77c5986355 100644 --- a/src/openrct2/scripting/bindings/world/ScTile.cpp +++ b/src/openrct2/scripting/bindings/world/ScTile.cpp @@ -9,23 +9,23 @@ #ifdef ENABLE_SCRIPTING -# include "ScTile.hpp" + #include "ScTile.hpp" -# include "../../../Context.h" -# include "../../../core/Guard.hpp" -# include "../../../entity/EntityRegistry.h" -# include "../../../object/LargeSceneryEntry.h" -# include "../../../ride/Track.h" -# include "../../../world/Footpath.h" -# include "../../../world/Scenery.h" -# include "../../../world/tile_element/LargeSceneryElement.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" -# include "ScTileElement.hpp" + #include "../../../Context.h" + #include "../../../core/Guard.hpp" + #include "../../../entity/EntityRegistry.h" + #include "../../../object/LargeSceneryEntry.h" + #include "../../../ride/Track.h" + #include "../../../world/Footpath.h" + #include "../../../world/Scenery.h" + #include "../../../world/tile_element/LargeSceneryElement.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" + #include "ScTileElement.hpp" -# include -# include -# include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScTile.hpp b/src/openrct2/scripting/bindings/world/ScTile.hpp index ff5c2b0271..7df486cfa0 100644 --- a/src/openrct2/scripting/bindings/world/ScTile.hpp +++ b/src/openrct2/scripting/bindings/world/ScTile.hpp @@ -11,14 +11,14 @@ #ifdef ENABLE_SCRIPTING -# include "../../Duktape.hpp" -# include "ScTileElement.hpp" + #include "../../Duktape.hpp" + #include "ScTileElement.hpp" -# include -# include -# include -# include -# include + #include + #include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.cpp b/src/openrct2/scripting/bindings/world/ScTileElement.cpp index dbd13a201c..60a848c1da 100644 --- a/src/openrct2/scripting/bindings/world/ScTileElement.cpp +++ b/src/openrct2/scripting/bindings/world/ScTileElement.cpp @@ -9,32 +9,32 @@ #ifdef ENABLE_SCRIPTING -# include "ScTileElement.hpp" + #include "ScTileElement.hpp" -# include "../../../Context.h" -# include "../../../core/Guard.hpp" -# include "../../../entity/EntityRegistry.h" -# include "../../../object/LargeSceneryEntry.h" -# include "../../../object/WallSceneryEntry.h" -# include "../../../ride/Ride.h" -# include "../../../ride/RideData.h" -# include "../../../ride/Track.h" -# include "../../../world/Footpath.h" -# include "../../../world/Scenery.h" -# include "../../../world/tile_element/BannerElement.h" -# include "../../../world/tile_element/EntranceElement.h" -# include "../../../world/tile_element/LargeSceneryElement.h" -# include "../../../world/tile_element/PathElement.h" -# include "../../../world/tile_element/SmallSceneryElement.h" -# include "../../../world/tile_element/SurfaceElement.h" -# include "../../../world/tile_element/TrackElement.h" -# include "../../../world/tile_element/WallElement.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../core/Guard.hpp" + #include "../../../entity/EntityRegistry.h" + #include "../../../object/LargeSceneryEntry.h" + #include "../../../object/WallSceneryEntry.h" + #include "../../../ride/Ride.h" + #include "../../../ride/RideData.h" + #include "../../../ride/Track.h" + #include "../../../world/Footpath.h" + #include "../../../world/Scenery.h" + #include "../../../world/tile_element/BannerElement.h" + #include "../../../world/tile_element/EntranceElement.h" + #include "../../../world/tile_element/LargeSceneryElement.h" + #include "../../../world/tile_element/PathElement.h" + #include "../../../world/tile_element/SmallSceneryElement.h" + #include "../../../world/tile_element/SurfaceElement.h" + #include "../../../world/tile_element/TrackElement.h" + #include "../../../world/tile_element/WallElement.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" -# include -# include -# include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.hpp b/src/openrct2/scripting/bindings/world/ScTileElement.hpp index b3c45e1343..f91bbe6fa5 100644 --- a/src/openrct2/scripting/bindings/world/ScTileElement.hpp +++ b/src/openrct2/scripting/bindings/world/ScTileElement.hpp @@ -11,18 +11,18 @@ #ifdef ENABLE_SCRIPTING -# include "../../../Context.h" -# include "../../../core/Guard.hpp" -# include "../../../entity/EntityRegistry.h" -# include "../../../ride/Track.h" -# include "../../../world/Footpath.h" -# include "../../../world/Scenery.h" -# include "../../Duktape.hpp" -# include "../../ScriptEngine.h" + #include "../../../Context.h" + #include "../../../core/Guard.hpp" + #include "../../../entity/EntityRegistry.h" + #include "../../../ride/Track.h" + #include "../../../world/Footpath.h" + #include "../../../world/Scenery.h" + #include "../../Duktape.hpp" + #include "../../ScriptEngine.h" -# include -# include -# include + #include + #include + #include namespace OpenRCT2::Scripting { diff --git a/src/openrct2/util/Prefetch.h b/src/openrct2/util/Prefetch.h index 8fbeb40556..146c0800e1 100644 --- a/src/openrct2/util/Prefetch.h +++ b/src/openrct2/util/Prefetch.h @@ -8,27 +8,27 @@ *****************************************************************************/ #if defined(__amd64__) || defined(_M_AMD64) || defined(__i386__) || defined(_M_IX86) -// Don't bother checking for CPUID, prefetch is available since Pentium 4 -# include -// This cannot be expressed as `constexpr` function, exclude it from clang-tidy check -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -# define PREFETCH(x) _mm_prefetch(reinterpret_cast(x), _MM_HINT_T0) + // Don't bother checking for CPUID, prefetch is available since Pentium 4 + #include + // This cannot be expressed as `constexpr` function, exclude it from clang-tidy check + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) + #define PREFETCH(x) _mm_prefetch(reinterpret_cast(x), _MM_HINT_T0) #elif defined(_MSC_VER) && defined(_M_ARM64) -// ARM64 prefetch is available since ARMv8. -// MSVC's help (https://learn.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170) -// is incorrect and points to a different header (arm64_neon.h), which doesn't contain prefetch. -// Correct header info taken from -// https://github.com/microsoft/wdkmetadata/blob/1ac0dd0719f19196334de12cf2a6dec20316d440/generation/WDK/IdlHeaders/km/crt/intrin.h#L2 -// and -// https://github.com/microsoft/wdkmetadata/blob/1ac0dd0719f19196334de12cf2a6dec20316d440/generation/WDK/IdlHeaders/km/crt/intrin.h#L411 -# include -# define PREFETCH(x) __prefetch(x) + // ARM64 prefetch is available since ARMv8. + // MSVC's help (https://learn.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170) + // is incorrect and points to a different header (arm64_neon.h), which doesn't contain prefetch. + // Correct header info taken from + // https://github.com/microsoft/wdkmetadata/blob/1ac0dd0719f19196334de12cf2a6dec20316d440/generation/WDK/IdlHeaders/km/crt/intrin.h#L2 + // and + // https://github.com/microsoft/wdkmetadata/blob/1ac0dd0719f19196334de12cf2a6dec20316d440/generation/WDK/IdlHeaders/km/crt/intrin.h#L411 + #include + #define PREFETCH(x) __prefetch(x) #elif defined(__GNUC__) -// Let the compiler handle prefetch instruction -# define PREFETCH(x) __builtin_prefetch(x) + // Let the compiler handle prefetch instruction + #define PREFETCH(x) __builtin_prefetch(x) #else -# define PREFETCH(x) + #define PREFETCH(x) #endif diff --git a/test/tests/tests.cpp b/test/tests/tests.cpp index 4293d589fe..fbbfa7b8f9 100644 --- a/test/tests/tests.cpp +++ b/test/tests/tests.cpp @@ -11,8 +11,8 @@ // directly into the test binary. #ifdef _MSC_VER -# include -# include + #include + #include int main(int argc, char** argv) { From cc8c3f62fda6480996fb18c914ce5b88a5cb3657 Mon Sep 17 00:00:00 2001 From: ninjum <138787523+ninjum@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:11:53 +0100 Subject: [PATCH 097/139] Add Galician translation to openrct2.appdata.xml --- distribution/linux/openrct2.appdata.xml | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/distribution/linux/openrct2.appdata.xml b/distribution/linux/openrct2.appdata.xml index 28396fa99e..93218e981b 100644 --- a/distribution/linux/openrct2.appdata.xml +++ b/distribution/linux/openrct2.appdata.xml @@ -7,12 +7,14 @@ Amusement park simulation Simulador de parcs d’atraccions Freizeitparksimulation + Simulador de parques de atraccións 놀이공원 시뮬레이션 Symulator parku rozrywki Simulador de parque de diversões The OpenRCT2 Team Equip de l’OpenRCT2 Das OpenRCT2-Team + O equipo OpenRCT2 OpenRCT2 팀 Zespół OpenRCT2 Equipe do OpenRCT2 @@ -46,6 +48,15 @@ erfüllen. In der Sandbox kann der Spieler einen flexibleren Park bauen – falls gewünscht ohne Einschränkungen.

+

+ OpenRCT2 é unha reimplementación de código aberto de RollerCoaster Tycoon 2 (RCT2). + O xogo centrase na construción e mantemento dun parque de atraccións que conten + atraccións, tendas e instalacións. O xogador debe tentar obter beneficios e manter + unha boa reputación do parque mentres mantén ledos aos visitantes. OpenRCT2 permite + xogar en escenario ou libre. Escenarios requiren que o xogador complete un determinado + obxectivo nun límite de tempo establecido mentres co libre permite ao xogador crear un + parque máis flexible, sen restriccións ou con opcións de finanzas sen límites. +

OpenRCT는 RollerCoaster Tycoon 2 (RCT2)의 오픈 소스 재구현판입니다. 놀이기구, 상점, 매점 등을 건설하고 유지하는 것이 게임 플레이의 중심이 됩니다. @@ -84,6 +95,9 @@

OpenRCT2 hat viele Änderungen im Verleich mit dem Originalspiel RollerCoaster Tycoon 2. Hier sind einige von ihnen aufgelistet.

+

+ OpenRCT2 presenta moitos cambios en comparación co xogo orixinal de RollerCoaster Tycoon 2. Algúns deles son: +

OpenRCT2는 오리지널 RollerCoaster Tycoon 2 게임에 비해 많은 기능적 변화가 있습니다. 여기에 일부 기능이 나열되어 있습니다.

@@ -98,6 +112,7 @@
  • User Interface theming.
  • Temes per a la interfície gràfica
  • Thematische User-Interface-Anpassung.
  • +
  • Personalización da interface de usuario.
  • 유저 인터페이스 커스터마이징
  • Edycja motywów interfejsu użytkownika
  • Customização por temas da interface de usuário.
  • @@ -105,6 +120,7 @@
  • Fast-forwarding gameplay.
  • Diferents velocitats de joc disponibles durant la partida
  • Spielsimulation beschleunigen.
  • +
  • Avance rápido no xogo.
  • 게임 속도 조절
  • Przyspieszanie rozgrywki
  • Dinâmica de jogo acelerável.
  • @@ -112,6 +128,7 @@
  • Multiplayer support.
  • Suport multijugador
  • Mehrspielerunterstützung.
  • +
  • Soporte multixogador.
  • 멀티플레이 지원
  • Tryb wieloosobowy
  • Suporte multijogador.
  • @@ -119,6 +136,7 @@
  • Multilingual. Improved translations.
  • Traduït a diversos idiomes i amb traduccions millorades
  • Mehrsprachig. Verbesserte Übersetzungen.
  • +
  • Traducido a varias linguas e con traducións melloradas.
  • 다국어 지원 및 번역 개선
  • Wielojęzyczność i ulepszone tłumaczenia
  • Multilíngue. Traduções aperfeiçoadas.
  • @@ -126,6 +144,7 @@
  • OpenGL hardware rendering.
  • Renderització OpenGL per maquinari
  • OpenGL-Hardwarerendering.
  • +
  • Renderizado OpenGL por soporte fisico.
  • OpenGL 하드웨어 렌더링
  • Obsługa renderowania OpenGL
  • Renderização por hardware OpenGL.
  • @@ -133,6 +152,7 @@
  • Various fixes and improvements for bugs in the original game.
  • Correccions i millores dels errors del joc original
  • Diverse Fehlerkorrekturen und Verbesserungen für Fehler im Originalspiel.
  • +
  • Correccións e melloras de erros do xogo orixinal.
  • 오리지널 게임에 있던 다양한 버그 수정 및 개선
  • Poprawki błędów i usprawnienia względem oryginalnej gry
  • Várias correções e melhorias para problemas no jogo original.
  • @@ -140,6 +160,7 @@
  • Native support for Linux and macOS.
  • Suport natiu per a Linux i macOS
  • Native Unterstützung für Linux und macOS.
  • +
  • Soporte nativo para Linux e macOS.
  • Linux 및 macOS 자체 지원
  • Natywna obsługa systemów Linux i macOS
  • Suporte nativo para Linux e macOS.
  • @@ -147,6 +168,7 @@
  • Added hacks and cheats.
  • Es poden fer trucs i trampes
  • Eingebaute Hacks und Cheats.
  • +
  • Engadidos trucos e trampas
  • 치트 기능 지원
  • Kody i hacki
  • Trapaças e hacks adicionados.
  • @@ -154,6 +176,7 @@
  • Auto-saving and giant screenshots.
  • Desades automàtiques i captures de pantalla gegants
  • Automatisches Speichern und gigantische Screenshots.
  • +
  • Gardado automático e capturas de pantalla xigantes.
  • 자동 저장 및 대형 스크린 샷
  • Autozapis i możliwość robienia ogromnych zrzutów ekranu
  • Salvamento automático e capturas de tela gigantes.
  • @@ -168,6 +191,9 @@

    Die Originaldateien von RollerCoaster Tycoon 2 oder RollerCoaster Tycoon Classic werden benötigt, um OpenRCT2 zu spielen.

    +

    + Os ficheiros do xogo RollerCoaster Tycoon 2 ou RollerCoaster Tycoon Classic son necesarios para xogar a OpenRCT2. +

    OpenRCT2를 플레이하기 위해서는 오리지널 RollerCoaster Tycoon 2 또는 RollerCoaster Tycoon Classic 게임 파일이 필요합니다.

    @@ -183,6 +209,7 @@ https://camo.githubusercontent.com/f513bc551e2c9e04e292724113ea4789726d23921d286f21dad39a6e955b5a56/68747470733a2f2f692e696d6775722e636f6d2f6537434b3553632e706e67 Amusement park featuring an inverted roller coaster, a river rapids ride and custom scenery Freizeitpark mit einer umgekehrten Achterbahn, einer Stromschnellenattraktion und einer eigens errichteten Szenerie + Parque de atraccións con montañas rusas invertidas, un percorrido de rápidos e escenarios personalizados. 인버티드 롤러코스터를 구현한 놀이공원과 리버 래피드 기구 및 커스텀 풍경 오브젝트 Park rozrywki z odwróconą kolejką górską, spływem rwącą rzeką i niestandardową scenerią Parque de diversões que conta com uma montanha-russa invertida, corredeira de rio e cenários customizados From 7d554b5790fa32660662c68725e1ec55e5a334a3 Mon Sep 17 00:00:00 2001 From: RedMarcher Date: Wed, 27 Nov 2024 19:15:28 +0000 Subject: [PATCH 098/139] Change int for cheats to int32_t --- src/openrct2/Cheats.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/openrct2/Cheats.h b/src/openrct2/Cheats.h index 15a133cdb9..7746d6c00d 100644 --- a/src/openrct2/Cheats.h +++ b/src/openrct2/Cheats.h @@ -130,11 +130,11 @@ enum }; constexpr auto kCheatsGiveGuestsMoney = 1000.00_GBP; -constexpr int kCheatsTramIncrement = 250; -constexpr int kCheatsDuckIncrement = 20; -constexpr int kCheatsStaffFastSpeed = 0xFF; -constexpr int kCheatsStaffNormalSpeed = 0x60; -constexpr int kCheatsStaffFreezeSpeed = 0; +constexpr int32_t kCheatsTramIncrement = 250; +constexpr int32_t kCheatsDuckIncrement = 20; +constexpr int32_t kCheatsStaffFastSpeed = 0xFF; +constexpr int32_t kCheatsStaffNormalSpeed = 0x60; +constexpr int32_t kCheatsStaffFreezeSpeed = 0; constexpr int32_t kForcedParkRatingDisabled = -1; void CheatsReset(); From c24e47dea1131cc0e032eece3a2fc41d471f84fd Mon Sep 17 00:00:00 2001 From: RedMarcher Date: Wed, 27 Nov 2024 19:30:19 +0000 Subject: [PATCH 099/139] Rename cheat variables to match new code style --- src/openrct2-ui/input/Shortcuts.cpp | 2 +- .../interface/ViewportInteraction.cpp | 4 +- src/openrct2-ui/windows/Cheats.cpp | 112 ++++++------ src/openrct2-ui/windows/Dropdown.cpp | 2 +- src/openrct2-ui/windows/Footpath.cpp | 12 +- src/openrct2-ui/windows/LandRights.cpp | 2 +- src/openrct2-ui/windows/Map.cpp | 2 +- src/openrct2-ui/windows/NewRide.cpp | 4 +- src/openrct2-ui/windows/Ride.cpp | 48 ++--- src/openrct2-ui/windows/RideConstruction.cpp | 26 +-- src/openrct2-ui/windows/Scenery.cpp | 4 +- src/openrct2-ui/windows/TopToolbar.cpp | 14 +- src/openrct2-ui/windows/TrackDesignPlace.cpp | 2 +- src/openrct2/Cheats.cpp | 166 +++++++++--------- src/openrct2/Cheats.h | 56 +++--- src/openrct2/actions/CheatSetAction.cpp | 56 +++--- src/openrct2/actions/ClearAction.cpp | 2 +- .../actions/FootpathAdditionPlaceAction.cpp | 2 +- .../actions/FootpathAdditionRemoveAction.cpp | 2 +- .../actions/FootpathLayoutPlaceAction.cpp | 4 +- src/openrct2/actions/FootpathPlaceAction.cpp | 6 +- src/openrct2/actions/FootpathRemoveAction.cpp | 2 +- src/openrct2/actions/GameAction.cpp | 2 +- src/openrct2/actions/LandLowerAction.cpp | 2 +- src/openrct2/actions/LandRaiseAction.cpp | 2 +- src/openrct2/actions/LandSetHeightAction.cpp | 10 +- src/openrct2/actions/LandSetRightsAction.cpp | 2 +- .../actions/LargeSceneryPlaceAction.cpp | 6 +- .../actions/LargeSceneryRemoveAction.cpp | 4 +- .../actions/LargeScenerySetColourAction.cpp | 2 +- src/openrct2/actions/MazePlaceTrackAction.cpp | 4 +- src/openrct2/actions/MazeSetTrackAction.cpp | 4 +- .../actions/ParkEntrancePlaceAction.cpp | 2 +- .../actions/ParkEntranceRemoveAction.cpp | 2 +- src/openrct2/actions/PeepSpawnPlaceAction.cpp | 2 +- src/openrct2/actions/RideCreateAction.cpp | 2 +- src/openrct2/actions/RideDemolishAction.cpp | 2 +- .../actions/RideEntranceExitPlaceAction.cpp | 6 +- src/openrct2/actions/RideSetSettingAction.cpp | 12 +- src/openrct2/actions/RideSetVehicleAction.cpp | 8 +- .../actions/SmallSceneryPlaceAction.cpp | 12 +- .../actions/SmallSceneryRemoveAction.cpp | 2 +- .../actions/SmallScenerySetColourAction.cpp | 2 +- src/openrct2/actions/StaffHireNewAction.cpp | 2 +- .../actions/SurfaceSetStyleAction.cpp | 6 +- src/openrct2/actions/TrackDesignAction.cpp | 4 +- src/openrct2/actions/TrackPlaceAction.cpp | 22 +-- src/openrct2/actions/TrackRemoveAction.cpp | 2 +- src/openrct2/actions/WallPlaceAction.cpp | 18 +- src/openrct2/actions/WallRemoveAction.cpp | 2 +- src/openrct2/actions/WallSetColourAction.cpp | 2 +- src/openrct2/actions/WaterLowerAction.cpp | 4 +- src/openrct2/actions/WaterRaiseAction.cpp | 4 +- src/openrct2/actions/WaterSetHeightAction.cpp | 6 +- src/openrct2/entity/Guest.cpp | 22 +-- src/openrct2/entity/Litter.cpp | 2 +- src/openrct2/interface/InteractiveConsole.cpp | 14 +- src/openrct2/management/Marketing.cpp | 2 +- src/openrct2/management/Research.cpp | 2 +- src/openrct2/paint/VirtualFloor.cpp | 2 +- .../paint/tile_element/Paint.Surface.cpp | 2 +- src/openrct2/ride/Ride.cpp | 14 +- src/openrct2/ride/RideConstruction.cpp | 4 +- src/openrct2/ride/RideData.cpp | 6 +- src/openrct2/ride/RideRatings.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 4 +- .../scripting/bindings/game/ScCheats.hpp | 96 +++++----- src/openrct2/world/Climate.cpp | 2 +- src/openrct2/world/ConstructionClearance.cpp | 2 +- src/openrct2/world/Footpath.cpp | 8 +- src/openrct2/world/Map.cpp | 12 +- src/openrct2/world/Scenery.cpp | 6 +- .../world/tile_element/TrackElement.cpp | 2 +- test/tests/PlayTests.cpp | 4 +- 74 files changed, 450 insertions(+), 450 deletions(-) diff --git a/src/openrct2-ui/input/Shortcuts.cpp b/src/openrct2-ui/input/Shortcuts.cpp index d91f354187..b2412ca430 100644 --- a/src/openrct2-ui/input/Shortcuts.cpp +++ b/src/openrct2-ui/input/Shortcuts.cpp @@ -597,7 +597,7 @@ static void ShortcutDecreaseElementHeight() static void ShortcutToggleClearanceChecks() { auto cheatSetAction = CheatSetAction( - CheatType::DisableClearanceChecks, GetGameState().Cheats.DisableClearanceChecks ? 0 : 1); + CheatType::DisableClearanceChecks, GetGameState().Cheats.disableClearanceChecks ? 0 : 1); GameActions::Execute(&cheatSetAction); } diff --git a/src/openrct2-ui/interface/ViewportInteraction.cpp b/src/openrct2-ui/interface/ViewportInteraction.cpp index b7d15b726d..54015cd4b3 100644 --- a/src/openrct2-ui/interface/ViewportInteraction.cpp +++ b/src/openrct2-ui/interface/ViewportInteraction.cpp @@ -377,7 +377,7 @@ namespace OpenRCT2::Ui else { // FIXME: Why does it *2 the value? - if (!GetGameState().Cheats.SandboxMode && !MapIsLocationOwned({ info.Loc, tileElement->GetBaseZ() * 2 })) + if (!GetGameState().Cheats.sandboxMode && !MapIsLocationOwned({ info.Loc, tileElement->GetBaseZ() * 2 })) { info.interactionType = ViewportInteractionItem::None; return info; @@ -508,7 +508,7 @@ namespace OpenRCT2::Ui return info; } case ViewportInteractionItem::ParkEntrance: - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) break; if (tileElement->GetType() != TileElementType::Entrance) diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index 8b06add9be..5469dd4f6a 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -549,10 +549,10 @@ static StringId window_cheats_page_titles[] = { { auto ft = Formatter::Common(); ft.Add(1000.00_GBP); - SetCheckboxValue(WIDX_GUEST_IGNORE_RIDE_INTENSITY, gameState.Cheats.IgnoreRideIntensity); - SetCheckboxValue(WIDX_GUEST_IGNORE_PRICE, gameState.Cheats.IgnorePrice); - SetCheckboxValue(WIDX_DISABLE_VANDALISM, gameState.Cheats.DisableVandalism); - SetCheckboxValue(WIDX_DISABLE_LITTERING, gameState.Cheats.DisableLittering); + SetCheckboxValue(WIDX_GUEST_IGNORE_RIDE_INTENSITY, gameState.Cheats.ignoreRideIntensity); + SetCheckboxValue(WIDX_GUEST_IGNORE_PRICE, gameState.Cheats.ignorePrice); + SetCheckboxValue(WIDX_DISABLE_VANDALISM, gameState.Cheats.disableVandalism); + SetCheckboxValue(WIDX_DISABLE_LITTERING, gameState.Cheats.disableLittering); break; } case WINDOW_CHEATS_PAGE_PARK: @@ -561,32 +561,32 @@ static StringId window_cheats_page_titles[] = { widgets[WIDX_OPEN_CLOSE_PARK].text = STR_CHEAT_CLOSE_PARK; SetCheckboxValue(WIDX_FORCE_PARK_RATING, Park::GetForcedRating() >= 0); - SetCheckboxValue(WIDX_NEVERENDING_MARKETING, gameState.Cheats.NeverendingMarketing); - SetCheckboxValue(WIDX_ALLOW_BUILD_IN_PAUSE_MODE, gameState.Cheats.BuildInPauseMode); - SetCheckboxValue(WIDX_ALLOW_REGULAR_PATH_AS_QUEUE, gameState.Cheats.AllowRegularPathAsQueue); - SetCheckboxValue(WIDX_ALLOW_SPECIAL_COLOUR_SCHEMES, gameState.Cheats.AllowSpecialColourSchemes); + SetCheckboxValue(WIDX_NEVERENDING_MARKETING, gameState.Cheats.neverendingMarketing); + SetCheckboxValue(WIDX_ALLOW_BUILD_IN_PAUSE_MODE, gameState.Cheats.buildInPauseMode); + SetCheckboxValue(WIDX_ALLOW_REGULAR_PATH_AS_QUEUE, gameState.Cheats.allowRegularPathAsQueue); + SetCheckboxValue(WIDX_ALLOW_SPECIAL_COLOUR_SCHEMES, gameState.Cheats.allowSpecialColourSchemes); break; case WINDOW_CHEATS_PAGE_RIDES: - SetCheckboxValue(WIDX_UNLOCK_OPERATING_LIMITS, gameState.Cheats.UnlockOperatingLimits); - SetCheckboxValue(WIDX_DISABLE_BRAKES_FAILURE, gameState.Cheats.DisableBrakesFailure); - SetCheckboxValue(WIDX_DISABLE_ALL_BREAKDOWNS, gameState.Cheats.DisableAllBreakdowns); - SetCheckboxValue(WIDX_SHOW_ALL_OPERATING_MODES, gameState.Cheats.ShowAllOperatingModes); + SetCheckboxValue(WIDX_UNLOCK_OPERATING_LIMITS, gameState.Cheats.unlockOperatingLimits); + SetCheckboxValue(WIDX_DISABLE_BRAKES_FAILURE, gameState.Cheats.disableBrakesFailure); + SetCheckboxValue(WIDX_DISABLE_ALL_BREAKDOWNS, gameState.Cheats.disableAllBreakdowns); + SetCheckboxValue(WIDX_SHOW_ALL_OPERATING_MODES, gameState.Cheats.showAllOperatingModes); SetCheckboxValue( - WIDX_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES, gameState.Cheats.ShowVehiclesFromOtherTrackTypes); - SetCheckboxValue(WIDX_DISABLE_TRAIN_LENGTH_LIMITS, gameState.Cheats.DisableTrainLengthLimit); - SetCheckboxValue(WIDX_ENABLE_CHAIN_LIFT_ON_ALL_TRACK, gameState.Cheats.EnableChainLiftOnAllTrack); - SetCheckboxValue(WIDX_ENABLE_ARBITRARY_RIDE_TYPE_CHANGES, gameState.Cheats.AllowArbitraryRideTypeChanges); - SetCheckboxValue(WIDX_DISABLE_RIDE_VALUE_AGING, gameState.Cheats.DisableRideValueAging); - SetCheckboxValue(WIDX_IGNORE_RESEARCH_STATUS, gameState.Cheats.IgnoreResearchStatus); - SetCheckboxValue(WIDX_ENABLE_ALL_DRAWABLE_TRACK_PIECES, gameState.Cheats.EnableAllDrawableTrackPieces); - SetCheckboxValue(WIDX_ALLOW_TRACK_PLACE_INVALID_HEIGHTS, gameState.Cheats.AllowTrackPlaceInvalidHeights); - SetCheckboxValue(WIDX_MAKE_DESTRUCTIBLE, gameState.Cheats.MakeAllDestructible); + WIDX_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES, gameState.Cheats.showVehiclesFromOtherTrackTypes); + SetCheckboxValue(WIDX_DISABLE_TRAIN_LENGTH_LIMITS, gameState.Cheats.disableTrainLengthLimit); + SetCheckboxValue(WIDX_ENABLE_CHAIN_LIFT_ON_ALL_TRACK, gameState.Cheats.enableChainLiftOnAllTrack); + SetCheckboxValue(WIDX_ENABLE_ARBITRARY_RIDE_TYPE_CHANGES, gameState.Cheats.allowArbitraryRideTypeChanges); + SetCheckboxValue(WIDX_DISABLE_RIDE_VALUE_AGING, gameState.Cheats.disableRideValueAging); + SetCheckboxValue(WIDX_IGNORE_RESEARCH_STATUS, gameState.Cheats.ignoreResearchStatus); + SetCheckboxValue(WIDX_ENABLE_ALL_DRAWABLE_TRACK_PIECES, gameState.Cheats.enableAllDrawableTrackPieces); + SetCheckboxValue(WIDX_ALLOW_TRACK_PLACE_INVALID_HEIGHTS, gameState.Cheats.allowTrackPlaceInvalidHeights); + SetCheckboxValue(WIDX_MAKE_DESTRUCTIBLE, gameState.Cheats.makeAllDestructible); break; case WINDOW_CHEATS_PAGE_STAFF: - SetCheckboxValue(WIDX_DISABLE_PLANT_AGING, gameState.Cheats.DisablePlantAging); + SetCheckboxValue(WIDX_DISABLE_PLANT_AGING, gameState.Cheats.disablePlantAging); break; case WINDOW_CHEATS_PAGE_WEATHER: - SetCheckboxValue(WIDX_FREEZE_WEATHER, gameState.Cheats.FreezeWeather); + SetCheckboxValue(WIDX_FREEZE_WEATHER, gameState.Cheats.freezeWeather); break; } @@ -595,7 +595,7 @@ static StringId window_cheats_page_titles[] = { // Staff speed window_cheats_staff_widgets[WIDX_STAFF_SPEED].text = _staffSpeedNames[EnumValue( - gameState.Cheats.SelectedStaffSpeed)]; + gameState.Cheats.selectedStaffSpeed)]; if (gScreenFlags & SCREEN_FLAGS_EDITOR) { @@ -1007,7 +1007,7 @@ static StringId window_cheats_page_titles[] = { WindowDropdownShowTextCustomWidth( { windowPos.x + dropdownWidget->left, windowPos.y + dropdownWidget->top }, dropdownWidget->height() + 1, colours[1], 0, Dropdown::Flag::StayOpen, 3, dropdownWidget->width() - 3); - Dropdown::SetChecked(EnumValue(gameState.Cheats.SelectedStaffSpeed), true); + Dropdown::SetChecked(EnumValue(gameState.Cheats.selectedStaffSpeed), true); } } } @@ -1060,7 +1060,7 @@ static StringId window_cheats_page_titles[] = { CheatsSet(CheatType::HaveFun); break; case WIDX_NEVERENDING_MARKETING: - CheatsSet(CheatType::NeverEndingMarketing, !gameState.Cheats.NeverendingMarketing); + CheatsSet(CheatType::NeverendingMarketing, !gameState.Cheats.neverendingMarketing); break; case WIDX_FORCE_PARK_RATING: if (Park::GetForcedRating() >= 0) @@ -1073,13 +1073,13 @@ static StringId window_cheats_page_titles[] = { } break; case WIDX_ALLOW_BUILD_IN_PAUSE_MODE: - CheatsSet(CheatType::BuildInPauseMode, !gameState.Cheats.BuildInPauseMode); + CheatsSet(CheatType::BuildInPauseMode, !gameState.Cheats.buildInPauseMode); break; case WIDX_ALLOW_REGULAR_PATH_AS_QUEUE: - CheatsSet(CheatType::AllowRegularPathAsQueue, !gameState.Cheats.AllowRegularPathAsQueue); + CheatsSet(CheatType::AllowRegularPathAsQueue, !gameState.Cheats.allowRegularPathAsQueue); break; case WIDX_ALLOW_SPECIAL_COLOUR_SCHEMES: - CheatsSet(CheatType::AllowSpecialColourSchemes, !gameState.Cheats.AllowSpecialColourSchemes); + CheatsSet(CheatType::AllowSpecialColourSchemes, !gameState.Cheats.allowSpecialColourSchemes); break; } } @@ -1105,7 +1105,7 @@ static StringId window_cheats_page_titles[] = { CheatsSet(CheatType::RemoveLitter); break; case WIDX_DISABLE_PLANT_AGING: - CheatsSet(CheatType::DisablePlantAging, !gameState.Cheats.DisablePlantAging); + CheatsSet(CheatType::DisablePlantAging, !gameState.Cheats.disablePlantAging); break; } } @@ -1116,7 +1116,7 @@ static StringId window_cheats_page_titles[] = { switch (widgetIndex) { case WIDX_FREEZE_WEATHER: - CheatsSet(CheatType::FreezeWeather, !gameState.Cheats.FreezeWeather); + CheatsSet(CheatType::FreezeWeather, !gameState.Cheats.freezeWeather); break; case WIDX_CREATE_DUCKS: CheatsSet(CheatType::CreateDucks, kCheatsDuckIncrement); @@ -1141,17 +1141,17 @@ static StringId window_cheats_page_titles[] = { switch (dropdownIndex) { case 0: - gameState.Cheats.SelectedStaffSpeed = StaffSpeedCheat::None; + gameState.Cheats.selectedStaffSpeed = StaffSpeedCheat::None; speed = kCheatsStaffNormalSpeed; break; case 1: - gameState.Cheats.SelectedStaffSpeed = StaffSpeedCheat::Frozen; + gameState.Cheats.selectedStaffSpeed = StaffSpeedCheat::Frozen; speed = kCheatsStaffFreezeSpeed; break; case 2: - gameState.Cheats.SelectedStaffSpeed = StaffSpeedCheat::Fast; + gameState.Cheats.selectedStaffSpeed = StaffSpeedCheat::Fast; speed = kCheatsStaffFastSpeed; } CheatsSet(CheatType::SetStaffSpeed, speed); @@ -1245,16 +1245,16 @@ static StringId window_cheats_page_titles[] = { CheatsSet(CheatType::GiveAllGuests, OBJECT_UMBRELLA); break; case WIDX_GUEST_IGNORE_RIDE_INTENSITY: - CheatsSet(CheatType::IgnoreRideIntensity, !gameState.Cheats.IgnoreRideIntensity); + CheatsSet(CheatType::IgnoreRideIntensity, !gameState.Cheats.ignoreRideIntensity); break; case WIDX_GUEST_IGNORE_PRICE: - CheatsSet(CheatType::IgnorePrice, !gameState.Cheats.IgnorePrice); + CheatsSet(CheatType::IgnorePrice, !gameState.Cheats.ignorePrice); break; case WIDX_DISABLE_VANDALISM: - CheatsSet(CheatType::DisableVandalism, !gameState.Cheats.DisableVandalism); + CheatsSet(CheatType::DisableVandalism, !gameState.Cheats.disableVandalism); break; case WIDX_DISABLE_LITTERING: - CheatsSet(CheatType::DisableLittering, !gameState.Cheats.DisableLittering); + CheatsSet(CheatType::DisableLittering, !gameState.Cheats.disableLittering); break; } } @@ -1268,19 +1268,19 @@ static StringId window_cheats_page_titles[] = { CheatsSet(CheatType::RenewRides); break; case WIDX_MAKE_DESTRUCTIBLE: - CheatsSet(CheatType::MakeDestructible, !gameState.Cheats.MakeAllDestructible); + CheatsSet(CheatType::MakeDestructible, !gameState.Cheats.makeAllDestructible); break; case WIDX_FIX_ALL: CheatsSet(CheatType::FixRides); break; case WIDX_UNLOCK_OPERATING_LIMITS: - CheatsSet(CheatType::FastLiftHill, !gameState.Cheats.UnlockOperatingLimits); + CheatsSet(CheatType::FastLiftHill, !gameState.Cheats.unlockOperatingLimits); break; case WIDX_DISABLE_BRAKES_FAILURE: - CheatsSet(CheatType::DisableBrakesFailure, !gameState.Cheats.DisableBrakesFailure); + CheatsSet(CheatType::DisableBrakesFailure, !gameState.Cheats.disableBrakesFailure); break; case WIDX_DISABLE_ALL_BREAKDOWNS: - CheatsSet(CheatType::DisableAllBreakdowns, !gameState.Cheats.DisableAllBreakdowns); + CheatsSet(CheatType::DisableAllBreakdowns, !gameState.Cheats.disableAllBreakdowns); break; case WIDX_RESET_CRASH_STATUS: CheatsSet(CheatType::ResetCrashStatus); @@ -1290,59 +1290,59 @@ static StringId window_cheats_page_titles[] = { break; case WIDX_SHOW_ALL_OPERATING_MODES: { - if (!gameState.Cheats.ShowAllOperatingModes) + if (!gameState.Cheats.showAllOperatingModes) { ContextShowError(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE, {}); } - CheatsSet(CheatType::ShowAllOperatingModes, !gameState.Cheats.ShowAllOperatingModes); + CheatsSet(CheatType::ShowAllOperatingModes, !gameState.Cheats.showAllOperatingModes); } break; case WIDX_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES: { - if (!gameState.Cheats.ShowVehiclesFromOtherTrackTypes) + if (!gameState.Cheats.showVehiclesFromOtherTrackTypes) { ContextShowError(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE, {}); } - CheatsSet(CheatType::ShowVehiclesFromOtherTrackTypes, !gameState.Cheats.ShowVehiclesFromOtherTrackTypes); + CheatsSet(CheatType::ShowVehiclesFromOtherTrackTypes, !gameState.Cheats.showVehiclesFromOtherTrackTypes); } break; case WIDX_DISABLE_TRAIN_LENGTH_LIMITS: { - if (!gameState.Cheats.DisableTrainLengthLimit) + if (!gameState.Cheats.disableTrainLengthLimit) { ContextShowError(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE, {}); } - CheatsSet(CheatType::DisableTrainLengthLimit, !gameState.Cheats.DisableTrainLengthLimit); + CheatsSet(CheatType::DisableTrainLengthLimit, !gameState.Cheats.disableTrainLengthLimit); } break; case WIDX_ENABLE_CHAIN_LIFT_ON_ALL_TRACK: - CheatsSet(CheatType::EnableChainLiftOnAllTrack, !gameState.Cheats.EnableChainLiftOnAllTrack); + CheatsSet(CheatType::EnableChainLiftOnAllTrack, !gameState.Cheats.enableChainLiftOnAllTrack); break; case WIDX_ENABLE_ARBITRARY_RIDE_TYPE_CHANGES: { - if (!gameState.Cheats.AllowArbitraryRideTypeChanges) + if (!gameState.Cheats.allowArbitraryRideTypeChanges) { ContextShowError(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE, {}); } - CheatsSet(CheatType::AllowArbitraryRideTypeChanges, !gameState.Cheats.AllowArbitraryRideTypeChanges); + CheatsSet(CheatType::AllowArbitraryRideTypeChanges, !gameState.Cheats.allowArbitraryRideTypeChanges); } break; case WIDX_DISABLE_RIDE_VALUE_AGING: - CheatsSet(CheatType::DisableRideValueAging, !gameState.Cheats.DisableRideValueAging); + CheatsSet(CheatType::DisableRideValueAging, !gameState.Cheats.disableRideValueAging); break; case WIDX_IGNORE_RESEARCH_STATUS: - CheatsSet(CheatType::IgnoreResearchStatus, !gameState.Cheats.IgnoreResearchStatus); + CheatsSet(CheatType::IgnoreResearchStatus, !gameState.Cheats.ignoreResearchStatus); break; case WIDX_ENABLE_ALL_DRAWABLE_TRACK_PIECES: - CheatsSet(CheatType::EnableAllDrawableTrackPieces, !gameState.Cheats.EnableAllDrawableTrackPieces); + CheatsSet(CheatType::EnableAllDrawableTrackPieces, !gameState.Cheats.enableAllDrawableTrackPieces); break; case WIDX_ALLOW_TRACK_PLACE_INVALID_HEIGHTS: { - if (!gameState.Cheats.AllowTrackPlaceInvalidHeights) + if (!gameState.Cheats.allowTrackPlaceInvalidHeights) { ContextShowError(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE, {}); } - CheatsSet(CheatType::AllowTrackPlaceInvalidHeights, !gameState.Cheats.AllowTrackPlaceInvalidHeights); + CheatsSet(CheatType::AllowTrackPlaceInvalidHeights, !gameState.Cheats.allowTrackPlaceInvalidHeights); } break; } diff --git a/src/openrct2-ui/windows/Dropdown.cpp b/src/openrct2-ui/windows/Dropdown.cpp index 2c6fcd0af0..a541064936 100644 --- a/src/openrct2-ui/windows/Dropdown.cpp +++ b/src/openrct2-ui/windows/Dropdown.cpp @@ -498,7 +498,7 @@ static constexpr colour_t kColoursDropdownOrder[] = { { int32_t defaultIndex = -1; - const bool specialColoursEnabled = !alwaysHideSpecialColours && GetGameState().Cheats.AllowSpecialColourSchemes; + const bool specialColoursEnabled = !alwaysHideSpecialColours && GetGameState().Cheats.allowSpecialColourSchemes; auto numColours = specialColoursEnabled ? static_cast(COLOUR_COUNT) : kColourNumNormal; // Set items for (uint64_t i = 0; i < numColours; i++) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index b6f0a551b6..45e8ec2bd4 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -670,7 +670,7 @@ namespace OpenRCT2::Ui::Windows uint32_t numPathTypes = 0; // If the game is in sandbox mode, also show paths that are normally restricted to the scenario editor - bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode); + bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode); _dropdownEntries.clear(); std::optional defaultIndex; @@ -688,14 +688,14 @@ namespace OpenRCT2::Ui::Windows } // If regular paths can be used as queue, only hide the path if we’re _not_ looking at a queue, // but the path surface is one. - if (GetGameState().Cheats.AllowRegularPathAsQueue && !showQueues + if (GetGameState().Cheats.allowRegularPathAsQueue && !showQueues && ((pathType->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0)) { continue; } // If the cheat is disabled, hide queues from the regular path view and vice versa. else if ( - !GetGameState().Cheats.AllowRegularPathAsQueue + !GetGameState().Cheats.allowRegularPathAsQueue && showQueues != ((pathType->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0)) { continue; @@ -821,7 +821,7 @@ namespace OpenRCT2::Ui::Windows auto info = GetMapCoordinatesFromPos(screenCoords, interactionFlags); if (info.interactionType != ViewportInteractionItem::None) { - const bool allowInvalidHeights = GetGameState().Cheats.AllowTrackPlaceInvalidHeights; + const bool allowInvalidHeights = GetGameState().Cheats.allowTrackPlaceInvalidHeights; const auto heightStep = kCoordsZStep * (!allowInvalidHeights ? 2 : 1); _footpathPlaceCtrlZ = Floor2(info.Element->GetBaseZ(), heightStep); @@ -854,7 +854,7 @@ namespace OpenRCT2::Ui::Windows _footpathPlaceShiftZ = mainWnd->viewport->zoom.ApplyTo(_footpathPlaceShiftZ); } - const bool allowInvalidHeights = GetGameState().Cheats.AllowTrackPlaceInvalidHeights; + const bool allowInvalidHeights = GetGameState().Cheats.allowTrackPlaceInvalidHeights; const auto heightStep = kCoordsZStep * (!allowInvalidHeights ? 2 : 1); _footpathPlaceShiftZ = Floor2(_footpathPlaceShiftZ, heightStep); @@ -1589,7 +1589,7 @@ namespace OpenRCT2::Ui::Windows void KeyboardShortcutDemolishCurrent() { if (IsWidgetDisabled(WIDX_REMOVE) || widgets[WIDX_REMOVE].type == WindowWidgetType::Empty - || (!GetGameState().Cheats.BuildInPauseMode && GameIsPaused())) + || (!GetGameState().Cheats.buildInPauseMode && GameIsPaused())) { return; } diff --git a/src/openrct2-ui/windows/LandRights.cpp b/src/openrct2-ui/windows/LandRights.cpp index 2d85fb0190..e509ee5cf1 100644 --- a/src/openrct2-ui/windows/LandRights.cpp +++ b/src/openrct2-ui/windows/LandRights.cpp @@ -98,7 +98,7 @@ namespace OpenRCT2::Ui::Windows bool IsOwnershipMode() const { - return (gScreenFlags & SCREEN_FLAGS_EDITOR) != 0 || GetGameState().Cheats.SandboxMode; + return (gScreenFlags & SCREEN_FLAGS_EDITOR) != 0 || GetGameState().Cheats.sandboxMode; } void SwitchToMode(LandRightsMode mode) diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 049532acc7..7cf558b873 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -73,7 +73,7 @@ namespace OpenRCT2::Ui::Windows static bool isEditorOrSandbox() { - return (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode; + return (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode; } static constexpr StringId WINDOW_TITLE = STR_MAP_LABEL; diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index 4d02634b6c..0ffcfd8ab5 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -618,7 +618,7 @@ namespace OpenRCT2::Ui::Windows auto currentRideEntry = GetRideEntryByIndex(rideEntryIndex); // Skip if vehicle type is not invented yet - if (!RideEntryIsInvented(rideEntryIndex) && !GetGameState().Cheats.IgnoreResearchStatus) + if (!RideEntryIsInvented(rideEntryIndex) && !GetGameState().Cheats.ignoreResearchStatus) { continue; } @@ -680,7 +680,7 @@ namespace OpenRCT2::Ui::Windows for (auto rideEntryIndex : rideEntries) { // Skip if vehicle type is not invented yet - if (!RideEntryIsInvented(rideEntryIndex) && !GetGameState().Cheats.IgnoreResearchStatus) + if (!RideEntryIsInvented(rideEntryIndex) && !GetGameState().Cheats.ignoreResearchStatus) continue; // Ride entries diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 2cb802cc02..e07b24c4f0 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -1708,7 +1708,7 @@ namespace OpenRCT2::Ui::Windows } } } - if (GetGameState().Cheats.AllowArbitraryRideTypeChanges) + if (GetGameState().Cheats.allowArbitraryRideTypeChanges) { minHeight += 15; } @@ -2010,7 +2010,7 @@ namespace OpenRCT2::Ui::Windows const auto& gameState = GetGameState(); const auto& rtd = ride.GetRideTypeDescriptor(); - if (gameState.Cheats.ShowVehiclesFromOtherTrackTypes + if (gameState.Cheats.showVehiclesFromOtherTrackTypes && !( rtd.HasFlag(RtdFlag::isFlatRide) || rtd.specialType == RtdSpecialType::maze || rtd.specialType == RtdSpecialType::miniGolf)) @@ -2051,7 +2051,7 @@ namespace OpenRCT2::Ui::Windows continue; // Skip if vehicle type has not been invented yet - if (!RideEntryIsInvented(rideEntryIndex) && !gameState.Cheats.IgnoreResearchStatus) + if (!RideEntryIsInvented(rideEntryIndex) && !gameState.Cheats.ignoreResearchStatus) continue; auto name = currentRideEntry->naming.Name; @@ -2339,7 +2339,7 @@ namespace OpenRCT2::Ui::Windows const auto& gameState = GetGameState(); disabled_widgets &= ~((1uLL << WIDX_DEMOLISH) | (1uLL << WIDX_CONSTRUCTION)); if (ride->lifecycle_flags & (RIDE_LIFECYCLE_INDESTRUCTIBLE | RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) - && !gameState.Cheats.MakeAllDestructible) + && !gameState.Cheats.makeAllDestructible) disabled_widgets |= (1uLL << WIDX_DEMOLISH); auto ft = Formatter::Common(); @@ -2378,7 +2378,7 @@ namespace OpenRCT2::Ui::Windows AnchorBorderWidgets(); - const int32_t offset = gameState.Cheats.AllowArbitraryRideTypeChanges ? 15 : 0; + const int32_t offset = gameState.Cheats.allowArbitraryRideTypeChanges ? 15 : 0; // Anchor main page specific widgets widgets[WIDX_VIEWPORT].right = width - 26; widgets[WIDX_VIEWPORT].bottom = height - (14 + offset); @@ -2396,7 +2396,7 @@ namespace OpenRCT2::Ui::Windows widgets[WIDX_RIDE_TYPE_DROPDOWN].top = height - 16; widgets[WIDX_RIDE_TYPE_DROPDOWN].bottom = height - 5; - if (!gameState.Cheats.AllowArbitraryRideTypeChanges) + if (!gameState.Cheats.allowArbitraryRideTypeChanges) { widgets[WIDX_RIDE_TYPE].type = WindowWidgetType::Empty; widgets[WIDX_RIDE_TYPE_DROPDOWN].type = WindowWidgetType::Empty; @@ -2812,7 +2812,7 @@ namespace OpenRCT2::Ui::Windows const auto& gameState = GetGameState(); // Trains - if (rideEntry->cars_per_flat_ride > 1 || gameState.Cheats.DisableTrainLengthLimit) + if (rideEntry->cars_per_flat_ride > 1 || gameState.Cheats.disableTrainLengthLimit) { widgets[WIDX_VEHICLE_TRAINS].type = WindowWidgetType::Spinner; widgets[WIDX_VEHICLE_TRAINS_INCREASE].type = WindowWidgetType::Button; @@ -2826,7 +2826,7 @@ namespace OpenRCT2::Ui::Windows } // Cars per train - if (rideEntry->zero_cars + 1 < rideEntry->max_cars_in_train || gameState.Cheats.DisableTrainLengthLimit) + if (rideEntry->zero_cars + 1 < rideEntry->max_cars_in_train || gameState.Cheats.disableTrainLengthLimit) { widgets[WIDX_VEHICLE_CARS_PER_TRAIN].type = WindowWidgetType::Spinner; widgets[WIDX_VEHICLE_CARS_PER_TRAIN_INCREASE].type = WindowWidgetType::Button; @@ -2840,7 +2840,7 @@ namespace OpenRCT2::Ui::Windows } if (ride->GetRideTypeDescriptor().HasFlag(RtdFlag::allowReversedTrains) - || (gameState.Cheats.DisableTrainLengthLimit && !ride->GetRideTypeDescriptor().HasFlag(RtdFlag::isFlatRide))) + || (gameState.Cheats.disableTrainLengthLimit && !ride->GetRideTypeDescriptor().HasFlag(RtdFlag::isFlatRide))) { widgets[WIDX_VEHICLE_REVERSED_TRAINS_CHECKBOX].type = WindowWidgetType::Checkbox; if (ride->HasLifecycleFlag(RIDE_LIFECYCLE_REVERSED_TRAINS)) @@ -3083,9 +3083,9 @@ namespace OpenRCT2::Ui::Windows const auto& operatingSettings = ride->GetRideTypeDescriptor().OperatingSettings; const auto& gameState = GetGameState(); uint8_t maxValue = operatingSettings.MaxValue; - uint8_t minValue = gameState.Cheats.UnlockOperatingLimits ? 0 : operatingSettings.MinValue; + uint8_t minValue = gameState.Cheats.unlockOperatingLimits ? 0 : operatingSettings.MinValue; - if (gameState.Cheats.UnlockOperatingLimits) + if (gameState.Cheats.unlockOperatingLimits) { maxValue = OpenRCT2::Limits::kCheatsMaxOperatingLimit; } @@ -3105,8 +3105,8 @@ namespace OpenRCT2::Ui::Windows const auto& operatingSettings = ride->GetRideTypeDescriptor().OperatingSettings; const auto& gameState = GetGameState(); uint8_t maxValue = operatingSettings.MaxValue; - uint8_t minValue = gameState.Cheats.UnlockOperatingLimits ? 0 : operatingSettings.MinValue; - if (gameState.Cheats.UnlockOperatingLimits) + uint8_t minValue = gameState.Cheats.unlockOperatingLimits ? 0 : operatingSettings.MinValue; + if (gameState.Cheats.unlockOperatingLimits) { maxValue = OpenRCT2::Limits::kCheatsMaxOperatingLimit; } @@ -3243,10 +3243,10 @@ namespace OpenRCT2::Ui::Windows ModeTweakDecrease(); break; case WIDX_LIFT_HILL_SPEED_INCREASE: - upperBound = GetGameState().Cheats.UnlockOperatingLimits + upperBound = GetGameState().Cheats.unlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit : ride->GetRideTypeDescriptor().LiftData.maximum_speed; - lowerBound = GetGameState().Cheats.UnlockOperatingLimits + lowerBound = GetGameState().Cheats.unlockOperatingLimits ? 0 : ride->GetRideTypeDescriptor().LiftData.minimum_speed; SetOperatingSetting( @@ -3254,10 +3254,10 @@ namespace OpenRCT2::Ui::Windows std::clamp(ride->lift_hill_speed + 1, lowerBound, upperBound)); break; case WIDX_LIFT_HILL_SPEED_DECREASE: - upperBound = GetGameState().Cheats.UnlockOperatingLimits + upperBound = GetGameState().Cheats.unlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit : ride->GetRideTypeDescriptor().LiftData.maximum_speed; - lowerBound = GetGameState().Cheats.UnlockOperatingLimits + lowerBound = GetGameState().Cheats.unlockOperatingLimits ? 0 : ride->GetRideTypeDescriptor().LiftData.minimum_speed; SetOperatingSetting( @@ -3305,7 +3305,7 @@ namespace OpenRCT2::Ui::Windows LoadDropdown(&widgets[widgetIndex]); break; case WIDX_OPERATE_NUMBER_OF_CIRCUITS_INCREASE: - upperBound = GetGameState().Cheats.UnlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit + upperBound = GetGameState().Cheats.unlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit : OpenRCT2::Limits::kMaxCircuitsPerRide; lowerBound = 1; SetOperatingSetting( @@ -3313,7 +3313,7 @@ namespace OpenRCT2::Ui::Windows std::clamp(ride->num_circuits + 1, lowerBound, upperBound)); break; case WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE: - upperBound = GetGameState().Cheats.UnlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit + upperBound = GetGameState().Cheats.unlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit : OpenRCT2::Limits::kMaxCircuitsPerRide; lowerBound = 1; SetOperatingSetting( @@ -3358,9 +3358,9 @@ namespace OpenRCT2::Ui::Windows const auto& operatingSettings = ride.GetRideTypeDescriptor().OperatingSettings; const auto& gameState = GetGameState(); - int16_t maxValue = gameState.Cheats.UnlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit + int16_t maxValue = gameState.Cheats.unlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit : operatingSettings.MaxValue; - int16_t minValue = gameState.Cheats.UnlockOperatingLimits ? 0 : operatingSettings.MinValue; + int16_t minValue = gameState.Cheats.unlockOperatingLimits ? 0 : operatingSettings.MinValue; const auto& title = widgets[WIDX_MODE_TWEAK_LABEL].text; Formatter ft; @@ -3441,9 +3441,9 @@ namespace OpenRCT2::Ui::Windows { const auto& operatingSettings = ride->GetRideTypeDescriptor().OperatingSettings; const auto& gameState = GetGameState(); - uint32_t maxValue = gameState.Cheats.UnlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit + uint32_t maxValue = gameState.Cheats.unlockOperatingLimits ? OpenRCT2::Limits::kCheatsMaxOperatingLimit : operatingSettings.MaxValue; - uint32_t minValue = gameState.Cheats.UnlockOperatingLimits ? 0 : operatingSettings.MinValue; + uint32_t minValue = gameState.Cheats.unlockOperatingLimits ? 0 : operatingSettings.MinValue; auto multiplier = ride->GetRideTypeDescriptor().OperatingSettings.OperatingSettingMultiplier; try @@ -5108,7 +5108,7 @@ namespace OpenRCT2::Ui::Windows } } - if (GetGameState().Cheats.UnlockOperatingLimits || musicObj->SupportsRideType(ride->type)) + if (GetGameState().Cheats.unlockOperatingLimits || musicObj->SupportsRideType(ride->type)) { musicOrder.push_back(i); } diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index e624a8f4e0..40fd197018 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -425,7 +425,7 @@ namespace OpenRCT2::Ui::Windows } } if (currentRide->GetRideTypeDescriptor().HasFlag(RtdFlag::upInclineRequiresLift) - && !GetGameState().Cheats.EnableAllDrawableTrackPieces) + && !GetGameState().Cheats.enableAllDrawableTrackPieces) { // Disable lift hill toggle and banking if current track piece is uphill if (_previousTrackPitchEnd == TrackPitch::Up25 || _previousTrackPitchEnd == TrackPitch::Up60 @@ -748,7 +748,7 @@ namespace OpenRCT2::Ui::Windows { disabledWidgets |= (1uLL << WIDX_SLOPE_DOWN); } - if ((_currentTrackHasLiftHill) && !GetGameState().Cheats.EnableChainLiftOnAllTrack) + if ((_currentTrackHasLiftHill) && !GetGameState().Cheats.enableChainLiftOnAllTrack) { if (_currentTrackPitchEnd != TrackPitch::None && !IsTrackEnabled(TrackGroup::liftHillCurve)) { @@ -841,7 +841,7 @@ namespace OpenRCT2::Ui::Windows { if (_currentTrackPitchEnd == TrackPitch::None && _previousTrackRollEnd != TrackRoll::None && (!currentRide->GetRideTypeDescriptor().HasFlag(RtdFlag::upInclineRequiresLift) - || GetGameState().Cheats.EnableAllDrawableTrackPieces)) + || GetGameState().Cheats.enableAllDrawableTrackPieces)) { disabledWidgets &= ~(1uLL << WIDX_SLOPE_UP); } @@ -905,7 +905,7 @@ namespace OpenRCT2::Ui::Windows } // If chain lift cheat is enabled then show the chain lift widget no matter what - if (GetGameState().Cheats.EnableChainLiftOnAllTrack) + if (GetGameState().Cheats.enableChainLiftOnAllTrack) { disabledWidgets &= ~(1uLL << WIDX_CHAIN_LIFT); } @@ -1330,7 +1330,7 @@ namespace OpenRCT2::Ui::Windows case WIDX_CHAIN_LIFT: RideConstructionInvalidateCurrentTrack(); _currentTrackHasLiftHill = !_currentTrackHasLiftHill; - if ((_currentTrackHasLiftHill) && !GetGameState().Cheats.EnableChainLiftOnAllTrack) + if ((_currentTrackHasLiftHill) && !GetGameState().Cheats.enableChainLiftOnAllTrack) _currentTrackAlternative.unset(AlternativeTrackFlag::alternativePieces); _currentTrackPrice = kMoney64Undefined; WindowRideConstructionUpdateActiveElements(); @@ -1383,7 +1383,7 @@ namespace OpenRCT2::Ui::Windows { auto trackSpeedIncrement = kDefaultSpeedIncrement; auto trackSpeedMinimum = kDefaultMinimumSpeed; - if (GetGameState().Cheats.UnlockOperatingLimits) + if (GetGameState().Cheats.unlockOperatingLimits) { trackSpeedMinimum = 0; } @@ -1414,7 +1414,7 @@ namespace OpenRCT2::Ui::Windows case WIDX_O_TRACK: RideConstructionInvalidateCurrentTrack(); _currentTrackAlternative.set(AlternativeTrackFlag::alternativePieces); - if (!GetGameState().Cheats.EnableChainLiftOnAllTrack) + if (!GetGameState().Cheats.enableChainLiftOnAllTrack) _currentTrackHasLiftHill = false; _currentTrackPrice = kMoney64Undefined; WindowRideConstructionUpdateActiveElements(); @@ -1775,13 +1775,13 @@ namespace OpenRCT2::Ui::Windows const auto& gameState = GetGameState(); if (currentRide->GetRideTypeDescriptor().HasFlag(RtdFlag::upInclineRequiresLift) && (_currentTrackPitchEnd == TrackPitch::Up25 || _currentTrackPitchEnd == TrackPitch::Up60) - && !gameState.Cheats.EnableAllDrawableTrackPieces) + && !gameState.Cheats.enableAllDrawableTrackPieces) { _currentTrackHasLiftHill = true; } if ((IsTrackEnabled(TrackGroup::liftHill) && !_currentlySelectedTrack.isTrackType) - || (gameState.Cheats.EnableChainLiftOnAllTrack + || (gameState.Cheats.enableChainLiftOnAllTrack && currentRide->GetRideTypeDescriptor().HasFlag(RtdFlag::hasTrack))) { widgets[WIDX_CHAIN_LIFT].type = WindowWidgetType::FlatBtn; @@ -2479,7 +2479,7 @@ namespace OpenRCT2::Ui::Windows { _currentTrackPitchEnd = slope; _currentTrackPrice = kMoney64Undefined; - if (_rideConstructionState == RideConstructionState::Front && !GetGameState().Cheats.EnableChainLiftOnAllTrack) + if (_rideConstructionState == RideConstructionState::Front && !GetGameState().Cheats.enableChainLiftOnAllTrack) { switch (slope) { @@ -3572,7 +3572,7 @@ namespace OpenRCT2::Ui::Windows // FIX not sure exactly why it starts trial and error place from a lower Z, but it causes issues with disable // clearance - if (!GetGameState().Cheats.DisableClearanceChecks && z > kMinimumLandZ) + if (!GetGameState().Cheats.disableClearanceChecks && z > kMinimumLandZ) { z -= LAND_HEIGHT_STEP; } @@ -4928,7 +4928,7 @@ namespace OpenRCT2::Ui::Windows if (coveredVariant != TrackElemType::None && (availableGroups.get(EnumValue(ted.definition.group)))) { trackType = coveredVariant; - if (!GetGameState().Cheats.EnableChainLiftOnAllTrack) + if (!GetGameState().Cheats.enableChainLiftOnAllTrack) liftHillAndInvertedState.unset(LiftHillAndInverted::liftHill); } } @@ -4978,7 +4978,7 @@ namespace OpenRCT2::Ui::Windows turnOffLiftHill = true; } - if (turnOffLiftHill && !GetGameState().Cheats.EnableChainLiftOnAllTrack) + if (turnOffLiftHill && !GetGameState().Cheats.enableChainLiftOnAllTrack) { liftHillAndInvertedState.unset(LiftHillAndInverted::liftHill); _currentTrackHasLiftHill = false; diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index 72a51fcb32..958a14e3b8 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -680,7 +680,7 @@ namespace OpenRCT2::Ui::Windows widgets[WIDX_SCENERY_ROTATE_OBJECTS_BUTTON].type = WindowWidgetType::FlatBtn; } - if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode) + if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode) { widgets[WIDX_RESTRICT_SCENERY].type = WindowWidgetType::Button; if (IsSceneryItemRestricted(tabSelectedScenery)) @@ -2364,7 +2364,7 @@ namespace OpenRCT2::Ui::Windows void Sub6E1F34UpdateScreenCoordsAndButtonsPressed(bool canRaiseItem, ScreenCoordsXY& screenPos) { - if (!canRaiseItem && !GetGameState().Cheats.DisableSupportLimits) + if (!canRaiseItem && !GetGameState().Cheats.disableSupportLimits) { gSceneryCtrlPressed = false; gSceneryShiftPressed = false; diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 319bc78b0b..2641aecd93 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -916,7 +916,7 @@ namespace OpenRCT2::Ui::Windows GfxDrawSprite(dpi, ImageId(SPR_G2_SANDBOX), screenPos); // Draw an overlay if clearance checks are disabled - if (GetGameState().Cheats.DisableClearanceChecks) + if (GetGameState().Cheats.disableClearanceChecks) { auto colour = ColourWithFlags{ COLOUR_DARK_ORANGE }.withFlag(ColourFlag::withOutline, true); DrawTextBasic( @@ -1448,15 +1448,15 @@ namespace OpenRCT2::Ui::Windows } auto& gameState = GetGameState(); - if (gameState.Cheats.SandboxMode) + if (gameState.Cheats.sandboxMode) { Dropdown::SetChecked(DDIDX_ENABLE_SANDBOX_MODE, true); } - if (gameState.Cheats.DisableClearanceChecks) + if (gameState.Cheats.disableClearanceChecks) { Dropdown::SetChecked(DDIDX_DISABLE_CLEARANCE_CHECKS, true); } - if (gameState.Cheats.DisableSupportLimits) + if (gameState.Cheats.disableSupportLimits) { Dropdown::SetChecked(DDIDX_DISABLE_SUPPORT_LIMITS, true); } @@ -1488,13 +1488,13 @@ namespace OpenRCT2::Ui::Windows ContextOpenWindow(WindowClass::EditorObjectiveOptions); break; case DDIDX_ENABLE_SANDBOX_MODE: - CheatsSet(CheatType::SandboxMode, !GetGameState().Cheats.SandboxMode); + CheatsSet(CheatType::SandboxMode, !GetGameState().Cheats.sandboxMode); break; case DDIDX_DISABLE_CLEARANCE_CHECKS: - CheatsSet(CheatType::DisableClearanceChecks, !GetGameState().Cheats.DisableClearanceChecks); + CheatsSet(CheatType::DisableClearanceChecks, !GetGameState().Cheats.disableClearanceChecks); break; case DDIDX_DISABLE_SUPPORT_LIMITS: - CheatsSet(CheatType::DisableSupportLimits, !GetGameState().Cheats.DisableSupportLimits); + CheatsSet(CheatType::DisableSupportLimits, !GetGameState().Cheats.disableSupportLimits); break; } } diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 54ae966d59..a4dad85240 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -207,7 +207,7 @@ namespace OpenRCT2::Ui::Windows } money64 cost = kMoney64Undefined; - if (GameIsNotPaused() || GetGameState().Cheats.BuildInPauseMode) + if (GameIsNotPaused() || GetGameState().Cheats.buildInPauseMode) { ClearProvisional(); auto res = FindValidTrackDesignPlaceHeight(trackLoc, GAME_COMMAND_FLAG_NO_SPEND | GAME_COMMAND_FLAG_GHOST); diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index d84407f232..7427f8931f 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -30,33 +30,33 @@ using namespace OpenRCT2; void CheatsReset() { auto& gameState = GetGameState(); - gameState.Cheats.SandboxMode = false; - gameState.Cheats.DisableClearanceChecks = false; - gameState.Cheats.DisableSupportLimits = false; - gameState.Cheats.ShowAllOperatingModes = false; - gameState.Cheats.ShowVehiclesFromOtherTrackTypes = false; - gameState.Cheats.DisableTrainLengthLimit = false; - gameState.Cheats.EnableChainLiftOnAllTrack = false; - gameState.Cheats.UnlockOperatingLimits = false; - gameState.Cheats.DisableBrakesFailure = false; - gameState.Cheats.DisableAllBreakdowns = false; - gameState.Cheats.BuildInPauseMode = false; - gameState.Cheats.IgnoreRideIntensity = false; - gameState.Cheats.IgnorePrice = false; - gameState.Cheats.DisableVandalism = false; - gameState.Cheats.DisableLittering = false; - gameState.Cheats.NeverendingMarketing = false; - gameState.Cheats.FreezeWeather = false; - gameState.Cheats.DisablePlantAging = false; - gameState.Cheats.AllowArbitraryRideTypeChanges = false; - gameState.Cheats.DisableRideValueAging = false; - gameState.Cheats.IgnoreResearchStatus = false; - gameState.Cheats.EnableAllDrawableTrackPieces = false; - gameState.Cheats.AllowTrackPlaceInvalidHeights = false; - gameState.Cheats.AllowRegularPathAsQueue = false; - gameState.Cheats.AllowSpecialColourSchemes = false; - gameState.Cheats.MakeAllDestructible = false; - gameState.Cheats.SelectedStaffSpeed = StaffSpeedCheat::None; + gameState.Cheats.sandboxMode = false; + gameState.Cheats.disableClearanceChecks = false; + gameState.Cheats.disableSupportLimits = false; + gameState.Cheats.showAllOperatingModes = false; + gameState.Cheats.showVehiclesFromOtherTrackTypes = false; + gameState.Cheats.disableTrainLengthLimit = false; + gameState.Cheats.enableChainLiftOnAllTrack = false; + gameState.Cheats.unlockOperatingLimits = false; + gameState.Cheats.disableBrakesFailure = false; + gameState.Cheats.disableAllBreakdowns = false; + gameState.Cheats.buildInPauseMode = false; + gameState.Cheats.ignoreRideIntensity = false; + gameState.Cheats.ignorePrice = false; + gameState.Cheats.disableVandalism = false; + gameState.Cheats.disableLittering = false; + gameState.Cheats.neverendingMarketing = false; + gameState.Cheats.freezeWeather = false; + gameState.Cheats.disablePlantAging = false; + gameState.Cheats.allowArbitraryRideTypeChanges = false; + gameState.Cheats.disableRideValueAging = false; + gameState.Cheats.ignoreResearchStatus = false; + gameState.Cheats.enableAllDrawableTrackPieces = false; + gameState.Cheats.allowTrackPlaceInvalidHeights = false; + gameState.Cheats.allowRegularPathAsQueue = false; + gameState.Cheats.allowSpecialColourSchemes = false; + gameState.Cheats.makeAllDestructible = false; + gameState.Cheats.selectedStaffSpeed = StaffSpeedCheat::None; gameState.Cheats.forcedParkRating = kForcedParkRatingDisabled; } @@ -86,36 +86,36 @@ void CheatsSerialise(DataSerialiser& ds) uint64_t countOffset = stream.GetPosition(); ds << count; - CheatEntrySerialise(ds, CheatType::SandboxMode, gameState.Cheats.SandboxMode, count); - CheatEntrySerialise(ds, CheatType::DisableClearanceChecks, gameState.Cheats.DisableClearanceChecks, count); - CheatEntrySerialise(ds, CheatType::DisableSupportLimits, gameState.Cheats.DisableSupportLimits, count); - CheatEntrySerialise(ds, CheatType::ShowAllOperatingModes, gameState.Cheats.ShowAllOperatingModes, count); + CheatEntrySerialise(ds, CheatType::SandboxMode, gameState.Cheats.sandboxMode, count); + CheatEntrySerialise(ds, CheatType::DisableClearanceChecks, gameState.Cheats.disableClearanceChecks, count); + CheatEntrySerialise(ds, CheatType::DisableSupportLimits, gameState.Cheats.disableSupportLimits, count); + CheatEntrySerialise(ds, CheatType::ShowAllOperatingModes, gameState.Cheats.showAllOperatingModes, count); CheatEntrySerialise( - ds, CheatType::ShowVehiclesFromOtherTrackTypes, gameState.Cheats.ShowVehiclesFromOtherTrackTypes, count); - CheatEntrySerialise(ds, CheatType::FastLiftHill, gameState.Cheats.UnlockOperatingLimits, count); - CheatEntrySerialise(ds, CheatType::DisableBrakesFailure, gameState.Cheats.DisableBrakesFailure, count); - CheatEntrySerialise(ds, CheatType::DisableAllBreakdowns, gameState.Cheats.DisableAllBreakdowns, count); - CheatEntrySerialise(ds, CheatType::BuildInPauseMode, gameState.Cheats.BuildInPauseMode, count); - CheatEntrySerialise(ds, CheatType::IgnoreRideIntensity, gameState.Cheats.IgnoreRideIntensity, count); - CheatEntrySerialise(ds, CheatType::DisableVandalism, gameState.Cheats.DisableVandalism, count); - CheatEntrySerialise(ds, CheatType::DisableLittering, gameState.Cheats.DisableLittering, count); - CheatEntrySerialise(ds, CheatType::NeverEndingMarketing, gameState.Cheats.NeverendingMarketing, count); - CheatEntrySerialise(ds, CheatType::FreezeWeather, gameState.Cheats.FreezeWeather, count); - CheatEntrySerialise(ds, CheatType::DisableTrainLengthLimit, gameState.Cheats.DisableTrainLengthLimit, count); - CheatEntrySerialise(ds, CheatType::DisablePlantAging, gameState.Cheats.DisablePlantAging, count); - CheatEntrySerialise(ds, CheatType::EnableChainLiftOnAllTrack, gameState.Cheats.EnableChainLiftOnAllTrack, count); + ds, CheatType::ShowVehiclesFromOtherTrackTypes, gameState.Cheats.showVehiclesFromOtherTrackTypes, count); + CheatEntrySerialise(ds, CheatType::FastLiftHill, gameState.Cheats.unlockOperatingLimits, count); + CheatEntrySerialise(ds, CheatType::DisableBrakesFailure, gameState.Cheats.disableBrakesFailure, count); + CheatEntrySerialise(ds, CheatType::DisableAllBreakdowns, gameState.Cheats.disableAllBreakdowns, count); + CheatEntrySerialise(ds, CheatType::BuildInPauseMode, gameState.Cheats.buildInPauseMode, count); + CheatEntrySerialise(ds, CheatType::IgnoreRideIntensity, gameState.Cheats.ignoreRideIntensity, count); + CheatEntrySerialise(ds, CheatType::DisableVandalism, gameState.Cheats.disableVandalism, count); + CheatEntrySerialise(ds, CheatType::DisableLittering, gameState.Cheats.disableLittering, count); + CheatEntrySerialise(ds, CheatType::NeverendingMarketing, gameState.Cheats.neverendingMarketing, count); + CheatEntrySerialise(ds, CheatType::FreezeWeather, gameState.Cheats.freezeWeather, count); + CheatEntrySerialise(ds, CheatType::DisableTrainLengthLimit, gameState.Cheats.disableTrainLengthLimit, count); + CheatEntrySerialise(ds, CheatType::DisablePlantAging, gameState.Cheats.disablePlantAging, count); + CheatEntrySerialise(ds, CheatType::EnableChainLiftOnAllTrack, gameState.Cheats.enableChainLiftOnAllTrack, count); CheatEntrySerialise( - ds, CheatType::AllowArbitraryRideTypeChanges, gameState.Cheats.AllowArbitraryRideTypeChanges, count); - CheatEntrySerialise(ds, CheatType::DisableRideValueAging, gameState.Cheats.DisableRideValueAging, count); - CheatEntrySerialise(ds, CheatType::IgnoreResearchStatus, gameState.Cheats.IgnoreResearchStatus, count); - CheatEntrySerialise(ds, CheatType::EnableAllDrawableTrackPieces, gameState.Cheats.EnableAllDrawableTrackPieces, count); + ds, CheatType::AllowArbitraryRideTypeChanges, gameState.Cheats.allowArbitraryRideTypeChanges, count); + CheatEntrySerialise(ds, CheatType::DisableRideValueAging, gameState.Cheats.disableRideValueAging, count); + CheatEntrySerialise(ds, CheatType::IgnoreResearchStatus, gameState.Cheats.ignoreResearchStatus, count); + CheatEntrySerialise(ds, CheatType::EnableAllDrawableTrackPieces, gameState.Cheats.enableAllDrawableTrackPieces, count); CheatEntrySerialise( - ds, CheatType::AllowTrackPlaceInvalidHeights, gameState.Cheats.AllowTrackPlaceInvalidHeights, count); - CheatEntrySerialise(ds, CheatType::AllowRegularPathAsQueue, gameState.Cheats.AllowRegularPathAsQueue, count); - CheatEntrySerialise(ds, CheatType::AllowSpecialColourSchemes, gameState.Cheats.AllowSpecialColourSchemes, count); - CheatEntrySerialise(ds, CheatType::MakeDestructible, gameState.Cheats.MakeAllDestructible, count); - CheatEntrySerialise(ds, CheatType::SetStaffSpeed, gameState.Cheats.SelectedStaffSpeed, count); - CheatEntrySerialise(ds, CheatType::IgnorePrice, gameState.Cheats.IgnorePrice, count); + ds, CheatType::AllowTrackPlaceInvalidHeights, gameState.Cheats.allowTrackPlaceInvalidHeights, count); + CheatEntrySerialise(ds, CheatType::AllowRegularPathAsQueue, gameState.Cheats.allowRegularPathAsQueue, count); + CheatEntrySerialise(ds, CheatType::AllowSpecialColourSchemes, gameState.Cheats.allowSpecialColourSchemes, count); + CheatEntrySerialise(ds, CheatType::MakeDestructible, gameState.Cheats.makeAllDestructible, count); + CheatEntrySerialise(ds, CheatType::SetStaffSpeed, gameState.Cheats.selectedStaffSpeed, count); + CheatEntrySerialise(ds, CheatType::IgnorePrice, gameState.Cheats.ignorePrice, count); CheatEntrySerialise(ds, CheatType::SetForcedParkRating, gameState.Cheats.forcedParkRating, count); // Remember current position and update count. @@ -141,88 +141,88 @@ void CheatsSerialise(DataSerialiser& ds) switch (static_cast(type)) { case CheatType::SandboxMode: - ds << gameState.Cheats.SandboxMode; + ds << gameState.Cheats.sandboxMode; break; case CheatType::DisableClearanceChecks: - ds << gameState.Cheats.DisableClearanceChecks; + ds << gameState.Cheats.disableClearanceChecks; break; case CheatType::DisableSupportLimits: - ds << gameState.Cheats.DisableSupportLimits; + ds << gameState.Cheats.disableSupportLimits; break; case CheatType::ShowAllOperatingModes: - ds << gameState.Cheats.ShowAllOperatingModes; + ds << gameState.Cheats.showAllOperatingModes; break; case CheatType::ShowVehiclesFromOtherTrackTypes: - ds << gameState.Cheats.ShowVehiclesFromOtherTrackTypes; + ds << gameState.Cheats.showVehiclesFromOtherTrackTypes; break; case CheatType::FastLiftHill: - ds << gameState.Cheats.UnlockOperatingLimits; + ds << gameState.Cheats.unlockOperatingLimits; break; case CheatType::DisableBrakesFailure: - ds << gameState.Cheats.DisableBrakesFailure; + ds << gameState.Cheats.disableBrakesFailure; break; case CheatType::DisableAllBreakdowns: - ds << gameState.Cheats.DisableAllBreakdowns; + ds << gameState.Cheats.disableAllBreakdowns; break; case CheatType::BuildInPauseMode: - ds << gameState.Cheats.BuildInPauseMode; + ds << gameState.Cheats.buildInPauseMode; break; case CheatType::IgnoreRideIntensity: - ds << gameState.Cheats.IgnoreRideIntensity; + ds << gameState.Cheats.ignoreRideIntensity; break; case CheatType::IgnorePrice: - ds << gameState.Cheats.IgnorePrice; + ds << gameState.Cheats.ignorePrice; break; case CheatType::DisableVandalism: - ds << gameState.Cheats.DisableVandalism; + ds << gameState.Cheats.disableVandalism; break; case CheatType::DisableLittering: - ds << gameState.Cheats.DisableLittering; + ds << gameState.Cheats.disableLittering; break; - case CheatType::NeverEndingMarketing: - ds << gameState.Cheats.NeverendingMarketing; + case CheatType::NeverendingMarketing: + ds << gameState.Cheats.neverendingMarketing; break; case CheatType::FreezeWeather: - ds << gameState.Cheats.FreezeWeather; + ds << gameState.Cheats.freezeWeather; break; case CheatType::DisableTrainLengthLimit: - ds << gameState.Cheats.DisableTrainLengthLimit; + ds << gameState.Cheats.disableTrainLengthLimit; break; case CheatType::DisablePlantAging: - ds << gameState.Cheats.DisablePlantAging; + ds << gameState.Cheats.disablePlantAging; break; case CheatType::EnableChainLiftOnAllTrack: - ds << gameState.Cheats.EnableChainLiftOnAllTrack; + ds << gameState.Cheats.enableChainLiftOnAllTrack; break; case CheatType::AllowArbitraryRideTypeChanges: - ds << gameState.Cheats.AllowArbitraryRideTypeChanges; + ds << gameState.Cheats.allowArbitraryRideTypeChanges; break; case CheatType::DisableRideValueAging: - ds << gameState.Cheats.DisableRideValueAging; + ds << gameState.Cheats.disableRideValueAging; break; case CheatType::IgnoreResearchStatus: - ds << gameState.Cheats.IgnoreResearchStatus; + ds << gameState.Cheats.ignoreResearchStatus; break; case CheatType::EnableAllDrawableTrackPieces: - ds << gameState.Cheats.EnableAllDrawableTrackPieces; + ds << gameState.Cheats.enableAllDrawableTrackPieces; break; case CheatType::AllowTrackPlaceInvalidHeights: - ds << gameState.Cheats.AllowTrackPlaceInvalidHeights; + ds << gameState.Cheats.allowTrackPlaceInvalidHeights; break; case CheatType::NoCapOnQueueLengthDummy: ds << dummyBool; break; case CheatType::AllowRegularPathAsQueue: - ds << gameState.Cheats.AllowRegularPathAsQueue; + ds << gameState.Cheats.allowRegularPathAsQueue; break; case CheatType::AllowSpecialColourSchemes: - ds << gameState.Cheats.AllowSpecialColourSchemes; + ds << gameState.Cheats.allowSpecialColourSchemes; break; case CheatType::MakeDestructible: - ds << gameState.Cheats.MakeAllDestructible; + ds << gameState.Cheats.makeAllDestructible; break; case CheatType::SetStaffSpeed: - ds << gameState.Cheats.SelectedStaffSpeed; + ds << gameState.Cheats.selectedStaffSpeed; break; case CheatType::SetForcedParkRating: ds << gameState.Cheats.forcedParkRating; @@ -309,7 +309,7 @@ const char* CheatsGetName(CheatType cheatType) return LanguageGetString(STR_CHANGE_WEATHER); case CheatType::FreezeWeather: return LanguageGetString(STR_CHEAT_FREEZE_WEATHER); - case CheatType::NeverEndingMarketing: + case CheatType::NeverendingMarketing: return LanguageGetString(STR_CHEAT_NEVERENDING_MARKETING); case CheatType::OpenClosePark: return LanguageGetString(STR_CHEAT_OPEN_PARK); diff --git a/src/openrct2/Cheats.h b/src/openrct2/Cheats.h index 7746d6c00d..bf1539fb30 100644 --- a/src/openrct2/Cheats.h +++ b/src/openrct2/Cheats.h @@ -20,33 +20,33 @@ enum class StaffSpeedCheat struct CheatsState { - bool SandboxMode; - bool DisableClearanceChecks; - bool DisableSupportLimits; - bool ShowAllOperatingModes; - bool ShowVehiclesFromOtherTrackTypes; - bool UnlockOperatingLimits; - bool DisableBrakesFailure; - bool DisableAllBreakdowns; - bool BuildInPauseMode; - bool IgnoreRideIntensity; - bool IgnorePrice; - bool DisableVandalism; - bool DisableLittering; - bool NeverendingMarketing; - bool FreezeWeather; - bool DisableTrainLengthLimit; - bool DisablePlantAging; - bool DisableRideValueAging; - bool EnableChainLiftOnAllTrack; - bool AllowArbitraryRideTypeChanges; - bool IgnoreResearchStatus; - bool EnableAllDrawableTrackPieces; - bool AllowTrackPlaceInvalidHeights; - bool AllowRegularPathAsQueue; - bool AllowSpecialColourSchemes; - bool MakeAllDestructible; - StaffSpeedCheat SelectedStaffSpeed; + bool sandboxMode; + bool disableClearanceChecks; + bool disableSupportLimits; + bool showAllOperatingModes; + bool showVehiclesFromOtherTrackTypes; + bool unlockOperatingLimits; + bool disableBrakesFailure; + bool disableAllBreakdowns; + bool buildInPauseMode; + bool ignoreRideIntensity; + bool ignorePrice; + bool disableVandalism; + bool disableLittering; + bool neverendingMarketing; + bool freezeWeather; + bool disableTrainLengthLimit; + bool disablePlantAging; + bool disableRideValueAging; + bool enableChainLiftOnAllTrack; + bool allowArbitraryRideTypeChanges; + bool ignoreResearchStatus; + bool enableAllDrawableTrackPieces; + bool allowTrackPlaceInvalidHeights; + bool allowRegularPathAsQueue; + bool allowSpecialColourSchemes; + bool makeAllDestructible; + StaffSpeedCheat selectedStaffSpeed; int32_t forcedParkRating; }; @@ -92,7 +92,7 @@ enum class CheatType : int32_t OpenClosePark, HaveFun, SetForcedParkRating, - NeverEndingMarketing, + NeverendingMarketing, AllowArbitraryRideTypeChanges, OwnAllLand, DisableRideValueAging, diff --git a/src/openrct2/actions/CheatSetAction.cpp b/src/openrct2/actions/CheatSetAction.cpp index 3106c75158..cc61d2b555 100644 --- a/src/openrct2/actions/CheatSetAction.cpp +++ b/src/openrct2/actions/CheatSetAction.cpp @@ -107,53 +107,53 @@ GameActions::Result CheatSetAction::Execute() const switch (static_cast(_cheatType.id)) { case CheatType::SandboxMode: - gameState.Cheats.SandboxMode = _param1 != 0; + gameState.Cheats.sandboxMode = _param1 != 0; WindowInvalidateByClass(WindowClass::Map); WindowInvalidateByClass(WindowClass::Footpath); break; case CheatType::DisableClearanceChecks: - gameState.Cheats.DisableClearanceChecks = _param1 != 0; + gameState.Cheats.disableClearanceChecks = _param1 != 0; // Required to update the clearance checks overlay on the Cheats button. WindowInvalidateByClass(WindowClass::TopToolbar); break; case CheatType::DisableSupportLimits: - gameState.Cheats.DisableSupportLimits = _param1 != 0; + gameState.Cheats.disableSupportLimits = _param1 != 0; break; case CheatType::ShowAllOperatingModes: - gameState.Cheats.ShowAllOperatingModes = _param1 != 0; + gameState.Cheats.showAllOperatingModes = _param1 != 0; break; case CheatType::ShowVehiclesFromOtherTrackTypes: - gameState.Cheats.ShowVehiclesFromOtherTrackTypes = _param1 != 0; + gameState.Cheats.showVehiclesFromOtherTrackTypes = _param1 != 0; break; case CheatType::FastLiftHill: - gameState.Cheats.UnlockOperatingLimits = _param1 != 0; + gameState.Cheats.unlockOperatingLimits = _param1 != 0; break; case CheatType::DisableBrakesFailure: - gameState.Cheats.DisableBrakesFailure = _param1 != 0; + gameState.Cheats.disableBrakesFailure = _param1 != 0; break; case CheatType::DisableAllBreakdowns: - gameState.Cheats.DisableAllBreakdowns = _param1 != 0; + gameState.Cheats.disableAllBreakdowns = _param1 != 0; break; case CheatType::DisableTrainLengthLimit: - gameState.Cheats.DisableTrainLengthLimit = _param1 != 0; + gameState.Cheats.disableTrainLengthLimit = _param1 != 0; break; case CheatType::EnableChainLiftOnAllTrack: - gameState.Cheats.EnableChainLiftOnAllTrack = _param1 != 0; + gameState.Cheats.enableChainLiftOnAllTrack = _param1 != 0; break; case CheatType::BuildInPauseMode: - gameState.Cheats.BuildInPauseMode = _param1 != 0; + gameState.Cheats.buildInPauseMode = _param1 != 0; break; case CheatType::IgnoreRideIntensity: - gameState.Cheats.IgnoreRideIntensity = _param1 != 0; + gameState.Cheats.ignoreRideIntensity = _param1 != 0; break; case CheatType::IgnorePrice: - gameState.Cheats.IgnorePrice = _param1 != 0; + gameState.Cheats.ignorePrice = _param1 != 0; break; case CheatType::DisableVandalism: - gameState.Cheats.DisableVandalism = _param1 != 0; + gameState.Cheats.disableVandalism = _param1 != 0; break; case CheatType::DisableLittering: - gameState.Cheats.DisableLittering = _param1 != 0; + gameState.Cheats.disableLittering = _param1 != 0; break; case CheatType::NoMoney: SetScenarioNoMoney(_param1 != 0); @@ -192,7 +192,7 @@ GameActions::Result CheatSetAction::Execute() const RemoveLitter(); break; case CheatType::DisablePlantAging: - gameState.Cheats.DisablePlantAging = _param1 != 0; + gameState.Cheats.disablePlantAging = _param1 != 0; break; case CheatType::SetStaffSpeed: SetStaffSpeed(_param1); @@ -201,7 +201,7 @@ GameActions::Result CheatSetAction::Execute() const RenewRides(); break; case CheatType::MakeDestructible: - gameState.Cheats.MakeAllDestructible = _param1 != 0; + gameState.Cheats.makeAllDestructible = _param1 != 0; WindowInvalidateByClass(WindowClass::Ride); break; case CheatType::FixRides: @@ -221,10 +221,10 @@ GameActions::Result CheatSetAction::Execute() const ClimateForceWeather(WeatherType{ static_cast(_param1) }); break; case CheatType::FreezeWeather: - gameState.Cheats.FreezeWeather = _param1 != 0; + gameState.Cheats.freezeWeather = _param1 != 0; break; - case CheatType::NeverEndingMarketing: - gameState.Cheats.NeverendingMarketing = _param1 != 0; + case CheatType::NeverendingMarketing: + gameState.Cheats.neverendingMarketing = _param1 != 0; break; case CheatType::OpenClosePark: ParkSetOpen(!gameState.Park.IsOpen()); @@ -236,20 +236,20 @@ GameActions::Result CheatSetAction::Execute() const Park::SetForcedRating(_param1); break; case CheatType::AllowArbitraryRideTypeChanges: - gameState.Cheats.AllowArbitraryRideTypeChanges = _param1 != 0; + gameState.Cheats.allowArbitraryRideTypeChanges = _param1 != 0; WindowInvalidateByClass(WindowClass::Ride); break; case CheatType::OwnAllLand: OwnAllLand(); break; case CheatType::DisableRideValueAging: - gameState.Cheats.DisableRideValueAging = _param1 != 0; + gameState.Cheats.disableRideValueAging = _param1 != 0; break; case CheatType::IgnoreResearchStatus: - gameState.Cheats.IgnoreResearchStatus = _param1 != 0; + gameState.Cheats.ignoreResearchStatus = _param1 != 0; break; case CheatType::EnableAllDrawableTrackPieces: - gameState.Cheats.EnableAllDrawableTrackPieces = _param1 != 0; + gameState.Cheats.enableAllDrawableTrackPieces = _param1 != 0; break; case CheatType::CreateDucks: CreateDucks(_param1); @@ -258,13 +258,13 @@ GameActions::Result CheatSetAction::Execute() const Duck::RemoveAll(); break; case CheatType::AllowTrackPlaceInvalidHeights: - gameState.Cheats.AllowTrackPlaceInvalidHeights = _param1 != 0; + gameState.Cheats.allowTrackPlaceInvalidHeights = _param1 != 0; break; case CheatType::AllowRegularPathAsQueue: - gameState.Cheats.AllowRegularPathAsQueue = _param1 != 0; + gameState.Cheats.allowRegularPathAsQueue = _param1 != 0; break; case CheatType::AllowSpecialColourSchemes: - gameState.Cheats.AllowSpecialColourSchemes = static_cast(_param1); + gameState.Cheats.allowSpecialColourSchemes = static_cast(_param1); break; case CheatType::RemoveParkFences: RemoveParkFences(); @@ -326,7 +326,7 @@ ParametersRange CheatSetAction::GetParameterRange(CheatType cheatType) const [[fallthrough]]; case CheatType::FreezeWeather: [[fallthrough]]; - case CheatType::NeverEndingMarketing: + case CheatType::NeverendingMarketing: [[fallthrough]]; case CheatType::AllowArbitraryRideTypeChanges: [[fallthrough]]; diff --git a/src/openrct2/actions/ClearAction.cpp b/src/openrct2/actions/ClearAction.cpp index 662bb77e65..2119c98da7 100644 --- a/src/openrct2/actions/ClearAction.cpp +++ b/src/openrct2/actions/ClearAction.cpp @@ -242,6 +242,6 @@ void ClearAction::ResetClearLargeSceneryFlag() bool ClearAction::MapCanClearAt(const CoordsXY& location) { - return (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode + return (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode || MapIsLocationOwnedOrHasRights(location); } diff --git a/src/openrct2/actions/FootpathAdditionPlaceAction.cpp b/src/openrct2/actions/FootpathAdditionPlaceAction.cpp index d175b002ce..8f47b12509 100644 --- a/src/openrct2/actions/FootpathAdditionPlaceAction.cpp +++ b/src/openrct2/actions/FootpathAdditionPlaceAction.cpp @@ -61,7 +61,7 @@ GameActions::Result FootpathAdditionPlaceAction::Query() const return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_POSITION_THIS_HERE, STR_OFF_EDGE_OF_MAP); } - if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode) && !MapIsLocationOwned(_loc)) + if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode) && !MapIsLocationOwned(_loc)) { return GameActions::Result(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); } diff --git a/src/openrct2/actions/FootpathAdditionRemoveAction.cpp b/src/openrct2/actions/FootpathAdditionRemoveAction.cpp index a9cfb875de..61c73ab5f9 100644 --- a/src/openrct2/actions/FootpathAdditionRemoveAction.cpp +++ b/src/openrct2/actions/FootpathAdditionRemoveAction.cpp @@ -53,7 +53,7 @@ GameActions::Result FootpathAdditionRemoveAction::Query() const return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REMOVE_THIS, STR_OFF_EDGE_OF_MAP); } - if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode) && !MapIsLocationOwned(_loc)) + if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode) && !MapIsLocationOwned(_loc)) { return GameActions::Result(GameActions::Status::Disallowed, STR_CANT_REMOVE_THIS, STR_LAND_NOT_OWNED_BY_PARK); } diff --git a/src/openrct2/actions/FootpathLayoutPlaceAction.cpp b/src/openrct2/actions/FootpathLayoutPlaceAction.cpp index 77a99bf527..010dd2e406 100644 --- a/src/openrct2/actions/FootpathLayoutPlaceAction.cpp +++ b/src/openrct2/actions/FootpathLayoutPlaceAction.cpp @@ -79,7 +79,7 @@ GameActions::Result FootpathLayoutPlaceAction::Query() const GameActions::Status::InvalidParameters, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_OFF_EDGE_OF_MAP); } - if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode) && !MapIsLocationOwned(_loc)) + if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode) && !MapIsLocationOwned(_loc)) { return GameActions::Result( GameActions::Status::Disallowed, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); @@ -169,7 +169,7 @@ GameActions::Result FootpathLayoutPlaceAction::ElementInsertQuery(GameActions::R const auto clearanceData = canBuild.GetData(); gFootpathGroundFlags = clearanceData.GroundFlags; - if (!GetGameState().Cheats.DisableClearanceChecks && (clearanceData.GroundFlags & ELEMENT_IS_UNDERWATER)) + if (!GetGameState().Cheats.disableClearanceChecks && (clearanceData.GroundFlags & ELEMENT_IS_UNDERWATER)) { return GameActions::Result( GameActions::Status::Disallowed, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER); diff --git a/src/openrct2/actions/FootpathPlaceAction.cpp b/src/openrct2/actions/FootpathPlaceAction.cpp index 5deeeb6ddc..8f93f4b9e7 100644 --- a/src/openrct2/actions/FootpathPlaceAction.cpp +++ b/src/openrct2/actions/FootpathPlaceAction.cpp @@ -87,7 +87,7 @@ GameActions::Result FootpathPlaceAction::Query() const return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_BUILD_FOOTPATH_HERE, STR_OFF_EDGE_OF_MAP); } - if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode) && !MapIsLocationOwned(_loc)) + if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode) && !MapIsLocationOwned(_loc)) { return GameActions::Result(GameActions::Status::Disallowed, STR_CANT_BUILD_FOOTPATH_HERE, STR_LAND_NOT_OWNED_BY_PARK); } @@ -144,7 +144,7 @@ GameActions::Result FootpathPlaceAction::Execute() const if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) { - if (_direction != INVALID_DIRECTION && !GetGameState().Cheats.DisableClearanceChecks) + if (_direction != INVALID_DIRECTION && !GetGameState().Cheats.disableClearanceChecks) { // It is possible, let's remove walls between the old and new piece of path auto zLow = _loc.z; @@ -324,7 +324,7 @@ GameActions::Result FootpathPlaceAction::ElementInsertQuery(GameActions::Result const auto clearanceData = canBuild.GetData(); gFootpathGroundFlags = clearanceData.GroundFlags; - if (!GetGameState().Cheats.DisableClearanceChecks && (clearanceData.GroundFlags & ELEMENT_IS_UNDERWATER)) + if (!GetGameState().Cheats.disableClearanceChecks && (clearanceData.GroundFlags & ELEMENT_IS_UNDERWATER)) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BUILD_FOOTPATH_HERE, STR_CANT_BUILD_THIS_UNDERWATER); diff --git a/src/openrct2/actions/FootpathRemoveAction.cpp b/src/openrct2/actions/FootpathRemoveAction.cpp index 39eafb1a58..4454052ea7 100644 --- a/src/openrct2/actions/FootpathRemoveAction.cpp +++ b/src/openrct2/actions/FootpathRemoveAction.cpp @@ -60,7 +60,7 @@ GameActions::Result FootpathRemoveAction::Query() const GameActions::Status::InvalidParameters, STR_CANT_REMOVE_FOOTPATH_FROM_HERE, STR_OFF_EDGE_OF_MAP); } - if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode) && !MapIsLocationOwned(_loc)) + if (!((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode) && !MapIsLocationOwned(_loc)) { return GameActions::Result( GameActions::Status::NotOwned, STR_CANT_REMOVE_FOOTPATH_FROM_HERE, STR_LAND_NOT_OWNED_BY_PARK); diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index 5d4dfa72a3..db9abbe56d 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -183,7 +183,7 @@ namespace OpenRCT2::GameActions { if (gGamePaused == 0) return true; - if (GetGameState().Cheats.BuildInPauseMode) + if (GetGameState().Cheats.buildInPauseMode) return true; if (actionFlags & GameActions::Flags::AllowWhilePaused) return true; diff --git a/src/openrct2/actions/LandLowerAction.cpp b/src/openrct2/actions/LandLowerAction.cpp index 7b3cf49f26..4439be05c7 100644 --- a/src/openrct2/actions/LandLowerAction.cpp +++ b/src/openrct2/actions/LandLowerAction.cpp @@ -96,7 +96,7 @@ GameActions::Result LandLowerAction::QueryExecute(bool isExecuting) const if (surfaceElement == nullptr) continue; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ x, y })) { diff --git a/src/openrct2/actions/LandRaiseAction.cpp b/src/openrct2/actions/LandRaiseAction.cpp index adae6589b2..99156a1381 100644 --- a/src/openrct2/actions/LandRaiseAction.cpp +++ b/src/openrct2/actions/LandRaiseAction.cpp @@ -97,7 +97,7 @@ GameActions::Result LandRaiseAction::QueryExecute(bool isExecuting) const if (surfaceElement == nullptr) continue; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ x, y })) { diff --git a/src/openrct2/actions/LandSetHeightAction.cpp b/src/openrct2/actions/LandSetHeightAction.cpp index c31217efca..a3bcd97382 100644 --- a/src/openrct2/actions/LandSetHeightAction.cpp +++ b/src/openrct2/actions/LandSetHeightAction.cpp @@ -72,7 +72,7 @@ GameActions::Result LandSetHeightAction::Query() const return GameActions::Result(GameActions::Status::Disallowed, STR_NONE, errorMessage); } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.sandboxMode) { if (!MapIsLocationInPark(_coords)) { @@ -81,7 +81,7 @@ GameActions::Result LandSetHeightAction::Query() const } money64 sceneryRemovalCost = 0; - if (!gameState.Cheats.DisableClearanceChecks) + if (!gameState.Cheats.disableClearanceChecks) { if (gameState.Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) { @@ -98,7 +98,7 @@ GameActions::Result LandSetHeightAction::Query() const } // Check for ride support limits - if (!gameState.Cheats.DisableSupportLimits) + if (!gameState.Cheats.disableSupportLimits) { errorMessage = CheckRideSupports(); if (errorMessage != STR_NONE) @@ -129,7 +129,7 @@ GameActions::Result LandSetHeightAction::Query() const return res; } - if (!gameState.Cheats.DisableClearanceChecks) + if (!gameState.Cheats.disableClearanceChecks) { uint8_t zCorner = _height; if (_style & kTileSlopeRaisedCornersMask) @@ -162,7 +162,7 @@ GameActions::Result LandSetHeightAction::Execute() const auto surfaceHeight = TileElementHeight(_coords); FootpathRemoveLitter({ _coords, surfaceHeight }); - if (!GetGameState().Cheats.DisableClearanceChecks) + if (!GetGameState().Cheats.disableClearanceChecks) { WallRemoveAt({ _coords, _height * 8 - 16, _height * 8 + 32 }); cost += GetSmallSceneryRemovalCost(); diff --git a/src/openrct2/actions/LandSetRightsAction.cpp b/src/openrct2/actions/LandSetRightsAction.cpp index a6308a903b..152b9d6f75 100644 --- a/src/openrct2/actions/LandSetRightsAction.cpp +++ b/src/openrct2/actions/LandSetRightsAction.cpp @@ -84,7 +84,7 @@ GameActions::Result LandSetRightsAction::QueryExecute(bool isExecuting) const res.Position = centre; res.Expenditure = ExpenditureType::LandPurchase; - if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.sandboxMode) { return GameActions::Result(GameActions::Status::NotInEditorMode, STR_NONE, STR_LAND_NOT_FOR_SALE); } diff --git a/src/openrct2/actions/LargeSceneryPlaceAction.cpp b/src/openrct2/actions/LargeSceneryPlaceAction.cpp index 53f8097c78..91aa584d8e 100644 --- a/src/openrct2/actions/LargeSceneryPlaceAction.cpp +++ b/src/openrct2/actions/LargeSceneryPlaceAction.cpp @@ -152,7 +152,7 @@ GameActions::Result LargeSceneryPlaceAction::Query() const const auto clearanceData = canBuild.GetData(); int32_t tempSceneryGroundFlags = clearanceData.GroundFlags & (ELEMENT_IS_ABOVE_GROUND | ELEMENT_IS_UNDERGROUND); - if (!gameState.Cheats.DisableClearanceChecks) + if (!gameState.Cheats.disableClearanceChecks) { if ((clearanceData.GroundFlags & ELEMENT_IS_UNDERWATER) || (clearanceData.GroundFlags & ELEMENT_IS_UNDERGROUND)) { @@ -175,7 +175,7 @@ GameActions::Result LargeSceneryPlaceAction::Query() const } if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !MapIsLocationOwned({ curTile, zLow }) - && !gameState.Cheats.SandboxMode) + && !gameState.Cheats.sandboxMode) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); @@ -297,7 +297,7 @@ GameActions::Result LargeSceneryPlaceAction::Execute() const if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) { FootpathRemoveLitter({ curTile, zLow }); - if (!GetGameState().Cheats.DisableClearanceChecks) + if (!GetGameState().Cheats.disableClearanceChecks) { WallRemoveAt({ curTile, zLow, zHigh }); } diff --git a/src/openrct2/actions/LargeSceneryRemoveAction.cpp b/src/openrct2/actions/LargeSceneryRemoveAction.cpp index ad6f412f90..496920d969 100644 --- a/src/openrct2/actions/LargeSceneryRemoveAction.cpp +++ b/src/openrct2/actions/LargeSceneryRemoveAction.cpp @@ -89,7 +89,7 @@ GameActions::Result LargeSceneryRemoveAction::Query() const auto currentTile = CoordsXYZ{ firstTile.x, firstTile.y, firstTile.z } + currentTileRotatedOffset; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (GetGameState().Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) { @@ -169,7 +169,7 @@ GameActions::Result LargeSceneryRemoveAction::Execute() const auto currentTile = CoordsXYZ{ firstTile.x, firstTile.y, firstTile.z } + rotatedCurrentTile; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationOwned({ currentTile.x, currentTile.y, currentTile.z })) { diff --git a/src/openrct2/actions/LargeScenerySetColourAction.cpp b/src/openrct2/actions/LargeScenerySetColourAction.cpp index b5c179fa3c..c4dee96c2e 100644 --- a/src/openrct2/actions/LargeScenerySetColourAction.cpp +++ b/src/openrct2/actions/LargeScenerySetColourAction.cpp @@ -127,7 +127,7 @@ GameActions::Result LargeScenerySetColourAction::QueryExecute(bool isExecuting) auto rotatedTileCoords = CoordsXYZ{ CoordsXY{ tile.offset }.Rotate(_loc.direction), tile.offset.z }; auto currentTile = CoordsXYZ{ baseTile.x, baseTile.y, baseTile.z } + rotatedTileCoords; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationOwned(currentTile)) { diff --git a/src/openrct2/actions/MazePlaceTrackAction.cpp b/src/openrct2/actions/MazePlaceTrackAction.cpp index 5784aa74b3..36fc6235a1 100644 --- a/src/openrct2/actions/MazePlaceTrackAction.cpp +++ b/src/openrct2/actions/MazePlaceTrackAction.cpp @@ -65,7 +65,7 @@ GameActions::Result MazePlaceTrackAction::Query() const return res; } auto& gameState = GetGameState(); - if (!MapIsLocationOwned(_loc) && !gameState.Cheats.SandboxMode) + if (!MapIsLocationOwned(_loc) && !gameState.Cheats.sandboxMode) { res.Error = GameActions::Status::NotOwned; res.ErrorMessage = STR_LAND_NOT_OWNED_BY_PARK; @@ -90,7 +90,7 @@ GameActions::Result MazePlaceTrackAction::Query() const auto clearanceHeight = _loc.z + MAZE_CLEARANCE_HEIGHT; auto heightDifference = baseHeight - surfaceElement->GetBaseZ(); - if (heightDifference >= 0 && !gameState.Cheats.DisableSupportLimits) + if (heightDifference >= 0 && !gameState.Cheats.disableSupportLimits) { heightDifference /= kCoordsZPerTinyZ; diff --git a/src/openrct2/actions/MazeSetTrackAction.cpp b/src/openrct2/actions/MazeSetTrackAction.cpp index e754f26134..b3d0e0ef17 100644 --- a/src/openrct2/actions/MazeSetTrackAction.cpp +++ b/src/openrct2/actions/MazeSetTrackAction.cpp @@ -101,7 +101,7 @@ GameActions::Result MazeSetTrackAction::Query() const return res; } auto& gameState = GetGameState(); - if (!MapIsLocationOwned(_loc) && !gameState.Cheats.SandboxMode) + if (!MapIsLocationOwned(_loc) && !gameState.Cheats.sandboxMode) { res.Error = GameActions::Status::NotOwned; res.ErrorMessage = STR_LAND_NOT_OWNED_BY_PARK; @@ -126,7 +126,7 @@ GameActions::Result MazeSetTrackAction::Query() const auto clearanceHeight = _loc.z + 32; auto heightDifference = baseHeight - surfaceElement->GetBaseZ(); - if (heightDifference >= 0 && !gameState.Cheats.DisableSupportLimits) + if (heightDifference >= 0 && !gameState.Cheats.disableSupportLimits) { heightDifference /= kCoordsZPerTinyZ; diff --git a/src/openrct2/actions/ParkEntrancePlaceAction.cpp b/src/openrct2/actions/ParkEntrancePlaceAction.cpp index 713d6f647d..a583d4de80 100644 --- a/src/openrct2/actions/ParkEntrancePlaceAction.cpp +++ b/src/openrct2/actions/ParkEntrancePlaceAction.cpp @@ -56,7 +56,7 @@ void ParkEntrancePlaceAction::Serialise(DataSerialiser& stream) GameActions::Result ParkEntrancePlaceAction::Query() const { - if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.sandboxMode) { return GameActions::Result(GameActions::Status::NotInEditorMode, STR_CANT_BUILD_THIS_HERE, STR_NONE); } diff --git a/src/openrct2/actions/ParkEntranceRemoveAction.cpp b/src/openrct2/actions/ParkEntranceRemoveAction.cpp index aee81da261..cff3e7a14a 100644 --- a/src/openrct2/actions/ParkEntranceRemoveAction.cpp +++ b/src/openrct2/actions/ParkEntranceRemoveAction.cpp @@ -43,7 +43,7 @@ void ParkEntranceRemoveAction::Serialise(DataSerialiser& stream) GameActions::Result ParkEntranceRemoveAction::Query() const { - if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.sandboxMode) { return GameActions::Result(GameActions::Status::NotInEditorMode, STR_CANT_REMOVE_THIS, STR_NONE); } diff --git a/src/openrct2/actions/PeepSpawnPlaceAction.cpp b/src/openrct2/actions/PeepSpawnPlaceAction.cpp index 5e2898a692..62a211955a 100644 --- a/src/openrct2/actions/PeepSpawnPlaceAction.cpp +++ b/src/openrct2/actions/PeepSpawnPlaceAction.cpp @@ -45,7 +45,7 @@ void PeepSpawnPlaceAction::Serialise(DataSerialiser& stream) GameActions::Result PeepSpawnPlaceAction::Query() const { - if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !GetGameState().Cheats.sandboxMode) { return GameActions::Result(GameActions::Status::NotInEditorMode, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_NONE); } diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index b5c01e369f..a3b0e9dbd8 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -164,7 +164,7 @@ GameActions::Result RideCreateAction::Execute() const ride->NumTrains = 1; auto& gameState = GetGameState(); - if (gameState.Cheats.DisableTrainLengthLimit) + if (gameState.Cheats.disableTrainLengthLimit) { // Reduce amount of proposed trains to prevent 32 trains from always spawning when limits are disabled if (rideEntry->cars_per_flat_ride == NoFlatRideCars) diff --git a/src/openrct2/actions/RideDemolishAction.cpp b/src/openrct2/actions/RideDemolishAction.cpp index 9ae83fbee3..f97ba1268d 100644 --- a/src/openrct2/actions/RideDemolishAction.cpp +++ b/src/openrct2/actions/RideDemolishAction.cpp @@ -67,7 +67,7 @@ GameActions::Result RideDemolishAction::Query() const if ((ride->lifecycle_flags & (RIDE_LIFECYCLE_INDESTRUCTIBLE | RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) && _modifyType == RIDE_MODIFY_DEMOLISH) - && !GetGameState().Cheats.MakeAllDestructible) + && !GetGameState().Cheats.makeAllDestructible) { return GameActions::Result( GameActions::Status::NoClearance, STR_CANT_DEMOLISH_RIDE, diff --git a/src/openrct2/actions/RideEntranceExitPlaceAction.cpp b/src/openrct2/actions/RideEntranceExitPlaceAction.cpp index b10188e9be..bf97fd04b4 100644 --- a/src/openrct2/actions/RideEntranceExitPlaceAction.cpp +++ b/src/openrct2/actions/RideEntranceExitPlaceAction.cpp @@ -102,7 +102,7 @@ GameActions::Result RideEntranceExitPlaceAction::Query() const { return GameActions::Result(GameActions::Status::InvalidParameters, errorTitle, STR_OFF_EDGE_OF_MAP); } - if (!GetGameState().Cheats.SandboxMode && !MapIsLocationOwned({ _loc, z })) + if (!GetGameState().Cheats.sandboxMode && !MapIsLocationOwned({ _loc, z })) { return GameActions::Result(GameActions::Status::NotOwned, errorTitle, STR_LAND_NOT_OWNED_BY_PARK); } @@ -173,7 +173,7 @@ GameActions::Result RideEntranceExitPlaceAction::Execute() const auto z = station.GetBaseZ(); if (!(GetFlags() & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && !(GetFlags() & GAME_COMMAND_FLAG_GHOST) - && !GetGameState().Cheats.DisableClearanceChecks) + && !GetGameState().Cheats.disableClearanceChecks) { FootpathRemoveLitter({ _loc, z }); WallRemoveAtZ({ _loc, z }); @@ -236,7 +236,7 @@ GameActions::Result RideEntranceExitPlaceAction::TrackPlaceQuery(const CoordsXYZ const auto errorTitle = isExit ? STR_CANT_BUILD_MOVE_EXIT_FOR_THIS_RIDE_ATTRACTION : STR_CANT_BUILD_MOVE_ENTRANCE_FOR_THIS_RIDE_ATTRACTION; - if (!GetGameState().Cheats.SandboxMode && !MapIsLocationOwned(loc)) + if (!GetGameState().Cheats.sandboxMode && !MapIsLocationOwned(loc)) { return GameActions::Result(GameActions::Status::NotOwned, errorTitle, STR_LAND_NOT_OWNED_BY_PARK); } diff --git a/src/openrct2/actions/RideSetSettingAction.cpp b/src/openrct2/actions/RideSetSettingAction.cpp index 245c1c23e6..437d94bfd5 100644 --- a/src/openrct2/actions/RideSetSettingAction.cpp +++ b/src/openrct2/actions/RideSetSettingAction.cpp @@ -70,7 +70,7 @@ GameActions::Result RideSetSettingAction::Query() const GameActions::Status::Disallowed, STR_CANT_CHANGE_OPERATING_MODE, STR_MUST_BE_CLOSED_FIRST); } - if (!RideIsModeValid(*ride) && !GetGameState().Cheats.ShowAllOperatingModes) + if (!RideIsModeValid(*ride) && !GetGameState().Cheats.showAllOperatingModes) { LOG_ERROR("Invalid ride mode: %u", _value); return GameActions::Result( @@ -149,7 +149,7 @@ GameActions::Result RideSetSettingAction::Query() const } break; case RideSetSetting::RideType: - if (!GetGameState().Cheats.AllowArbitraryRideTypeChanges) + if (!GetGameState().Cheats.allowArbitraryRideTypeChanges) { LOG_ERROR("Arbitrary ride type changes not allowed."); return GameActions::Result(GameActions::Status::Disallowed, STR_CANT_CHANGE_OPERATING_MODE, STR_NONE); @@ -263,15 +263,15 @@ bool RideSetSettingAction::RideIsModeValid(const Ride& ride) const bool RideSetSettingAction::RideIsValidLiftHillSpeed(const Ride& ride) const { auto& gameState = GetGameState(); - int32_t minSpeed = gameState.Cheats.UnlockOperatingLimits ? 0 : ride.GetRideTypeDescriptor().LiftData.minimum_speed; - int32_t maxSpeed = gameState.Cheats.UnlockOperatingLimits ? 255 : ride.GetRideTypeDescriptor().LiftData.maximum_speed; + int32_t minSpeed = gameState.Cheats.unlockOperatingLimits ? 0 : ride.GetRideTypeDescriptor().LiftData.minimum_speed; + int32_t maxSpeed = gameState.Cheats.unlockOperatingLimits ? 255 : ride.GetRideTypeDescriptor().LiftData.maximum_speed; return _value >= minSpeed && _value <= maxSpeed; } bool RideSetSettingAction::RideIsValidNumCircuits() const { int32_t minNumCircuits = 1; - int32_t maxNumCircuits = GetGameState().Cheats.UnlockOperatingLimits ? 255 : Limits::kMaxCircuitsPerRide; + int32_t maxNumCircuits = GetGameState().Cheats.unlockOperatingLimits ? 255 : Limits::kMaxCircuitsPerRide; return _value >= minNumCircuits && _value <= maxNumCircuits; } @@ -280,7 +280,7 @@ bool RideSetSettingAction::RideIsValidOperationOption(const Ride& ride) const const auto& operatingSettings = ride.GetRideTypeDescriptor().OperatingSettings; uint8_t minValue = operatingSettings.MinValue; uint8_t maxValue = operatingSettings.MaxValue; - if (GetGameState().Cheats.UnlockOperatingLimits) + if (GetGameState().Cheats.unlockOperatingLimits) { minValue = 0; maxValue = 255; diff --git a/src/openrct2/actions/RideSetVehicleAction.cpp b/src/openrct2/actions/RideSetVehicleAction.cpp index 3b1d994ad2..b2b66d4549 100644 --- a/src/openrct2/actions/RideSetVehicleAction.cpp +++ b/src/openrct2/actions/RideSetVehicleAction.cpp @@ -159,7 +159,7 @@ GameActions::Result RideSetVehicleAction::Execute() const } uint8_t clampValue = _value; static_assert(sizeof(clampValue) == sizeof(ride->proposed_num_cars_per_train)); - if (!GetGameState().Cheats.DisableTrainLengthLimit) + if (!GetGameState().Cheats.disableTrainLengthLimit) { clampValue = std::clamp(clampValue, rideEntry->min_cars_in_train, rideEntry->max_cars_in_train); } @@ -182,7 +182,7 @@ GameActions::Result RideSetVehicleAction::Execute() const } RideSetVehicleColoursToRandomPreset(*ride, _colour); - if (!GetGameState().Cheats.DisableTrainLengthLimit) + if (!GetGameState().Cheats.disableTrainLengthLimit) { ride->proposed_num_cars_per_train = std::clamp( ride->proposed_num_cars_per_train, rideEntry->min_cars_in_train, rideEntry->max_cars_in_train); @@ -230,7 +230,7 @@ bool RideSetVehicleAction::RideIsVehicleTypeValid(const Ride& ride) const { const auto& rtd = ride.GetRideTypeDescriptor(); - if (gameState.Cheats.ShowVehiclesFromOtherTrackTypes + if (gameState.Cheats.showVehiclesFromOtherTrackTypes && !( ride.GetRideTypeDescriptor().HasFlag(RtdFlag::isFlatRide) || rtd.specialType == RtdSpecialType::maze || rtd.specialType == RtdSpecialType::miniGolf)) @@ -265,7 +265,7 @@ bool RideSetVehicleAction::RideIsVehicleTypeValid(const Ride& ride) const { if (rideEntryIndex == _value) { - if (!RideEntryIsInvented(rideEntryIndex) && !gameState.Cheats.IgnoreResearchStatus) + if (!RideEntryIsInvented(rideEntryIndex) && !gameState.Cheats.ignoreResearchStatus) { return false; } diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.cpp b/src/openrct2/actions/SmallSceneryPlaceAction.cpp index 8e0a12cffe..a552a43860 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.cpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.cpp @@ -172,7 +172,7 @@ GameActions::Result SmallSceneryPlaceAction::Query() const } auto& gameState = GetGameState(); - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.SandboxMode + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.sandboxMode && !MapIsLocationOwned({ _loc.x, _loc.y, targetHeight })) { return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_POSITION_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); @@ -180,7 +180,7 @@ GameActions::Result SmallSceneryPlaceAction::Query() const auto* surfaceElement = MapGetSurfaceElementAt(_loc); - if (surfaceElement != nullptr && !gameState.Cheats.DisableClearanceChecks && surfaceElement->GetWaterHeight() > 0) + if (surfaceElement != nullptr && !gameState.Cheats.disableClearanceChecks && surfaceElement->GetWaterHeight() > 0) { int32_t water_height = surfaceElement->GetWaterHeight() - 1; if (water_height > targetHeight) @@ -190,7 +190,7 @@ GameActions::Result SmallSceneryPlaceAction::Query() const } } - if (!gameState.Cheats.DisableClearanceChecks && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE))) + if (!gameState.Cheats.disableClearanceChecks && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE))) { if (isOnWater) { @@ -208,13 +208,13 @@ GameActions::Result SmallSceneryPlaceAction::Query() const } } - if (!gameState.Cheats.DisableClearanceChecks && (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE)) + if (!gameState.Cheats.disableClearanceChecks && (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_REQUIRE_FLAT_SURFACE)) && !supportsRequired && !isOnWater && surfaceElement != nullptr && (surfaceElement->GetSlope() != kTileSlopeFlat)) { return GameActions::Result(GameActions::Status::Disallowed, STR_CANT_POSITION_THIS_HERE, STR_LEVEL_LAND_REQUIRED); } - if (!gameState.Cheats.DisableSupportLimits && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE)) && supportsRequired) + if (!gameState.Cheats.disableSupportLimits && !(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_STACKABLE)) && supportsRequired) { if (!isOnWater) { @@ -367,7 +367,7 @@ GameActions::Result SmallSceneryPlaceAction::Execute() const if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST)) { FootpathRemoveLitter({ _loc, targetHeight }); - if (!GetGameState().Cheats.DisableClearanceChecks && (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_NO_WALLS))) + if (!GetGameState().Cheats.disableClearanceChecks && (sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_NO_WALLS))) { WallRemoveAt({ _loc, targetHeight, targetHeight + sceneryEntry->height }); } diff --git a/src/openrct2/actions/SmallSceneryRemoveAction.cpp b/src/openrct2/actions/SmallSceneryRemoveAction.cpp index 443145bbb3..dea1d928b2 100644 --- a/src/openrct2/actions/SmallSceneryRemoveAction.cpp +++ b/src/openrct2/actions/SmallSceneryRemoveAction.cpp @@ -76,7 +76,7 @@ GameActions::Result SmallSceneryRemoveAction::Query() const res.Position = _loc; if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !(GetFlags() & GAME_COMMAND_FLAG_GHOST) - && !GetGameState().Cheats.SandboxMode) + && !GetGameState().Cheats.sandboxMode) { // Check if allowed to remove item if (GetGameState().Park.Flags & PARK_FLAGS_FORBID_TREE_REMOVAL) diff --git a/src/openrct2/actions/SmallScenerySetColourAction.cpp b/src/openrct2/actions/SmallScenerySetColourAction.cpp index 5283e66107..7dae014d62 100644 --- a/src/openrct2/actions/SmallScenerySetColourAction.cpp +++ b/src/openrct2/actions/SmallScenerySetColourAction.cpp @@ -84,7 +84,7 @@ GameActions::Result SmallScenerySetColourAction::QueryExecute(bool isExecuting) return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_OFF_EDGE_OF_MAP); } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationOwned(_loc)) { diff --git a/src/openrct2/actions/StaffHireNewAction.cpp b/src/openrct2/actions/StaffHireNewAction.cpp index 1fb573abd8..fb2bf4e8d5 100644 --- a/src/openrct2/actions/StaffHireNewAction.cpp +++ b/src/openrct2/actions/StaffHireNewAction.cpp @@ -201,7 +201,7 @@ GameActions::Result StaffHireNewAction::QueryExecute(bool execute) const newPeep->TrousersColour = colour; // Staff energy determines their walking speed - switch (GetGameState().Cheats.SelectedStaffSpeed) + switch (GetGameState().Cheats.selectedStaffSpeed) { case StaffSpeedCheat::None: newPeep->Energy = kCheatsStaffNormalSpeed; diff --git a/src/openrct2/actions/SurfaceSetStyleAction.cpp b/src/openrct2/actions/SurfaceSetStyleAction.cpp index 950f291521..41228a9067 100644 --- a/src/openrct2/actions/SurfaceSetStyleAction.cpp +++ b/src/openrct2/actions/SurfaceSetStyleAction.cpp @@ -88,7 +88,7 @@ GameActions::Result SurfaceSetStyleAction::Query() const auto& gameState = GetGameState(); // Do nothing if not in editor, sandbox mode or landscaping is forbidden - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.SandboxMode + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.sandboxMode && (gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES)) { return GameActions::Result( @@ -105,7 +105,7 @@ GameActions::Result SurfaceSetStyleAction::Query() const if (!LocationValid(coords)) continue; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.sandboxMode) { if (!MapIsLocationInPark(coords)) continue; @@ -173,7 +173,7 @@ GameActions::Result SurfaceSetStyleAction::Execute() const if (!LocationValid(coords)) continue; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(coords)) continue; diff --git a/src/openrct2/actions/TrackDesignAction.cpp b/src/openrct2/actions/TrackDesignAction.cpp index 824f07499e..25234108b9 100644 --- a/src/openrct2/actions/TrackDesignAction.cpp +++ b/src/openrct2/actions/TrackDesignAction.cpp @@ -72,7 +72,7 @@ GameActions::Result TrackDesignAction::Query() const { // Force a fallback if the entry is not invented yet a track design of it is selected, // which can happen in select-by-track-type mode - if (!RideEntryIsInvented(entryIndex) && !gameState.Cheats.IgnoreResearchStatus) + if (!RideEntryIsInvented(entryIndex) && !gameState.Cheats.ignoreResearchStatus) { entryIndex = OBJECT_ENTRY_INDEX_NULL; } @@ -146,7 +146,7 @@ GameActions::Result TrackDesignAction::Execute() const { // Force a fallback if the entry is not invented yet a track design using it is selected. // This can happen on rides with multiple vehicles where some have been invented and some haven’t. - if (!RideEntryIsInvented(entryIndex) && !gameState.Cheats.IgnoreResearchStatus) + if (!RideEntryIsInvented(entryIndex) && !gameState.Cheats.ignoreResearchStatus) { entryIndex = OBJECT_ENTRY_INDEX_NULL; } diff --git a/src/openrct2/actions/TrackPlaceAction.cpp b/src/openrct2/actions/TrackPlaceAction.cpp index 500b21416d..cbb5ea7ed2 100644 --- a/src/openrct2/actions/TrackPlaceAction.cpp +++ b/src/openrct2/actions/TrackPlaceAction.cpp @@ -99,7 +99,7 @@ GameActions::Result TrackPlaceAction::Query() const } auto& gameState = GetGameState(); - if (_rideType != ride->type && !gameState.Cheats.AllowArbitraryRideTypeChanges) + if (_rideType != ride->type && !gameState.Cheats.allowArbitraryRideTypeChanges) { return GameActions::Result( GameActions::Status::InvalidParameters, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NONE); @@ -137,7 +137,7 @@ GameActions::Result TrackPlaceAction::Query() const if (!(GetActionFlags() & GameActions::Flags::AllowWhilePaused)) { - if (GameIsPaused() && !gameState.Cheats.BuildInPauseMode) + if (GameIsPaused() && !gameState.Cheats.buildInPauseMode) { return GameActions::Result( GameActions::Status::Disallowed, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, @@ -167,7 +167,7 @@ GameActions::Result TrackPlaceAction::Query() const } // Backwards steep lift hills are allowed, even on roller coasters that do not support forwards steep lift hills. if (_trackPlaceFlags.has(LiftHillAndInverted::liftHill) && !rtd.SupportsTrackGroup(TrackGroup::liftHillSteep) - && !gameState.Cheats.EnableChainLiftOnAllTrack) + && !gameState.Cheats.enableChainLiftOnAllTrack) { const auto& ted = GetTrackElementDescriptor(_trackType); if (ted.flags & TRACK_ELEM_FLAG_IS_STEEP_UP) @@ -193,7 +193,7 @@ GameActions::Result TrackPlaceAction::Query() const return GameActions::Result( GameActions::Status::InvalidParameters, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_OFF_EDGE_OF_MAP); } - if (!MapIsLocationOwned(tileCoords) && !gameState.Cheats.SandboxMode) + if (!MapIsLocationOwned(tileCoords) && !gameState.Cheats.sandboxMode) { return GameActions::Result( GameActions::Status::Disallowed, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_LAND_NOT_OWNED_BY_PARK); @@ -209,7 +209,7 @@ GameActions::Result TrackPlaceAction::Query() const STR_TILE_ELEMENT_LIMIT_REACHED); } - if (!gameState.Cheats.AllowTrackPlaceInvalidHeights) + if (!gameState.Cheats.allowTrackPlaceInvalidHeights) { if (ted.flags & TRACK_ELEM_FLAG_STARTS_AT_HALF_HEIGHT) { @@ -312,7 +312,7 @@ GameActions::Result TrackPlaceAction::Query() const } } - if (clearanceData.GroundFlags & ELEMENT_IS_UNDERWATER && !gameState.Cheats.DisableClearanceChecks) + if (clearanceData.GroundFlags & ELEMENT_IS_UNDERWATER && !gameState.Cheats.disableClearanceChecks) { return GameActions::Result( GameActions::Status::Disallowed, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, @@ -378,7 +378,7 @@ GameActions::Result TrackPlaceAction::Query() const STR_ERR_SURFACE_ELEMENT_NOT_FOUND); } - if (!gameState.Cheats.DisableSupportLimits) + if (!gameState.Cheats.disableSupportLimits) { int32_t ride_height = clearanceZ - surfaceElement->GetBaseZ(); if (ride_height >= 0) @@ -504,7 +504,7 @@ GameActions::Result TrackPlaceAction::Execute() const } auto& gameState = GetGameState(); - if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !gameState.Cheats.DisableClearanceChecks) + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !gameState.Cheats.disableClearanceChecks) { FootpathRemoveLitter(mapLoc); if (rtd.HasFlag(RtdFlag::noWallsAroundTrack)) @@ -638,7 +638,7 @@ GameActions::Result TrackPlaceAction::Execute() const uint32_t availableDirections = entranceDirections & 0x0F; if (availableDirections != 0) { - if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !gameState.Cheats.DisableClearanceChecks) + if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !gameState.Cheats.disableClearanceChecks) { for (int32_t chosenDirection = Numerics::bitScanForward(availableDirections); chosenDirection != -1; chosenDirection = Numerics::bitScanForward(availableDirections)) @@ -680,7 +680,7 @@ GameActions::Result TrackPlaceAction::Execute() const } } - if (!gameState.Cheats.DisableClearanceChecks || !(GetFlags() & GAME_COMMAND_FLAG_GHOST)) + if (!gameState.Cheats.disableClearanceChecks || !(GetFlags() & GAME_COMMAND_FLAG_GHOST)) { FootpathConnectEdges(mapLoc, tileElement, GetFlags()); } @@ -711,7 +711,7 @@ GameActions::Result TrackPlaceAction::Execute() const if (ride->mode == RideMode::PoweredLaunch) { if (rtd.SupportsRideMode(RideMode::PoweredLaunchBlockSectioned) - || GetGameState().Cheats.ShowAllOperatingModes) + || GetGameState().Cheats.showAllOperatingModes) newMode = RideMode::PoweredLaunchBlockSectioned; else newMode = RideMode::PoweredLaunch; diff --git a/src/openrct2/actions/TrackRemoveAction.cpp b/src/openrct2/actions/TrackRemoveAction.cpp index 4a76c160ab..f0469553ee 100644 --- a/src/openrct2/actions/TrackRemoveAction.cpp +++ b/src/openrct2/actions/TrackRemoveAction.cpp @@ -440,7 +440,7 @@ GameActions::Result TrackRemoveAction::Execute() const InvalidateTestResults(*ride); FootpathQueueChainReset(); - if (!GetGameState().Cheats.DisableClearanceChecks || !(tileElement->IsGhost())) + if (!GetGameState().Cheats.disableClearanceChecks || !(tileElement->IsGhost())) { FootpathRemoveEdgesAt(mapLoc, tileElement); } diff --git a/src/openrct2/actions/WallPlaceAction.cpp b/src/openrct2/actions/WallPlaceAction.cpp index 13918ca308..4e2a8846c7 100644 --- a/src/openrct2/actions/WallPlaceAction.cpp +++ b/src/openrct2/actions/WallPlaceAction.cpp @@ -92,7 +92,7 @@ GameActions::Result WallPlaceAction::Query() const auto& gameState = GetGameState(); auto mapSizeMax = GetMapSizeMaxXY(); if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !(GetFlags() & GAME_COMMAND_FLAG_TRACK_DESIGN) - && !gameState.Cheats.SandboxMode) + && !gameState.Cheats.sandboxMode) { if (_loc.z == 0) { @@ -151,14 +151,14 @@ GameActions::Result WallPlaceAction::Query() const { uint16_t waterHeight = surfaceElement->GetWaterHeight(); - if (targetHeight < waterHeight && !gameState.Cheats.DisableClearanceChecks) + if (targetHeight < waterHeight && !gameState.Cheats.disableClearanceChecks) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CANT_BUILD_THIS_UNDERWATER); } } - if (targetHeight < surfaceElement->GetBaseZ() && !gameState.Cheats.DisableClearanceChecks) + if (targetHeight < surfaceElement->GetBaseZ() && !gameState.Cheats.disableClearanceChecks) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); @@ -171,7 +171,7 @@ GameActions::Result WallPlaceAction::Query() const newBaseHeight += 2; if (surfaceElement->GetSlope() & (1 << newEdge)) { - if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.DisableClearanceChecks) + if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.disableClearanceChecks) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); @@ -187,7 +187,7 @@ GameActions::Result WallPlaceAction::Query() const if (surfaceElement->GetSlope() & (1 << newEdge)) { newBaseHeight += 2; - if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.DisableClearanceChecks) + if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.disableClearanceChecks) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, @@ -202,7 +202,7 @@ GameActions::Result WallPlaceAction::Query() const newEdge = (_edge + 3) & 3; if (surfaceElement->GetSlope() & (1 << newEdge)) { - if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.DisableClearanceChecks) + if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.disableClearanceChecks) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, STR_CAN_ONLY_BUILD_THIS_ABOVE_GROUND); @@ -218,7 +218,7 @@ GameActions::Result WallPlaceAction::Query() const if (surfaceElement->GetSlope() & (1 << newEdge)) { newBaseHeight += 2; - if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.DisableClearanceChecks) + if (targetHeight / 8 < newBaseHeight && !gameState.Cheats.disableClearanceChecks) { return GameActions::Result( GameActions::Status::Disallowed, STR_CANT_BUILD_THIS_HERE, @@ -261,7 +261,7 @@ GameActions::Result WallPlaceAction::Query() const clearanceHeight += wallEntry->height; bool wallAcrossTrack = false; - if (!(GetFlags() & GAME_COMMAND_FLAG_TRACK_DESIGN) && !gameState.Cheats.DisableClearanceChecks) + if (!(GetFlags() & GAME_COMMAND_FLAG_TRACK_DESIGN) && !gameState.Cheats.disableClearanceChecks) { auto result = WallCheckObstruction(wallEntry, targetHeight / 8, clearanceHeight, &wallAcrossTrack); if (result.Error != GameActions::Status::Ok) @@ -339,7 +339,7 @@ GameActions::Result WallPlaceAction::Execute() const clearanceHeight += wallEntry->height; bool wallAcrossTrack = false; - if (!(GetFlags() & GAME_COMMAND_FLAG_TRACK_DESIGN) && !gameState.Cheats.DisableClearanceChecks) + if (!(GetFlags() & GAME_COMMAND_FLAG_TRACK_DESIGN) && !gameState.Cheats.disableClearanceChecks) { auto result = WallCheckObstruction(wallEntry, targetHeight / kCoordsZStep, clearanceHeight, &wallAcrossTrack); if (result.Error != GameActions::Status::Ok) diff --git a/src/openrct2/actions/WallRemoveAction.cpp b/src/openrct2/actions/WallRemoveAction.cpp index f524c96370..04d03eeeab 100644 --- a/src/openrct2/actions/WallRemoveAction.cpp +++ b/src/openrct2/actions/WallRemoveAction.cpp @@ -51,7 +51,7 @@ GameActions::Result WallRemoveAction::Query() const } const bool isGhost = GetFlags() & GAME_COMMAND_FLAG_GHOST; - if (!isGhost && !(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode + if (!isGhost && !(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode && !MapIsLocationOwned(_loc)) { return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_REMOVE_THIS, STR_LAND_NOT_OWNED_BY_PARK); diff --git a/src/openrct2/actions/WallSetColourAction.cpp b/src/openrct2/actions/WallSetColourAction.cpp index 9cbedcc2d3..f5e24fea19 100644 --- a/src/openrct2/actions/WallSetColourAction.cpp +++ b/src/openrct2/actions/WallSetColourAction.cpp @@ -67,7 +67,7 @@ GameActions::Result WallSetColourAction::Query() const return GameActions::Result(GameActions::Status::InvalidParameters, STR_CANT_REPAINT_THIS, STR_OFF_EDGE_OF_MAP); } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !MapIsLocationInPark(_loc) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !MapIsLocationInPark(_loc) && !GetGameState().Cheats.sandboxMode) { return GameActions::Result(GameActions::Status::NotOwned, STR_CANT_REPAINT_THIS, STR_LAND_NOT_OWNED_BY_PARK); } diff --git a/src/openrct2/actions/WaterLowerAction.cpp b/src/openrct2/actions/WaterLowerAction.cpp index 9005b0a01f..897d933381 100644 --- a/src/openrct2/actions/WaterLowerAction.cpp +++ b/src/openrct2/actions/WaterLowerAction.cpp @@ -80,7 +80,7 @@ GameActions::Result WaterLowerAction::QueryExecute(bool isExecuting) const if (surfaceElement == nullptr) continue; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ x, y })) { @@ -139,7 +139,7 @@ uint8_t WaterLowerAction::GetLowestHeight(const MapRange& validRange) const { for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += kCoordsXYStep) { - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ x, y })) { diff --git a/src/openrct2/actions/WaterRaiseAction.cpp b/src/openrct2/actions/WaterRaiseAction.cpp index eede825891..c09e3262d8 100644 --- a/src/openrct2/actions/WaterRaiseAction.cpp +++ b/src/openrct2/actions/WaterRaiseAction.cpp @@ -80,7 +80,7 @@ GameActions::Result WaterRaiseAction::QueryExecute(bool isExecuting) const if (surfaceElement == nullptr) continue; - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ x, y })) { @@ -152,7 +152,7 @@ uint16_t WaterRaiseAction::GetHighestHeight(const MapRange& validRange) const { for (int32_t x = validRange.GetLeft(); x <= validRange.GetRight(); x += kCoordsXYStep) { - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ x, y })) { diff --git a/src/openrct2/actions/WaterSetHeightAction.cpp b/src/openrct2/actions/WaterSetHeightAction.cpp index 129d8bc69d..41b6ccef91 100644 --- a/src/openrct2/actions/WaterSetHeightAction.cpp +++ b/src/openrct2/actions/WaterSetHeightAction.cpp @@ -52,7 +52,7 @@ GameActions::Result WaterSetHeightAction::Query() const res.Position = { _coords, _height * kCoordsZStep }; auto& gameState = GetGameState(); - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.SandboxMode + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.sandboxMode && gameState.Park.Flags & PARK_FLAGS_FORBID_LANDSCAPE_CHANGES) { return GameActions::Result(GameActions::Status::Disallowed, STR_NONE, STR_FORBIDDEN_BY_THE_LOCAL_AUTHORITY); @@ -69,7 +69,7 @@ GameActions::Result WaterSetHeightAction::Query() const return GameActions::Result(GameActions::Status::NotOwned, STR_NONE, STR_LAND_NOT_OWNED_BY_PARK); } - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !gameState.Cheats.sandboxMode) { if (!MapIsLocationInPark(_coords)) { @@ -121,7 +121,7 @@ GameActions::Result WaterSetHeightAction::Execute() const int32_t surfaceHeight = TileElementHeight(_coords); FootpathRemoveLitter({ _coords, surfaceHeight }); - if (!GetGameState().Cheats.DisableClearanceChecks) + if (!GetGameState().Cheats.disableClearanceChecks) WallRemoveAtZ({ _coords, surfaceHeight }); SurfaceElement* surfaceElement = MapGetSurfaceElementAt(_coords); diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index e13d43a9ed..5a46a3a0a9 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -1592,7 +1592,7 @@ bool Guest::DecideAndBuyItem(Ride& ride, const ShopItem shopItem, money64 price) if (Happiness >= 180) itemValue /= 2; } - if (itemValue > (static_cast(ScenarioRand() & 0x07)) && !(GetGameState().Cheats.IgnorePrice)) + if (itemValue > (static_cast(ScenarioRand() & 0x07)) && !(GetGameState().Cheats.ignorePrice)) { // "I'm not paying that much for x" InsertNewThought(shopItemDescriptor.TooMuchThought, ride.id); @@ -2067,7 +2067,7 @@ bool Guest::ShouldGoOnRide(Ride& ride, StationIndex entranceNum, bool atQueue, b // excitement check and will only do a basic intensity check when they arrive at the ride itself. if (ride.id == GuestHeadingToRideId) { - if (ride.ratings.intensity > RIDE_RATING(10, 00) && !GetGameState().Cheats.IgnoreRideIntensity) + if (ride.ratings.intensity > RIDE_RATING(10, 00) && !GetGameState().Cheats.ignoreRideIntensity) { PeepRideIsTooIntense(this, ride, peepAtRide); return false; @@ -2094,7 +2094,7 @@ bool Guest::ShouldGoOnRide(Ride& ride, StationIndex entranceNum, bool atQueue, b // ride intensity check and get me on a sheltered ride! if (!isPrecipitating || !ShouldRideWhileRaining(ride)) { - if (!GetGameState().Cheats.IgnoreRideIntensity) + if (!GetGameState().Cheats.ignoreRideIntensity) { // Intensity calculations. Even though the max intensity can go up to 15, it's capped // at 10.0 (before happiness calculations). A full happiness bar will increase the max @@ -2160,7 +2160,7 @@ bool Guest::ShouldGoOnRide(Ride& ride, StationIndex entranceNum, bool atQueue, b return false; } - if (!GetGameState().Cheats.IgnoreRideIntensity) + if (!GetGameState().Cheats.ignoreRideIntensity) { if (ride.max_positive_vertical_g > FIXED_2DP(5, 00) || ride.max_negative_vertical_g < FIXED_2DP(-4, 00) || ride.max_lateral_g > FIXED_2DP(4, 00)) @@ -2183,7 +2183,7 @@ bool Guest::ShouldGoOnRide(Ride& ride, StationIndex entranceNum, bool atQueue, b // Peeps won't pay more than twice the value of the ride. ridePrice = RideGetPrice(ride); - if ((ridePrice > (value * 2)) && !(gameState.Cheats.IgnorePrice)) + if ((ridePrice > (value * 2)) && !(gameState.Cheats.ignorePrice)) { if (peepAtRide) { @@ -2251,7 +2251,7 @@ bool Guest::ShouldGoToShop(Ride& ride, bool peepAtShop) // The amount that peeps are willing to pay to use the Toilets scales with their toilet stat. // It effectively has a minimum of $0.10 (due to the check above) and a maximum of $0.60. - if ((RideGetPrice(ride) * 40 > Toilet) && !GetGameState().Cheats.IgnorePrice) + if ((RideGetPrice(ride) * 40 > Toilet) && !GetGameState().Cheats.ignorePrice) { if (peepAtShop) { @@ -2658,7 +2658,7 @@ static bool PeepCheckRidePriceAtEntrance(Guest* peep, const Ride& ride, money64 auto value = ride.value; if (value != RIDE_VALUE_UNDEFINED) { - if (((value * 2) < ridePrice) && !(GetGameState().Cheats.IgnorePrice)) + if (((value * 2) < ridePrice) && !(GetGameState().Cheats.ignorePrice)) { peep->InsertNewThought(PeepThoughtType::BadValue, peep->CurrentRide); PeepUpdateRideAtEntranceTryLeave(peep); @@ -2874,7 +2874,7 @@ static bool PeepShouldGoOnRideAgain(Guest* peep, const Ride& ride) return false; if (!RideHasRatings(ride)) return false; - if (ride.ratings.intensity > RIDE_RATING(10, 00) && !GetGameState().Cheats.IgnoreRideIntensity) + if (ride.ratings.intensity > RIDE_RATING(10, 00) && !GetGameState().Cheats.ignoreRideIntensity) return false; if (peep->Happiness < 180) return false; @@ -2919,7 +2919,7 @@ static bool PeepReallyLikedRide(Guest* peep, const Ride& ride) return false; if (!RideHasRatings(ride)) return false; - if (ride.ratings.intensity > RIDE_RATING(10, 00) && !GetGameState().Cheats.IgnoreRideIntensity) + if (ride.ratings.intensity > RIDE_RATING(10, 00) && !GetGameState().Cheats.ignoreRideIntensity) return false; return true; } @@ -3038,7 +3038,7 @@ static PeepThoughtType PeepAssessSurroundings(int16_t centre_x, int16_t centre_y if (nearby_music == 1 && num_rubbish < 20) return PeepThoughtType::Music; - if (num_rubbish < 2 && !GetGameState().Cheats.DisableLittering) + if (num_rubbish < 2 && !GetGameState().Cheats.disableLittering) // if disable littering cheat is enabled, peeps will not have the "clean and tidy park" thought return PeepThoughtType::VeryClean; @@ -6218,7 +6218,7 @@ static PathElement* FindBreakableElement(const CoordsXYZ& loc) */ static void PeepUpdateWalkingBreakScenery(Guest* peep) { - if (GetGameState().Cheats.DisableVandalism) + if (GetGameState().Cheats.disableVandalism) return; if (!(peep->PeepFlags & PEEP_FLAGS_ANGRY)) diff --git a/src/openrct2/entity/Litter.cpp b/src/openrct2/entity/Litter.cpp index 3a8d38fe33..34d3f4b7d3 100644 --- a/src/openrct2/entity/Litter.cpp +++ b/src/openrct2/entity/Litter.cpp @@ -52,7 +52,7 @@ static bool IsLocationLitterable(const CoordsXYZ& mapPos) void Litter::Create(const CoordsXYZD& litterPos, Type type) { auto& gameState = GetGameState(); - if (gameState.Cheats.DisableLittering) + if (gameState.Cheats.disableLittering) return; auto offsetLitterPos = litterPos diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 1b4d2a787a..c37be28bc8 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -209,7 +209,7 @@ static int32_t ConsoleCommandRides(InteractiveConsole& console, const arguments_ auto res = SetOperatingSetting(RideId::FromUnderlying(ride_index), RideSetSetting::RideType, type); if (res == kMoney64Undefined) { - if (!GetGameState().Cheats.AllowArbitraryRideTypeChanges) + if (!GetGameState().Cheats.allowArbitraryRideTypeChanges) { console.WriteFormatLine( "That didn't work. Try enabling the 'Allow arbitrary ride type changes' cheat"); @@ -718,15 +718,15 @@ static int32_t ConsoleCommandGet(InteractiveConsole& console, const arguments_t& } else if (argv[0] == "cheat_sandbox_mode") { - console.WriteFormatLine("cheat_sandbox_mode %d", GetGameState().Cheats.SandboxMode); + console.WriteFormatLine("cheat_sandbox_mode %d", GetGameState().Cheats.sandboxMode); } else if (argv[0] == "cheat_disable_clearance_checks") { - console.WriteFormatLine("cheat_disable_clearance_checks %d", GetGameState().Cheats.DisableClearanceChecks); + console.WriteFormatLine("cheat_disable_clearance_checks %d", GetGameState().Cheats.disableClearanceChecks); } else if (argv[0] == "cheat_disable_support_limits") { - console.WriteFormatLine("cheat_disable_support_limits %d", GetGameState().Cheats.DisableSupportLimits); + console.WriteFormatLine("cheat_disable_support_limits %d", GetGameState().Cheats.disableSupportLimits); } else if (argv[0] == "current_rotation") { @@ -1109,7 +1109,7 @@ static int32_t ConsoleCommandSet(InteractiveConsole& console, const arguments_t& } else if (argv[0] == "cheat_sandbox_mode" && InvalidArguments(&invalidArgs, int_valid[0])) { - if (GetGameState().Cheats.SandboxMode != (int_val[0] != 0)) + if (GetGameState().Cheats.sandboxMode != (int_val[0] != 0)) { auto cheatSetAction = CheatSetAction(CheatType::SandboxMode, int_val[0] != 0); cheatSetAction.SetCallback([&console](const GameAction*, const GameActions::Result* res) { @@ -1127,7 +1127,7 @@ static int32_t ConsoleCommandSet(InteractiveConsole& console, const arguments_t& } else if (argv[0] == "cheat_disable_clearance_checks" && InvalidArguments(&invalidArgs, int_valid[0])) { - if (GetGameState().Cheats.DisableClearanceChecks != (int_val[0] != 0)) + if (GetGameState().Cheats.disableClearanceChecks != (int_val[0] != 0)) { auto cheatSetAction = CheatSetAction(CheatType::DisableClearanceChecks, int_val[0] != 0); cheatSetAction.SetCallback([&console](const GameAction*, const GameActions::Result* res) { @@ -1145,7 +1145,7 @@ static int32_t ConsoleCommandSet(InteractiveConsole& console, const arguments_t& } else if (argv[0] == "cheat_disable_support_limits" && InvalidArguments(&invalidArgs, int_valid[0])) { - if (GetGameState().Cheats.DisableSupportLimits != (int_val[0] != 0)) + if (GetGameState().Cheats.disableSupportLimits != (int_val[0] != 0)) { auto cheatSetAction = CheatSetAction(CheatType::DisableSupportLimits, int_val[0] != 0); cheatSetAction.SetCallback([&console](const GameAction*, const GameActions::Result* res) { diff --git a/src/openrct2/management/Marketing.cpp b/src/openrct2/management/Marketing.cpp index 849f3ea48c..a22e23e140 100644 --- a/src/openrct2/management/Marketing.cpp +++ b/src/openrct2/management/Marketing.cpp @@ -113,7 +113,7 @@ void MarketingUpdate() auto& gameState = GetGameState(); - if (gameState.Cheats.NeverendingMarketing) + if (gameState.Cheats.neverendingMarketing) return; for (auto it = gameState.MarketingCampaigns.begin(); it != gameState.MarketingCampaigns.end();) diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index c213f7e5f9..2e7c592256 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -640,7 +640,7 @@ bool SceneryGroupIsInvented(int32_t sgIndex) return true; } - if (GetGameState().Cheats.IgnoreResearchStatus) + if (GetGameState().Cheats.ignoreResearchStatus) { return true; } diff --git a/src/openrct2/paint/VirtualFloor.cpp b/src/openrct2/paint/VirtualFloor.cpp index 2eb7285a92..5122c58823 100644 --- a/src/openrct2/paint/VirtualFloor.cpp +++ b/src/openrct2/paint/VirtualFloor.cpp @@ -247,7 +247,7 @@ static void VirtualFloorGetTileProperties( *tileOwned = MapIsLocationOwned({ loc, height }); - if (GetGameState().Cheats.SandboxMode) + if (GetGameState().Cheats.sandboxMode) *tileOwned = true; // Iterate through the map elements of the current tile to find: diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index 81937e7172..37343a9c91 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -1111,7 +1111,7 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con auto& gameState = GetGameState(); // Draw Peep Spawns - if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gameState.Cheats.SandboxMode) + if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gameState.Cheats.sandboxMode) && session.ViewFlags & VIEWPORT_FLAG_LAND_OWNERSHIP) { const CoordsXY& pos = session.MapPosition; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 7212779676..9c5b72ae2c 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -1453,7 +1453,7 @@ static void RideBreakdownUpdate(Ride& ride) // continues. if ((ride.reliability == 0 || static_cast(ScenarioRand() & 0x2FFFFF) <= 1u + kRideInitialReliability - ride.reliability) - && !gameState.Cheats.DisableAllBreakdowns) + && !gameState.Cheats.disableAllBreakdowns) { int32_t breakdownReason = RideGetNewBreakdownProblem(ride); if (breakdownReason != -1) @@ -1511,7 +1511,7 @@ static int32_t RideGetNewBreakdownProblem(const Ride& ride) return -1; // If brakes failure is disabled, also take it out of the equation (see above comment why) - if (GetGameState().Cheats.DisableBrakesFailure) + if (GetGameState().Cheats.disableBrakesFailure) return -1; auto monthsOld = ride.GetAge(); @@ -5108,7 +5108,7 @@ void Ride::UpdateMaxVehicles() } int32_t newCarsPerTrain = std::max(proposed_num_cars_per_train, rideEntry->min_cars_in_train); maxCarsPerTrain = std::max(maxCarsPerTrain, static_cast(rideEntry->min_cars_in_train)); - if (!GetGameState().Cheats.DisableTrainLengthLimit) + if (!GetGameState().Cheats.disableTrainLengthLimit) { newCarsPerTrain = std::min(maxCarsPerTrain, newCarsPerTrain); } @@ -5197,7 +5197,7 @@ void Ride::UpdateMaxVehicles() maxNumTrains = rideEntry->cars_per_flat_ride; } - if (GetGameState().Cheats.DisableTrainLengthLimit) + if (GetGameState().Cheats.disableTrainLengthLimit) { maxNumTrains = OpenRCT2::Limits::kMaxTrainsPerRide; } @@ -5532,7 +5532,7 @@ int32_t RideGetEntryIndex(int32_t rideType, int32_t rideSubType) } // Can happen in select-by-track-type mode - if (!RideEntryIsInvented(rideEntryIndex) && !GetGameState().Cheats.IgnoreResearchStatus) + if (!RideEntryIsInvented(rideEntryIndex) && !GetGameState().Cheats.ignoreResearchStatus) { continue; } @@ -5761,7 +5761,7 @@ void Ride::FormatNameTo(Formatter& ft) const uint64_t Ride::GetAvailableModes() const { - if (GetGameState().Cheats.ShowAllOperatingModes) + if (GetGameState().Cheats.showAllOperatingModes) return AllRideModesAvailable; return GetRideTypeDescriptor().RideModes; @@ -5943,7 +5943,7 @@ ResultWithMessage Ride::ChangeStatusCheckTrackValidity(const CoordsXYE& trackEle } } - if (subtype != OBJECT_ENTRY_INDEX_NULL && !GetGameState().Cheats.EnableAllDrawableTrackPieces) + if (subtype != OBJECT_ENTRY_INDEX_NULL && !GetGameState().Cheats.enableAllDrawableTrackPieces) { const auto* rideEntry = GetRideEntryByIndex(subtype); if (rideEntry->flags & RIDE_ENTRY_FLAG_NO_INVERSIONS) diff --git a/src/openrct2/ride/RideConstruction.cpp b/src/openrct2/ride/RideConstruction.cpp index ebb333b08e..1dd7978fb8 100644 --- a/src/openrct2/ride/RideConstruction.cpp +++ b/src/openrct2/ride/RideConstruction.cpp @@ -636,7 +636,7 @@ void RideConstructionSetDefaultNextPiece() _previousTrackPitchEnd = slope; _currentTrackHasLiftHill = tileElement->AsTrack()->HasChain() && ((slope != TrackPitch::Down25 && slope != TrackPitch::Down60) - || GetGameState().Cheats.EnableChainLiftOnAllTrack); + || GetGameState().Cheats.enableChainLiftOnAllTrack); break; } case RideConstructionState::Back: @@ -682,7 +682,7 @@ void RideConstructionSetDefaultNextPiece() // Set track slope and lift hill _currentTrackPitchEnd = slope; _previousTrackPitchEnd = slope; - if (!GetGameState().Cheats.EnableChainLiftOnAllTrack) + if (!GetGameState().Cheats.enableChainLiftOnAllTrack) { _currentTrackHasLiftHill = tileElement->AsTrack()->HasChain(); } diff --git a/src/openrct2/ride/RideData.cpp b/src/openrct2/ride/RideData.cpp index 0412f2624e..bbba6640a4 100644 --- a/src/openrct2/ride/RideData.cpp +++ b/src/openrct2/ride/RideData.cpp @@ -408,7 +408,7 @@ void UpdateEnabledRideGroups(TrackDrawerDescriptor trackDrawerDescriptor) { trackDrawerDescriptor.Regular.GetAvailableTrackGroups(_enabledRideGroups); - if (!GetGameState().Cheats.EnableAllDrawableTrackPieces) + if (!GetGameState().Cheats.enableAllDrawableTrackPieces) { _enabledRideGroups &= ~_disabledRideGroups; } @@ -422,14 +422,14 @@ void UpdateDisabledRideGroups(const RideTrackGroups& res) void TrackDrawerEntry::GetAvailableTrackGroups(RideTrackGroups& res) const { res = enabledTrackGroups; - if (GetGameState().Cheats.EnableAllDrawableTrackPieces) + if (GetGameState().Cheats.enableAllDrawableTrackPieces) res |= extraTrackGroups; } bool TrackDrawerEntry::SupportsTrackGroup(const TrackGroup trackGroup) const { return enabledTrackGroups.get(EnumValue(trackGroup)) - || (GetGameState().Cheats.EnableAllDrawableTrackPieces && extraTrackGroups.get(EnumValue(trackGroup))); + || (GetGameState().Cheats.enableAllDrawableTrackPieces && extraTrackGroups.get(EnumValue(trackGroup))); } bool TrackDrawerDescriptor::HasCoveredPieces() const diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 7d251e7371..40105e0cee 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -1141,7 +1141,7 @@ static void RideRatingsCalculateValue(Ride& ride) + (((ride.ratings.nausea * ratingsMultipliers.nausea) * 32) >> 15); int32_t monthsOld = 0; - if (!GetGameState().Cheats.DisableRideValueAging) + if (!GetGameState().Cheats.disableRideValueAging) { monthsOld = ride.GetAge(); } diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index f55ceeb5ab..ed61e08155 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -728,7 +728,7 @@ static std::optional TrackDesignPlaceSceneryElementGetEntry(c { result.Type = obj->GetObjectType(); result.Index = objectMgr.GetLoadedObjectEntryIndex(obj); - if (!GetGameState().Cheats.IgnoreResearchStatus) + if (!GetGameState().Cheats.ignoreResearchStatus) { objectUnavailable = !ResearchIsInvented(result.Type, result.Index); } @@ -1951,7 +1951,7 @@ static bool TrackDesignPlacePreview( { gameStateData.setFlag(TrackDesignGameStateFlag::VehicleUnavailable, true); } - else if (!RideEntryIsInvented(entry_index) && !GetGameState().Cheats.IgnoreResearchStatus) + else if (!RideEntryIsInvented(entry_index) && !GetGameState().Cheats.ignoreResearchStatus) { gameStateData.setFlag(TrackDesignGameStateFlag::VehicleUnavailable, true); } diff --git a/src/openrct2/scripting/bindings/game/ScCheats.hpp b/src/openrct2/scripting/bindings/game/ScCheats.hpp index c69a41cb1c..8419b63ee8 100644 --- a/src/openrct2/scripting/bindings/game/ScCheats.hpp +++ b/src/openrct2/scripting/bindings/game/ScCheats.hpp @@ -79,266 +79,266 @@ namespace OpenRCT2::Scripting private: bool allowArbitraryRideTypeChanges_get() { - return GetGameState().Cheats.AllowArbitraryRideTypeChanges; + return GetGameState().Cheats.allowArbitraryRideTypeChanges; } void allowArbitraryRideTypeChanges_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.AllowArbitraryRideTypeChanges = value; + GetGameState().Cheats.allowArbitraryRideTypeChanges = value; } bool allowTrackPlaceInvalidHeights_get() { - return GetGameState().Cheats.AllowTrackPlaceInvalidHeights; + return GetGameState().Cheats.allowTrackPlaceInvalidHeights; } void allowTrackPlaceInvalidHeights_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.AllowTrackPlaceInvalidHeights = value; + GetGameState().Cheats.allowTrackPlaceInvalidHeights = value; } bool buildInPauseMode_get() { - return GetGameState().Cheats.BuildInPauseMode; + return GetGameState().Cheats.buildInPauseMode; } void buildInPauseMode_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.BuildInPauseMode = value; + GetGameState().Cheats.buildInPauseMode = value; } bool disableAllBreakdowns_get() { - return GetGameState().Cheats.DisableAllBreakdowns; + return GetGameState().Cheats.disableAllBreakdowns; } void disableAllBreakdowns_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableAllBreakdowns = value; + GetGameState().Cheats.disableAllBreakdowns = value; } bool disableBrakesFailure_get() { - return GetGameState().Cheats.DisableBrakesFailure; + return GetGameState().Cheats.disableBrakesFailure; } void disableBrakesFailure_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableBrakesFailure = value; + GetGameState().Cheats.disableBrakesFailure = value; } bool disableClearanceChecks_get() { - return GetGameState().Cheats.DisableClearanceChecks; + return GetGameState().Cheats.disableClearanceChecks; } void disableClearanceChecks_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableClearanceChecks = value; + GetGameState().Cheats.disableClearanceChecks = value; } bool disableLittering_get() { - return GetGameState().Cheats.DisableLittering; + return GetGameState().Cheats.disableLittering; } void disableLittering_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableLittering = value; + GetGameState().Cheats.disableLittering = value; } bool disablePlantAging_get() { - return GetGameState().Cheats.DisablePlantAging; + return GetGameState().Cheats.disablePlantAging; } void disablePlantAging_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisablePlantAging = value; + GetGameState().Cheats.disablePlantAging = value; } bool allowRegularPathAsQueue_get() { - return GetGameState().Cheats.AllowRegularPathAsQueue; + return GetGameState().Cheats.allowRegularPathAsQueue; } void allowRegularPathAsQueue_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.AllowRegularPathAsQueue = value; + GetGameState().Cheats.allowRegularPathAsQueue = value; } bool allowSpecialColourSchemes_get() { - return GetGameState().Cheats.AllowSpecialColourSchemes; + return GetGameState().Cheats.allowSpecialColourSchemes; } void allowSpecialColourSchemes_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.AllowSpecialColourSchemes = value; + GetGameState().Cheats.allowSpecialColourSchemes = value; } bool disableRideValueAging_get() { - return GetGameState().Cheats.DisableRideValueAging; + return GetGameState().Cheats.disableRideValueAging; } void disableRideValueAging_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableRideValueAging = value; + GetGameState().Cheats.disableRideValueAging = value; } bool disableSupportLimits_get() { - return GetGameState().Cheats.DisableSupportLimits; + return GetGameState().Cheats.disableSupportLimits; } void disableSupportLimits_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableSupportLimits = value; + GetGameState().Cheats.disableSupportLimits = value; } bool disableTrainLengthLimit_get() { - return GetGameState().Cheats.DisableTrainLengthLimit; + return GetGameState().Cheats.disableTrainLengthLimit; } void disableTrainLengthLimit_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableTrainLengthLimit = value; + GetGameState().Cheats.disableTrainLengthLimit = value; } bool disableVandalism_get() { - return GetGameState().Cheats.DisableVandalism; + return GetGameState().Cheats.disableVandalism; } void disableVandalism_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.DisableVandalism = value; + GetGameState().Cheats.disableVandalism = value; } bool enableAllDrawableTrackPieces_get() { - return GetGameState().Cheats.EnableAllDrawableTrackPieces; + return GetGameState().Cheats.enableAllDrawableTrackPieces; } void enableAllDrawableTrackPieces_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.EnableAllDrawableTrackPieces = value; + GetGameState().Cheats.enableAllDrawableTrackPieces = value; } bool enableChainLiftOnAllTrack_get() { - return GetGameState().Cheats.EnableChainLiftOnAllTrack; + return GetGameState().Cheats.enableChainLiftOnAllTrack; } void enableChainLiftOnAllTrack_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.EnableChainLiftOnAllTrack = value; + GetGameState().Cheats.enableChainLiftOnAllTrack = value; } bool fastLiftHill_get() { - return GetGameState().Cheats.UnlockOperatingLimits; + return GetGameState().Cheats.unlockOperatingLimits; } void fastLiftHill_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.UnlockOperatingLimits = value; + GetGameState().Cheats.unlockOperatingLimits = value; } bool freezeWeather_get() { - return GetGameState().Cheats.FreezeWeather; + return GetGameState().Cheats.freezeWeather; } void freezeWeather_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.FreezeWeather = value; + GetGameState().Cheats.freezeWeather = value; } bool ignoreResearchStatus_get() { - return GetGameState().Cheats.IgnoreResearchStatus; + return GetGameState().Cheats.ignoreResearchStatus; } void ignoreResearchStatus_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.IgnoreResearchStatus = value; + GetGameState().Cheats.ignoreResearchStatus = value; } bool ignoreRideIntensity_get() { - return GetGameState().Cheats.IgnoreRideIntensity; + return GetGameState().Cheats.ignoreRideIntensity; } void ignoreRideIntensity_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.IgnoreRideIntensity = value; + GetGameState().Cheats.ignoreRideIntensity = value; } bool neverendingMarketing_get() { - return GetGameState().Cheats.NeverendingMarketing; + return GetGameState().Cheats.neverendingMarketing; } void neverendingMarketing_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.NeverendingMarketing = value; + GetGameState().Cheats.neverendingMarketing = value; } bool sandboxMode_get() { - return GetGameState().Cheats.SandboxMode; + return GetGameState().Cheats.sandboxMode; } void sandboxMode_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.SandboxMode = value; + GetGameState().Cheats.sandboxMode = value; } bool showAllOperatingModes_get() { - return GetGameState().Cheats.ShowAllOperatingModes; + return GetGameState().Cheats.showAllOperatingModes; } void showAllOperatingModes_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.ShowAllOperatingModes = value; + GetGameState().Cheats.showAllOperatingModes = value; } bool showVehiclesFromOtherTrackTypes_get() { - return GetGameState().Cheats.ShowVehiclesFromOtherTrackTypes; + return GetGameState().Cheats.showVehiclesFromOtherTrackTypes; } void showVehiclesFromOtherTrackTypes_set(bool value) { ThrowIfGameStateNotMutable(); - GetGameState().Cheats.ShowVehiclesFromOtherTrackTypes = value; + GetGameState().Cheats.showVehiclesFromOtherTrackTypes = value; } }; } // namespace OpenRCT2::Scripting diff --git a/src/openrct2/world/Climate.cpp b/src/openrct2/world/Climate.cpp index 127ae7f172..256a9c66c3 100644 --- a/src/openrct2/world/Climate.cpp +++ b/src/openrct2/world/Climate.cpp @@ -125,7 +125,7 @@ void ClimateUpdate() if (gScreenFlags & (~SCREEN_FLAGS_PLAYING)) return; - if (!GetGameState().Cheats.FreezeWeather) + if (!GetGameState().Cheats.freezeWeather) { if (gameState.ClimateUpdateTimer) { diff --git a/src/openrct2/world/ConstructionClearance.cpp b/src/openrct2/world/ConstructionClearance.cpp index a3d65ad733..3d4e4e7585 100644 --- a/src/openrct2/world/ConstructionClearance.cpp +++ b/src/openrct2/world/ConstructionClearance.cpp @@ -146,7 +146,7 @@ GameActions::Result MapCanConstructWithClearAt( return res; } - if (GetGameState().Cheats.DisableClearanceChecks) + if (GetGameState().Cheats.disableClearanceChecks) { res.SetData(ConstructClearResult{ groundFlags }); return res; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 347aa277ac..cd4c241316 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -561,7 +561,7 @@ static void Loc6A6D7E( FootpathNeighbourList* neighbourList) { auto targetPos = CoordsXY{ initialTileElementPos } + CoordsDirectionDelta[direction]; - if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode) && MapIsEdge(targetPos)) + if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode) && MapIsEdge(targetPos)) { if (query) { @@ -1808,7 +1808,7 @@ void FootpathRemoveEdgesAt(const CoordsXY& footpathPos, TileElement* tileElement static ObjectEntryIndex FootpathGetDefaultSurface(bool queue) { - bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode); + bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode); for (ObjectEntryIndex i = 0; i < kMaxFootpathSurfaceObjects; i++) { auto pathEntry = GetPathSurfaceEntry(i); @@ -1832,7 +1832,7 @@ static bool FootpathIsSurfaceEntryOkay(ObjectEntryIndex index, bool queue) auto pathEntry = GetPathSurfaceEntry(index); if (pathEntry != nullptr) { - bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode); + bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode); if (!showEditorPaths && (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)) { return false; @@ -1860,7 +1860,7 @@ static ObjectEntryIndex FootpathGetDefaultRailings() static bool FootpathIsLegacyPathEntryOkay(ObjectEntryIndex index) { - bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.SandboxMode); + bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || GetGameState().Cheats.sandboxMode); auto& objManager = OpenRCT2::GetContext()->GetObjectManager(); auto footpathObj = objManager.GetLoadedObject(index); if (footpathObj != nullptr) diff --git a/src/openrct2/world/Map.cpp b/src/openrct2/world/Map.cpp index 3e69e19bdc..b79b1a5ad3 100644 --- a/src/openrct2/world/Map.cpp +++ b/src/openrct2/world/Map.cpp @@ -830,7 +830,7 @@ bool MapCanBuildAt(const CoordsXYZ& loc) { if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) return true; - if (GetGameState().Cheats.SandboxMode) + if (GetGameState().Cheats.sandboxMode) return true; if (MapIsLocationOwned(loc)) return true; @@ -966,7 +966,7 @@ uint8_t MapGetLowestLandHeight(const MapRange& range) if (surfaceElement != nullptr && min_height > surfaceElement->BaseHeight) { - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ xi, yi })) { @@ -995,7 +995,7 @@ uint8_t MapGetHighestLandHeight(const MapRange& range) auto* surfaceElement = MapGetSurfaceElementAt(CoordsXY{ xi, yi }); if (surfaceElement != nullptr) { - if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.SandboxMode) + if (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && !GetGameState().Cheats.sandboxMode) { if (!MapIsLocationInPark(CoordsXY{ xi, yi })) { @@ -1318,8 +1318,8 @@ void MapRemoveOutOfRangeElements() // Map resize has to become its own Game Action to properly solve this issue. // auto& gameState = GetGameState(); - bool buildState = gameState.Cheats.BuildInPauseMode; - gameState.Cheats.BuildInPauseMode = true; + bool buildState = gameState.Cheats.buildInPauseMode; + gameState.Cheats.buildInPauseMode = true; for (int32_t y = MAXIMUM_MAP_SIZE_BIG - kCoordsXYStep; y >= 0; y -= kCoordsXYStep) { @@ -1340,7 +1340,7 @@ void MapRemoveOutOfRangeElements() } // Reset cheat state - gameState.Cheats.BuildInPauseMode = buildState; + gameState.Cheats.buildInPauseMode = buildState; } static void MapExtendBoundarySurfaceExtendTile(const SurfaceElement& sourceTile, SurfaceElement& destTile) diff --git a/src/openrct2/world/Scenery.cpp b/src/openrct2/world/Scenery.cpp index e25c3ebf47..d5dc982134 100644 --- a/src/openrct2/world/Scenery.cpp +++ b/src/openrct2/world/Scenery.cpp @@ -179,7 +179,7 @@ void SmallSceneryElement::UpdateAge(const CoordsXY& sceneryPos) } auto& gameState = GetGameState(); - if (gameState.Cheats.DisablePlantAging && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_BE_WATERED)) + if (gameState.Cheats.disablePlantAging && sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_CAN_BE_WATERED)) { return; } @@ -310,7 +310,7 @@ bool IsSceneryAvailableToBuild(const ScenerySelection& item) } auto& gameState = GetGameState(); - if (!gameState.Cheats.IgnoreResearchStatus) + if (!gameState.Cheats.ignoreResearchStatus) { if (!SceneryIsInvented(item)) { @@ -318,7 +318,7 @@ bool IsSceneryAvailableToBuild(const ScenerySelection& item) } } - if (!gameState.Cheats.SandboxMode && !(gScreenFlags & SCREEN_FLAGS_EDITOR)) + if (!gameState.Cheats.sandboxMode && !(gScreenFlags & SCREEN_FLAGS_EDITOR)) { if (IsSceneryItemRestricted(item)) { diff --git a/src/openrct2/world/tile_element/TrackElement.cpp b/src/openrct2/world/tile_element/TrackElement.cpp index 0e96088da3..46dfb7880e 100644 --- a/src/openrct2/world/tile_element/TrackElement.cpp +++ b/src/openrct2/world/tile_element/TrackElement.cpp @@ -252,7 +252,7 @@ void TrackElement::SetBrakeClosed(bool isClosed) bool TrackElement::IsIndestructible() const { - return (Flags2 & TRACK_ELEMENT_FLAGS2_INDESTRUCTIBLE_TRACK_PIECE) != 0 && !GetGameState().Cheats.MakeAllDestructible; + return (Flags2 & TRACK_ELEMENT_FLAGS2_INDESTRUCTIBLE_TRACK_PIECE) != 0 && !GetGameState().Cheats.makeAllDestructible; } void TrackElement::SetIsIndestructible(bool isIndestructible) diff --git a/test/tests/PlayTests.cpp b/test/tests/PlayTests.cpp index 1cbeb80f2b..f5ff736982 100644 --- a/test/tests/PlayTests.cpp +++ b/test/tests/PlayTests.cpp @@ -116,7 +116,7 @@ TEST_F(PlayTests, SecondGuestInQueueShouldNotRideIfNoFunds) execute(ferrisWheel.id, 0, true); // Ignore intensity to stimulate peeps to queue into ferris wheel - gameState.Cheats.IgnoreRideIntensity = true; + gameState.Cheats.ignoreRideIntensity = true; // Insert a rich guest auto richGuest = Park::GenerateGuest(); @@ -175,7 +175,7 @@ TEST_F(PlayTests, CarRideWithOneCarOnlyAcceptsTwoGuests) execute(carRide.id, 0, true); // Ignore intensity to stimulate peeps to queue into the ride - gameState.Cheats.IgnoreRideIntensity = true; + gameState.Cheats.ignoreRideIntensity = true; // Create some guests std::vector guests; From a87341888a5ccea242c76564b920b63f5a6d3498 Mon Sep 17 00:00:00 2001 From: mix <167040362+mixiate@users.noreply.github.com> Date: Sun, 1 Dec 2024 20:26:37 +0000 Subject: [PATCH 100/139] Stand-Up Roller Coaster fixes * Fix misaligned Stand-Up Roller Coaster banked turns * Fix Stand Up RC using Corkscrew diag right bank to 25 deg down piece * Fix Stand Up RC steep track clipping * Fix Stand-Up RC steep supports * Fix Stand Up RC orthogonal unbanked to banked supports * Fix Stand Up RC diagonal brake supports * Fix Stand Up RC diagonal slope supports * Fix Stand Up RC diagonal banked supports * Fix Stand Up RC small gentle turn supports * Fix Stand Up RC corkscrew supports * Fix Stand Up RC large banked turn supports * Fix Stand Up RC medium banked turn supports * Fix Stand Up RC small turn supports * Fix Stand Up RC small banked turn supports * Fix Stand Up RC small half loop clipping and supports * Fix Stand Up RC vertical loops clipping and supports * Fix Stand Up RC small helix supports * Fix Stand Up RC large helix supports * Change alignment of Stand-Up RC flat to right bank sprite 25285 * Change alignment of Stand-Up RC diagonal bank track sprites --- distribution/changelog.txt | 2 + resources/g2/sprites.json | 372 +++++++ resources/g2/track/standup/25455.png | Bin 0 -> 5406 bytes resources/g2/track/standup/25457.png | Bin 0 -> 5172 bytes resources/g2/track/standup/25459.png | Bin 0 -> 5312 bytes resources/g2/track/standup/25461.png | Bin 0 -> 5185 bytes resources/g2/track/standup/25462.png | Bin 0 -> 5187 bytes resources/g2/track/standup/25463.png | Bin 0 -> 5130 bytes resources/g2/track/standup/25464.png | Bin 0 -> 5012 bytes resources/g2/track/standup/25466.png | Bin 0 -> 5156 bytes resources/g2/track/standup/25468.png | Bin 0 -> 5139 bytes resources/g2/track/standup/25470.png | Bin 0 -> 5013 bytes resources/g2/track/standup/25471.png | Bin 0 -> 5113 bytes resources/g2/track/standup/25472.png | Bin 0 -> 5172 bytes resources/g2/track/standup/25473.png | Bin 0 -> 5217 bytes resources/g2/track/standup/25521.png | Bin 0 -> 5515 bytes resources/g2/track/standup/25523.png | Bin 0 -> 5391 bytes resources/g2/track/standup/25526.png | Bin 0 -> 5042 bytes resources/g2/track/standup/25528.png | Bin 0 -> 4992 bytes resources/g2/track/standup/25530.png | Bin 0 -> 5041 bytes resources/g2/track/standup/25659.png | Bin 0 -> 5352 bytes resources/g2/track/standup/25661.png | Bin 0 -> 5026 bytes resources/g2/track/standup/25664.png | Bin 0 -> 5286 bytes resources/g2/track/standup/25665.png | Bin 0 -> 5048 bytes resources/g2/track/standup/25666.png | Bin 0 -> 5121 bytes resources/g2/track/standup/25668.png | Bin 0 -> 5362 bytes resources/g2/track/standup/25672.png | Bin 0 -> 5170 bytes resources/g2/track/standup/25673.png | Bin 0 -> 5071 bytes resources/g2/track/standup/25676.png | Bin 0 -> 5194 bytes resources/g2/track/standup/25677.png | Bin 0 -> 5085 bytes resources/g2/track/standup/25680.png | Bin 0 -> 5284 bytes resources/g2/track/standup/25684.png | Bin 0 -> 5349 bytes resources/g2/track/standup/25685.png | Bin 0 -> 5044 bytes resources/g2/track/standup/25686.png | Bin 0 -> 5142 bytes resources/g2/track/standup/25687.png | Bin 0 -> 5287 bytes resources/g2/track/standup/25689.png | Bin 0 -> 5025 bytes resources/g2/track/standup/25781.png | Bin 0 -> 5410 bytes resources/g2/track/standup/25783.png | Bin 0 -> 5204 bytes resources/g2/track/standup/25785.png | Bin 0 -> 5268 bytes resources/g2/track/standup/25787.png | Bin 0 -> 5191 bytes resources/g2/track/standup/25788.png | Bin 0 -> 5167 bytes resources/g2/track/standup/25792.png | Bin 0 -> 5215 bytes resources/g2/track/standup/25794.png | Bin 0 -> 5126 bytes resources/g2/track/standup/25796.png | Bin 0 -> 5018 bytes resources/g2/track/standup/25797.png | Bin 0 -> 5101 bytes resources/g2/track/standup/25798.png | Bin 0 -> 5189 bytes resources/g2/track/standup/25799.png | Bin 0 -> 5203 bytes resources/g2/track/standup/25803.png | Bin 0 -> 5328 bytes resources/g2/track/standup/25805.png | Bin 0 -> 5206 bytes resources/g2/track/standup/25807.png | Bin 0 -> 5326 bytes resources/g2/track/standup/25809.png | Bin 0 -> 5181 bytes resources/g2/track/standup/25810.png | Bin 0 -> 5183 bytes resources/g2/track/standup/25811.png | Bin 0 -> 5074 bytes resources/g2/track/standup/25812.png | Bin 0 -> 5006 bytes resources/g2/track/standup/25814.png | Bin 0 -> 5220 bytes resources/g2/track/standup/25816.png | Bin 0 -> 5184 bytes resources/g2/track/standup/25820.png | Bin 0 -> 5161 bytes resources/g2/track/standup/25821.png | Bin 0 -> 5207 bytes resources/g2/track/standup/25825.png | Bin 0 -> 5410 bytes resources/g2/track/standup/25827.png | Bin 0 -> 5260 bytes resources/g2/track/standup/25834.png | Bin 0 -> 5060 bytes resources/g2/track/standup/25835.png | Bin 0 -> 5046 bytes resources/g2/track/standup/25843.png | Bin 0 -> 5038 bytes resources/g2/track/standup/25844.png | Bin 0 -> 5070 bytes src/openrct2/drawing/Drawing.Sprite.cpp | 186 ++++ .../track/coaster/StandUpRollerCoaster.cpp | 932 ++++++++++++------ src/openrct2/sprites.h | 64 +- 67 files changed, 1261 insertions(+), 295 deletions(-) create mode 100644 resources/g2/track/standup/25455.png create mode 100644 resources/g2/track/standup/25457.png create mode 100644 resources/g2/track/standup/25459.png create mode 100644 resources/g2/track/standup/25461.png create mode 100644 resources/g2/track/standup/25462.png create mode 100644 resources/g2/track/standup/25463.png create mode 100644 resources/g2/track/standup/25464.png create mode 100644 resources/g2/track/standup/25466.png create mode 100644 resources/g2/track/standup/25468.png create mode 100644 resources/g2/track/standup/25470.png create mode 100644 resources/g2/track/standup/25471.png create mode 100644 resources/g2/track/standup/25472.png create mode 100644 resources/g2/track/standup/25473.png create mode 100644 resources/g2/track/standup/25521.png create mode 100644 resources/g2/track/standup/25523.png create mode 100644 resources/g2/track/standup/25526.png create mode 100644 resources/g2/track/standup/25528.png create mode 100644 resources/g2/track/standup/25530.png create mode 100644 resources/g2/track/standup/25659.png create mode 100644 resources/g2/track/standup/25661.png create mode 100644 resources/g2/track/standup/25664.png create mode 100644 resources/g2/track/standup/25665.png create mode 100644 resources/g2/track/standup/25666.png create mode 100644 resources/g2/track/standup/25668.png create mode 100644 resources/g2/track/standup/25672.png create mode 100644 resources/g2/track/standup/25673.png create mode 100644 resources/g2/track/standup/25676.png create mode 100644 resources/g2/track/standup/25677.png create mode 100644 resources/g2/track/standup/25680.png create mode 100644 resources/g2/track/standup/25684.png create mode 100644 resources/g2/track/standup/25685.png create mode 100644 resources/g2/track/standup/25686.png create mode 100644 resources/g2/track/standup/25687.png create mode 100644 resources/g2/track/standup/25689.png create mode 100644 resources/g2/track/standup/25781.png create mode 100644 resources/g2/track/standup/25783.png create mode 100644 resources/g2/track/standup/25785.png create mode 100644 resources/g2/track/standup/25787.png create mode 100644 resources/g2/track/standup/25788.png create mode 100644 resources/g2/track/standup/25792.png create mode 100644 resources/g2/track/standup/25794.png create mode 100644 resources/g2/track/standup/25796.png create mode 100644 resources/g2/track/standup/25797.png create mode 100644 resources/g2/track/standup/25798.png create mode 100644 resources/g2/track/standup/25799.png create mode 100644 resources/g2/track/standup/25803.png create mode 100644 resources/g2/track/standup/25805.png create mode 100644 resources/g2/track/standup/25807.png create mode 100644 resources/g2/track/standup/25809.png create mode 100644 resources/g2/track/standup/25810.png create mode 100644 resources/g2/track/standup/25811.png create mode 100644 resources/g2/track/standup/25812.png create mode 100644 resources/g2/track/standup/25814.png create mode 100644 resources/g2/track/standup/25816.png create mode 100644 resources/g2/track/standup/25820.png create mode 100644 resources/g2/track/standup/25821.png create mode 100644 resources/g2/track/standup/25825.png create mode 100644 resources/g2/track/standup/25827.png create mode 100644 resources/g2/track/standup/25834.png create mode 100644 resources/g2/track/standup/25835.png create mode 100644 resources/g2/track/standup/25843.png create mode 100644 resources/g2/track/standup/25844.png diff --git a/distribution/changelog.txt b/distribution/changelog.txt index b4c76b4d27..65caffd754 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,8 @@ - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). - Improved: [#23233] Add diagonal booster to LSM Launched Coaster. - Fix: [#22726] ‘Force park rating’ cheat is not saved with the park. +- Fix: [#23064] Stand-Up Roller Coaster unbanked to banked track pieces are misaligned. +- Fix: [#23066] Stand-Up Roller Coaster has many supports that don't join up to the track. - Fix: [#23206] Multiplayer desyncs when FPS is uncapped. - Fix: [#23238] Updating a guest’s favourite ride works differently from vanilla RCT2. - Fix: [objects#355] Fix colour preset settings of the Stand-Up Roller Coaster trains. diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index f2d753e98c..9490124b8b 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -10432,6 +10432,378 @@ "y": -9, "palette": "keep" }, + { + "path": "track/standup/25455.png", + "x": -23, + "y": -4, + "palette": "keep" + }, + { + "path": "track/standup/25457.png", + "x": -24, + "y": -13, + "palette": "keep" + }, + { + "path": "track/standup/25459.png", + "x": -26, + "y": -3, + "palette": "keep" + }, + { + "path": "track/standup/25461.png", + "x": -28, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25462.png", + "x": 3, + "y": 3, + "palette": "keep" + }, + { + "path": "track/standup/25463.png", + "x": -30, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25464.png", + "x": -2, + "y": 1, + "palette": "keep" + }, + { + "path": "track/standup/25466.png", + "x": -18, + "y": -9, + "palette": "keep" + }, + { + "path": "track/standup/25468.png", + "x": -18, + "y": -8, + "palette": "keep" + }, + { + "path": "track/standup/25470.png", + "x": -14, + "y": 1, + "palette": "keep" + }, + { + "path": "track/standup/25471.png", + "x": 7, + "y": 3, + "palette": "keep" + }, + { + "path": "track/standup/25472.png", + "x": -27, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25473.png", + "x": 4, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25521.png", + "x": -23, + "y": -6, + "palette": "keep" + }, + { + "path": "track/standup/25523.png", + "x": -32, + "y": -6, + "palette": "keep" + }, + { + "path": "track/standup/25526.png", + "x": -8, + "y": -2, + "palette": "keep" + }, + { + "path": "track/standup/25528.png", + "x": -6, + "y": 0, + "palette": "keep" + }, + { + "path": "track/standup/25530.png", + "x": -4, + "y": -2, + "palette": "keep" + }, + { + "path": "track/standup/25659.png", + "x": -23, + "y": -4, + "palette": "keep" + }, + { + "path": "track/standup/25661.png", + "x": -12, + "y": 0, + "palette": "keep" + }, + { + "path": "track/standup/25664.png", + "x": -26, + "y": 2, + "palette": "keep" + }, + { + "path": "track/standup/25665.png", + "x": 16, + "y": 8, + "palette": "keep" + }, + { + "path": "track/standup/25666.png", + "x": -10, + "y": -4, + "palette": "keep" + }, + { + "path": "track/standup/25668.png", + "x": -32, + "y": -8, + "palette": "keep" + }, + { + "path": "track/standup/25672.png", + "x": -4, + "y": -2, + "palette": "keep" + }, + { + "path": "track/standup/25673.png", + "x": -32, + "y": 11, + "palette": "keep" + }, + { + "path": "track/standup/25676.png", + "x": -28, + "y": -2, + "palette": "keep" + }, + { + "path": "track/standup/25677.png", + "x": 12, + "y": 10, + "palette": "keep" + }, + { + "path": "track/standup/25680.png", + "x": -22, + "y": -8, + "palette": "keep" + }, + { + "path": "track/standup/25684.png", + "x": -10, + "y": 1, + "palette": "keep" + }, + { + "path": "track/standup/25685.png", + "x": -30, + "y": 9, + "palette": "keep" + }, + { + "path": "track/standup/25686.png", + "x": -11, + "y": -5, + "palette": "keep" + }, + { + "path": "track/standup/25687.png", + "x": -24, + "y": -4, + "palette": "keep" + }, + { + "path": "track/standup/25689.png", + "x": -8, + "y": 0, + "palette": "keep" + }, + { + "path": "track/standup/25781.png", + "x": -23, + "y": -5, + "palette": "keep" + }, + { + "path": "track/standup/25783.png", + "x": -28, + "y": -17, + "palette": "keep" + }, + { + "path": "track/standup/25785.png", + "x": -18, + "y": -11, + "palette": "keep" + }, + { + "path": "track/standup/25787.png", + "x": -27, + "y": 3, + "palette": "keep" + }, + { + "path": "track/standup/25788.png", + "x": -1, + "y": 2, + "palette": "keep" + }, + { + "path": "track/standup/25792.png", + "x": -33, + "y": -10, + "palette": "keep" + }, + { + "path": "track/standup/25794.png", + "x": -16, + "y": -14, + "palette": "keep" + }, + { + "path": "track/standup/25796.png", + "x": -12, + "y": 0, + "palette": "keep" + }, + { + "path": "track/standup/25797.png", + "x": 9, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25798.png", + "x": -26, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25799.png", + "x": 5, + "y": 3, + "palette": "keep" + }, + { + "path": "track/standup/25803.png", + "x": -23, + "y": -10, + "palette": "keep" + }, + { + "path": "track/standup/25805.png", + "x": -32, + "y": -17, + "palette": "keep" + }, + { + "path": "track/standup/25807.png", + "x": -24, + "y": -5, + "palette": "keep" + }, + { + "path": "track/standup/25809.png", + "x": -26, + "y": 3, + "palette": "keep" + }, + { + "path": "track/standup/25810.png", + "x": 2, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25811.png", + "x": -31, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25812.png", + "x": -5, + "y": 0, + "palette": "keep" + }, + { + "path": "track/standup/25814.png", + "x": -32, + "y": -14, + "palette": "keep" + }, + { + "path": "track/standup/25816.png", + "x": -12, + "y": -9, + "palette": "keep" + }, + { + "path": "track/standup/25820.png", + "x": -25, + "y": 4, + "palette": "keep" + }, + { + "path": "track/standup/25821.png", + "x": 5, + "y": 3, + "palette": "keep" + }, + { + "path": "track/standup/25825.png", + "x": -23, + "y": -4, + "palette": "keep" + }, + { + "path": "track/standup/25827.png", + "x": -24, + "y": -9, + "palette": "keep" + }, + { + "path": "track/standup/25834.png", + "x": -9, + "y": -2, + "palette": "keep" + }, + { + "path": "track/standup/25835.png", + "x": 19, + "y": 9, + "palette": "keep" + }, + { + "path": "track/standup/25843.png", + "x": -32, + "y": 9, + "palette": "keep" + }, + { + "path": "track/standup/25844.png", + "x": -10, + "y": -3, + "palette": "keep" + }, { "path": "track/steeplechase/brake_horizontal.png", "x": -32, diff --git a/resources/g2/track/standup/25455.png b/resources/g2/track/standup/25455.png new file mode 100644 index 0000000000000000000000000000000000000000..6bcf7506945a5140c112345a2099817e329d4b5b GIT binary patch literal 5406 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25457.png b/resources/g2/track/standup/25457.png new file mode 100644 index 0000000000000000000000000000000000000000..3c9d50ca9622ebac5a638ef2552e5e7710ddefd4 GIT binary patch literal 5172 zcmeHLe^gV~9lwAWgj%ZD#)>vMp*>j}LVmo2goHHEfPuykN?0SNE<9ddVg|`e^P&Oi z8Y^~G(=}CAgT=`zTC8-YtH)(s=0OEZTUMjeiZ)%b#fh8Mbh4IJZQpJJBA)e}9nV?+ zGs(-#``*v@bHCru_j~WjdmAe&)N|7pr2_!wmY0=O!80Eo3)52Iw=d_V%kb2{wtBg{ z3iU9ZF2Z7Kz?tqQC(gthZ599;Ke1OD=l3zwu8%EHtS=Nf7Z2@14i@`O)hFM5T|T-g zcVF6iY~oaF7r6cp51X}-M~Xv7I--aO1|4X;6HqN zulif_u8Dh2)$r$dzZ2}d@aF1|zTm!?`(pbq*P)dIp(?@3W2WU3BGth9r8~)JVEl`r z=-a)0CGs4$)v{!+)0q6!$|CC*Up{{!^%W$ry2|Qr*Z0X0iPjn-yh!MT?J`^t*T7OOx-Bn)g(!d1Btc$xWqiReqBGJ6ZcvS5vi% zwk)8l4<9&tcA)O#!$)fjG(+({*TK_koK^14^Qpjs75$CQPyL>W2Rt$GS`EJUOjc_3 zhr*K^+uH|&o1Qb=RlA^g7W47HeAKq>Xl~)au;Q6#4*I^zjgj7$ig(uv53%Q~w>g&g zXZMpGTaPt$O8Y<9^4K#Kh4}H*jf{8l!q?w@=iFO|5Y^KBCG5NB`F7`R4Y$8C_m#%2 z(l_@k`ddap;ND}#?H~XAHwR+xn-=D-;@rP)Xt6q3Q^rc2C;Z2r-==5GTOqDmw#%kG z|2c!a{;=!)b9>iq#*)N)US6#HH{<%{Q@O{Mh06~wJbtY%%E&6JrLPhi$2TlzqPjRiF1mxF51GTlMks}4=S~KPkDLwzOBT%7FF%rC1)-^5W9Tw@}&{v()Z7T0OmR%d#isN?7KBK*k8-F z%VZc~&qK{b9iG={cf!U4pitT9M6r6@&8)+%Hiv>03-_{^HnW0d5Nr8brwU(XD_iTr z^=m7tv9^%HZ#~na5%#AntkvYq_?PsUloB zQwF0(~eRkC!70$wRttK4p>w2|u|bK(?}93?o3xol3ijc_pIoM;`f+O1%*;5hR}e0HZ+J5BE(r&NG? z@ETDkPmssw+3mcU9;CZ;4J4Tg=m$N>YPd{!RX9nkc42tw8rvz*fh@D=$&7;`7VQ1ZFeK5RV9i$s|V0fGglIPhV4?iE1)YS=uTr-aHxgx$0;Yy`q0at+J3-T@SjS1^! zQ0QDX*p+C*%&6j2W=JKH3i8Dmif{$_`3P5pAr@|dKxE-c(E<#Y@P%Ro(d5API5-*GlrURu#3^Z) z%ZFJwS@bd+3FmK0m?qbh9)EiBYVxwdmRL+oW@1^$P;4><5?wP@amY0}gsnmyRvhjh zQw@8=Zu@~|kl=_|Y_^!WVpuS)2ko zZe4IE*!VcY14=p2X)=t)tonL}rfzZ7z`58f!48T*F>yOoefMJ z;86mW_q);{cLuZT)tnY8?ai3 zz21wRom6jcHjDXs-;KM7S?wSnnF=4Lz2x?=g9RO4JI)X zDxy`_+G*+x5uu2;FWMFv>mHft%~XOcJ)m0wqZzRMG)X629b_AOl|;ng8zH-5{yu8I zj+2E+vOQ{!&mix{RAEvdX~BjA7hpZGP5LXjscNal`4;3@58VTk0%hfLZOkNp;#12m*NQx(qE4|1#{s@73s*O(_9^AC*&$F2=eP#K)eObMN? zX5{EOJWMVpHM&+4Bx?@(+6KCV(Z0y|h!U7IG*X}GH8K44oQ`H?PpdxMVIAo44)=D9 z4flM^?4!)f!YySuP(xFr(l85@gGaIS1CK$n2 zq%J9g7jv9tHBhXKtoV@xUfsSB8forwZ7JRoA&?! literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25459.png b/resources/g2/track/standup/25459.png new file mode 100644 index 0000000000000000000000000000000000000000..26ad69b6c390f23dd292deaf02112696c9289b12 GIT binary patch literal 5312 zcmeHLe^e7!7JdjA1r-syXt5?I*iCIrCdnj(1ZbcE1I8GZunn5pI825RA(@zogdc6u z#TF6UsH_G{TdXX_l~p{omRi=LMMY(6sI=0WTJ&J0TdV1oUD3te*_VKdXM4^b&)NQG zP9`(&zI(rS?|1KgCvR%9m#L;lJRSi6n4XoHo&)a!cs(&C6#n{dFjvA`S9xxpGY50A z><+TPQcSR%Wp;u^lv)Y^D7|3KJ{J9nVA^O!#Nv%S&f1e%mcw}H$?mM@cdfgzTfRg4 z+ohv}FE^>H4{W=7VhQg_+54-vUwx&yCZWD=#{AUGmlgl0X`gxAP^w)~bGyllRNc0` z@NHCl$Eye4er4}v(ztlm>GIt#sAlfP!gfxoPHXTkX}<8&?G0Qubm-$- zH$V7+UVm!FV#nm-$*GDZh5Q2tS)(kaig9*s^-kos(d}Id6noWXO?QGE$?{T zajId**|NsO<7c)#`{J@>qBp#Td6?gE=j7ol2acl3#R*SvW<=LE^LKRAZ=b%sbVuT! z_B{S=q|Ec!S;L!OtbXf||Fm(=qC)Q6{eAOPlhm2)@MzKZdv--cMz4_MEd7H;arH8j zy0g%6`pVvQTk#Odo-Okfx0rWsoL_WyX-C$vIlZI#K4whns@OtF@#yH69~e06=(!)B zlmB}~Og+8e$Y-B@qB`1}U|)0bvnwf=9E>?-=bltL7AQ3D74(kqpWJReR!;1(fE1xi1Y$3sw^8FPKt7OC%#H~8 z0>o-XCR$L=j1mYk?$FO#P`R*6ksN{|*E(<_qlBMqPr={RNSr7OYmyRiqAp_WD? zPbcxU0r#@fQ`mv^7nsjxsK%EyH~q1YtiiBU|(!z8GTmw<^9O_&T5$ zP+2z0iP>->00qJM7Knr4i5QV65%Thdi6#gklkj9hiHTPrPLPTV3KDQZqId#?)?tBF zi4{-uDgb4IP%@DW$1y_26A@C3C&ncbUOtM8d16AGpD&b|FoGxuLYZ*+V$xy7U^*>U z%uFD5n>jcUAY7i7ot45C@dfuK*~OT%02;s^u-Htbi@HCRYq1hKCl=sSC`CmQu~>i# z5(QGR5WTPT9O0l~Ee2490zR4;oCzdG4#R=eVu4D906{s7My_-an3Html4NlTJKz*6 zV0mv^0~^YOIk9xiNkCA6NGul$GrD zTKJ&8tB?rf0aC^j3V9PKV$N36u zI=|p&JP*I%3K06yA`ivyBf1{Z^-v5vl=7qMdPLVlG4N2zkE-kcMpwlB!xUkI|A1WZ zsB~)vIuC$Qki9fF10J_RLP91@niLuu8Wt879v(h<@?-{sF=fh>sZ*!M#>dB_D56v< zbUHPT8z_pbs;csM8r$01ySn;(KL7AAiU36t(5fR1hM1xvrmF&}u1)eZXj|Hh9i3E< zw{~E#Ny%mClOjoVY^9#*#yO1?daz2_>CyMJk-qNgAz#yoze^Pdj9lPS0Jo0OLNYpQ zqxxH7hI``ZA%q?_(xYyg?urLM3xJWqAfuux0?k@VEmK%dh<6J6k ztv;y*S9VZ3Zx!C}p$1#4{GFZ=Z!1066%`}paP_FvtWdgix>_7>aJkxQYdaeoz3uG- zeSLnvp9XOx;CL8lOO&!BPS?XV4=Ae#4NXI?4!^r^xNT^(e}s5~*NQU(v?5aBj@33XjqM!L zm*n;vT8CX7Bc7ho_5r%z&xrw2CPRfp85GPS9a>>lyDN*D>MA>0>%3j9L%uG0ctEOF z)9rxv0h)%nsE(_uV3>`-sE=}y-89`WIH+rDLmNC5Jv~Z;L043SS5%NFQYA$^3ba*; zcB+v+Eq6#CPaBzZC5LW6>2?L}Rns(m>Z|pER}LZ0oMk$Ydi6{Aatnmyt5xY>WB3!9 za4^-Lxg3%e856idz#DJQfkK8eOOwI)E^_XS>7uxA=WK>Hd0FXcxrsg7a}7JHSkudXK7{3wXnHRr?Abv1>{yWXug zh-(}fWl5T8jnSF=N}j&e`0o5SHtpNk+q^P$o_RwLZWwyiV>t%Y0u z)qIiLy1S$hefsu?pM;$f>-VMbTiBAAOAG7&n8@MSP5jr+o=@AhCjU%L`JdHSpPL~p ztMAqHZNB`fuK2yDCLi7W{ms%Df$QgNL-U8?P40_@8HJO7sh4VL`4O_*J;fyYCdH=$No*!;+ z-72go-2Ca#-j4mnf*kwJ_M{eYU>0~dEj-jR)VZYqiJo65Hkkam!ju`GT6v#Wmh EAI7=eMgRZ+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25461.png b/resources/g2/track/standup/25461.png new file mode 100644 index 0000000000000000000000000000000000000000..6a1806038490585e07d6f6d909e55188eeebeb52 GIT binary patch literal 5185 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25462.png b/resources/g2/track/standup/25462.png new file mode 100644 index 0000000000000000000000000000000000000000..a0133a9dfdbca9af251b5d9560ab2a20b8c9b15d GIT binary patch literal 5187 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 gT*VIkXxwBtV|!r3&dcr4_pnPqyPW_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25463.png b/resources/g2/track/standup/25463.png new file mode 100644 index 0000000000000000000000000000000000000000..6f93d84ec5e2c69d29ed2e56d9a9e1f0cd07198a GIT binary patch literal 5130 zcmeHLe^3)w9)E~20$QrH4Vt#e1+TFelTES-2>}{0VBlg1B}^mYT-aZE20lRkW$alUCaEY;3tJ&PluX5)g5&GdIp$ z|1*=#?)(1uyzlq({k}JO`)o$|dZ(+-UgYXvGShm_* ziut&14{3AM5M1vDH^C+995w*zK6REv=7+>{C+wTIRQ~3U`}-ZGud%%o7nbjS>vGXU ziA~4T&zQr^&*sc!69YhnlY}i&70+@^)5AkMI|2 zx4Tv!Wgn$FwjJNlsXY4O^D7=J&LK`Pp5+`A1t#7*_{AGXP|eEB`}lV(Xx=H>7HEHQ z{)=_nlzVn9{xT)2?e60hFMaapANEH-FsCo85-fUs@LugKT_KOLK>GJxe@sqUutr|G z>Q#sO;@>#b#Dks>zS#ZbRy;wztL0wxRnEjWr4y4RgM`9Ntksb6Y5OVs+8SI_=D{8h(y zN3IA@1TTJn`t$y;6I*t^zKwjcQB(P5{@F|SN58rB&E;YA@{dn|Hr%sc^~TZdu;#P=#kh6O8W*Li%jLy!Rq#0`MtIz~iMKkJw_0Dq z)sP;7D-+2?Vqrm@W4)C3P%<~iW3{PD^H)wmz)>!*%IkHj5X9&6iF~Mt^w<$eR#p}w zmLgKA5LyVS4K6QMCv;I6F^EZwe1gI~4!74qy0|e+%tF?Bb9p?d=U$J`>DKF~;a$`e z3y=?_4s#2=s{kabgRF-<(3nSns}Y22Hv zujd{&hE{sLDxbt_W8oF$=kj9ntE?pMu&UyZVzD^OilUfMVzbDEGHI4fh{-J$p(RsJ z5QJPRkyxcOpo(0S7jxl63<`pa91zEXTjZG-DiJC%C4`X4Z9=6KmkO;moRAQiGBitx z&44g?9Iz{~nwe3>psWxoQ$a|qm_#PD;u5J)X0<7WO1V5sn3*ZZWC~O%5nC*AC@Zd7 zNqU?ZET_YX*$Kq$vd0xM!c}=CMY%kwNPI(5QiFMI&;hOihs#R(s2i#>hm$aRu^68c z1uB)xWD>b7Q?ASsXWlS+gz!+X7h|Xru?SVhHL=2|U^kn zZe4IEM5edGDZXH=Kj&wv4nOAB2(BRsa$~$*Qsfc-%@zNSHNiR$^k}?Afy!491)}bC^u#+_`g; zl9E^%85t;wXf$f0QHSFd6h$^RHnz2O_V)ILLW7Y=bZiVofI1r(bSV`TY1P#nUp>;) zoZZ%8=OhY&}_=?#x()T7;eOe+NhD9#%Qo@JlsQ%gi_NKe1Qp7*wq@J(b$aR9X?-g zb91n>Gu+oVJUAGQMrpt%0l$rjcBg6rY~z5yKCEdPspuN@1)~1JvEI>ZL*sOcAT?FN zVre-UMgf9nXHz;ulNo~5_cpioclSm@;jv*gFzc9eW3>#z2R?zo%g+ z*fBa38XLPrs{t?pKmp(fpa+0{07jUAhF^n*uBYgpE;=$~-~$o`t!mJx1rYqK1Ja8SZ3y(VhC@B0 zkq|vLtkCJ`K0rqRO~YC=u^a1|b~7-WQhj7UO?Qlp7<+rsj<))N0Zm1PvAPbEv1R8;*{Etq`_h3uEg$b;oT;@w^Wi;@XC=zkR(sBM9bY`c ze(&j)ANHQsCB0xN|Fd@dk$IfbH`BbYz3*AI{r%@IA9(c8M{70~y+AYmdHLLdH{V{W g{^7_;$5pWWiQVaEA2_rGMhl7xit}GzQTf~d0CcK~egFUf literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25464.png b/resources/g2/track/standup/25464.png new file mode 100644 index 0000000000000000000000000000000000000000..c5ab71e08be48e9837732662b9644d6a982d05e3 GIT binary patch literal 5012 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
  • 2 zEqKnqv*fjXOaGZI?Y!f->4i@pdGTQU19QQudd`ylBg-`Nv=yxMMZ$mWdnqe>(FSqN z+P^rI-+aX&uiWSP;M}WQp21SY`*ti-{+n^-;;B`~*M=+KEjTf4i7|55)aBQU8>Xi} zd&|V$LM{2*N!iaEa(7X8ANu&?_cVu36uUQm@$osuSr4tC<>Wmo&)rJho^@$oM$dQs zaQJ)fiNS9!pZap>+teL<_wOXOw5safRG+@EJbv-Q#qY+D?|%LR=)^n+Wv?IE4Xdu% z0jq1BZmkR>8jDaXVZn?1jc!&MNiGAV4GTMVbD_1{W#wD_BWf8N5$S^H|KJir1-NtclniB3+suirn`Z6nlIjpketw4(LEn;yo*D97`T#?nr=UPN1Qm(W_ zh!;z3d_-hJ=Rj4uNH6Nb@B|bDFLFQ}vCWEPm5PFXTRwddn*Q*4S6+%fYC?b|xQ7&$iTDT&MRl>DMF$-5%EU{t5#VB7Ql_a68 znCt<<(}==!IvPG^5x^B^RQw-dc@~!In zztNR-{bdSw!6zUed{ydbslx$C1=VY7%i-%*N=nMSdGk_JQ`6GY($mxD&!11D(K0eJ zGBY#t3kwSogr`y|4F)ZSnMjgoZEfxB?C$R$h(tzWvH0X9!UIY<&}*|zrd+3!;S2EE z+U1>H`rdwXc#s^9wvUbXs5msEJe$zw2aSvn#_lGO1FfpTPUCPt5gTfoi1kdxBN{p| zbAV3?LIzqdK^tt(8STxT9HvtfJZjQRO@}BdQV4(^05gq7xb<2 z(O~dGcQ-XSNJnxDmH9k9LvChk2#zs`U?Dl#rE2Zdc7zQ*!{&jQogty~G=*{lM~g{J zgow{@Gl2Z(`aFcRyCPV|mV4dy68t^wrR0V4p|A)2H+U(?Sv4JwJKv3-o}iH9Q8 z0X-)dlhAz{PPbn-A=-+Kc9P?Lt?|Lmsc0WH9?8j-usKFVVppns217fBb@_b# z?d^lz-O+)8v5}E@JWc^R0oa{1q&G(urW=Mi_Ayo4xT$Bt7mkNUCi^F*N2jQ4PEL*_ zKVQQrG;nyBTuy5BZDt4-=x^^B>g|t3qLX7vVAj$|Lr&1l2st@j0cBsCA>3sj>I;qz zc1?^%CMPdYN&t)ikN|`L=mTH~fN>h2;9swz0wmSfL&Zk*Y(OBOLkR{nAf^YD0Z>Ff z)s9d-dTPK)4YyIT9*{`91ZY*jsHZux{GgB15z_SbVBv6UG}<>Y5vAZ-bUQ!-*~(D9 zzK3BRU=uNUC~oST^o6H7ho=X|sL?n(7f2X14KK%}WH=2-z^)Aiojo1Fa9>9>(l-%{ zP?KX4t(F=9R18oQ%taf$H9)hQf!UbjBZerdYkb_$-;Z>428M@KCX>PG!~y{V;k8P5 zol2xng$!zWBYMt+v5+z|s34o_LZ|^H71dG{^^enA6Q3MXyfsw@u;!c3;I}Q1V$o{U zV0-$V6>yO0u2>Jr%Faz3Dd71R3g9HoTd6CjozGsfaLJP0Q^oLm1~^oyE~{M;eLS@O zH?7Ru%Dr}zAM<=2-UExUM6=I{^8rjIY7Ubo*E4b*82@8OuS+ zSxd<)a@(5=D;KDj-Qh&HH#B{DRHl9K!&9KCU~(gS1s?oemN7Fo_k%}*<<+Ma)Ltmq zds({D6IK7c>?nKxlcxges5I35^MVr(8()3M6S=%Oh5v1)_tLiUH((&3vb;*Y|Ngpd F{{a?rj4J>D literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25468.png b/resources/g2/track/standup/25468.png new file mode 100644 index 0000000000000000000000000000000000000000..35a6482a3ea56a674a0e30a91fb948dbd4f816aa GIT binary patch literal 5139 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 mX`34N@i$CvdHn7xNo>pf3rp_5vHh+@Cx0*i literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25470.png b/resources/g2/track/standup/25470.png new file mode 100644 index 0000000000000000000000000000000000000000..9c28d669242e7769a9803ff1abb057c8cf9feb90 GIT binary patch literal 5013 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 U9KWXo1q8**OiUsHv7*vF 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25530.png b/resources/g2/track/standup/25530.png new file mode 100644 index 0000000000000000000000000000000000000000..2f2aafdd73eea07b561c2ab90edf3a24aabfb368 GIT binary patch literal 5041 zcmeHLe{h=R9eQ>EuK`-i#6+*%QRDT={0KB^(J=Qmbu2gdmw3>-n`rO zZvIz}m-l_Y&*%GjzTeOH`#i_{9&Bq>ttq~>7yz)Qxv8N&dxpo2MFsG8&^mb@o)UXI zcDUOy56kHy&DJi0K0RaTzzfFXpFg(t=&s{^dp2~+OaJoQ{XO2pnSBfQ?a>_c9UTAcJ^!cY zs&0Cz?}^r}wGVbaQ}Tm>*S{|6mYgfS;Msaa*(50zt=jd=hmP-(MqcicB;Fhw`l#+7 zpY2}UYx|r3!M@UU?puDfVe^T*nlky)iH+pOX5R~vPzCp^E&u-H9C$6ydVFX1&p8z^ zx4Z|fN@ZKKQh6yIn8dRW9I9_hY_53Qply8b`waOJiRnmd?|pX-KL2Rr%WWSOAC*0Q z|Gx@bZvFB4GSwTuK67T$`2HJj@6<7LTW(qe-M!9s_n~$4@cLbEd7U2zJqzFUq`}X2 z62JJcw4md(@b?FgJv|k9^nu8Rx9&Vp#JXFc)tGOY__D&V@a2WSSHC&&TJme@!%rMI z1xA}H@Dte0Q$vTB=ckfq^Q>U=~mWLnf+WS*U!#z)( z*ztvNdu_+roo8Qu?uSnxpWeS+LUwNt_k8d=$B&JT9W@8yP2INV)8^qDPaRqmJ!HJu zs|bv_ILKU zx^n55aD?b0><~)9Sp`>3scLR%yX=vbz+$yKb6!yFtB`K1`HEOq#g-k(rL!^+=zf{^ zD)gn?b6|*SX^}OMcuzLG=7xH9c7BQ+H3W337IrjZEnxFgNMy zAjz(Jb~Xf7*7Ndk3tUhp%#Af*ZUU0>g(8_iAQRSf2x?>kv5b#$`Ft6F1)eln&3*q1 zon1bxx}~BwSt&SwU(U3&rnE%&(%sT+mo>MTSghQ#kYV^z3KZ5$m~wGKuB9Qo6LVMy zxPL4+>?OPP8=3(%@x>A`D(3M;QVCBa5@N8Q#73Ufh?xW;J``4HyqcXN&2A6oBDPqd zj!-MupgFBrcP^LeuB-8$P9j?eC>c*6;H{91jVvdNWOs~9+14TdrAJ*3uwsjWeoHpE zb-|qwxx5uF>y_PfzQxaS9lpgGAocZ0u1VkPa$T3}niRMu@b&JxF4r|Fa82Or-SvNy ztN6;p6ybpXfIRR~Y4AeTp8zNTZQD8;;p0|bUS58FenCOOs#U8B3kz?!;RXhSQB+j4 zdiCnEs;Vj!MU+Z~R;$KwJw=iI{r$tkqmf87k(f@U(wPj30EHZA)Fpa-sm)gD@gV~N z`S6HlJYtB&si|aOb}ppkGIa71QeEcPRR(d+D1}b+E91kusR)^x9GFjq7Sah-IWTa6 zM*)Ib#yH7{2beSCrJ1R6dLE%O2Kr)F5O{LtxQITAoAH{=mYDC!|Ru9Frp(#T&WvLXGBdRL7maE3adQwRa zXa+_Nqfs)N^e0k7$@%fwg*a0IO0}TO0xErg6J&@-%Ty7LKCU2>y1*y(AkPOpv31+F7!_}c;i$dwqY6Cbv;_*ZRf%xcX zG8&zoo=&IJG$sIb=#6 zOzXoLPi$d$>SA=3o=I~`fw+>PLYR6*rA>?aEb5@&78>%$!b8bKcs`Y&GqYl~nvMcG z1!x-9VxYX=$FLZHLC5rvlQcatH>Zt6(2-%^)Ra=M*V=5j&qtz2zZe--pkXB%S0mFJ z?!2ywHdNAn4n2a>Q3ah;(=`3ghx@ay9P-@lty-}8^FP9uTOiM;gZ zJE2%5rP(779Da5KG&0=HEscynmwbnLbHUL;QU9Z-nYoD}lJbm^(`Jm?XXYC2ebC%uOjhYWC cHZ86v^1s;6?e3G~u+brFV{5}pTlXCJ4^?hj+yDRo literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25659.png b/resources/g2/track/standup/25659.png new file mode 100644 index 0000000000000000000000000000000000000000..562ee358e8e74ac1ef7a8b6d7a65e27fd725c81b GIT binary patch literal 5352 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25664.png b/resources/g2/track/standup/25664.png new file mode 100644 index 0000000000000000000000000000000000000000..b95d69f8ac82d9ee306835f3b5d1f3def4ef142a GIT binary patch literal 5286 zcmeHLe^e7!7Jh&b1e98^tfe(EsIjJDl1xHKfJPc9(1=M1HCn`Um`p+n$)uS;_|cZO zxQj^FsMKW(SZq~B=M=#!8-C_TN5JnF7Gy4lm;SoqRrVsx z!Lr&&gQ=2W*=wx?i>NUf0H`@{R+r3$T+J zV<`do@^kZ~^H7)Mz2Rsp8ur`fgLBy}Co-k}qAS0?78nRW8pZ*umoHT8zYajyI+H@7 zE>I|L}jDSq{dmztyZEqy4e=#Nb5 zTj%-f3y&7;0*B@qHi+{mUk+`d;bH}o{(H9Qvb@DF^MYdP@u0C>j@1>a+ z>ZA6bJM1|RE99R54A)~x9ho8sU3EbKR3q9>Bfr}G9%mVhzil|t#$qxX%L zQgs#o9KI5EO0D%t-aEd4|HO{3tJ)kB_V2$Rdu?Td{O?C?e~o>ANdoM3Q91cgS15G7uMnoW$N)f&g5ej(_ z!J}#|cC3bHp;CerlN>n&h1*P4yNR^0f}B_xS!K^+v*A4JMto*#Vc|`B3pJ$z)B~x( ztcW0$kC@HKbPvj&TMbF30{U4Gsu*rlq==x%DjQDZRudL`%5(}ne$(GtWvdLOqsI}V zk}yLk1y>c^wq#yGq57srPy(aLYz=uqv2R1#O@>=y-4dJ;G3Wuc#hB&{sXAky>7(g-0>M3jknWd=zaPsHc*4HBs! zJf{J-qI*Rc`QcTE`ip2y^nx3Y|F;px>CDSQX zHWTbhta5r(K`K3@;^R`OzD#1^5s;H7l3-;#DT;}BVquzCFG2@U%#P(?b^?;}g(8_iAQOs<1tJ+Ll8Mu~e7=l74NvM#hT8vy4sIV- z=48?HO%ziXgTaW7j-EMlW>QK@ z3W_2Mgy?tKqKp-$SK8_+lo&i+K*piZjiVCKq9%*XHXzNh* z^y=Im%I9wx8tztb8QP3kQkm4CWjb+A7lj^dRCwC7zFsnLvS}pHJu&9ZO9nbFaL9pE z!{{Lyo|gE*o`i8Y_cKWHcc~o`k5F89GiL$<;QXxHE(5P&B%ft!_=XPuCYPG9}4KUP^|BtHdQGq=IZx zHFfE_`p7C!`}D=35TmiB}Tczq0zM9c!$H$+tT9c z>hkyX4Gj#8jg8SDnFO3R2HF#^a3^bgT;q_UX}F|&#Ni%u4vhDX{5Uv4$8zK2B}qwn z%oGh5!80-_rK(8>$?AJsT2J=$2E6|9Avw?~8I&fzLC17fa69Vdt|pDU!+6rwFzD$R z8T5{iU#8^%XaS%Aa01{0;3NRU3_!!TNu|EGQ1_mq|$`uyO;7wf&>KH6k>V{zu2)TVgL_S)x9 zFM1f4RjwTrmdA*Piz_ciJ)Hc;nP)!mbgn9xyUH+JsgCOXM!KAH-{BW!abs2O`Rx|z z@!8*KiYUXD&*tRLK7u`WdDFQyK2cGv7R5L|Q8gNu&cu8I$BtQcO8Zf4b1e6)p z{I5AVdGC9__kQlZpL_53SA1*FI~yG34Slb@zw(XVts+8x@_>5KQT?HC>EV^P9}C|%b$;LY z=n++9-=3XkZ$8#}?UUQ0TdzOB+S$AA=3fk6x9&mCn*5goPdLUutU9Jp_v@A9u9-uh z44kth5u~i)P(L<+Ck6PY7`s%$#ma+B+UxUqCTuq+cE1BS``;ND}-V1o=ZuTYt6*{&m zB*Giw{mWJCODgwS+!*I z zmIqeh|gokG#>||>-KRFWR^GIto-&m#XVf~MNsI8ncaX!R5=hOpun?Oko| zmUKE+93ff=Csd`OSMg;o)s0&HMT-;#cGBreTS2lf)AW$GOJrRZTWTkr&f-9z`9<8z zv@hhIR)$(yt)h;?+fv~*)>ZRU{uNdVC#{O~tq83USuAA|VY$>=E|g+6R4A9jpE9Yq z9F)36s)sA5qmT9MvK6-EKmfz)EDPK5wzIm||(aub+`ayL^{ zOEo_g6fb3Yaa#)q%8GfgI?O{rP?1Ec5Q`O(vSzVVftD%Ia)C&s5G~TDtfZ~ue`%-2 zhgUUU^ahfK{yWm5`I#~ho99>a%N8;{OgvtCEEE_%p8}0-A*|^*A=dmBz6oo!6Y%_4 zXxIyK@;jOV#ca5(LPQ8rncOCn+RAaErCekcVpc+e%4Bj2Dn>6yrzxAqi@AwfJLC~^ z1sgQY6>rT#scyYo-@A!O)d5llyF|E%GCs19ERs4gE@WGUe2b5&w8Ekz2HMTb;L!z7 zLgeC6xWHHH(D@!e3w8J&JwWKIPOgaGt8`tZ>xvk-BIT>yb(O9wV&ICDuXfk}jjr5F z4^u=d{0HQPk4l=y-u7AreDJ0~ZH zQ&d!hqKHbRG#E5EZlY{3O8#<4J!810@;gyxblbs;bdfL93u z2G$V8iuSN4h6-lK3YlqynKd)#0t^!?0ze0VnZ=^mY=2>4prj;JS$R;W8@1af{Qi#y z2AF8H5G^QDau6N2(p;jZ1V%rK2P)})RoAelZ^RH9Ge;73uB;GI7gZVr8eC?gR8+UF zd%!#pp(1gAEYTOA9-5qsvX!8~062EQ^?{NAOE$n!hf7RRB^5XJOwyrbAjTZj2?}so zp;s;FF;))Ysu9`{@4_d7^we-yG8&wV4>MCSc7d!!U_@nhrOInC^x$~E*BkEXi4F|J zBazAR@nkZ|fI7!%khRozpj(6o0X85o}pPoJBZWAX%Swv5A3bBhcD z1h1^5HM(vy1oMS^`bLMsiCBDgQVGl&7Hwer&D?-P(C`yL~M5U zBSr~;5da#1006@Pi~=yl0u21>RE&>ihC@tZLRSJP6!a-UL=6%;z!(5SahM*I3F(-K zgBj~)5+RT(ybNemz^G$6aE{+A=nJTaLior?S3EvEJsoGDuR=ROeR;|NM;GFnBPCR# zGLSS4&w5AZf@9|*lgvc2qyWgcEH%P5DY*^<>a%MCen+U!KQi1Gj}1>JV$AHMOrv2U zfJp#`fwkx^?DDbfW?(k5z0@ef^iNG0!eO*O=o=eTnM?+U1NZqT6zP&7K_xn@LZcdF zTql?|7BOZn<1bXk!=r)j+b)SNj9-)?~ni$+}s9$j`*16<^| z8t#Q;<-vCrc?B8Z$vr=WLYAjdThE%wyM9Gc@dxFDpFxqXv97i`d*YtnvE@fZ*{XN_ zhksPF;qSf{!C!N4FV(F(j9rs|&F0biolos{{c&pV_3wY)P{6dTr+wj1!O5cMKRuYy p{Eg_@cMp{v^md&6*A1PSH4gb(Pe1lX2ZRQV_3P{Q-|^tj{tKF1VLAW+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25666.png b/resources/g2/track/standup/25666.png new file mode 100644 index 0000000000000000000000000000000000000000..8154bcbc874321c66b484817c81f59d368f8c62a GIT binary patch literal 5121 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 O&``Io_Q>kZPyGkEM`Z&5 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25676.png b/resources/g2/track/standup/25676.png new file mode 100644 index 0000000000000000000000000000000000000000..375acafa9df70865ff541c368091a342785b39a7 GIT binary patch literal 5194 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 ovT;TI;@{Zbc z$U4S;?CrYYFROlT*gIr8iWF`xrUEwv3*S@Kez+a`=5OPBPaS+Ve7MCWo$}xM{D!d~ z-eMmLEje-Br1p=C>j$@{J)`Shu=s}IhLca%To=e*x9^dqi@r*%>D({-bjy17SxL|d zK-$BEN>yK{QeDgkX0hj&J1c7=t8aY6*tCD|FBppF%c?g$`}tn(j{T3<9Iii=b5Q>D zz2`Hu%bv_%B!wdL3?>q5Y>();qk+FfSs8cx|KjWXuOs|;t zz*EF4b+1-c3=sG4ncnU_u>9@8_+Ynu!xR7BdG^T&xu>hNV~e>yx^Hs3ckuQj-u;Wr zw`?eUu5i&?kKg&-rw1aUIR7tq?tk;1>Ccb_pS{0JGDhqu+;PkDCmsgb(x=vL+n#ms zww0L;FBMSde5Za`{-@>6UB`!yJak+BV@C@vFduYV^MBvBXW!}tXC6Fqz$Z98p0T@i zE7p_ud4q>X~8l+l*)}g{T z5w-13T;IN?5o@<%$s0*)%Vn_Mo396{V}cZpkELOLyou)Mq+ z5r`0xhz~XR)E2u7ZR6Xiq9nu&Mm0`hPQu|LNINHqi8hn1u1YQ!&T}rtXLD$^m*DNx zEDMkiqz!c-!V&>uvmtXWC|Av92r?Vck6KWTaG4?vI7PNPF}!9oZg&;Ug)m{4>>aJn zmQ*?>48dD)8&svBSK$>d)pgqXOBP8AEQHOGvVvq^q3I&bm&v*!w&YAIowtFGiG{mV@xMwsL?k0P{LWRgkvW=WZlFDWxi_~obo=bK9L zGBGADH;bjxIZ$UQE)wvY&CO;$E)a>zO%fr7OG{Hw zCQN<@>9nD+oP-Uv;E2O+NlhdPmsi!-RdPiog3FTn7Sv^i25=1!b`$BQE>ATQHeByQ zlY9zgVv$rLm5OCjkx*DV6LkvlZrn-1UQD721tsFLlzFl+a+nUJ7EN|41W3tYHgc5{ zM_r_|ktACxxk(64((=-@7A`0g>O!kg7Y;!MB8glml#8T|LWx{lCYQ>10)bpGN1rqi z<}LqAJGp!~6*EPzB`D~BOG-4eru6s&GozVd3z1q(98PLk$Wd%21q$7an^JK?teGin z6Kc2MaQ~QX*o$)FN1CBoBrC&lOu)yQWg@;rXhvZlh)Q8UnMI;f%#53bNOH%xm~92}Uwl-g6y|I( z&~8Qsw=TF7BA2$pS-z5+&QJK6t;0{~0YYDMa#j3Zqw5-7SH-|pDPQZZYjj-|16QSd zt-Jnjbmd$=OyPF;56BIVN{gS|JqbWMsK2YR1|GN4($eP5o0p!RK7aoFjEs!T%uEJ@ zk(HH|ot@1pDk>6-5tT}**K07WiK0la*X#H927{qUWHc5_OihUqpi}^zCby|6&uT4j zcOacz3V)BTFK8SHQzOx?@ri(n$1o^zNe#}j0DNpP-i?Am`+60 zY+&R8w-WgDj6RYP?qZJhH7SwKMtDE2XAy)1RGxGAh8qlT_=Dv&PvPehn`vSOY=EVC$8ZoR$>!+PBA zU{_bTw>KIJjgO8d5(yfxNl@%(i2InT0k(dGXBk&@PBaDL?tz4FbSfDCer%e~I=pq(W!AIFlrc-p6M|b_^iC14rPC*exS!P)bAM! z_r%8{Q&VSYB>)BhC;)r_^aC&izyt%(@T*hN9TeRkpkrgYVnB*Pw-SWZAf^Mf9?&F< z?h?}h9UZdLBb{_C0Fs550gVb6bPOxT^0;~3K6PIJ8yN6Lqy6!Cl!m_879j4(Rr*-E zK!Gt-OvV(xL{tBidtll>@_lHW9!nJG0a*bjCf^; zUn%ZaiNhLXRL6@OifCg2?J1^v#B@kWM>RA}4}Y{R`N|>9)v!hnR!@Ei-)@1lW{tWU zJeF}&EgWP!YS%-ua^X9R+`Kffd(ToRWVq_IHHB+{!alJ(2O7UEdwxzhCr^ zLuGyJE+0&)xTq-OB1Dj*h(Y&I-x-7oOXAa{Jbsw{pMq k(7CnCnA=u+c*B|KVX4)Q2+n{ literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25680.png b/resources/g2/track/standup/25680.png new file mode 100644 index 0000000000000000000000000000000000000000..f0d9e2548d80bd7188cb6ed0f624ab77759b7bc0 GIT binary patch literal 5284 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25684.png b/resources/g2/track/standup/25684.png new file mode 100644 index 0000000000000000000000000000000000000000..a6b104ad85662544b29620423b2c132020125037 GIT binary patch literal 5349 zcmeHLeN+=y7Jr}+KGe9Pr4`$RprVZ-ACr&}z(@lIOk3`=2>U zChxs_fA`+s{WzIfS3F-fHeqrC0AOrUVSWj`GT?_6Hwu0qUKMu3OZ$q_h4vDygKo9q z22(jkw=cJ1bgbHB0HFGurMPUIpFZYhU}n|mA6CE8cV^G#D)*zVT{~1?7-mjy@0|Mf z^`E}{_OsM-{qpZit6MLv;V`ki#hfY^_KHoW3*J9nGO(lP}zjR^xyhU?-6F$ETK-3zOR9ajl zmEMjAMzL+x#@s^xoGB+YWjnV&Mah0gl)ve4V|7GLVH~jdv+DzwiLvdio<#q1%C-%E{jx$VqHuVpw<34(I z-ajww_VYrlPv-4B^~}K6>@i=T-OTSXZAjfPZR+c5K)hhnf*04t?Rk7=Y{?-S@xABV zzo#CZYTJCGbN}kcC$2q0yG4D$VV=0FY1@uDW3Ifgf47Hou{UOGW!H__M|NM1zvztJ z`{|LkbKvsqqL$XfXMV?df9&GLtpXGE{V$_lY2+_RwtOV(E}H?u#vc_~ORhY0NlxaGR0M&C1GRb9ihXj|C-I z#PSNewwhHzq(vZxF!C`1wVAAT6J9}&U}|-Er9GFyfamnv{#mRF#U1zxVweTU2fJEp zWpgt)Y>S0GQiHG;R6&qohkjLqD1~jxF2M-A(uQIMRak{RZ6t&qy`yifw3QErqet0T zIc9;P1hmS%$E2)CQG7=uLV?j_u?}iMvhR_!n+$i!y2rQ3$zV7m9f9h1aPN`69s8g# zlu{_f`8Zk`ajz&pml3fq*5jy2FCO}-7m9THER4nD2{|l2m#bxEaRdSukB=Bc2*&4Q z9R3KXq6)&Utw6B|6a>#OK^%inz(o+DfQ9h2JQiPs30NYXz`)XF@`XCCC{v5+cq1T` zHWRE$ZTU#AB2an=CDdZjs6oWi=`*#^8-5l`l*u!&_2l*`~{aPICDmuu|?r~rGwRH4Tm#NDG(lLb@RwGlqKLWC#a z3o?0JAva4X6y6nj8nY3w79*%!P6jgML?kg{7!IUX8>v(XFsK2e5ld~D){fgsalAa2 z5pjwh(Y$l4fDNVB+O_#wI|e~HJieIA74rn8T)vpk5%aiA4oA!xA&=`#hUNcDI?_J$ zoS~!_nh0or`QX-2PpPnFL#v@>xoNPO==8z15Npw)5D0A*rXTbZVhtUkOSKh749<_? zg1xhVC25|eL&X(y6%gC`x1UoT@UEGF9z;Q_(663-{?xX zdozVqz<)pvc&l`L?kN(0QK0zA(gJw96%`c~9UVPt)Tq&;N5{m(#Ky)_D3rLkxcK<^ zYH7!3FKBWxha21Iy(`UC%e=%51QUcAP3#jwt96}3m)vK2?f0aVZST|Xqdnu z0Ui~l38%ExQhS<``nyud5S#4RkT*Rf=}!Yd34n$|!KqYNN{S~v-J6|#P^s)N8hc!> ztBs9hTU!c}lqN}LD{0x9bQ#W6yAafqO*BZ|&GI^*%G;%B4H{{}6t*laTg8;4!ZKWn z*C=ZmHI1!!Yry3X)&)XMy#sAj2}n|bWFw$CLAr+`Y)qE5q?ffx@PN9um+*!?e)6D_ znS=^c95QCDI=cy#`Uq9PjrPnTVRRq9Jobuo>-(we?9Z^+>bd%F8uLN|K`$V4WUDojq6 z(b7~*HkzGH$dxr32U%sPDSj+DrC?)02RZMv<|pWfGcMg*c6JkIU?>bNQO<0{-Su&`KsCRaCNz2MqW;5z^;t1Oh1vH>AmC1gNOl4R!>FGe0YMA=K`tH7MgpTnnHAWA2f<%6{` zj~2p3ytQx5-b!J<1 z>i9KB$+O$JiO!@Yk9|C6=OT1*-}Ap5-l-9s&y~jAJh+DZWZE8bPUErcbZloyYZ+;*OuDAIRAL^6@RcNh@cn-}r0a4fiar zqJ{5Y9fyeLKQ+FoA?a<~*zSM*J^G2PS;A<>#%IPZ+FBVNNX_f}A%(KG?}hPW_wS0s zS82X`OXN14o}xX3ocsPr8mH}@c}wPSa{h7X+>H&Z;{uwP(cg7ePFViQwdYbk{{5S= zo6GAyLe3x9)xGx%cEX#J7#Y5^qTDfOw(KgbTmSB{>sR_-J6YP0x?W@~-Mw&qNBrd4 z7k^Qt&HV1Q@^AXfPhU${oDS8Pk91<<{g%w5jMM5H2P>BSc?`WOcrwtm-ksoHdcYFZ wf9YoN(Nm_QXS$5BYYf|3savHP9puVUn`D;+8E3W&U?Mvg_1g|jJyXA@)D91TM}uclr&^gOO=qvgCK#2JQC6} zr4G;16kDv(p(ZsRvCAga*mW&xJcqW_rJ5;fR^y7AuJM$*x^Y}QW@@*$50a+ondj{E zocUilz~j5$y}x_!@80_z-s^4Js9aifV-WygY2*6(W_Vqa`4r~CZ)4=ZDR?=)y=Akz z+34XqU6k3{L2}*OoFtd*wweLxK5cJGE{&sw7cIN?wBFp+x?)JZ-|_AjfxO-ttGqj{Pn4WzP|^k z^rnB^^pn#!yjq3XmK>cbbb503^+s@BAa(X^s|qumjMd$=gWdkuyF0&L^WNJ44tz+rdUUw1P-{ov}@BIN2TE68(xAUW*XXa*48c^Zm%fo`A z)i3;Z=&WdEzy608htJ0g3(!3;pIjo`d+#5QcK-b1czj}{FyWHVq|S$?3-W4n?|D^{-N<4qA*MDN&LI3_`=3DMr z`OL~?Z|=JD>rW2E#VO%CckchgmYGkHC7+&pLNa09vvSWZs~&wAES5gL>7m}j7jL_@ zp!xS4`itP{f3JFVmFtOPClBtpZTZe4oQv!SJ+|e)9vXQ5_9f>ZJa{08o|(*lx^wKC zHAfDdTYSb_@Y0`-#7={AYZ`~6hu^&(eP!v^tx>6!{mMrell=I)4wn-S)SsFLO>d>BjJ*$5x`7p8vcv@+yv^z+ zu7YxrTuFtb0u?rNTf4-(HAUQ7m&q(^uD@dr06l9-E}-3+~;13&+b&K=iwdn z91D;Sq}%93L=`Avw<8NJXm>*w1epuyJ1yuIIHX83NmHFJf^6s_9q#gl5GG>Y-r4Eu z$fjc=5VC``Lsc4j639BSHD#VC3 z6N!?9ScKsVpc);t+vp(33={;futFT86g8u`#0;%T2!RsS!s;pl6Pl|{IEs^mL~14% zKxkZ6*po#Wi6ycay zDv?%7s-=};R3y5rbQkHOVJ~J-MQ8;!8$_lsGMEme)|ly32#~da*~k{7R4kE+L^83oMI@0)P?@A!fTA*Vfj(ujnz#Kg?acUa zYiEnT-bzFN+p?nBnbMN?&#q>d9oFnHak<&CkQs^D6lh}?Y0Ab4v1Yf3cB8{W!t-OU zVK2$8-_Z<}sF@^iky$8};J8pyRgDSTswAk;WG1WHa2zMA#Ixkhqtlex?J>H@wHC-D z<_ ziZ0(wkq-C|$OCVc@~{FO0C}KkLrVj^-O9G(8l^pF!CBrl6xUviw1i&K) zK`m>DV#NaNiJ_9|u`(uwFw+L++aSZl%K^{;U|_K*HrrQL7Uc88H8qDcno)~o!soj% zILO3eWmrkMycE%JY7BfOCD8dWB3MKBEBp~v--tFmW{4&&9J~xsme*(nDgxJ23aUrb zGiVr$QqhDjp6pAch9+lXY&j^=f>I0McmY4i!Us#0!+d>AP9=1KNjjVk#+gGJK?#AE zd6a^Hu4af(jL_PIpO^^IQxShU7Me*!n5j6s1m_EM7;cd(JX&plAo@L?;XoiZIGBh= zC&$Or=`;h%D8LV~upzc$q)a;|uuLj?ru5;IXCxgQpB_$qJ2Ar)3)pPDv{cC{*9s7# zriNB&dJGWEI~?d69U4x?6VsD&U{JAWE!$_{1Z{$TuRPMD9qG4>Mtl>o{?tT#dinw* z2LM)|1|SGP1b|ThrdWW1Z;gWS(o7`GBqua{Kw+Ry4x&ns)Br{c7^;*BU`$xUL~YDi z50eaoOyO~$QUINXWg|*`9zkDFITR*FM*N9HB$Y}q&{vrSVBTVRuv8P~7@~YCSrbg_ zBh#Ldnb6p`(Me_^%`X8showZ=dO63Y#k>|(&}R$x`9>mriFhQHj5E`dxJt!D0h0s_ z18dP!=J&EJ24K*!J=7?}^iNG`hljELkauiMq1S6|Hp1(rFvO1|AvqRNU@;Xkt`Vek z<&1&D`1nje#zf^zLd7u5$v;1odE}7eZr-Q`x1akEKHCC0Z7O9w*qMLRdbn8ZTz@wt zs~A4BC@#qXPY>Jxg)DcYx`B1R_{Ymui|*q*^&S+d8|&A$6i%pjAG>}BTDa)5Smo~R zA2vSO`j5w+eRgKcht=G-2J~m&8Q6N=x>Ji*>_7a;v9XViJe5;=N3-r_{DqzSj(c`3 k+rtU{D%O2rujQ4T+yX3r^ML6u5EwKzY^;B2UF$FY1BWbLNB{r; literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25686.png b/resources/g2/track/standup/25686.png new file mode 100644 index 0000000000000000000000000000000000000000..972cfe971f2448e4a9a33afd640720b80a6516bb GIT binary patch literal 5142 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25687.png b/resources/g2/track/standup/25687.png new file mode 100644 index 0000000000000000000000000000000000000000..7ce24146d7a184f2436ac255dc4cc306391da1f1 GIT binary patch literal 5287 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25788.png b/resources/g2/track/standup/25788.png new file mode 100644 index 0000000000000000000000000000000000000000..f20e54eb57d865ee56e90957a57bb438ac43a68c GIT binary patch literal 5167 zcmeHLe^gWV75^eX!VfE2Tw|q52zF@G@RGb>Ab?Q=4H#o6p^X@Ae0h0^86+>w3kFTw zSaC&VGb(jy#f`PmQHvIx)wHE;)YyS#HQSi7lCEfRhRwR19(trz+qZ85BA)e}9nV?+ zGbhQ*_kQpF+P+SNyDLMy&V zp8D{N;m&ZpC4S44-6HPsm-Raz+p{-u?<3dr%Wc2UoX; zbH}dD`Sf$_^>aOEU#WQ>%$03wOKqOvC-HV1>6yyi^~@hn)<5_6K%l=XIcSrNhKD^PN%6%~o_*Q$ zUd8)Min~ld+c&zc@zA`F&xFskh}Z1=X4lo-0dimSLgxlUWpMwMZH;G^9&J1@&G6`& z?B8ThJG*_^x1S#h2*TWR%MScu)#znp>gDr$g#D%+**hMcw{r_f$$$CD7q=xJer!Qf z)!SLrSMGuD=e;}6w&zsO(M^xd+ry0C=9$3BFmv2gc=d-w%+JsLs&1YqOn)x7N{8~}C zcKD&;HPpu1YeQeh^;D{RMJG>X^Pb%QWxdBSYQKIx^6Jwr$v@w>T}V4UKLd8%dK2uf zm5SwJoHXZQdQwN^HJGii?Eom2G*~gbmawyQgwbRvVMn_BY?eu1!dB-icnYhOSZ6BV zXd_e`S5)I0Ywin#vhUKgn+$izx+}KmPAr|tfk5*K+`F`I z=N?mrS_*}@l*H?!;Z>BDu%rIPdJ;G3#j&3}Lm?04;{q;$5<0FB!wR?<6mbd6P*AwA zK!ob_*d(Y53uVVFI1z<{;CUv9BPt+x1vrn#)fFy8xx#!Q&Mh?P3%LcD&Y&X-bwc4n zbP|NpW`bRb)lH5n3Z;ioxB){6A+*I%VLn$V6rkKfEMLGC>J}OVLLRQe$D#DN_zBWx z#$Y*3X3R(+R*Ny_BTBe;`B6XTW69lMd?6R<+4YsO(sjPre8h z(_1^IkbBoOiMC_PQsDATJb zqYIvd$iz`N&KHdJ$9#>~;m35rV%>LgPyF7e>porg#K1i%-|w#bblnpJ_oRHkyZ&!< zrQW%jA}sJ9kOST-{rk6@Jpjam%H`E%@OCRME^f+{De>{~2?+^_iHS)`Nel)fIXO8c zC54%jlY^p&R4P%a5a^agm0U zl1<8{Hf@`a^aWjkP)jh}J~--6mw*fvU>ZS|6Xd!XqBf?iGgsr6kU@3xAmxp?1N1Q^ zCj%E{I%J$?bx}Jm?V?n{M!erc4Rtg|{GQQZ2R#%>&k*Hu)TqcPkvdeWW*l#II69k~ z{cUYQpKq|QFA|B+Ad>{S9tPT;F73)x^>U1Z(xxGeH|*$&xcf#r!#Dd!=`>Dyx`@e? zW#y-OwdKHb7IJT)g{^YHYd ze>^_mmkmsBJ_xqfyq5dw!RuKM_Givmy3k#|ZHLXfXu5Cl@(TmkJ}#M~ui5$Tt7rGT zzkBiZrG{@W+#EP|kh!d@&Ht-aA4Kv#JNMl{!rH@$``=wzGB>d2lLOx?ax8-@np*$> literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25792.png b/resources/g2/track/standup/25792.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d6a84e061a102da6eb30b253d19980e6bad377 GIT binary patch literal 5215 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 NCCiH6Sp3Kz{sVsjs5$@u literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25794.png b/resources/g2/track/standup/25794.png new file mode 100644 index 0000000000000000000000000000000000000000..529edfe3b509e273cdb569e09259229f9625d1df GIT binary patch literal 5126 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25796.png b/resources/g2/track/standup/25796.png new file mode 100644 index 0000000000000000000000000000000000000000..88d87285c61f9dc86cd2716a421c5a85e2b6b5eb GIT binary patch literal 5018 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 I_RTy03(x*iwg3PC literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25797.png b/resources/g2/track/standup/25797.png new file mode 100644 index 0000000000000000000000000000000000000000..4effad4389be7993eb2a02d8d5e594a3411c479c GIT binary patch literal 5101 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 wEk{q@-_x7N9P4>J)v%32AyEi=XADnA}%>V!Z literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25798.png b/resources/g2/track/standup/25798.png new file mode 100644 index 0000000000000000000000000000000000000000..6b18a9b87133f4422c0a5a796af03a8f368c0335 GIT binary patch literal 5189 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25799.png b/resources/g2/track/standup/25799.png new file mode 100644 index 0000000000000000000000000000000000000000..bc00e610dd0750cf29813cdbf7b359f9f90092d3 GIT binary patch literal 5203 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25803.png b/resources/g2/track/standup/25803.png new file mode 100644 index 0000000000000000000000000000000000000000..aaa3ffa182431bc96e810dbc270fe5c636b44d29 GIT binary patch literal 5328 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25805.png b/resources/g2/track/standup/25805.png new file mode 100644 index 0000000000000000000000000000000000000000..e1fdaff5e81783423cd9758259ecfb5849160986 GIT binary patch literal 5206 zcmeHLe{d6Z7XOw?(;q;UmaAvEOGwcmG2JAaG)>YPAgyVvZE91A7`b$_*@Rr$Y{;ff zOOz@>3-*Qp)vHIrswq}28adRU;U;3h7OTda0tKp+u^g$&P46t)6Y%!FNeh%YXKt7| z|09!R^L^jsroAYya;Q~rC7FnR`asR+ObpW(7`Q=!EWtIbJ|ez z(T&|deg9bZFlfJv*LG~BE#+fk$P&h#0N9Xz~B$Ivam^)gu7=%{vWn@@LSKXRza@rBPl`CIomApIX^`?={$ zUVp9UE5V{p{esJZu}EqPf6H6_b9mc+_sIthk9`@5424poPQ_$wtYac2xoFnfXRYt6 z4=gVVS%1HCapk{^*g(v&fvY$DR`nS+^|Oa_8c$8$p`**$1E8ochMnyHl#) zW>Ww3o%;9U_ZB;!JJ`SXiKW?_-eq3ST<^AJztXd_d)b_^^?UdD_-96D?`Rmfc<;M= z&ZV94q`Z0b-S8=J?p}2u_|E6I@%PVt^wFT$nz{drq^G+?59ZV#Q4Q*sfN{%(3Tf@w zuf|qW>ui4?y^z#jr5liZaBva-!S3@79qvij4?m3mX=RJz>jTc?86Pgmf{oW`g$?#_ z#RD>&tk1_xq>;#Ps&~N7gUzUDa$vZPaIuVp#cD5RkB7o+meo|u)`=_l6%Hk_##*+{ zNodzq*5K=GxYWc}+?!t1B!d9;gbQOe)z{f6SyM4Pfh&W*<6?x(N~pMO#q5VGs#r?W zNw7ruqI^EDw8`2iWZ#?4Dsr04vg(rirXk>}n7zj3a>x+G?RMw8(R|WrK?G8%6yXaI zp^yhPcvQ39g*EZ)R9+ln3ZsOeaHrMbvXXXI91}B=4X$D~8}75N#8>aAsJIGmr>0qe zd>~Dj0}yI}%oq?CUgLR`WHou8S?clSpS~Akh3O?seK% za!)8jt%?d+35hqv!&8?Ov*Z3{CK9)rWQm_U|>77!?IGzyIgC=)Kb zk95{!u$UDcFl~Q~^I9Elill3nPQ+Kx(mgr$T^)9A+a^Itk20 zI%`O>u9zK%V8t!3Zdbs8GGQ*P1alD(lrI#?1Ok~*Tq6+4#6p>H|!O;^=F#FER>=mfmFzoh^2+Fp9nKgD#VODzJL&jBoZM?;8PX6icXPcmm6~u z%Po*c$Q5kR1Xrvj)1|um`e@v1hB>Cs4LmW0FAp%RNi>DFr7aJtDRDod)ptXP| zbLcjd_G{>%jUH&Fhy5U4cnK(10-c6o!*g2P+;*R;$B&0X-e|Np7K_r*SFQ!1o(zRA zN8@K2f*f*K?i<(lPPjvp9RrtwBlOTXCksfJ3>A{8S1@f_)MF|4wb=aaEur4_Xrwnb z9HA#hB<1CF5YWSbreQ5wbG;sh#Q+StOgGs_)19NE+CTv9?C=Z>DD`@+&4znCB#L+? zNQVOLRifc?WKhG6>GEg;lWyVAohTht(9v?5ru$Dm8Gq!EXPL(g#*W) z)z9~`=9HeKkH5a@%k-@q!*_k>dU4)`fMwy4#b0D>c(JCWlTq;fQ|`W#?MsvMUfVJF zytnJ8&s&dQdQ%+iN7VN}a`mgf(^XL0_GA7-IesxWBVAd8izQ2-xM(x zK65Plz(Z(OKht9e*>j7`A*=F8<;WW$}s7otL-ds_; F;Xe;EtjYiY literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25807.png b/resources/g2/track/standup/25807.png new file mode 100644 index 0000000000000000000000000000000000000000..7efece319e7e8e28fe1e162b02ff2dc6eb3e4473 GIT binary patch literal 5326 zcmeHLe^^uX8vi1~_@S#yE3lIB?~% zS!8&fM23Y$IgJu)n&vF5sl$s!PwPfXx(cs&1+&5;rLx<(X9E$R+wyd}G8ZnR&pqs{6!oUOILSNXsk7Slf4ELwK+n9A!DVE0 z)bIKDzMe~dDB}tX-QFla`q~qXdy-S*zYJ_K@B7y;Pt4x+2Gzid?tu*Yshxi8A?Js&Tnvc-nZAibDCl1%Ji4gr+x7B zf}g+I9TX1mK3=f%@5@KdK~v71*dppRZA#xXbH?WNATjIN#p^aCyfJ5XeCd8B@xABt zZ!_MRVcT-#_}<6nq&{_k`73>`!<_nR+qNC^rVOs#yW7J*(--$bP4_Qz59~glc*Yt3 z=4S^2r@{HTMLz%ApWMzrICaGef0l`U@QauyTSbc*mJgIY<+H$$@kdq8LxXn=t|Zo& zzwQ4q=6H#=TYUIPI)CwwZ)%zyBlas-hMr&Il3zGvJDGfRRtnX3t4&mYEmbX)qPQg! z(c=|ZX063aH68%D@>(l`nlU@80yCPb^VmZj0XEB|&tq$|RD6|HfmNCc*Vr)4nnh*k z8Z(-sXUpd%<9@$ByDksprTr#AZcR?B+c7QdJ2{f!i>aC{vWl z=M~hNRtwp4lUTVny+K-C3gZ8!Dqso+) zN+r$5(V9qjMfrK`h<~XbM@@QZ^szz=XYmbLe4as+oy`+TL=qkXiv>J1i!T1cmjml zW}>R;|}7wsLW)+G2|eRzhfeDIDXA^8H7C#_I4#x?r(xIk_o*Z_#y&uA5@urj&1W*Dbnkih-L_zSUj- zH@cFpZ>F$n>K~AU+A1l3bAJLrEGSu6RzPjHVq#(@O_~%N8#{UO{ZuR;6!C+4~JTyEELqIMA>f+?`@)Wa~>2N~z z4YKAIb(>Gu5g@ul4SoGy1(&9kCF8{mmzL>4Ijsb|&#eeFYrB1TxT}63>>U{jD${_D z3mkIb(a_p(TA+d6+mLJNs1^{XRbTk@Hr@PY9JRFW!Cflc0cNvYn zF4x7@Rx%JsgHtl(3`otC={QQ9t98MsM@F2$ji*Vs*Wa0(1Hrn!4J2;b3UEPY!g&G(tmn>6jifx5X)Muh(?67`xhCy@8g2 z-r(@?MN$rc761YO4*=}|bOF#$10?lTD@Z3nwtLBNubKmJ7&OU&UkSo$KxzPqGsp&* z^r}g}ne477!(I?6yciTKfL2X2qYRgW+vHKUdC`szcPP|8Fc2asUui}FJCo%ehT6;2 z`8jx4<{2t)A9i$%G%G*p&m7NK$}78n52tCw!oxcPKJs}l01HDUF66i#$LKe1LmFooI2eCF%`wieDGA< zUka(0L~G$PimYVn%py4@2E4HC&(t8zUZg6Z4JO|?Eo-_sb$x)cp>~w>%Ou@f$`(K8 zW=%Qwo0c2*=*Ja4}Q0JC+`^Nr>&nJm>Jl}Nh+G% z&Yt}7dn*0R#M@4+{=TSSNmY8og=Y^QJ)SSLUwX9bOzzp|93!2uS+NULi<%G)*imxv;Wlx z8pD@AxnCPTHgLP~V9TEO@7azE)(d>Q6Iynie&q1k(mIEB%gNqt!Yj&#y{av){dGFz b-JfH^ug9P2tzH#9Cn_pfl>g>^4?X@Lat-Tg literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25809.png b/resources/g2/track/standup/25809.png new file mode 100644 index 0000000000000000000000000000000000000000..ce7dfbcebbae803965d798d4113ab4c1c7fd75cc GIT binary patch literal 5181 zcmeHLe{fS(7QUsl=?}21t#&0YO;a${Z2FQWZGN;Rl(e=nl$54xz=GlB3F>LNwyP)M;(QbKf^U3eriF>~|#Jb#i z_u+YKon<)|IwNb#;l>O5?`X4qsoU9@`pJ=%XV2t6@`z|Mfs^#lI~`~951za7>7b{4 z_Qbx2pS`&As3d*O2b#dM`LjIF-Tzka3T58Q^SE<=D>Se1UO@Iaw*Be5wOhvDyrlfw z58og9Y82hIW2>8g;N4lJJ3&|a__EcH&RbPFuvjnNyl#urE=eF3N>|AXmWk;ABs^u5 z$!g^?+0|@d4%;8yT2>uga`!u$hTdJjqm}FtRW$DSdKa^!cXQ>dwWredOa8F>$E2G1 z&u3*<9XWXB%%Jw8Bk!zI)70hju7GtdmO9(k+bM6>L&sVzpLy()3+z!q^c>CVVW;K) zd2inryxgvaJFX0j2UC){9j_jr!`b@qdvCAbbUGLu@u!5W(#goUcOp5lbk@2TjECiK zmY4dCk8Gc8ckNsF_hXS`osu{~UF_JPuMO=!-|jlL^fg!SZTdxPa(Cw5 zc4G4bmp|VZER1m8f1vl>hbGS=bIyMBqF}_>k=wCo;g+XBYS9ZTo@h_mf8V{yb+6}; z-+4~`d*NRfT3nzw+Usz$tKkv3$UH@Z_(!Z_Hi2+E--Ec;mB#r@I9!vdt%|h8yxh)NrvzymtJ~ z@ipW|(>G%m6OPxahlFn*$>pxt{q=gUebRR6QgqvcPU)9#T0c%dnx6@~uEhwuYh}$c z2}YO;P#vMg3tG(<*meMvN?R=`X2NX@Ep9M2mocOM0Fz zP#`Gaaw=PmErra*X^c{?#gHk(C)Aa=XGz|JoqtOkT97K;&XAyQb# zfd~${q1lGEa+=A!7{wGv1x{jCqs3+6V zhTu)O8A3_um3M>7DtS%qHH(-82BX;$w}N8dfV3I)*TuRaw%AHMotc3^^J}~}ps(g0 z2SZd%jiiFW*2lt=SClbh{v|pBGwLK$KY5tGh$|Fwa9n_L1VXWhgNm^t4v#C+ighBr zPJrPvsN~J04QxL~fYMK;K%yZ3np(md(Pje<&yVSb zy*h9FnP%W}^mz6Zcg9Fx=EM-4iXha4hWg1vQNcU_lmKXGG$JFzNvC^Qte%pR14`wf!7$=s)L1YhQ^;bg`9gzKW>=})7}jOC54hcd?(UG! zH#$5VjYcUzCjiS!(%+9XL$y2cr ztfYigDBCoU%rW5Z9PAqi2SXF1QlL@LNL7YYljAY5yByN~HkH52Fxc-L33Nq9f)f)L zC@BDH07w8l0Q3Ve2*4N(Q1GpkQ4W&o@1epYN){mapi>HbRUoVclnPKpHs$71Jxa=F zqK4Y2a1V$TUI-L2pjOgMShmy7?(|gk^P;2tMKxB3>!KU&aq8 zkYOb|qRyi?LC{{XrW|5wm0AAYuYdA@>$!jWUvuf3(CNqkSx|D6h{CnLjAMJ;+E& zs*O4i-SgyvMc@8IuR2*g{O;l7B4W;_Wpxidc%nZy`{6mq-*ey9QXq6~oB!gVcfpbi zr&kYU9Q`r%a%1NcU$u45RXsY|vE;eKmUFMKxU@g{tMR@(E^pDgy7v1X(>8W&`r>>j z|1)y$TdY$R!^cj3`drF*%Cjy1+9B+`T>ZJiuz4>X-pGCkLig_Zdh1f=Q$?1tw!-#J zPhZj>^t7Ki*GMSne9DjNM!c)slUuat+F zb@OnsA;`EOjf-7MZhUCj8Pt|e$v#iI9u9T`SG;g1{v!>$r z|7h6%sr+K((Q76B39m^1u<7Sm^<4)R zrYO4J7#iv>KiBpC{W^xO;I;|y@D_WibN>R`w{YXB8v6yWYkY|-1jv^67PfE_GG9L0 z`Z+(XNq_r9`)D9;HgE51r{{3@KXCTl>fe152=sNt1s$^Skx}2+?3ldhho7|kN%?j` zUWetOL*wE?Yu?!R;(Kptwyac?!11P@=VuRXQucJdxZPZ+9Mxq9RC8D^ToNR1bvphX?yQpx^EYV7e2ZEk@~n-mM@!K`Z|;P z*4zK@rEe{DJk@pj_|D}E_nc%-B<*ln7rxkf=u?tkMi^LcO1-L%Osv?RTGA?mSa!TJ>28AY!?6NJp)t0fPP-Z8qF z+GhP~`1`2SCAuEbyIpC#^@lH4`&{GBD_25K-|Lb6^KHl96W_~BhE=!40;}sj^*Sj| z+OjYsSx#it*zBT9eO?;7Z|pco<=`A}UU6KKnj(2}@2o2$mpA zkj3K`)mXM}QL z9pPv35StB|X+b%Qwm^_6hknt5Duas@DJ3Yf+JO^ATZk%W`b-ETK5cKWc2q{fG2#eO zN!Xw&1!v{oFr`ANE}6CnQ((5(>=7$S_6?d&i|IO9H~1EoM8cWr2sEF@y+Qk0>=9+C zrB+J|NxVAjp0Y5X9iCrmByo#T8hMqVghX79iMTk5mU9IXlY}eIHVL^BUN#Tql@o*r zH_d=jR#8r@3Max)5IoBQad1>D&fys`E-HkE0zyD=F@jHU1txyEh{q>TG0L9-p>bGX zRbrJhy$VAaA(R-$goMCk;tEYB2p~a4+;WK+j@SCbAK2GeP= zVP*ocSD7P%FyYdI5@kL+JBxRHq@)sanxFw(1C}Zy>7uTS$}BcQ>%_u*@>@K z@WebZY_2QaOE@T4i(yngFAJTNgcBo$;XrD!aHT?khy{#BDt8c=lXR4kWMw`(>=Y|( zIW1Ph1!csXSRv*lASf?eAm#I=*}^iuKq?eSc{~n}2ixoVq|sv9`oFZp%ZHUWne;Ul z3eLYZGBmlSw8X=cy~%E+C9;@UtjMyEV)$eT6t;z!{ku;HH#sRoDNGu7vA{DWVGg z19HKmQhoC-c+8IhCF{zH;BhM|Dk?fUIwmG&)~s2vv9Ysf&t@FFqn z$mKGvR)ynwiXv-kYkj`v_I7_D&^s^?8XH3qAj<_BRia*>Y_&37Zltau*Vm+JZ8vmu zQa!u^q7IZ>ZR#GIsh5~3=9UDl;lZG^=4$W8b2Hu9 znTjT-%Tf>xGuM!zAUQe@ihFaZCV6d}scxRFfBx^y688F=-!^;pgrzqMp^qn#?sB0LcT0-6ceL}-Y#zm`|+2HKh=??~15aLj}9x?z3Gh^r&y?Hy|$x!N~QCvuXKL@6l>X1bPx z;JLY!N>gWmVD9#Y#_rbkfk1F4+c=z$gxPP_=H;w6@?K9ksz=+sH_ehI6Hw0qRbac~dkkOoKmz z9LV*C^lf9Vj&WblRsSH}7s^NmA|^wDBLs}^;eRbG#^rP0&T)))-5jSK|nu|bha zMf(9g0B9QKqAs=8%`h8)L6_tryJ@;NsBA` zg#NT_$=8KN-LEUV?m1`S){lL*SYq#b%eC`r^89{TLE+x$RY%`=c9!#}rB4rSTDI+- z-B}0J$rjl+2T$yX-4n8Jxcp99SX5EK$0HrEBjn?)dGT=gtoPaX~2) zk8gZs{D}p&dundOIg7;AAJ4B?eCNkYj@|Rf=a)Y`jk}WF&ASVWCl={nd};g9w5|o4 zy+43QZ{M(Mfq(n*B>_Q__DhlV+b32RyL$2;&*TwL&AUgwoFG(z+;bpMBajm-n z^{|~T(n7T0Z1*N7&c@pa3jl4W?e)fmQFiu~sYR7f9%%k&>0Y(9-T&jr?FYJE!Qc4% z!6WH}uafn7$usKbp0Ba>NxRiuZ+x8oj^o>^w_GoArKLwc)PLe%&pTdG@j+YFp*mKY z=i^$8-Rd7)b+q-jj)%ut4dC@+wGJih{xk8_K1r~mlY9~m6ag^ z5h4=tp#`7XHdBgf`)Yo6r&c=)@1SN_ zfP5frs1p$u3lO^U=mX`6$L^2`2RB9Fr zEM*pRnWSV6l-fbLQ3r-6p&)oM0dXX#K!(dKQhupOi1H=UGMwLp!@dfnGK;7bFB3{p z;T#B^i-1#!w#>~c31x;*B1~vTOHiC&Rw|Y7B_$|K#DbRaphgNvS|A5DQCW*Nh&-T@;+fB&twQEG|uHl8uqWav-&6a#A5cN)D@$D_uD1CS8pr z*;2_#CdE#A&Z@O=Lzz)GT8+AK2r3Xs&jd z3Jz$BEB5l4R^4-bHlAiY*#}4&Unu0yp^Ssf6pJKJjH}gFApgZjMap2#5d;0EW$@^N zCm}L>6wdGkbNwM-Gky3WL$KL5gWM3mH|e@b*9|dnL&i6!>n2?{#J~+1-<+=h8(q2A zZl-Vt{0HQLw@N#z6&wIEK>g~*8hE>vmX?;Do}Q7BF>l_y%*@QJtSknDk)55Llao_W zR8%AuBTA)0uh(Fhk)lYy-yaP2^!JCO(UEvOF*zwlfTA4eGC#{e7CQ0exuL6pmY2vO+{vRIcY~Fqx55k{!B^ z9#c=4499%YcvozqcWf%cRDgUvD6j&S7jOd%SxNN#5X-CzrAM#t#ISCUr@yl^($f-H-8I`jkG)}cP%Xry~$G&(tX zo>l;00DuA@06-rALja6301e+dCGDl?z7QQB)o}qS23-meR)M$<(0V|V1$3vF4(aHy zjUMix;~|i2ybNfRz@TH;umYcl*A-CphOmJFe=OEFF%hF-tU@agd-D{50$qq@3UkSL zc_3lzoAeA!1&1$($LP@nHy_AY3>CsODp)qX*lX1Ue6~=RZ=kO$7VVpeN9oBinMOm0 z0UZZ44SUg1==U(EgcaM+j`}@V+LGSRe(rDD%Y?#+eiV?pI2`a>WN^wMk zjOch1h9cU;qJ3PtTTF))bWB6j^vP3CBp*4Xxf|;Apz7>j;nOXU)}&EYgDshN)xt%N zv-TlKRvvt2k(ZwaUfg**6f)duZ4KjG-W>}{mY!17&It6SF literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25812.png b/resources/g2/track/standup/25812.png new file mode 100644 index 0000000000000000000000000000000000000000..dfd2437beb683dd58af1e60540fd7228238ef2fa GIT binary patch literal 5006 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 SPKzN8pr~+d!J(Cp|K>knUAAKY literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25816.png b/resources/g2/track/standup/25816.png new file mode 100644 index 0000000000000000000000000000000000000000..3a1e0a1f7102fefbbe722d77995b1c92e822becd GIT binary patch literal 5184 zcmeHLe^^uX8vi1~_@T}l+{;x;=CF&kJI=PVIT+x?K?8A)7&&d$Iy*a?Ym75@4vZhx zDoi5Gr9?~NMz>{DSY(>3R?pIDP;}e9k#Um>x|CSjU4=r+2$Q90jZ)#act_X)XWz3wy_g-d61Y zqkh|&1&3wHw;k5Iw)MwOZf{t0!^*jte@GL|+3jv$b?htI;WxS$e8ZBpd|(^-XRD1I zILl7?c3bDRUB}W#@16bHuKV6O^2s7@>sPx5p6kl|WaWi#zn;ArY`SNC{ajnF3V@g` z7KNg`RH3*S5DcU9o*e}x!4=mZ)$8^=eH$z9xtyYne>(j%cl(})i(f83p7f&Zi48x; zsTS@`O;a9vb#%1PaO}|0^;(v;aQ=C)sn%XW@3@Zfq~3m{&i<*}Il0Ig2Bi0Js+X6v z^o8fU{~=u5q5JLm-jl(Ec)|9U`{(d?-1+|7HJd*R28a9!A%}c&{G?|hJ~n^WrpGLA zl)hP*@3-9DIoZ;*cgcH4#*ehg?s)X49jA5%$Bc)2 zKe>3`yAQAW*XMhKqH+EQtM*ViF-a$23za2Xh(_gL~kiLCrvEbHcPS<#xll0lM;azK8@~_`?e4KoEX$ma7S_>?& zb*j}eoU~goGsuN*I8;s+~rA}e238_t0=l<8Un5gxEpEOE<+Hf)0yo=vq^^;5$5LRA_5U2 z67iu1pQ^8>u{wS=l^KDU!YCpr++nfP7P6WX!Nd$?4PC(H!hOy~|7>=Z>Jof4HO&I# z1F6I8h%j4#*lfs53yLnTg&@-o{h|d`3HubOASklNffL2GL^Yi`6T*mJvbWbbs-oc- zafGNMY*3YgrwXq)Qdz1hzhn`iz-+PEqgIgYD>P|~=`vYY_!ilThBMOOZj3nN5IE&aUmZwh>Sub zCXooSoEcE1)fA0Y<3t1sf@fPGj=+dXQG+yxpDV^ie6c}f;u{1a0UtFOOcIF{6$ykh zA=C~FtV*nErdJUtBZNXxqeLtaqkNH2AmNL1ahz{J1vz}wm}`=X2+1 zPX1KVODq&TzdkCO>M0GeX=*jKtg=L#iNlGug$%=|LZGl(!Wi`vVohz~8?kCL0q4hb z!CsVGexVp3aVAtm5d7R+0@f3rgYk2Pgo!UQ2nk#$5=jLj;!1RiG|^7XK@^%HkB}=^ zpi!w*U|e%2!tw!`rQxn3!3!X2r(F&YnFxE-o%UKAy#5B_t#yCMKq3 zW@e%&qEN^+nlc>MQ54zK)a3DW_4fLL!NK9-@Wcd)0C^rzmnG|TDOPKSvk_@-&GU4q zyL;w( ztzmVOtUxP!s5@n1Ae|XUmOQl1$mKfK z)x`t?>1ax(JPlE2BNb$` zy17f=aK}I9Ua;cd-MGR}X+ll-kcS%UX$l8Clc64FEXYogX7RMB)GSvxHJVl&?{GSMTU!HN zT_K-uWNPXq5LfYy2JNz8=?5pksU} zI5BaGkprLwfC9h`Ko0($0EG5F$$uq1Pw9#DVc3Hh`E`Lv3DA+ST9AqX& zq-AA{4=}@kVPGzr)0-MuW zf2ErcUjN{WD*rZJQT7-(OxckGto?&+jbWcJ9NrhMTt1 ztJV5Nix$_kjP|eig1fct*%6*?Eh6l0Y&XUFT0-KHZGTIqxBR=*{ml>T{K>B$=}Zot hKYNb;@$ob9H}Ct)4+rq=gD^r+TD+#{rImL*@E^;+uSx&_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25820.png b/resources/g2/track/standup/25820.png new file mode 100644 index 0000000000000000000000000000000000000000..53159afd1a49547dd036b25e00a69a388ad250f8 GIT binary patch literal 5161 zcmeHLe{@sz75|n((;q-Ki)2z~LRu{t)0gC>O`HA*C2i9hLrT+`YSH-e@{-0heIYM2 zrI|zxTA_{z#l=yy&H&w3G%$v7E5`^yiYpqmXo09j%c0#t$Z=Jwf_wWWEl`f0v%@*_ zKXQ`1eDC+(&%O6^@Asa(x1n~0VqW^9bO6A-n(B%=cwH3#q$b1fm$n|b3@?Y;>l++( zn3H3(lSXqh!Evm$5gek;Yy_a~l(n|}mM|yvz@?34&U0G-re*jN}N2|b;qK2zj35D-+5x5dVdwYvUljT zV8^Pws&*#!;!}5h9?(^N$vRSzy>9)=jO;xb3sOq&dR65+$NHEbsg;?Z8!x%2e)Gh| zJKp{*X(DBLLCSH)TZLQRS8?#Fy;V;(ta{n?RJi$`e@9-Lzk_L%JV2d)Z80Y@bl7_ z{N>NRUkDd>H{N4?Xwo=5t%Z&Y?_Qcx z_cu26mG{(ta{iuUfBxXny^r6$;F;IimznFFmIb?dx9?ascYNL6-Cn`zkvZGe41Qns z`tGx7r(G$p9e+J^3Y;yg2?Y1Q|4YFe^H!}2=9`&se3JBZk9Z}^`i^3#aS4c-zE%}I zGQM#9A*$VSe)Q|4qqW*W$y)~(3s&y9}|?_J{l3vVR@0f1Gh>Nha*NRx|9b z2GxC1oV4a)22xMtwOMVj?Eol|wb?M-LO3{j!enkK<;MC$T#ngL%GKtp1S*@HXfju~ z+X+qkih8`=f)^RMvahW^Hbvq-~|#1g;eRj*Ag4C!yl7lyVzXwH!HV zCph9fah`x**=BAPam&&dnSYdziMw=V{cBR zW55xjnXp1t3VIb@=TcFls=aCvr@&;k+7ecf?CUfgX5%%ou8S?clSpS~Akh3O?seK% za!)8jEtN`ILE>xT;nh@>a^wD`1`;!sj;9~-bm@h6Q3Jj8>d;--Q6Ho?R zT1DEe7%ZpRikS$+)?!L*#0i&{*VdGBMR|g2lGVT1 zZh|~Qu3&>ExZ*6CF4fZO^_@*bybh2uKJ1YhlyQ;iWRdv9xRPxN@*_S<5(+a$478h) z!O;aLA#!yTPV*HXIzQuUx(+|12MB%B$qn&)ldhX|-4FveqJ%K(^BCIV3{uH*YuR2rw}(RadE_CVb}&Fj2Rg>0{>fNakp*-- z;FJNchS5thLY>Uv-pq-?EP4!~Cv@~BFHMKD0Z;>=V=zc2)18&&&CT@}7w=Q62TZ16 zxBFaA4;>0+p_$n-7NTYs>v9z&PwPf;Z!y&^_w*^d`ZfMRT`+25OR^9}cCm)1#3hZS zoa|6{^yqqmWH90mN4p|py(5z$rVM0i0Lui}E|BYGNP1X`KyG75Mn<%qBa}bp4b%J7 zyi8n@5i|#~e zznTtO=)n#;>Id<{OMp@iv}%S0XStocF0Z23kN5X`B9Xqau?P))Wtjl#%8+?kYCl^S z%q646-dJPbgtLFrH+U&HLJ!AsGl7K7P$0}k8QY>kT_&a1ZSi-x`}?{g;l8nGn4TDs zD3x>&&{06suofLz9v8!;13E3!Ne<9-_vol55J0 zXh?|+sd;1CY+A>r-MMr(N(W_hL`l>1(UVWaA2}pB>Q-pLva=`Pvn`OMS1KyNGjo1j z4Hs#)>IWcM8St4!MrIP&w*6O7$Z*uCDjDM$x6PL>41T`K3`K`(D$47ZL>~K4xyZwr zJNxt}bo099U#xs`?fa^M)(`6b*z68J3qE*b)9=m>o@rQCvcC86Te(zI{e?59j%~e= z<2_b&{GLnI5BIg@oRJK^%iDJ{?Ssdf+P3-bUcJBe)OX#-OL?99tN88gzaHDCE#o{L zNO|whR%7%SO% zXrJqeTfY&W_l)1RbfWvU?e7s^mA#M=_-y{(qaQwQ@w=;{nOlE9GNMZMzXP)YHI*wW KUR(ailm7({zMv8S literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25821.png b/resources/g2/track/standup/25821.png new file mode 100644 index 0000000000000000000000000000000000000000..179bc681587bef227c1cfc5c5bcbe53de3b79be8 GIT binary patch literal 5207 zcmeHLeQ;A%7Qdym=?4Zh zIGlvpT8A@SO%9xaH(JdAG@i0oM`wf?(=J;!ZhDffI40SljK8;NAlSP7u~j{?Gc9+Z z+b#`_Zmv&Vx@E_L75X<$GSsu(DuL|BLofWT7FoSYFqZTE?O&|en}G<|y}D16pGyDg zk529vI)9ojlQcG5t4BK2r7irR{3~NO{Jp zP*f`wimUa&Dz-hbxok=JzF!|P=y$&M5KXpQQod^YH?J`_?c7+gxB67p8`7;Se@s)) z-ZC?{^3dC-PY)PBJ9Oj`9Zk3B_A6k`TE{Zi<~yj4nJW%AI==L~$L?{*0TFnAW`LDd z^!gvV|H_@yslW3|@LV_}owI50(P`|>j~zSM@c38Z@K9ey#3>((o$DA)Pc5CY<^}6} z$^(l^`>dC2h*x`2RqtE}a`TUkJv8_$yX);$wcARbX9lpQUw{yCA-lKC~ znKS*vjSu|u>pfv!jD7rpogb_iJA+I+^Vy4nA?v0&o94}Z{uz)deBr^TS~K3bcYgY^ zxAMsg{!>5AeRr<&#Y0DXpS*YGhW+_h=}zl!DI*%cFo_>;H*oQ zW5N);4!1*75=Q0T5VBIKuD<4xpul3aJCa_I>>DgyR`YeTZpba6NtQD?5$Jvm_Xg{$ zwI_|Cm0B$=C$NS@ddl)LW+J}SL||5vH2IS&5gP@j5*}O3HHz2*p2)~H8hIsbiP^~K zas(W6iBK>JN?A|3(0U9{Ktb?gE5yOLW**-x60*5sGlbysMQo!$%x6nXMnQ>DB;<%n zjFTWVPAi;Bv~F@%2`CeU;z~FYZV4)8b2&mDTOgDe*{DDQk@-R~zr>6RaX74r88Bhe z#e~z2!ggBis0BwH^_HX}LAZ2LwX%%KE9P96RM(*{GjxD^z*=u2+~jptjn$58U1)+& zu9(jg3PfU_NWc-o%XOoNaVH69F@ehE6!RrXO`P5;X} zv3(e&<4s>;C1L!gq-cCkY4J7VtMO%>HMyA>jO4bEqS$x|B)S$K=NMv*tFTpQy#@WPv1BynO~t+o{TFFs0>29u5$=r=Bd zM;AN^k!wfc1Ya=rFZr72!!H?v!MGLVrue-@*Dbnkih-LlzBOI9=(;HeZp!%9bp7Ax z%DR3th1bJ>KyG-eRP@0SEdZ&YdTC7syxmGkNtrTbN@{BA)TvX`($dn?(`htXMn*?qSC=_z7R)t}Dk|caSUq?q*Fc=DlPeh~f(NR7EuMKt*`Lt!Ps(s}uqUq*H+d_Ai6K5byo5QVmKTPe@ zuyQbQp1YFOrjvDJiat^s@nJ(97ho#^c-;^OUD;mDUe5i!VVh0o37}~(+;vM!-|#>eIVxUi~CQE24k0p#;9x-oi5JJ zt;{dbvJgxrBUPFf0|fH~+u8@ZgVAtgbXX1yDjKP!dky)18>`bJ?`hHYby@~`yhHt+ zv7zwj=y^&GfDQl>06zdd01N;yLIV_hYZR1+q4{ z@u`4@3fZW^7AhJ5iN=e8N&$2lnhneKx>@c1%I*Nx*XN5wdSbB%1!Lt|0N;}>_vdN? z`G!y-5taGl`kqmD-&n`s<lp&w;7E+yjDkP^ODvF|xo_s3t$RWkGtV#>+JNpHEx&=~*V( zA?@xZaFOX)@(3g=8$Pqh&Pf3;Z@UW$X)dL@f_5(ZSJS1%T_b14py)eg`J$Slh<%Il zB_C&6S_8Fj-l3QLPk+3%!uyxB1A?y)vd(-mb%wCH^ofhK_bz<&t{m-}d&!qa?%Ew2 zs~X;}W|#dVFO;XZ+}Zo=(t(j(vuY#HD$2iqC+j47yyn!-di{~w&e$o z9hJ@SyYJEOoVn=kl-`5I$9=kaJ3nvQh_7orkVO|uYIoD|vk!$j0>@m-R|jjG#rrp` zo_Ft;TUc9X^0~WNn6eR_uiEwP;FT5APp{83zdF$R^>1~fT74|z!oD%v`Y9{_eAj}Z z+BN$wY~T$K?PV<}_}<<5`uZKz!=*ERy4ZCt^>S)eRLC!U%l!ka94ITQ%HO=d_UV5E Db}Oqc literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25825.png b/resources/g2/track/standup/25825.png new file mode 100644 index 0000000000000000000000000000000000000000..112cf37168cd8715009594226cab358a9b1c7526 GIT binary patch literal 5410 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 M%-oEOV literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25827.png b/resources/g2/track/standup/25827.png new file mode 100644 index 0000000000000000000000000000000000000000..deaff64a3a3bb5b281ff80f4f9a7353d5e584079 GIT binary patch literal 5260 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 D+@i{0 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25834.png b/resources/g2/track/standup/25834.png new file mode 100644 index 0000000000000000000000000000000000000000..f9fb3978489de6021430f030d3e51dc6bd1c47d7 GIT binary patch literal 5060 zcmeHLeNbCf7Qgg^@YO~I8!ft|p)S>IcrRasB+#@58e&XC3ENatH$L8b3E7amG%pY+ zuGnH1E0tKmjY=ysrWIYPsatK-ID>7fRH>VtWfj}F(iOL1r**QsbY-=UZ*Kynbk>=j z&aD46lf3utx##@OIlpu6o!qy(cB5ul&dMABz%p%3RUN$N!(U$3Vt5TNZ#fKaC$`sb z@z!BJuG>Rd?M)=t+vX;@WUJi@KTf9c-oqs z|HaAG+DqrZsR?KNRDb`9p;tc1YaDz3_8p`~^~~>na)F)w#JPt)oVnqamp2vc+8q4; z)Y!`24M$KJco#4@eF;XAOc#a-v!dlM5Vxc@|}`!m09<|n=+ zpn}H>g8ZB{zkPY|3*oAM^UdFdrlMJyXwTu3d4j#aIQ4GxLw}A&$0J!Wk7_0{6`0Ok zT(M|dpZ#s^JL@YV_FwLs+1+_)^@k@CCwdhRJo)dv=bwsF`?|~8+pM**1Lt;kp1Aw9 z&V$RXcRaA_`Blq5c>JDkK0g!{B?P~}=ivMI&wPpGefjazl5u;_s-8PmKlv!gmiBGh zu{-OPyY9@ad%cMMhyTp?tKVAfdHUGN*B-g6;IX4c-?1O|ISO7J+;?DI-qgdd9rB}R zCzd|fJo@e0qleCApKZ^4^-o8K&wz7lwW07Ef4C8SbJ^CdVX2+{=4Tnd9*}I}I6u&g znb&}%?V?`(;M9t#2k7mNuO=^MoUApC%HBP;3f*+zLUX`38xMdARjV7r9i*4rK-%oCN?tND%;VaLN}fro zNA+$s*=VoX?jeoaH`e3Z9k`s}sn+IHv??Hglk{TTR%eroRj+Q#u_2N60492~}z6Rd|(4jaFYfZ;_(FW_P;NR*>wgG`)7~6|%01Ej5!)XJH`F zd>;2I?aR5Rm7$hiuc)H%=2Upvs!CqUzk;A}JE2HFTE#M4h+-0fkQA2-B+>>{ASY!) zfrvmw7;0@O!^+SFP+Ax5#auXw2XxPgc34=9L22y9FvQM1d7QCY&NTTbeghyeVB(_ zZ-YESu3&?vx#F&wE7hG>N8@WGQ+0rp352ju=P8r%khx@$)Q)jE+Y02r_^3!LEZAb8 z-K-35U2rEv=C{H*zF@3B=4Y-BKc)*V_qvm7;`cgT*Xg<@2Chl@dUsu?>zWw2Cgtnh z^?#!)=gMJK6q4Gd34*q09Xua@2#(f$E}Qvj75tUEnd8M$&w{YmoClB%w(}x zSy@@x+1Z@p;$pEFQL9x(qYlT-G);AOb_N0ip-?y)9gD}4)6-%EsFc8<%Qc(x9gZSj zJJQvy4D=fYLzc)eJsRttm<+11BJNl8$tJYq16 z*lgn+9p?uInBn06^?a8ar4-X8)!r_Urv1BsIfI%9*s>;sDMSsqK)hhOOfBf?{8NPbr~c5wvnNZ z@!|f&cyxODJfi}@1ON?yAAlhMMgW*(0S0~zYNnlLhJs9d+)x52G3Zr+um;2pfH4Aw z;xOG}CTL*74ra8Ai3dTd@G_uN1CxQ}z&Ra0ey?9M7{nuy&RA?Hk%%$SSD_7v+jCWZ zjv-iN371fDr9WvNn)XFz0;8A06U=zBBp=9%SQ>pbYwvQTNnEuI0V<;r<544Yts?BDj!-2QAQ(~l3 zh6GgNA+>l|hm0Bc2~#m+DPlTGn0_%6RxvRh!!RdL??}CJ$ne%}G=g>KK80_$Kt_X3 zQw1JddV38VWV>tbgJk8xcNV$%8Q{5nw?HAwtJPPtrgCp(gTk+rea}IWSzEQfK5N|B zvwry_+`J_-3^n%pA;Yo0MI7OVO>VYcaax;uvG1Ne+PT^Pl6hsZitG%%Dn<17%guzHNzX(q8N$2x)scXG7OPDStDqy@^E=j?FK z{EwXE-upfuzxR25&-1<~@7>+JRaE_&#u!U{m=IY)D9L0nLL+4e;5!%L2TCSTjPX8gC4EXKQU==2|* z*!~u1i=+#j1v~Qh4*hDw8c}24z2o`1-q*x;e(=H3og)h7Crb+dxVYcu-?IC=${;(> zJAUwyMep8v3a^%wJo@cIuDABigP9#~uikaG?6&;z;GH+loZYwaQLyCB6XT_u?>q4PLWQXz4J^ZUFLj z5NdUElUjWxADG2~NB7h<#_##*>t@rTgXTch=n58-S()sfvo8CM5`bHzexa!u+U~7k~#j|G-9a{Xr=}y;&LGSbuZw8RzQ;WmA z(&c}6Ztx@F(tgvAE=MlLi;D!kN6yUW@A>(gC)ytwkH?d-;)Gi@oxT{FDk`YW-})5s zO4F;WYGcHf1Jk<$hnM~3boz9k@}VdHz30;2IC-FFg|ExnoOt%a?!f8QM+1j$vEK2} z(%&q-_Zng8*7PfLDGqGe@`Iy?EDg_GRW{Ui;$T4IX&*p7|FaJ9;=MI6qOizkT%U zmB$ZXC^_#ddf~6fhtGivE1M$Gm)>3|czMBt4@RW~^W_iob`D6^u^eYLW2WUGWBWp< zc=+OvFFr(Vv;TAQi@Y<<#!=aclS>8bp8d2v`DNzU8~mzIUUk1;c4~P!?6(dA z_SgNo`;-{zs75X1CcL`S;ew3^K&`6Ng<^Kx!`Xz}2xlEP6C37o2umH;DAfscE;YWH zXx!$;4cpeXV%zMP!opRpEUoQSLI4NuK{=g{HYcU*tmEczmGC($M!1}uiN{{YyA{v&Z97B8b=Pt@etmNw*CVDijJt zAVNeUKD6LdT}}_$$#+tfS%?{odYr=Cgv&#aPEHmR-9)x~>bP8}=Uj=;;nL}@!aJ#1 z79bx;C+b3k)dIxfK<0W-o`wzxG8@qMdQh!!nIbJXMYg*!yrBbkdMf8aSg@=9u6B1@ zE*%So;BB}Ano@99;dN7Lnsm)qJ+c(o2!|`@1NjOj&j<}q*oFYrOa#eFv9amH>xF%_CLp@gL0M`KFw2)rvnyQs>;06zxhja)~_qq>x-Q+JL($*o#?Ip`cnU&uOxSQNnZ}wP?0eAwW(Jvr($uIO-wYtt8o2 z$IS-C$$DN@>)?X2pdPdy_23XxAd)DBLZwLBDwHY(0;NR8gIB>Ed(uK!yZ)DTcKL8> zXNulPP;maPoM>iE8St$$qnTkFky}h0PHtH!QEVm!3hlrxxi}%#j0)R~I&C=IKV}>D zik$eKW{~2jTquw#U>^uzGl)E6!Nc8Cg&ov$s*Yu<4U%*$ba!sn=_cR#X!Fq8Qi+yPKaFH z3TOGsZaP2UXSNPM;0zG@<|H@7?@hXH(se@&+>r6j?z&0W4KZ*-#y7j`|3+8owZjzd zg#UoN@Tm05uGc;Rpa3-A*V+J&TX}hT`T6+;1qJiw%_}S{EGjBuFc`(f#U&*rtjfwt zu^3USRR)6=!%P%K1_FUlXdn`a#^YnDRAy>Qi~v;)&}+*~rgFQT?e!tuJvE_z{b0l# z8>U7RJrk2*HIHGeDI>KkzmXlpssQB>;K=%nSy}Wcn*Af>l-Fnwn#J{fNz$^!qOj4A8^F z72@(r6${a`Ys^&|l4tabv0x3=uMP}p`(lRhs5zRlv1JvArn1Js(_%6csV2Mi-2>)< zC>c%oMsL7!~W;isR7@{ZR%yL;3&nTAJRBErm(1T(9UT>tQXLw*B5sgla zjb$EGS#sP!zj--q3)hEh11?xCO9?~Nq>`^rptItri{hXuqzEb1goi` zwEAu{1oK6D`bGvLsd!>)LIuoP24!IS&Fr9^*Y8sebsJ*+wvi!!a=1U8j89EnqE!GG z0iXZ~0x$%?2mq4|K*O(IP5UT%C`_l4`YJ$*L7xglH6W!2v;oj0i|!HAVLctS)1%#V zDh#rPmjSIB81)Q0#`1f4eL>A&7>mUMiNsJkouJ`d6*eIDm8pU(eVA>IR*|WiV8%2w z<&8~;M!$(p(8)|yIgqg#8iZ+5vF!%2&!!Ff?cqLuY^X00A4;d<^wfk*tEHoWP63*R zwdk%0_!u@bFdLa(a)hS)CnpV&h`2xG8y!`fOa{9h^Z7_I5|AMwm3T-k9@ZjbdS2RC zNt@ZUzl!b`(@_?-_OBOH{t8aG0+ z%HTVTvhqBz|G;ff$nZ4j8WKTRo#wrP^4?BU)5TiT;IFymJ^)$tN%>@0MOL1w*H0H5C7snOyXjz literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25843.png b/resources/g2/track/standup/25843.png new file mode 100644 index 0000000000000000000000000000000000000000..422182453e0184c188b98b4b72f9ccc226a3074f GIT binary patch literal 5038 zcmeHLe{dRg7XQ*TAx&C2P3}023MJK48M45V5FjaSNhFa{(vXu@+QVg8=t{^UOG?^! zO}+GtHCkGua%ZAZX&W_F+UXBG@djJ!r5aE4qUJ1WI!!0UQ_FSYG^h4%?+Z!Obk3QZ z&Yb_1;m3a8_r1@1@AKaK4!b+*S8EsL-INCaSX5VA-H`r;pS;{G_`O!V!^~Ptveo?S<@1r#b>QCjps{H-> z@3ZwcJyFQj9y@aS^q}?QV{flBu}v#}b`dQ-M0P{HGc zL1Es~S6=QvBU#*I{`tkwL@YN)yz{`xg`(ZRe($Z82S1O+Mk2X!k9sOO5tz)$s+{-0 zljIw9Z?33}koWga?daIQEe(~wi>}Ohr zzF&59|M-H_Z8@)fbToPjj4!JTg^zr2z4-M->(__NNY3k@u^#S|t>L=f(GHuJf|TQ1 zz2d%!UrcPEw>ZBU`<8XG-ZUhC>)2xPnmu2)1bkE83l~yx+6 zg5zZ?74L)jpdRU#|L2+S&yO2jsitgNC!gh_F+2vgv=1V^P3xnepR8?L;I z^0+WqPSS-r2*lm&$oNPTu3S-HS0#{^iZ4s*n=r2(8o(JKn{AYjzP!~)x(K5eOYL;QEEH{=A}H1 z6xCEENC(AFTh4Cl;Xv6iFIJ6t2?#2d%9Ij`Qd-t1DN~B!g+eG6E5&p4DI00u{J*r* z>%Lz zG1IV@SqU5!VdZuiZm*Epadf&FX3=TN?)70FVub_p z2)Tj{n&FDSbf#2yTp5jTBayBHq)Y@mZ4PAuWF}c8ePUe7wi5X-J}NT`bB-8jH!Xul z7d#1(*`siVFBt1j`I@Q2Pw9fszvkqs_`OEgHM*{ffvZx!)?L@=x+(^)O8HuM{om-y zyL>Z6G{b*DK6tBi?kFGu$O84N8f)O~7K_E2H*a26R@VIa^Ru(Fb8>RnY<6yL?t%pi zxW&cAD2iw_YNJty<7S$sIyyQ6fxb{E9E%Mn5~;~a6ai`#FzE8l<^rda=W9bcyHtT5 zLx0E;iPA&yuFtmwPBDA1b%|#46m8C>W2~F)N?pM)0nvMZocf=SRvV;>3p1cUr7ORXx9WFOh8miOK z*=OksQ{i}fEYTfL_K!|QIciW~1Y8H;wSf{pTi(ajhDyv)H5E5?jncuCKgJv~2n%p| zkxwh^GO7A;O@ubaJMfVJJvPvhiUy|Q1I$>AQy?!9nozkzt??O+T{zz3^M$&)qJ4ew zaCmfhIF(8rgO|3O!^`z|L|le`NPN*lP~0Otj1e#tm+3;8pn(ZH znW0W55d`VN%YjYMGkWrk%8`bY#^D4F_WWmosJ0u zCIJ`*)}phhqmAvb0E>y^qXrqKXKc(E3ZXrLwxJ=7*=%$=@wPS!MLOh2K#dM)(5Ma> zHVBiZV#dN_+Dn)olnJYuxQ=0%lb=46e&oRNHmo*+<>P;YkG25Is?%13N3w6Jg^LC5 z+I5hueE7^Fzkmgv>HQ@Xvb}Zs8umo~jU3i3w`jmQD5|ZiUeTC4qJR9@qHW@ZSrNvw z{LHGAXAi%`nZNzct{b-eMyz9p9N+xML>bL4(7 iT$z7h&2wivi#~iBIr6ANvJPT`x|-G1udTfAxBmem6kt67 literal 0 HcmV?d00001 diff --git a/resources/g2/track/standup/25844.png b/resources/g2/track/standup/25844.png new file mode 100644 index 0000000000000000000000000000000000000000..dd1f913620553ec33b8b950dd058ec3ab369ba1c GIT binary patch literal 5070 zcmeHLe{@sT9lxct=?@@kyH)I1LW&ERr7y`#lQwCIC9R>vlG=0x2`s+6yo6_(yqK3Z zh3Kk_$AUd0U}0glTL*!47_>4bQKKhdz@ptTo`bGRoaI(LswfIz}wRE)SgQcf2YwWQmt-jQme1!1G5--VprYj`29aRWilSz|1*~IkJSyEfBX4<-j0LMHon|)w&+F0 z-i_bpHQ)1GX_@B4E9cIQm_Iym>R|)RP=Ci2@K~p-)wAm^CRn=RWS8rcfOq=G-ZY>> zZKFP~l@-1YOn9PfDiZ}Iq8v>@SDO{XSBmRSn ztoLqO`n#oz-g$P-H=iDkOH#u3)*O6$!}NJ%!TAsONXN(>OLyG6Z0FOUuxj^1Pi-%F z@xB%Lt$*gw{|cPFy6m-O?mZ_?A9?b=(rw2$SJ=Ps+Drd1G;rYl1(UxxayTG5H=g%= z$LO~!j~%{Hc+Qvq(g(+4XTgP)O~a8_-oI1y>cWj1BUL2()lYJs8I(R$=6FYQ#<(1$ zZI_yB9+~{%{#xJspaQ2Hm6(Mx6O~;K7i>HLYE@k>47U>=u9>ir&N^N?8sl+EOC8Tp)hudu zsfo?x>aA`ziA+YRXM;rIpf3k+89g?3D0U7IACc7OSGQ;elBScvr{U?D4o12;%j6E4^qX<+dT> znwlC!Btaw+Aw&r2Elv;CC3Mmi8HyQ>27<=jq{~B6PHu)1GgBR&Ivx+sbFanca5Xny zr+3n`DnLDuF3g39D@BOIfy}j_J&m1^WHzAhw4mGIGDTVmn(A=lL}Mr6^i<5Hu;AD2 zT^;WBY&sSkA=(KCgwoKf_$HT{rskIG78wa_q{Ef9f@0r<^pMsYV%-#5W+t1?+(4lD zb>5rM*K*H-A*#7q(LmuHnedt#>UbId3JZmk7RAh^OjK==Nl~FpPE-k{HS%hqSthp% z%~FXJg&#sHk`JVCZd4g63#5|EP)oH;CKpzt60uM!7h%F`j6j7}+#;M=*&!}FbbFslorc$DkR8Sz-$z1H-UL5 zcN;~u*YPqzaWj_Jr<>t|vS1#p0rL=$R3woq#A1b{s!d#_5J?nLu|OnJi00ra3u)c* zztEZG!>yeu`f8Gf{iw=C+;8E+#HFyDStKK9d5CbrP0roRDi~3g3)5 zZ3NsuW*hd}IQbpTfLie?Tq3CvTBOympNJYQnVYNhTskT;Iq%zEWGdoRLJzmUB z)Z3trP%GG=S*^IsXG^u>X1sSZk*NceOehu$=SapwW|KuSJI1waYmxubqc#hev&BHW znK8I^!JQDfz7@{umDzN@$JcBfzDEy``nHo>()YGpx8=Ge1#Ss^ySr}7bxR7|68Ls^ z{omv&x^b8yobVrz7ao;rM#G;1kPBKKY-@zat(=^kdGqGw=H||yKR+)oFF!w@#bOl{ z6ciQ~mQ_?#peUkNtMqy;jvHy3^85Y4;Nb9ZBpyGLOs1!%Pz0!yK&LG>8cXbUj@O6u z^eTh>x}jlHG)9jmddDY1Y5~ijET*(&-3Cqo=MU28QNKDCG>i^Y$&sE^GBllzYs!I1 z0K6&?(6fdpR;-sjHdHb-TF#^pX3E4|4lqo-0stKVCKiigv%Aa71AKl+sXVIFjo55s z-Q5=l2box`94)C(l_5Hg(!|$L0z)^72b6Tb+8@^TMfIUkQzU8Q$jcE;g;Foj;&LOU zrh0TegQmd<6-ji*lYNQQ(D-zWtpX)_P-X)hAK(XA^1(9AFy9zcQ3*ruI2}p{;>=N< zpahqfdo_YygK`L0M`?Y+kB?^A_)^wECXNVt0})}I=S zPfcB9Q~($NpaBQ~5C&ibfC(00;9I9=d^8gdG08CecjP;Um_k(CF9K0xLm7c zB7jK(hJm%{DfjzWHWM%z*j{RcVfrT~^uxnwf6zBNsx}(+c02C#Q7Gb<^CniUGXM0wmk>uP2d!_MFT=p0Fa4zjsXv{sz`5$`Vf8>)uFwQ#{AC-KU??a9{PnbbMb~Rdfuhp&fR^rG51R3&=TknG&Qbm Kcxlxmzx)q4*K6?r literal 0 HcmV?d00001 diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index 3449239987..dc29987901 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -116,6 +116,191 @@ static inline uint32_t rctc_to_rct2_index(uint32_t image) } // clang-format on +static void OverrideElementOffsets(size_t index, G1Element& element) +{ + switch (index) + { + case 25285: + element.x_offset -= 1; + break; + case 25286: + case 25317: + case 25318: + case 25323: + case 25324: + case 25325: + case 25326: + case 25455: + case 25456: + case 25457: + case 25458: + case 25459: + case 25460: + case 25461: + case 25462: + case 25463: + case 25464: + case 25465: + case 25466: + case 25467: + case 25468: + case 25469: + case 25470: + case 25471: + case 25472: + case 25473: + case 25474: + case 25475: + case 25476: + case 25521: + case 25522: + case 25523: + case 25524: + case 25525: + case 25526: + case 25527: + case 25528: + case 25529: + case 25530: + case 25531: + case 25532: + case 25533: + case 25534: + case 25659: + case 25660: + case 25661: + case 25662: + case 25663: + case 25664: + case 25665: + case 25666: + case 25667: + case 25668: + case 25669: + case 25670: + case 25671: + case 25672: + case 25673: + case 25674: + case 25675: + case 25676: + case 25677: + case 25678: + case 25679: + case 25680: + case 25681: + case 25682: + case 25683: + case 25684: + case 25685: + case 25686: + case 25687: + case 25688: + case 25689: + case 25690: + case 25719: + case 25721: + case 25723: + case 25725: + case 25727: + case 25728: + case 25730: + case 25732: + case 25733: + case 25735: + case 25737: + case 25738: + case 25740: + case 25742: + case 25743: + case 25745: + case 25747: + case 25748: + case 25781: + case 25782: + case 25783: + case 25784: + case 25785: + case 25786: + case 25787: + case 25788: + case 25789: + case 25790: + case 25791: + case 25792: + case 25793: + case 25794: + case 25795: + case 25796: + case 25797: + case 25798: + case 25799: + case 25800: + case 25801: + case 25803: + case 25804: + case 25805: + case 25806: + case 25807: + case 25808: + case 25809: + case 25810: + case 25811: + case 25812: + case 25813: + case 25814: + case 25815: + case 25816: + case 25817: + case 25818: + case 25819: + case 25820: + case 25821: + case 25822: + case 25823: + case 25824: + case 25825: + case 25826: + case 25827: + case 25828: + case 25829: + case 25830: + case 25831: + case 25832: + case 25833: + case 25834: + case 25835: + case 25836: + case 25837: + case 25838: + case 25839: + case 25840: + case 25841: + case 25842: + case 25843: + case 25844: + case 25845: + case 25846: + case 25847: + case 25848: + case 25849: + case 25850: + case 25851: + case 25852: + element.y_offset += 1; + break; + case 25307: + case 25315: + case 25319: + element.x_offset -= 1; + element.y_offset += 1; + break; + case 25802: + element.y_offset += 2; + break; + } +} + static void ReadAndConvertGxDat(IStream* stream, size_t count, bool is_rctc, G1Element* elements) { auto g1Elements32 = std::make_unique(count); @@ -290,6 +475,7 @@ bool GfxLoadG1(const IPlatformEnvironment& env) for (uint32_t i = 0; i < _g1.header.num_entries; i++) { _g1.elements[i].offset += reinterpret_cast(_g1.data.get()); + OverrideElementOffsets(i, _g1.elements[i]); } return true; } diff --git a/src/openrct2/paint/track/coaster/StandUpRollerCoaster.cpp b/src/openrct2/paint/track/coaster/StandUpRollerCoaster.cpp index 2d6a0d4c10..6a72094b3f 100644 --- a/src/openrct2/paint/track/coaster/StandUpRollerCoaster.cpp +++ b/src/openrct2/paint/track/coaster/StandUpRollerCoaster.cpp @@ -236,12 +236,12 @@ static void StandUpRCTrack60DegUp( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25398), { 0, 6, height }, - { { 29, 10, height }, { 1, 10, 75 } }); + { { 0, 27, height }, { 32, 1, 98 } }); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25390), { 0, 6, height }, - { { 29, 10, height }, { 1, 10, 75 } }); + { { 0, 27, height }, { 32, 1, 98 } }); break; case 3: PaintAddImageAsParentRotated( @@ -250,7 +250,7 @@ static void StandUpRCTrack60DegUp( } if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) { - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 32, height, session.SupportColours); + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 26, height, session.SupportColours); } } else @@ -264,12 +264,12 @@ static void StandUpRCTrack60DegUp( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25244), { 0, 6, height }, - { { 29, 10, height }, { 1, 10, 75 } }); + { { 0, 27, height }, { 32, 1, 98 } }); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25236), { 0, 6, height }, - { { 29, 10, height }, { 1, 10, 75 } }); + { { 0, 27, height }, { 32, 1, 98 } }); break; case 3: PaintAddImageAsParentRotated( @@ -278,7 +278,7 @@ static void StandUpRCTrack60DegUp( } if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) { - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 32, height, session.SupportColours); + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 26, height, session.SupportColours); } } if (direction == 0 || direction == 3) @@ -378,18 +378,18 @@ static void StandUpRCTrack25DegUpTo60DegUp( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25411), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25402), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25409), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25392), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 3: PaintAddImageAsParentRotated( @@ -412,18 +412,18 @@ static void StandUpRCTrack25DegUpTo60DegUp( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25277), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25248), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25275), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25238), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 3: PaintAddImageAsParentRotated( @@ -463,18 +463,18 @@ static void StandUpRCTrack60DegUpTo25DegUp( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25412), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25408), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25410), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25394), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 3: PaintAddImageAsParentRotated( @@ -497,18 +497,18 @@ static void StandUpRCTrack60DegUpTo25DegUp( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25278), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25254), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25276), { 0, 6, height }, - { { 0, 10, height }, { 32, 10, 43 } }); + { { 0, 27, height }, { 32, 1, 66 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25240), { 0, 6, height }, - { { 0, 4, height }, { 32, 2, 43 } }); + { { 0, 6, height }, { 32, 20, 3 } }); break; case 3: PaintAddImageAsParentRotated( @@ -849,24 +849,40 @@ static void StandUpRCTrackFlatToLeftBank( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25281), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25286), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25280), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25283), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, 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); @@ -882,24 +898,40 @@ static void StandUpRCTrackFlatToRightBank( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25279), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25284), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25282), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25285), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, 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); @@ -915,24 +947,40 @@ static void StandUpRCTrackLeftBankToFlat( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25282), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25285), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25279), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25284), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, 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); @@ -948,24 +996,40 @@ static void StandUpRCTrackRightBankToFlat( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25280), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25283), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25281), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25286), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, 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); @@ -983,29 +1047,36 @@ static void StandUpRCTrackBankedLeftQuarterTurn5( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25464), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25464), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25475), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25469), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25474), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25459), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25459), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -1028,17 +1099,17 @@ static void StandUpRCTrackBankedLeftQuarterTurn5( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25463), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25463), { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25468), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25468), { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 1 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25473), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25473), { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); break; case 3: @@ -1062,7 +1133,7 @@ static void StandUpRCTrackBankedLeftQuarterTurn5( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25462), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25462), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; case 1: @@ -1072,12 +1143,12 @@ static void StandUpRCTrackBankedLeftQuarterTurn5( break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25472), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25472), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25457), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25457), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); break; } @@ -1099,17 +1170,17 @@ static void StandUpRCTrackBankedLeftQuarterTurn5( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25461), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25461), { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25466), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25466), { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 32, 1 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25471), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25471), { 0, 0, height }, { { 0, 0, height }, { 16, 32, 3 } }); break; case 3: @@ -1135,27 +1206,34 @@ static void StandUpRCTrackBankedLeftQuarterTurn5( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25460), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25465), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25470), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25470), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25476), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25455), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25455), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); switch (direction) { case 2: @@ -1197,24 +1275,40 @@ static void StandUpRCTrackLeftBankTo25DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25315), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25316), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25317), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25318), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); - } if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -1237,24 +1331,40 @@ static void StandUpRCTrackRightBankTo25DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25319), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25320), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25321), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25322), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); - } if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -1277,24 +1387,40 @@ static void StandUpRCTrack25DegUpToLeftBank( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25311), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25312), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25313), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25314), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 9, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); - } if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::Flat); @@ -1317,24 +1443,40 @@ static void StandUpRCTrack25DegUpToRightBank( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25307), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 9, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25308), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25309), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25310), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); - } if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::Flat); @@ -1389,24 +1531,40 @@ static void StandUpRCTrackLeftBank( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25323), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25324), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + } break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25325), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + } break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25326), { 0, 6, height }, { 32, 20, 3 }); + if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) + { + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); + } break; } - if (TrackPaintUtilShouldPaintSupports(session.MapPosition)) - { - MetalASupportsPaintSetup(session, supportType.metal, 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); @@ -2369,21 +2527,28 @@ static void StandUpRCTrackLeftVerticalLoop( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25477), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25485), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25484), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25492), { 0, 6, height }, { 32, 20, 7 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); @@ -2405,11 +2570,12 @@ static void StandUpRCTrackLeftVerticalLoop( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25478), { 0, 0, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 20, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 22, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25486), { 0, 14, height }, { 32, 2, 63 }); + session, direction, session.TrackColours.WithIndex(25486), { 0, 14, height }, + { { 0, 27, height }, { 32, 2, 63 } }); MetalASupportsPaintSetup( session, supportType.metal, MetalSupportPlace::Centre, 15, height, session.SupportColours); break; @@ -2423,7 +2589,7 @@ static void StandUpRCTrackLeftVerticalLoop( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25491), { 0, 6, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 16, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; } PaintUtilSetSegmentSupportHeight( @@ -2575,17 +2741,18 @@ static void StandUpRCTrackLeftVerticalLoop( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25491), { 0, 6, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 16, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25478), { 0, 0, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 20, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 22, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25486), { 0, 14, height }, { 32, 2, 63 }); + session, direction, session.TrackColours.WithIndex(25486), { 0, 14, height }, + { { 0, 27, height }, { 32, 2, 63 } }); MetalASupportsPaintSetup( session, supportType.metal, MetalSupportPlace::Centre, 15, height, session.SupportColours); break; @@ -2656,21 +2823,28 @@ static void StandUpRCTrackRightVerticalLoop( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25508), { 0, 6, height }, { 32, 20, 7 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25500), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25501), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25493), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height - 8, kTunnelGroup, TunnelSubType::SlopeStart); @@ -2684,7 +2858,7 @@ static void StandUpRCTrackRightVerticalLoop( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25507), { 0, 6, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 16, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -2694,7 +2868,8 @@ static void StandUpRCTrackRightVerticalLoop( break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25502), { 0, 14, height }, { 32, 2, 63 }); + session, direction, session.TrackColours.WithIndex(25502), { 0, 14, height }, + { { 0, 27, height }, { 32, 2, 63 } }); MetalASupportsPaintSetup( session, supportType.metal, MetalSupportPlace::Centre, 15, height, session.SupportColours); break; @@ -2702,7 +2877,7 @@ static void StandUpRCTrackRightVerticalLoop( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25494), { 0, 0, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 20, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 22, height, session.SupportColours); break; } PaintUtilSetGeneralSupportHeight(session, height + 72); @@ -2806,7 +2981,8 @@ static void StandUpRCTrackRightVerticalLoop( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25502), { 0, 14, height }, { 32, 2, 63 }); + session, direction, session.TrackColours.WithIndex(25502), { 0, 14, height }, + { { 0, 27, height }, { 32, 2, 63 } }); MetalASupportsPaintSetup( session, supportType.metal, MetalSupportPlace::Centre, 15, height, session.SupportColours); break; @@ -2814,13 +2990,13 @@ static void StandUpRCTrackRightVerticalLoop( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25494), { 0, 0, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 20, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 22, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25507), { 0, 6, height }, { 32, 26, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 16, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( @@ -2881,21 +3057,28 @@ static void StandUpRCTrackLeftQuarterTurn3( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25514), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25517), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25520), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25511), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -2949,21 +3132,28 @@ static void StandUpRCTrackLeftQuarterTurn3( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25512), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25515), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25518), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25509), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); switch (direction) { case 2: @@ -3007,29 +3197,36 @@ static void StandUpRCTrackLeftQuarterTurn3Bank( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25526), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25526), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25533), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25529), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25532), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25523), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25523), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -3057,7 +3254,7 @@ static void StandUpRCTrackLeftQuarterTurn3Bank( break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25528), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25528), { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 16, 1 } }); break; case 2: @@ -3088,27 +3285,34 @@ static void StandUpRCTrackLeftQuarterTurn3Bank( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25524), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25527), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25530), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25530), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25534), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25521), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25521), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); switch (direction) { case 2: @@ -3155,22 +3359,28 @@ static void StandUpRCTrackLeftQuarterTurn325DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25562), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 13, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25564), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25566), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25560), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); break; } - MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); } else { @@ -3179,22 +3389,28 @@ static void StandUpRCTrackLeftQuarterTurn325DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25546), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 13, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25548), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25550), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25544), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); break; } - MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); } if (direction == 0 || direction == 3) { @@ -3224,22 +3440,28 @@ static void StandUpRCTrackLeftQuarterTurn325DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25561), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25563), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25565), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25559), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; } - MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); } else { @@ -3248,22 +3470,28 @@ static void StandUpRCTrackLeftQuarterTurn325DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25545), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25547), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25549), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25543), { 6, 0, height }, { 20, 32, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; } - MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); } switch (direction) { @@ -3302,22 +3530,28 @@ static void StandUpRCTrackRightQuarterTurn325DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25551), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25553), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25555), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25557), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 13, height, session.SupportColours); break; } - MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); } else { @@ -3326,22 +3560,28 @@ static void StandUpRCTrackRightQuarterTurn325DegUp( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25535), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25537), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25539), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25541), { 0, 6, height }, { 32, 20, 3 }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 13, height, session.SupportColours); break; } - MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); } if (direction == 0 || direction == 3) { @@ -3378,7 +3618,7 @@ static void StandUpRCTrackRightQuarterTurn325DegUp( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25554), { 6, 0, height }, { 20, 32, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( @@ -3390,7 +3630,7 @@ static void StandUpRCTrackRightQuarterTurn325DegUp( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25558), { 6, 0, height }, { 20, 32, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; } } @@ -3408,7 +3648,7 @@ static void StandUpRCTrackRightQuarterTurn325DegUp( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25538), { 6, 0, height }, { 20, 32, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( @@ -3420,7 +3660,7 @@ static void StandUpRCTrackRightQuarterTurn325DegUp( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25542), { 6, 0, height }, { 20, 32, 3 }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; } } @@ -3509,18 +3749,19 @@ static void StandUpRCTrackHalfLoopUp( session, direction, session.TrackColours.WithIndex(25576), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::Centre, 20, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::Centre, 15, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25584), { 0, 14, height }, { 32, 2, 63 }); + session, direction, session.TrackColours.WithIndex(25584), { 0, 14, height }, + { { 0, 6, height + 68 }, { 32, 20, 3 } }); MetalASupportsPaintSetup( session, supportType.metal, MetalSupportPlace::Centre, 15, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25581), { 0, 6, height }, - { { 0, 20, height }, { 32, 2, 3 } }); + { { 0, 6, height + 68 }, { 32, 20, 3 } }); MetalASupportsPaintSetup( session, supportType.metal, MetalSupportPlace::Centre, 16, height, session.SupportColours); break; @@ -3635,9 +3876,7 @@ static void StandUpRCTrackLeftCorkscrewUp( { { 0, 6, height + 4 }, { 32, 20, 3 } }); break; } - - TrackPaintUtilLeftCorkscrewUpSupports(session, direction, height); - + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -3752,7 +3991,7 @@ static void StandUpRCTrackRightCorkscrewUp( { { 0, 6, height + 4 }, { 32, 20, 3 } }); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); + MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -3872,29 +4111,36 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25844), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25844), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25851), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25847), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25850), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25841), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -3917,7 +4163,7 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25843), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25843), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 1: @@ -3953,11 +4199,15 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25842), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25845), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( @@ -3966,14 +4216,17 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25852), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25839), { 0, 0, height }, { { 6, 0, height + 8 }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); switch (direction) { case 2: @@ -4000,27 +4253,34 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25841), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25844), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25844), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25851), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25847), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25850), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); switch (direction) { case 0: @@ -4053,7 +4313,7 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25843), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25843), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; case 2: @@ -4084,16 +4344,22 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25839), { 0, 0, height }, { { 0, 6, height + 8 }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25842), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25845), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( @@ -4102,9 +4368,10 @@ static void StandUpRCTrackLeftHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25852), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); @@ -4134,29 +4401,36 @@ static void StandUpRCTrackRightHalfBankedHelixUpSmall( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25825), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25825), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25828), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25831), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25834), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25834), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25838), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -4194,7 +4468,7 @@ static void StandUpRCTrackRightHalfBankedHelixUpSmall( break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25835), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25835), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; } @@ -4213,8 +4487,10 @@ static void StandUpRCTrackRightHalfBankedHelixUpSmall( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25827), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25827), { 0, 0, height }, { { 6, 0, height + 8 }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -4223,19 +4499,24 @@ static void StandUpRCTrackRightHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25837), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25833), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25836), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); switch (direction) { case 0: @@ -4262,27 +4543,34 @@ static void StandUpRCTrackRightHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25828), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25831), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25834), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25834), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25838), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25825), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25825), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 2, height, session.SupportColours); switch (direction) { case 2: @@ -4320,7 +4608,7 @@ static void StandUpRCTrackRightHalfBankedHelixUpSmall( break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25835), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25835), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; case 3: @@ -4349,24 +4637,31 @@ static void StandUpRCTrackRightHalfBankedHelixUpSmall( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25837), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25833), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25836), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25827), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25827), { 0, 0, height }, { { 0, 6, height + 8 }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 8, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 6, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); @@ -4426,29 +4721,36 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25812), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25812), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25823), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25817), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25822), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25807), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25807), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -4471,17 +4773,17 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25811), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25811), { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25816), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25816), { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 1 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25821), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25821), { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); break; case 3: @@ -4505,22 +4807,22 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25810), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25810), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25815), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 1 } }); + { { 16, 16, height + 29 }, { 16, 16, 1 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25820), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25820), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25805), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25805), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); break; } @@ -4542,13 +4844,13 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25809), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25809), { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25814), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 32, 1 } }); + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25814), { 0, 0, height }, + { { 0, 0, height + 29 }, { 16, 32, 1 } }); break; case 2: PaintAddImageAsParentRotated( @@ -4578,11 +4880,15 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25808), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25813), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( @@ -4591,14 +4897,17 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25824), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25803), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25803), { 0, 0, height }, { { 6, 0, height + 8 }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); switch (direction) { case 2: @@ -4623,29 +4932,36 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25807), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25807), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 3, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25812), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25812), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25823), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25817), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25822), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); switch (direction) { case 0: @@ -4678,17 +4994,17 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25811), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25811), { 0, 0, height }, { { 0, 0, height }, { 16, 32, 3 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25816), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25816), { 0, 0, height }, { { 0, 0, height + 27 }, { 16, 32, 1 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25821), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25821), { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); break; } @@ -4707,12 +5023,12 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25805), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25805), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25810), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25810), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 2: @@ -4722,7 +5038,7 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25820), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25820), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; } @@ -4748,12 +5064,12 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25809), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25809), { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25814), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25814), { 0, 0, height }, { { 0, 0, height + 27 }, { 32, 16, 1 } }); break; case 3: @@ -4777,18 +5093,24 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25803), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25803), { 0, 0, height }, { { 0, 6, height + 8 }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25808), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25813), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( @@ -4797,9 +5119,10 @@ static void StandUpRCTrackLeftHalfBankedHelixUpLarge( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25824), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); @@ -4829,29 +5152,36 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25781), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25781), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25786), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25791), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25796), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25796), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25802), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -4879,17 +5209,17 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25787), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25787), { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25792), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 1 } }); + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25792), { 0, 0, height }, + { { 0, 0, height + 29 }, { 32, 16, 1 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25797), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25797), { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); break; } @@ -4908,22 +5238,22 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25783), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25783), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25788), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25788), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25793), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 1 } }); + { { 16, 16, height + 29 }, { 16, 16, 1 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25798), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25798), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; } @@ -4954,12 +5284,12 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25794), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 32, 1 } }); + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25794), { 0, 0, height }, + { { 0, 0, height + 29 }, { 16, 32, 1 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25799), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25799), { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); break; } @@ -4978,8 +5308,10 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25785), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25785), { 0, 0, height }, { { 6, 0, height + 8 }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -4988,19 +5320,24 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25801), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25795), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25800), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); switch (direction) { case 0: @@ -5027,27 +5364,34 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25786), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 5, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25791), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25796), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25796), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25802), { 0, 0, height }, { { 27, 0, height }, { 1, 32, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25781), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25781), { 0, 0, height }, { { 6, 0, height }, { 20, 32, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 1, height, session.SupportColours); switch (direction) { case 2: @@ -5075,17 +5419,17 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25787), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25787), { 0, 0, height }, { { 16, 0, height }, { 16, 32, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25792), { 0, 0, height }, - { { 0, 0, height + 27 }, { 16, 32, 1 } }); + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25792), { 0, 0, height }, + { { 0, 0, height + 29 }, { 16, 32, 1 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25797), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25797), { 0, 0, height }, { { 0, 0, height }, { 16, 32, 3 } }); break; case 3: @@ -5109,22 +5453,22 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25788), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25788), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25793), { 0, 0, height }, - { { 16, 16, height + 27 }, { 16, 16, 1 } }); + { { 16, 16, height + 29 }, { 16, 16, 1 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25798), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25798), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25783), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25783), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); break; } @@ -5151,12 +5495,12 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25794), { 0, 0, height }, - { { 0, 0, height + 27 }, { 32, 16, 1 } }); + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25794), { 0, 0, height }, + { { 0, 0, height + 29 }, { 32, 16, 1 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25799), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25799), { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); break; case 3: @@ -5185,24 +5529,31 @@ static void StandUpRCTrackRightHalfBankedHelixUpLarge( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25801), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25795), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25800), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 11, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25785), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25785), { 0, 0, height }, { { 0, 6, height + 8 }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 10, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 7, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height + 8, kTunnelGroup, TunnelSubType::Flat); @@ -5670,24 +6021,31 @@ static void StandUpRCTrackLeftEighthBankToDiag( PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25675), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25679), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25683), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25687), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25687), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -5701,17 +6059,17 @@ static void StandUpRCTrackLeftEighthBankToDiag( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25676), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25676), { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25680), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25680), { 0, 0, height }, { { 0, 0, height + 27 }, { 34, 16, 0 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25684), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25684), { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); break; case 3: @@ -5735,7 +6093,7 @@ static void StandUpRCTrackLeftEighthBankToDiag( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25677), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25677), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; case 1: @@ -5745,12 +6103,12 @@ static void StandUpRCTrackLeftEighthBankToDiag( break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25685), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25685), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25689), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25689), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); break; } @@ -5794,7 +6152,7 @@ static void StandUpRCTrackLeftEighthBankToDiag( break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25686), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25686), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); MetalASupportsPaintSetup( session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); @@ -5804,7 +6162,7 @@ static void StandUpRCTrackLeftEighthBankToDiag( session, direction, session.TrackColours.WithIndex(25690), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); break; } PaintUtilSetSegmentSupportHeight( @@ -5832,26 +6190,33 @@ static void StandUpRCTrackRightEighthBankToDiag( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25659), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25659), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25663), { 0, 0, height }, { { 0, 6, height }, { 32, 20, 3 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 4, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25667), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25671), { 0, 0, height }, { { 0, 27, height }, { 32, 1, 26 } }); + MetalASupportsPaintSetup( + session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); break; } - MetalASupportsPaintSetup(session, supportType.metal, MetalSupportPlace::Centre, 0, height, session.SupportColours); if (direction == 0 || direction == 3) { PaintUtilPushTunnelRotated(session, direction, height, kTunnelGroup, TunnelSubType::Flat); @@ -5870,17 +6235,17 @@ static void StandUpRCTrackRightEighthBankToDiag( break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25664), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25664), { 0, 0, height }, { { 0, 16, height }, { 32, 16, 3 } }); break; case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25668), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25668), { 0, 0, height }, { { 0, 0, height + 27 }, { 34, 16, 0 } }); break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25672), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25672), { 0, 0, height }, { { 0, 0, height }, { 32, 16, 3 } }); break; } @@ -5899,12 +6264,12 @@ static void StandUpRCTrackRightEighthBankToDiag( { case 0: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25661), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25661), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25665), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25665), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); break; case 2: @@ -5914,7 +6279,7 @@ static void StandUpRCTrackRightEighthBankToDiag( break; case 3: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25673), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25673), { 0, 0, height }, { { 0, 16, height }, { 16, 16, 3 } }); break; } @@ -5947,14 +6312,14 @@ static void StandUpRCTrackRightEighthBankToDiag( session, direction, session.TrackColours.WithIndex(25662), { 0, 0, height }, { { 16, 0, height }, { 16, 16, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(25666), { 0, 0, height }, + session, direction, session.TrackColours.WithIndex(SPR_G2_STANDUP_TRACK_25666), { 0, 0, height }, { { 0, 0, height }, { 16, 16, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 1, height, session.SupportColours); break; case 2: PaintAddImageAsParentRotated( @@ -6019,38 +6384,17 @@ static void StandUpRCTrackDiagBrakes( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - TrackPaintUtilDiagTilesPaint( - session, 3, height, direction, trackSequence, StandupRCDiagBrakeImages, defaultDiagTileOffsets, defaultDiagBoundLengths, - nullptr); - - if (trackSequence == 3) - { - MetalASupportsPaintSetup( - session, supportType.metal, kDiagSupportPlacement[direction], 8, height, session.SupportColours); - } - - int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence]; - PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + TrackPaintUtilDiagTilesPaintExtra( + session, 3, height, direction, trackSequence, StandupRCDiagBrakeImages, supportType.metal); } static void StandUpRCTrackDiagBlockBrakes( PaintSession& session, const Ride& ride, uint8_t trackSequence, uint8_t direction, int32_t height, const TrackElement& trackElement, SupportType supportType) { - TrackPaintUtilDiagTilesPaint( + TrackPaintUtilDiagTilesPaintExtra( session, 3, height, direction, trackSequence, StandupRCDiagBlockBrakeImages[trackElement.IsBrakeClosed()], - defaultDiagTileOffsets, defaultDiagBoundLengths, nullptr); - - if (trackSequence == 3) - { - MetalASupportsPaintSetup( - session, supportType.metal, kDiagSupportPlacement[direction], 8, height, session.SupportColours); - } - - int32_t blockedSegments = BlockedSegments::kDiagStraightFlat[trackSequence]; - PaintUtilSetSegmentSupportHeight(session, PaintUtilRotateSegments(blockedSegments, direction), 0xFFFF, 0); - PaintUtilSetGeneralSupportHeight(session, height + kDefaultGeneralSupportHeight); + supportType.metal); } /** rct2: 0x008A7524 */ @@ -6165,7 +6509,7 @@ static void StandUpRCTrackDiag25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 8, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 9, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6190,7 +6534,7 @@ static void StandUpRCTrackDiag25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 8, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 9, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6334,7 +6678,7 @@ static void StandUpRCTrackDiag60DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 32, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 36, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6345,11 +6689,11 @@ static void StandUpRCTrackDiag60DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 32, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 36, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::BottomCorner, 36, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::BottomCorner, 34, height, session.SupportColours); break; } } @@ -6359,7 +6703,7 @@ static void StandUpRCTrackDiag60DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 32, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 36, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6370,11 +6714,11 @@ static void StandUpRCTrackDiag60DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 32, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 36, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::BottomCorner, 36, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::BottomCorner, 34, height, session.SupportColours); break; } } @@ -6503,7 +6847,7 @@ static void StandUpRCTrackDiagFlatTo25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6514,7 +6858,7 @@ static void StandUpRCTrackDiagFlatTo25DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( @@ -6528,7 +6872,7 @@ static void StandUpRCTrackDiagFlatTo25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6539,7 +6883,7 @@ static void StandUpRCTrackDiagFlatTo25DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( @@ -6841,7 +7185,7 @@ static void StandUpRCTrackDiag60DegUpTo25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 21, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 23, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6852,7 +7196,7 @@ static void StandUpRCTrackDiag60DegUpTo25DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 21, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 23, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( @@ -6866,7 +7210,7 @@ static void StandUpRCTrackDiag60DegUpTo25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 21, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 23, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -6877,7 +7221,7 @@ static void StandUpRCTrackDiag60DegUpTo25DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 21, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 23, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( @@ -7010,7 +7354,7 @@ static void StandUpRCTrackDiag25DegUpToFlat( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 6, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -7021,7 +7365,7 @@ static void StandUpRCTrackDiag25DegUpToFlat( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 6, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( @@ -7035,7 +7379,7 @@ static void StandUpRCTrackDiag25DegUpToFlat( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 6, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -7046,7 +7390,7 @@ static void StandUpRCTrackDiag25DegUpToFlat( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 6, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( @@ -8157,11 +8501,11 @@ static void StandUpRCTrackDiagFlatToLeftBank( session, direction, session.TrackColours.WithIndex(25724), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 2, height, session.SupportColours); break; case 2: MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); break; case 3: MetalASupportsPaintSetup( @@ -8252,14 +8596,14 @@ static void StandUpRCTrackDiagFlatToRightBank( { case 0: MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 3, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25729), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 1, height, session.SupportColours); break; case 2: MetalASupportsPaintSetup( @@ -8361,7 +8705,7 @@ static void StandUpRCTrackDiagLeftBankToFlat( session, direction, session.TrackColours.WithIndex(25731), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 1, height, session.SupportColours); break; case 2: MetalASupportsPaintSetup( @@ -8558,7 +8902,7 @@ static void StandUpRCTrackDiagLeftBankTo25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 1, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -8569,11 +8913,11 @@ static void StandUpRCTrackDiagLeftBankTo25DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 1, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::BottomCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::BottomCorner, 2, height, session.SupportColours); break; } PaintUtilSetSegmentSupportHeight( @@ -8660,7 +9004,7 @@ static void StandUpRCTrackDiagRightBankTo25DegUp( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 2, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -8671,11 +9015,11 @@ static void StandUpRCTrackDiagRightBankTo25DegUp( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 1, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::BottomCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::BottomCorner, 2, height, session.SupportColours); break; } PaintUtilSetSegmentSupportHeight( @@ -8762,7 +9106,7 @@ static void StandUpRCTrackDiag25DegUpToLeftBank( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 6, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -8773,11 +9117,11 @@ static void StandUpRCTrackDiag25DegUpToLeftBank( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 9, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::BottomCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::BottomCorner, 5, height, session.SupportColours); break; } PaintUtilSetSegmentSupportHeight( @@ -8864,7 +9208,7 @@ static void StandUpRCTrackDiag25DegUpToRightBank( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 10, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( @@ -8875,11 +9219,11 @@ static void StandUpRCTrackDiag25DegUpToRightBank( break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 8, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::BottomCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::BottomCorner, 5, height, session.SupportColours); break; } PaintUtilSetSegmentSupportHeight( @@ -8970,7 +9314,7 @@ static void StandUpRCTrackDiagLeftBankTo25DegDown( session, direction, session.TrackColours.WithIndex(25741), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 8, height, session.SupportColours); break; case 2: MetalBSupportsPaintSetup( @@ -9042,10 +9386,10 @@ static void StandUpRCTrackDiagRightBankTo25DegDown( { case 2: PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(16676), { -16, -16, height }, + session, direction, session.TrackColours.WithIndex(25733), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); PaintAddImageAsParentRotated( - session, direction, session.TrackColours.WithIndex(16680), { -16, -16, height }, + session, direction, session.TrackColours.WithIndex(25737), { -16, -16, height }, { { -16, -16, height + 35 }, { 32, 32, 0 } }); break; } @@ -9070,7 +9414,7 @@ static void StandUpRCTrackDiagRightBankTo25DegDown( session, direction, session.TrackColours.WithIndex(25736), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 8, height, session.SupportColours); break; case 2: MetalBSupportsPaintSetup( @@ -9173,11 +9517,11 @@ static void StandUpRCTrackDiag25DegDownToLeftBank( session, direction, session.TrackColours.WithIndex(25751), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); break; case 2: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 7, height, session.SupportColours); break; case 3: MetalBSupportsPaintSetup( @@ -9268,14 +9612,14 @@ static void StandUpRCTrackDiag25DegDownToRightBank( { case 0: MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 8, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25746), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalBSupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 4, height, session.SupportColours); break; case 2: MetalBSupportsPaintSetup( @@ -9374,11 +9718,11 @@ static void StandUpRCTrackDiagLeftBank( session, direction, session.TrackColours.WithIndex(25720), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 1, height, session.SupportColours); break; case 2: MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::RightCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::RightCorner, 6, height, session.SupportColours); break; case 3: MetalASupportsPaintSetup( @@ -9466,14 +9810,14 @@ static void StandUpRCTrackDiagRightBank( { case 0: MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::LeftCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::LeftCorner, 6, height, session.SupportColours); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(25722), { -16, -16, height }, { { -16, -16, height }, { 32, 32, 3 } }); MetalASupportsPaintSetup( - session, supportType.metal, MetalSupportPlace::TopCorner, 0, height, session.SupportColours); + session, supportType.metal, MetalSupportPlace::TopCorner, 1, height, session.SupportColours); break; case 2: MetalASupportsPaintSetup( diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index 98a16a7a99..daa0909219 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1367,7 +1367,69 @@ enum : ImageIndex SPR_G2_STANDUP_RC_BEGIN = SPR_G2_MINETRAIN_RC_END, SPR_G2_STANDUP_DIAG_BRAKES = SPR_G2_STANDUP_RC_BEGIN, - SPR_G2_STANDUP_RC_END = SPR_G2_STANDUP_DIAG_BRAKES + 6, + SPR_G2_STANDUP_TRACK_25455 = SPR_G2_STANDUP_DIAG_BRAKES + 6, + SPR_G2_STANDUP_TRACK_25457, + SPR_G2_STANDUP_TRACK_25459, + SPR_G2_STANDUP_TRACK_25461, + SPR_G2_STANDUP_TRACK_25462, + SPR_G2_STANDUP_TRACK_25463, + SPR_G2_STANDUP_TRACK_25464, + SPR_G2_STANDUP_TRACK_25466, + SPR_G2_STANDUP_TRACK_25468, + SPR_G2_STANDUP_TRACK_25470, + SPR_G2_STANDUP_TRACK_25471, + SPR_G2_STANDUP_TRACK_25472, + SPR_G2_STANDUP_TRACK_25473, + SPR_G2_STANDUP_TRACK_25521, + SPR_G2_STANDUP_TRACK_25523, + SPR_G2_STANDUP_TRACK_25526, + SPR_G2_STANDUP_TRACK_25528, + SPR_G2_STANDUP_TRACK_25530, + SPR_G2_STANDUP_TRACK_25659, + SPR_G2_STANDUP_TRACK_25661, + SPR_G2_STANDUP_TRACK_25664, + SPR_G2_STANDUP_TRACK_25665, + SPR_G2_STANDUP_TRACK_25666, + SPR_G2_STANDUP_TRACK_25668, + SPR_G2_STANDUP_TRACK_25672, + SPR_G2_STANDUP_TRACK_25673, + SPR_G2_STANDUP_TRACK_25676, + SPR_G2_STANDUP_TRACK_25677, + SPR_G2_STANDUP_TRACK_25680, + SPR_G2_STANDUP_TRACK_25684, + SPR_G2_STANDUP_TRACK_25685, + SPR_G2_STANDUP_TRACK_25686, + SPR_G2_STANDUP_TRACK_25687, + SPR_G2_STANDUP_TRACK_25689, + SPR_G2_STANDUP_TRACK_25781, + SPR_G2_STANDUP_TRACK_25783, + SPR_G2_STANDUP_TRACK_25785, + SPR_G2_STANDUP_TRACK_25787, + SPR_G2_STANDUP_TRACK_25788, + SPR_G2_STANDUP_TRACK_25792, + SPR_G2_STANDUP_TRACK_25794, + SPR_G2_STANDUP_TRACK_25796, + SPR_G2_STANDUP_TRACK_25797, + SPR_G2_STANDUP_TRACK_25798, + SPR_G2_STANDUP_TRACK_25799, + SPR_G2_STANDUP_TRACK_25803, + SPR_G2_STANDUP_TRACK_25805, + SPR_G2_STANDUP_TRACK_25807, + SPR_G2_STANDUP_TRACK_25809, + SPR_G2_STANDUP_TRACK_25810, + SPR_G2_STANDUP_TRACK_25811, + SPR_G2_STANDUP_TRACK_25812, + SPR_G2_STANDUP_TRACK_25814, + SPR_G2_STANDUP_TRACK_25816, + SPR_G2_STANDUP_TRACK_25820, + SPR_G2_STANDUP_TRACK_25821, + SPR_G2_STANDUP_TRACK_25825, + SPR_G2_STANDUP_TRACK_25827, + SPR_G2_STANDUP_TRACK_25834, + SPR_G2_STANDUP_TRACK_25835, + SPR_G2_STANDUP_TRACK_25843, + SPR_G2_STANDUP_TRACK_25844, + SPR_G2_STANDUP_RC_END, SPR_G2_STEEPLECHASE_RC_BEGIN = SPR_G2_STANDUP_RC_END, SPR_G2_STEEPLECHASE_DIAG_BRAKES = SPR_G2_STEEPLECHASE_RC_BEGIN, From e8c7a8909a721e2bca17c5338cf0a2bf5afefb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 2 Dec 2024 02:16:59 +0200 Subject: [PATCH 101/139] Eliminate allocations when guests choose their train, add sfl library --- src/openrct2/entity/Guest.cpp | 21 +- src/openrct2/entity/Guest.h | 1 - src/thirdparty/sfl/private.hpp | 2512 ++++++++++++++++++++ src/thirdparty/sfl/segmented_devector.hpp | 2589 +++++++++++++++++++++ src/thirdparty/sfl/segmented_vector.hpp | 1808 ++++++++++++++ src/thirdparty/sfl/small_vector.hpp | 2540 ++++++++++++++++++++ src/thirdparty/sfl/static_vector.hpp | 1119 +++++++++ 7 files changed, 10580 insertions(+), 10 deletions(-) create mode 100644 src/thirdparty/sfl/private.hpp create mode 100644 src/thirdparty/sfl/segmented_devector.hpp create mode 100644 src/thirdparty/sfl/segmented_vector.hpp create mode 100644 src/thirdparty/sfl/small_vector.hpp create mode 100644 src/thirdparty/sfl/static_vector.hpp diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index 5a46a3a0a9..ee4dde5ec8 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -71,6 +71,8 @@ #include #include #include +#include +#include using namespace OpenRCT2; @@ -2458,19 +2460,19 @@ static void PeepRideIsTooIntense(Guest* peep, Ride& ride, bool peepAtRide) * * rct2: 0x00691C6E */ -static Vehicle* PeepChooseCarFromRide(Peep* peep, const Ride& ride, std::vector& car_array) +static Vehicle* PeepChooseCarFromRide(Peep* peep, const Ride& ride, std::span carArray) { uint8_t chosen_car = ScenarioRand(); if (ride.GetRideTypeDescriptor().HasFlag(RtdFlag::hasGForces) && ((chosen_car & 0xC) != 0xC)) { - chosen_car = (ScenarioRand() & 1) ? 0 : static_cast(car_array.size()) - 1; + chosen_car = (ScenarioRand() & 1) ? 0 : static_cast(carArray.size()) - 1; } else { - chosen_car = (chosen_car * static_cast(car_array.size())) >> 8; + chosen_car = (chosen_car * static_cast(carArray.size())) >> 8; } - peep->CurrentCar = car_array[chosen_car]; + peep->CurrentCar = carArray[chosen_car]; Vehicle* vehicle = GetEntity(ride.vehicles[peep->CurrentTrain]); if (vehicle == nullptr) @@ -2551,7 +2553,8 @@ void Guest::GoToRideEntrance(const Ride& ride) RemoveFromQueue(); } -bool Guest::FindVehicleToEnter(const Ride& ride, std::vector& car_array) +static bool FindVehicleToEnter( + Guest& guest, const Ride& ride, sfl::static_vector& car_array) { uint8_t chosen_train = RideStation::kNoTrain; @@ -2577,14 +2580,14 @@ bool Guest::FindVehicleToEnter(const Ride& ride, std::vector& car_array } else { - chosen_train = ride.GetStation(CurrentRideStation).TrainAtStation; + chosen_train = ride.GetStation(guest.CurrentRideStation).TrainAtStation; } if (chosen_train >= OpenRCT2::Limits::kMaxTrainsPerRide) { return false; } - CurrentTrain = chosen_train; + guest.CurrentTrain = chosen_train; int32_t i = 0; @@ -3497,7 +3500,7 @@ void Guest::UpdateRideAtEntrance() } } - std::vector carArray; + sfl::static_vector carArray; if (ride->GetRideTypeDescriptor().HasFlag(RtdFlag::noVehicles)) { @@ -3506,7 +3509,7 @@ void Guest::UpdateRideAtEntrance() } else { - if (!FindVehicleToEnter(*ride, carArray)) + if (!FindVehicleToEnter(*this, *ride, carArray)) return; } diff --git a/src/openrct2/entity/Guest.h b/src/openrct2/entity/Guest.h index 915d4f8316..4c67dd79fa 100644 --- a/src/openrct2/entity/Guest.h +++ b/src/openrct2/entity/Guest.h @@ -423,7 +423,6 @@ private: void GivePassingPeepsIceCream(Guest* passingPeep); Ride* FindBestRideToGoOn(); OpenRCT2::BitSet FindRidesToGoOn(); - bool FindVehicleToEnter(const Ride& ride, std::vector& car_array); void GoToRideEntrance(const Ride& ride); }; diff --git a/src/thirdparty/sfl/private.hpp b/src/thirdparty/sfl/private.hpp new file mode 100644 index 0000000000..9c03194298 --- /dev/null +++ b/src/thirdparty/sfl/private.hpp @@ -0,0 +1,2512 @@ +// +// Copyright (c) 2022 Slaven Falandys +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef SFL_PRIVATE_HPP_INCLUDED +#define SFL_PRIVATE_HPP_INCLUDED + +#include // move, copy, etc. +#include // assert +#include // size_t +#include // abort +#include // iterator_traits, xxxxx_iterator_tag +#include // addressof, allocator_traits, pointer_traits +#include // length_error, out_of_range +#include // enable_if, is_convertible, is_function, true_type... +#include // forward, move, move_if_noexcept + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// MACROS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +#define SFL_ASSERT(x) assert(x) + +#if defined(_MSC_VER) && defined(_MSVC_LANG) + #define SFL_CXX_VERSION _MSVC_LANG +#else + #define SFL_CXX_VERSION __cplusplus +#endif + +#if SFL_CXX_VERSION >= 201402L + #define SFL_CONSTEXPR_14 constexpr +#else + #define SFL_CONSTEXPR_14 +#endif + +#if SFL_CXX_VERSION >= 201703L + #define SFL_NODISCARD [[nodiscard]] +#else + #define SFL_NODISCARD +#endif + +#ifdef SFL_NO_EXCEPTIONS + #define SFL_TRY if (true) + #define SFL_CATCH(x) if (false) + #define SFL_RETHROW +#else + #define SFL_TRY try + #define SFL_CATCH(x) catch (x) + #define SFL_RETHROW throw +#endif + +namespace sfl +{ + +namespace dtl +{ + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// UTILITY FUNCTIONS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// +// This function is used for silencing warnings about unused variables. +// +template +SFL_CONSTEXPR_14 +void ignore_unused(Args&&...) +{ + // Do nothing. +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// TYPE TRAITS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +template +using void_t = void; + +template +using enable_if_t = typename std::enable_if::type; + +template +using remove_cvref_t = typename std::remove_cv::type>::type; + +// +// This struct provides information about segmented iterators. +// +// The architecture about segmented iterator traits is based on this article: +// "Segmented Iterators and Hierarchical Algorithms", Matthew H. Austern. +// +template +struct segmented_iterator_traits +{ + using is_segmented_iterator = std::false_type; + + // + // Specialized struct must define the following types and functions: + // + // using iterator = xxxxx; (it is usually `T`) + // using segment_iterator = xxxxx; + // using local_iterator = xxxxx; + // + // static segment_iterator segment(iterator); + // static local_iterator local(iterator); + // + // static local_iterator begin(segment_iterator); + // static local_iterator end(segment_iterator); + // + // static iterator compose(segment_iterator, local_iterator); + // +}; + +// +// Checks if `T` is segmented iterator. +// +template +struct is_segmented_iterator : + sfl::dtl::segmented_iterator_traits::is_segmented_iterator {}; + +// +// Checks if `T` is input iterator. +// +template +struct is_input_iterator : std::false_type {}; + +template +struct is_input_iterator< + Iterator, + sfl::dtl::enable_if_t< + std::is_convertible< + typename std::iterator_traits::iterator_category, + std::input_iterator_tag + >::value + > +> : std::true_type {}; + +// +// Checks if `T` is exactly input iterator. +// +template +struct is_exactly_input_iterator : std::false_type {}; + +template +struct is_exactly_input_iterator< + T, + sfl::dtl::enable_if_t< + std::is_convertible< + typename std::iterator_traits::iterator_category, + std::input_iterator_tag + >::value + && + !std::is_convertible< + typename std::iterator_traits::iterator_category, + std::forward_iterator_tag + >::value + > +> : std::true_type {}; + +// +// Checks if `T` is forward iterator. +// +template +struct is_forward_iterator : std::false_type {}; + +template +struct is_forward_iterator< + T, + sfl::dtl::enable_if_t< + std::is_convertible< + typename std::iterator_traits::iterator_category, + std::forward_iterator_tag + >::value + > +> : std::true_type {}; + +// +// Checks if `T` is random access iterator. +// +template +struct is_random_access_iterator : std::false_type {}; + +template +struct is_random_access_iterator< + T, + sfl::dtl::enable_if_t< + std::is_convertible< + typename std::iterator_traits::iterator_category, + std::random_access_iterator_tag + >::value + > +> : std::true_type {}; + +// +// Checks if `Type` has member `is_transparent`. +// +template +struct has_is_transparent : std::false_type {}; + +template +struct has_is_transparent< + Type, SfinaeType, sfl::dtl::void_t +> : std::true_type {}; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// POINTER TRAITS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// +// Raw pointer overload. +// Obtains a dereferenceable pointer to its argument. +// +template +constexpr +T* to_address(T* p) noexcept +{ + static_assert(!std::is_function::value, "not a function pointer"); + return p; +} + +// +// Fancy pointer overload. +// Obtains a raw pointer from a fancy pointer. +// +template +constexpr +auto to_address(const Pointer& p) noexcept -> typename std::pointer_traits::element_type* +{ + return sfl::dtl::to_address(p.operator->()); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// ITERATORS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +template +class normal_iterator +{ + template + friend class normal_iterator; + + friend Container; + +private: + + Iterator it_; + +public: + + using difference_type = typename std::iterator_traits::difference_type; + using value_type = typename std::iterator_traits::value_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + using iterator_category = typename std::iterator_traits::iterator_category; +#if SFL_CXX_VERSION >= 202002L + using iterator_concept = std::contiguous_iterator_tag; +#endif + +private: + + explicit normal_iterator(const Iterator& it) noexcept + : it_(it) + {} + +public: + + // Default constructor + normal_iterator() noexcept + : it_() + {} + + // Copy constructor + normal_iterator(const normal_iterator& other) noexcept + : it_(other.it_) + {} + + // Converting constructor (from iterator to const_iterator) + template ::value>* = nullptr> + normal_iterator(const normal_iterator& other) noexcept + : it_(other.it_) + {} + + // Copy assignment operator + normal_iterator& operator=(const normal_iterator& other) noexcept + { + it_ = other.it_; + return *this; + } + + SFL_NODISCARD + reference operator*() const noexcept + { + return *it_; + } + + SFL_NODISCARD + pointer operator->() const noexcept + { + return sfl::dtl::to_address(it_); + } + + normal_iterator& operator++() noexcept + { + ++it_; + return *this; + } + + normal_iterator operator++(int) noexcept + { + auto temp = *this; + ++it_; + return temp; + } + + normal_iterator& operator--() noexcept + { + --it_; + return *this; + } + + normal_iterator operator--(int) noexcept + { + auto temp = *this; + --it_; + return temp; + } + + normal_iterator& operator+=(difference_type n) noexcept + { + it_ += n; + return *this; + } + + normal_iterator& operator-=(difference_type n) noexcept + { + it_ -= n; + return *this; + } + + SFL_NODISCARD + normal_iterator operator+(difference_type n) const noexcept + { + return normal_iterator(it_ + n); + } + + SFL_NODISCARD + normal_iterator operator-(difference_type n) const noexcept + { + return normal_iterator(it_ - n); + } + + SFL_NODISCARD + reference operator[](difference_type n) const noexcept + { + return it_[n]; + } + + SFL_NODISCARD + friend normal_iterator operator+(difference_type n, const normal_iterator& it) noexcept + { + return it + n; + } + + SFL_NODISCARD + friend difference_type operator-(const normal_iterator& x, const normal_iterator& y) noexcept + { + return x.it_ - y.it_; + } + + SFL_NODISCARD + friend bool operator==(const normal_iterator& x, const normal_iterator& y) noexcept + { + return x.it_ == y.it_; + } + + SFL_NODISCARD + friend bool operator!=(const normal_iterator& x, const normal_iterator& y) noexcept + { + return !(x == y); + } + + SFL_NODISCARD + friend bool operator<(const normal_iterator& x, const normal_iterator& y) noexcept + { + return x.it_ < y.it_; + } + + SFL_NODISCARD + friend bool operator>(const normal_iterator& x, const normal_iterator& y) noexcept + { + return y < x; + } + + SFL_NODISCARD + friend bool operator<=(const normal_iterator& x, const normal_iterator& y) noexcept + { + return !(y < x); + } + + SFL_NODISCARD + friend bool operator>=(const normal_iterator& x, const normal_iterator& y) noexcept + { + return !(x < y); + } +}; + +template +class segmented_iterator +{ + template + friend class segmented_iterator; + + friend Container; + + template + friend struct sfl::dtl::segmented_iterator_traits; + +private: + + SegmentIterator segment_; + LocalIterator local_; + +public: + + using difference_type = typename std::iterator_traits::difference_type; + using value_type = typename std::iterator_traits::value_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + using iterator_category = typename std::iterator_traits::iterator_category; + +private: + + explicit segmented_iterator(const SegmentIterator& segment, const LocalIterator& local) noexcept + : segment_(segment) + , local_(local) + {} + +public: + + // Default constructor + segmented_iterator() noexcept + : segment_() + , local_() + {} + + // Copy constructor + segmented_iterator(const segmented_iterator& other) noexcept + : segment_(other.segment_) + , local_(other.local_) + {} + + // Converting constructor (from iterator to const_iterator) + template ::value && + std::is_convertible::value >* = nullptr > + segmented_iterator(const segmented_iterator& other) noexcept + : segment_(other.segment_) + , local_(other.local_) + {} + + // Copy assignment operator + segmented_iterator& operator=(const segmented_iterator& other) noexcept + { + segment_ = other.segment_; + local_ = other.local_; + return *this; + } + + SFL_NODISCARD + reference operator*() const noexcept + { + return *local_; + } + + SFL_NODISCARD + pointer operator->() const noexcept + { + return sfl::dtl::to_address(local_); + } + + segmented_iterator& operator++() noexcept + { + ++local_; + + if (local_ == *segment_ + SegmentSize) + { + ++segment_; + local_ = *segment_; + } + + return *this; + } + + segmented_iterator operator++(int) noexcept + { + auto temp = *this; + this->operator++(); + return temp; + } + + segmented_iterator& operator--() noexcept + { + if (local_ == *segment_) + { + --segment_; + local_ = *segment_ + SegmentSize; + } + + --local_; + + return *this; + } + + segmented_iterator operator--(int) noexcept + { + auto temp = *this; + this->operator--(); + return temp; + } + + segmented_iterator& operator+=(difference_type n) noexcept + { + const difference_type offset = std::distance(LocalIterator(*segment_), local_) + n; + + if (offset >= 0 && offset < difference_type(SegmentSize)) + { + local_ += n; + } + else + { + const difference_type segment_offset = + offset > 0 + ? offset / difference_type(SegmentSize) + : -difference_type((-offset - 1) / SegmentSize) - 1; + + segment_ += segment_offset; + + local_ = *segment_ + (offset - segment_offset * difference_type(SegmentSize)); + } + + return *this; + } + + segmented_iterator& operator-=(difference_type n) noexcept + { + return this->operator+=(-n); + } + + SFL_NODISCARD + segmented_iterator operator+(difference_type n) const noexcept + { + auto temp = *this; + temp += n; + return temp; + } + + SFL_NODISCARD + segmented_iterator operator-(difference_type n) const noexcept + { + auto temp = *this; + temp -= n; + return temp; + } + + SFL_NODISCARD + reference operator[](difference_type n) const noexcept + { + auto temp = *this; + temp += n; + return *temp; + } + + SFL_NODISCARD + friend segmented_iterator operator+(difference_type n, const segmented_iterator& it) noexcept + { + return it + n; + } + + SFL_NODISCARD + friend difference_type operator-(const segmented_iterator& x, const segmented_iterator& y) noexcept + { + return (x.segment_ - y.segment_) * difference_type(SegmentSize) + + (x.local_ - *x.segment_) - (y.local_ - *y.segment_); + } + + SFL_NODISCARD + friend bool operator==(const segmented_iterator& x, const segmented_iterator& y) noexcept + { + return x.local_ == y.local_; + } + + SFL_NODISCARD + friend bool operator!=(const segmented_iterator& x, const segmented_iterator& y) noexcept + { + return !(x == y); + } + + SFL_NODISCARD + friend bool operator<(const segmented_iterator& x, const segmented_iterator& y) noexcept + { + return (x.segment_ == y.segment_) ? (x.local_ < y.local_) : (x.segment_ < y.segment_); + } + + SFL_NODISCARD + friend bool operator>(const segmented_iterator& x, const segmented_iterator& y) noexcept + { + return y < x; + } + + SFL_NODISCARD + friend bool operator<=(const segmented_iterator& x, const segmented_iterator& y) noexcept + { + return !(y < x); + } + + SFL_NODISCARD + friend bool operator>=(const segmented_iterator& x, const segmented_iterator& y) noexcept + { + return !(x < y); + } +}; + +template +struct segmented_iterator_traits> +{ + using is_segmented_iterator = std::true_type; + + using iterator = sfl::dtl::segmented_iterator; + + using segment_iterator = SegmentIterator; + + using local_iterator = LocalIterator; + + static segment_iterator segment(iterator it) noexcept + { + return it.segment_; + } + + static local_iterator local(iterator it) noexcept + { + return it.local_; + } + + static local_iterator begin(segment_iterator it) noexcept + { + return *it; + } + + static local_iterator end(segment_iterator it) noexcept + { + return *it + SegmentSize; + } + + static iterator compose(segment_iterator segment, local_iterator local) noexcept + { + SFL_ASSERT(begin(segment) <= local && local <= end(segment)); + + if (local == end(segment)) + { + ++segment; + local = begin(segment); + } + + return iterator(segment, local); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// INITIALIZED MEMORY ALGORITHMS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +template ::value && + !sfl::dtl::is_segmented_iterator::value) || + (!sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_segmented_iterator::value && + !sfl::dtl::is_random_access_iterator::value) >* = nullptr> +OutputIt copy(InputIt first, InputIt last, OutputIt d_first) +{ + return std::copy(first, last, d_first); +} + +template ::value && + sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_random_access_iterator::value >* = nullptr> +OutputIt copy(InputIt first, InputIt last, OutputIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + if (first == last) + { + return d_first; + } + else + { + auto curr = first; + + auto d_local = traits::local(d_first); + auto d_seg = traits::segment(d_first); + + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + std::distance(curr, last), + std::distance(d_local, traits::end(d_seg)) + ); + + const auto next = curr + count; + + d_local = sfl::dtl::copy + ( + curr, + next, + d_local + ); + + curr = next; + + if (curr == last) + { + return traits::compose(d_seg, d_local); + } + + ++d_seg; + + d_local = traits::begin(d_seg); + } + } +} + +template ::value >* = nullptr> +OutputIt copy(InputIt first, InputIt last, OutputIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + return sfl::dtl::copy + ( + traits::local(first), + traits::local(last), + d_first + ); + } + else + { + d_first = sfl::dtl::copy + ( + traits::local(first), + traits::end(first_seg), + d_first + ); + + ++first_seg; + + while (first_seg != last_seg) + { + d_first = sfl::dtl::copy + ( + traits::begin(first_seg), + traits::end(first_seg), + d_first + ); + + ++first_seg; + } + + d_first = sfl::dtl::copy + ( + traits::begin(last_seg), + traits::local(last), + d_first + ); + + return d_first; + } +} + +template +OutputIt copy_n(InputIt first, Size count, OutputIt d_first) +{ + return std::copy_n(first, count, d_first); +} + +template ::value && + !sfl::dtl::is_segmented_iterator::value) || + (!sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_segmented_iterator::value && + !sfl::dtl::is_random_access_iterator::value) >* = nullptr> +BidirIt2 copy_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) +{ + return std::copy_backward(first, last, d_last); +} + +template ::value && + sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_random_access_iterator::value>* = nullptr> +BidirIt2 copy_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + if (first == last) + { + return d_last; + } + else + { + auto curr = last; + + auto d_local = traits::local(d_last); + auto d_seg = traits::segment(d_last); + + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + std::distance(first, curr), + std::distance(traits::begin(d_seg), d_local) + ); + + const auto prev = curr - count; + + d_local = sfl::dtl::copy_backward + ( + prev, + curr, + d_local + ); + + curr = prev; + + if (curr == first) + { + return traits::compose(d_seg, d_local); + } + + --d_seg; + + d_local = traits::end(d_seg); + } + } +} + +template ::value >* = nullptr> +BidirIt2 copy_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + return sfl::dtl::copy_backward + ( + traits::local(first), + traits::local(last), + d_last + ); + } + else + { + d_last = sfl::dtl::copy_backward + ( + traits::begin(last_seg), + traits::local(last), + d_last + ); + + --last_seg; + + while (first_seg != last_seg) + { + d_last = sfl::dtl::copy_backward + ( + traits::begin(last_seg), + traits::end(last_seg), + d_last + ); + + --last_seg; + } + + d_last = sfl::dtl::copy_backward + ( + traits::local(first), + traits::end(last_seg), + d_last + ); + + return d_last; + } +} + +template ::value && + !sfl::dtl::is_segmented_iterator::value) || + (!sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_segmented_iterator::value && + !sfl::dtl::is_random_access_iterator::value) >* = nullptr> +OutputIt move(InputIt first, InputIt last, OutputIt d_first) +{ + return std::move(first, last, d_first); +} + +template ::value && + sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_random_access_iterator::value >* = nullptr> +OutputIt move(InputIt first, InputIt last, OutputIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + if (first == last) + { + return d_first; + } + else + { + auto curr = first; + + auto d_local = traits::local(d_first); + auto d_seg = traits::segment(d_first); + + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + std::distance(curr, last), + std::distance(d_local, traits::end(d_seg)) + ); + + const auto next = curr + count; + + d_local = sfl::dtl::move + ( + curr, + next, + d_local + ); + + curr = next; + + if (curr == last) + { + return traits::compose(d_seg, d_local); + } + + ++d_seg; + + d_local = traits::begin(d_seg); + } + } +} + +template ::value >* = nullptr> +OutputIt move(InputIt first, InputIt last, OutputIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + return sfl::dtl::move + ( + traits::local(first), + traits::local(last), + d_first + ); + } + else + { + d_first = sfl::dtl::move + ( + traits::local(first), + traits::end(first_seg), + d_first + ); + + ++first_seg; + + while (first_seg != last_seg) + { + d_first = sfl::dtl::move + ( + traits::begin(first_seg), + traits::end(first_seg), + d_first + ); + + ++first_seg; + } + + d_first = sfl::dtl::move + ( + traits::begin(last_seg), + traits::local(last), + d_first + ); + + return d_first; + } +} + +template ::value && + !sfl::dtl::is_segmented_iterator::value) || + (!sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_segmented_iterator::value && + !sfl::dtl::is_random_access_iterator::value) >* = nullptr> +BidirIt2 move_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) +{ + return std::move_backward(first, last, d_last); +} + +template ::value && + sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_random_access_iterator::value >* = nullptr> +BidirIt2 move_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + if (first == last) + { + return d_last; + } + else + { + auto curr = last; + + auto d_local = traits::local(d_last); + auto d_seg = traits::segment(d_last); + + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + std::distance(first, curr), + std::distance(traits::begin(d_seg), d_local) + ); + + const auto prev = curr - count; + + d_local = sfl::dtl::move_backward + ( + prev, + curr, + d_local + ); + + curr = prev; + + if (curr == first) + { + return traits::compose(d_seg, d_local); + } + + --d_seg; + + d_local = traits::end(d_seg); + } + } +} + +template ::value >* = nullptr> +BidirIt2 move_backward(BidirIt1 first, BidirIt1 last, BidirIt2 d_last) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + return sfl::dtl::move_backward + ( + traits::local(first), + traits::local(last), + d_last + ); + } + else + { + d_last = sfl::dtl::move_backward + ( + traits::begin(last_seg), + traits::local(last), + d_last + ); + + --last_seg; + + while (first_seg != last_seg) + { + d_last = sfl::dtl::move_backward + ( + traits::begin(last_seg), + traits::end(last_seg), + d_last + ); + + --last_seg; + } + + d_last = sfl::dtl::move_backward + ( + traits::local(first), + traits::end(last_seg), + d_last + ); + + return d_last; + } +} + +template ::value >* = nullptr> +void fill(ForwardIt first, ForwardIt last, const T& value) +{ + std::fill(first, last, value); +} + +template ::value >* = nullptr> +void fill(ForwardIt first, ForwardIt last, const T& value) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + sfl::dtl::fill + ( + traits::local(first), + traits::local(last), + value + ); + } + else + { + sfl::dtl::fill + ( + traits::local(first), + traits::end(first_seg), + value + ); + + ++first_seg; + + while (first_seg != last_seg) + { + sfl::dtl::fill + ( + traits::begin(first_seg), + traits::end(first_seg), + value + ); + + ++first_seg; + } + + sfl::dtl::fill + ( + traits::begin(last_seg), + traits::local(last), + value + ); + } +} + +template +OutputIt fill_n(OutputIt first, Size count, const T& value) +{ + return std::fill_n(first, count, value); +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// UNINITIALIZED MEMORY ALGORITHMS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +template +auto allocate(Allocator& a, Size n) -> typename std::allocator_traits::pointer +{ + if (n != 0) + { + return std::allocator_traits::allocate(a, n); + } + return nullptr; +} + +template +void deallocate(Allocator& a, Pointer p, Size n) noexcept +{ + if (p != nullptr) + { + std::allocator_traits::deallocate(a, p, n); + } +} + +template +void construct_at_a(Allocator& a, Pointer p, Args&&... args) +{ + std::allocator_traits::construct + ( + a, + sfl::dtl::to_address(p), + std::forward(args)... + ); +} + +template +void destroy_at_a(Allocator& a, Pointer p) noexcept +{ + std::allocator_traits::destroy + ( + a, + sfl::dtl::to_address(p) + ); +} + +template ::value >* = nullptr> +void destroy_a(Allocator& a, ForwardIt first, ForwardIt last) noexcept +{ + while (first != last) + { + sfl::dtl::destroy_at_a(a, std::addressof(*first)); + ++first; + } +} + +template ::value >* = nullptr> +void destroy_a(Allocator& a, ForwardIt first, ForwardIt last) noexcept +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + sfl::dtl::destroy_a + ( + a, + traits::local(first), + traits::local(last) + ); + } + else + { + sfl::dtl::destroy_a + ( + a, + traits::local(first), + traits::end(first_seg) + ); + + ++first_seg; + + while (first_seg != last_seg) + { + sfl::dtl::destroy_a + ( + a, + traits::begin(first_seg), + traits::end(first_seg) + ); + + ++first_seg; + } + + sfl::dtl::destroy_a + ( + a, + traits::begin(last_seg), + traits::local(last) + ); + } +} + +template ::value >* = nullptr> +ForwardIt destroy_n_a(Allocator& a, ForwardIt first, Size n) noexcept +{ + while (n > 0) + { + sfl::dtl::destroy_at_a(a, std::addressof(*first)); + ++first; + --n; + } + return first; +} + +template ::value >* = nullptr> +ForwardIt destroy_n_a(Allocator& a, ForwardIt first, Size n) noexcept +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto curr_local = traits::local(first); + auto curr_seg = traits::segment(first); + + auto remainining = n; + + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + remainining, + std::distance(curr_local, traits::end(curr_seg)) + ); + + curr_local = sfl::dtl::destroy_n_a + ( + a, + curr_local, + count + ); + + remainining -= count; + + SFL_ASSERT(remainining <= n && "Bug in algorithm. Please report it."); + + if (remainining == 0) + { + return traits::compose(curr_seg, curr_local); + } + + ++curr_seg; + + curr_local = traits::begin(curr_seg); + } +} + +template ::value >* = nullptr> +void uninitialized_default_construct_a(Allocator& a, ForwardIt first, ForwardIt last) +{ + ForwardIt curr = first; + SFL_TRY + { + while (curr != last) + { + sfl::dtl::construct_at_a(a, std::addressof(*curr)); + ++curr; + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a(a, first, curr); + SFL_RETHROW; + } +} + +template ::value >* = nullptr> +void uninitialized_default_construct_a(Allocator& a, ForwardIt first, ForwardIt last) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + sfl::dtl::uninitialized_default_construct_a + ( + a, + traits::local(first), + traits::local(last) + ); + } + else + { + sfl::dtl::uninitialized_default_construct_a + ( + a, + traits::local(first), + traits::end(first_seg) + ); + + ++first_seg; + + SFL_TRY + { + while (first_seg != last_seg) + { + sfl::dtl::uninitialized_default_construct_a + ( + a, + traits::begin(first_seg), + traits::end(first_seg) + ); + + ++first_seg; + } + + sfl::dtl::uninitialized_default_construct_a + ( + a, + traits::begin(last_seg), + traits::local(last) + ); + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + first, + traits::compose(first_seg, traits::begin(first_seg)) + ); + + SFL_RETHROW; + } + } +} + +template ::value >* = nullptr> +ForwardIt uninitialized_default_construct_n_a(Allocator& a, ForwardIt first, Size n) +{ + ForwardIt curr = first; + SFL_TRY + { + while (n > 0) + { + sfl::dtl::construct_at_a(a, std::addressof(*curr)); + ++curr; + --n; + } + return curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a(a, first, curr); + SFL_RETHROW; + } +} + +template ::value >* = nullptr> +ForwardIt uninitialized_default_construct_n_a(Allocator& a, ForwardIt first, Size n) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto curr_local = traits::local(first); + auto curr_seg = traits::segment(first); + + auto remainining = n; + + SFL_TRY + { + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + remainining, + std::distance(curr_local, traits::end(curr_seg)) + ); + + curr_local = sfl::dtl::uninitialized_default_construct_n_a + ( + a, + curr_local, + count + ); + + remainining -= count; + + SFL_ASSERT(remainining <= n && "Bug in algorithm. Please report it."); + + if (remainining == 0) + { + return traits::compose(curr_seg, curr_local); + } + + ++curr_seg; + + curr_local = traits::begin(curr_seg); + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_n_a(a, first, n - remainining); + SFL_RETHROW; + } +} + +template ::value >* = nullptr> +void uninitialized_fill_a(Allocator& a, ForwardIt first, ForwardIt last, const T& value) +{ + ForwardIt curr = first; + SFL_TRY + { + while (curr != last) + { + sfl::dtl::construct_at_a(a, std::addressof(*curr), value); + ++curr; + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a(a, first, curr); + SFL_RETHROW; + } +} + +template ::value >* = nullptr> +void uninitialized_fill_a(Allocator& a, ForwardIt first, ForwardIt last, const T& value) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + sfl::dtl::uninitialized_fill_a + ( + a, + traits::local(first), + traits::local(last), + value + ); + } + else + { + sfl::dtl::uninitialized_fill_a + ( + a, + traits::local(first), + traits::end(first_seg), + value + ); + + ++first_seg; + + SFL_TRY + { + while (first_seg != last_seg) + { + sfl::dtl::uninitialized_fill_a + ( + a, + traits::begin(first_seg), + traits::end(first_seg), + value + ); + + ++first_seg; + } + + sfl::dtl::uninitialized_fill_a + ( + a, + traits::begin(last_seg), + traits::local(last), + value + ); + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + first, + traits::compose(first_seg, traits::begin(first_seg)) + ); + + SFL_RETHROW; + } + } +} + +template ::value >* = nullptr> +ForwardIt uninitialized_fill_n_a(Allocator& a, ForwardIt first, Size n, const T& value) +{ + ForwardIt curr = first; + SFL_TRY + { + while (n > 0) + { + sfl::dtl::construct_at_a(a, std::addressof(*curr), value); + ++curr; + --n; + } + return curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a(a, first, curr); + SFL_RETHROW; + } +} + +template ::value >* = nullptr> +ForwardIt uninitialized_fill_n_a(Allocator& a, ForwardIt first, Size n, const T& value) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto curr_local = traits::local(first); + auto curr_seg = traits::segment(first); + + auto remainining = n; + + SFL_TRY + { + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + remainining, + std::distance(curr_local, traits::end(curr_seg)) + ); + + curr_local = sfl::dtl::uninitialized_fill_n_a + ( + a, + curr_local, + count, + value + ); + + remainining -= count; + + SFL_ASSERT(remainining <= n && "Bug in algorithm. Please report it."); + + if (remainining == 0) + { + return traits::compose(curr_seg, curr_local); + } + + ++curr_seg; + + curr_local = traits::begin(curr_seg); + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_n_a(a, first, n - remainining); + SFL_RETHROW; + } +} + +template ::value && + !sfl::dtl::is_segmented_iterator::value) || + (!sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_segmented_iterator::value && + !sfl::dtl::is_random_access_iterator::value) >* = nullptr> +ForwardIt uninitialized_copy_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + ForwardIt d_curr = d_first; + SFL_TRY + { + while (first != last) + { + sfl::dtl::construct_at_a(a, std::addressof(*d_curr), *first); + ++d_curr; + ++first; + } + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a(a, d_first, d_curr); + SFL_RETHROW; + } +} + +template ::value && + sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_random_access_iterator::value >* = nullptr> +ForwardIt uninitialized_copy_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + if (first == last) + { + return d_first; + } + else + { + auto curr = first; + + auto d_local = traits::local(d_first); + auto d_seg = traits::segment(d_first); + + SFL_TRY + { + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + std::distance(curr, last), + std::distance(d_local, traits::end(d_seg)) + ); + + const auto next = curr + count; + + d_local = sfl::dtl::uninitialized_copy_a + ( + a, + curr, + next, + d_local + ); + + curr = next; + + if (curr == last) + { + return traits::compose(d_seg, d_local); + } + + ++d_seg; + + d_local = traits::begin(d_seg); + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + d_first, + traits::compose(d_seg, d_local) + ); + SFL_RETHROW; + } + } +} + +template ::value >* = nullptr> +ForwardIt uninitialized_copy_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + return sfl::dtl::uninitialized_copy_a + ( + a, + traits::local(first), + traits::local(last), + d_first + ); + } + else + { + auto d_curr = d_first; + + d_curr = sfl::dtl::uninitialized_copy_a + ( + a, + traits::local(first), + traits::end(first_seg), + d_curr + ); + + ++first_seg; + + SFL_TRY + { + while (first_seg != last_seg) + { + d_curr = sfl::dtl::uninitialized_copy_a + ( + a, + traits::begin(first_seg), + traits::end(first_seg), + d_curr + ); + + ++first_seg; + } + + d_curr = sfl::dtl::uninitialized_copy_a + ( + a, + traits::begin(last_seg), + traits::local(last), + d_curr + ); + + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + d_first, + d_curr + ); + SFL_RETHROW; + } + } +} + +template ::value && + !sfl::dtl::is_segmented_iterator::value) || + (!sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_segmented_iterator::value && + !sfl::dtl::is_random_access_iterator::value) >* = nullptr> +ForwardIt uninitialized_move_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + ForwardIt d_curr = d_first; + SFL_TRY + { + while (first != last) + { + sfl::dtl::construct_at_a(a, std::addressof(*d_curr), std::move(*first)); + ++d_curr; + ++first; + } + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a(a, d_first, d_curr); + SFL_RETHROW; + } +} + +template ::value && + sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_random_access_iterator::value >* = nullptr> +ForwardIt uninitialized_move_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + if (first == last) + { + return d_first; + } + else + { + auto curr = first; + + auto d_local = traits::local(d_first); + auto d_seg = traits::segment(d_first); + + SFL_TRY + { + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + std::distance(curr, last), + std::distance(d_local, traits::end(d_seg)) + ); + + const auto next = curr + count; + + d_local = sfl::dtl::uninitialized_move_a + ( + a, + curr, + next, + d_local + ); + + curr = next; + + if (curr == last) + { + return traits::compose(d_seg, d_local); + } + + ++d_seg; + + d_local = traits::begin(d_seg); + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + d_first, + traits::compose(d_seg, d_local) + ); + SFL_RETHROW; + } + } +} + +template ::value >* = nullptr> +ForwardIt uninitialized_move_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + return sfl::dtl::uninitialized_move_a + ( + a, + traits::local(first), + traits::local(last), + d_first + ); + } + else + { + auto d_curr = d_first; + + d_curr = sfl::dtl::uninitialized_move_a + ( + a, + traits::local(first), + traits::end(first_seg), + d_curr + ); + + ++first_seg; + + SFL_TRY + { + while (first_seg != last_seg) + { + d_curr = sfl::dtl::uninitialized_move_a + ( + a, + traits::begin(first_seg), + traits::end(first_seg), + d_curr + ); + + ++first_seg; + } + + d_curr = sfl::dtl::uninitialized_move_a + ( + a, + traits::begin(last_seg), + traits::local(last), + d_curr + ); + + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + d_first, + d_curr + ); + SFL_RETHROW; + } + } +} + +template ::value && + !sfl::dtl::is_segmented_iterator::value) || + (!sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_segmented_iterator::value && + !sfl::dtl::is_random_access_iterator::value) >* = nullptr> +ForwardIt uninitialized_move_if_noexcept_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + ForwardIt d_curr = d_first; + SFL_TRY + { + while (first != last) + { + sfl::dtl::construct_at_a(a, std::addressof(*d_curr), std::move_if_noexcept(*first)); + ++d_curr; + ++first; + } + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a(a, d_first, d_curr); + SFL_RETHROW; + } +} + +template ::value && + sfl::dtl::is_segmented_iterator::value && + sfl::dtl::is_random_access_iterator::value >* = nullptr> +ForwardIt uninitialized_move_if_noexcept_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + if (first == last) + { + return d_first; + } + else + { + auto curr = first; + + auto d_local = traits::local(d_first); + auto d_seg = traits::segment(d_first); + + SFL_TRY + { + while (true) + { + using difference_type = + typename std::iterator_traits::difference_type; + + const auto count = std::min + ( + std::distance(curr, last), + std::distance(d_local, traits::end(d_seg)) + ); + + const auto next = curr + count; + + d_local = sfl::dtl::uninitialized_move_if_noexcept_a + ( + a, + curr, + next, + d_local + ); + + curr = next; + + if (curr == last) + { + return traits::compose(d_seg, d_local); + } + + ++d_seg; + + d_local = traits::begin(d_seg); + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + d_first, + traits::compose(d_seg, d_local) + ); + SFL_RETHROW; + } + } +} + +template ::value >* = nullptr> +ForwardIt uninitialized_move_if_noexcept_a(Allocator& a, InputIt first, InputIt last, ForwardIt d_first) +{ + using traits = sfl::dtl::segmented_iterator_traits; + + auto first_seg = traits::segment(first); + auto last_seg = traits::segment(last); + + if (first_seg == last_seg) + { + return sfl::dtl::uninitialized_move_if_noexcept_a + ( + a, + traits::local(first), + traits::local(last), + d_first + ); + } + else + { + auto d_curr = d_first; + + d_curr = sfl::dtl::uninitialized_move_if_noexcept_a + ( + a, + traits::local(first), + traits::end(first_seg), + d_curr + ); + + ++first_seg; + + SFL_TRY + { + while (first_seg != last_seg) + { + d_curr = sfl::dtl::uninitialized_move_if_noexcept_a + ( + a, + traits::begin(first_seg), + traits::end(first_seg), + d_curr + ); + + ++first_seg; + } + + d_curr = sfl::dtl::uninitialized_move_if_noexcept_a + ( + a, + traits::begin(last_seg), + traits::local(last), + d_curr + ); + + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + a, + d_first, + d_curr + ); + SFL_RETHROW; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +template +void default_construct_at(T* p) +{ + ::new (static_cast(p)) T; +} + +template +void value_construct_at(T* p) +{ + ::new (static_cast(p)) T(); +} + +template +void construct_at(T* p, Args&&... args) +{ + ::new (static_cast(p)) T(std::forward(args)...); +} + +template +void destroy_at(T* p) noexcept +{ + p->~T(); +} + +template +void destroy(ForwardIt first, ForwardIt last) noexcept +{ + while (first != last) + { + sfl::dtl::destroy_at(std::addressof(*first)); + ++first; + } +} + +template +ForwardIt uninitialized_default_construct_n(ForwardIt first, Size n) +{ + ForwardIt curr = first; + SFL_TRY + { + while (n > 0) + { + sfl::dtl::default_construct_at(std::addressof(*curr)); + ++curr; + --n; + } + return curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy(first, curr); + SFL_RETHROW; + } +} + +template +ForwardIt uninitialized_value_construct_n(ForwardIt first, Size n) +{ + ForwardIt curr = first; + SFL_TRY + { + while (n > 0) + { + sfl::dtl::value_construct_at(std::addressof(*curr)); + ++curr; + --n; + } + return curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy(first, curr); + SFL_RETHROW; + } +} + +template +void uninitialized_fill(ForwardIt first, ForwardIt last, const T& value) +{ + ForwardIt curr = first; + SFL_TRY + { + while (curr != last) + { + sfl::dtl::construct_at(std::addressof(*curr), value); + ++curr; + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy(first, curr); + SFL_RETHROW; + } +} + +template +ForwardIt uninitialized_fill_n(ForwardIt first, Size n, const T& value) +{ + ForwardIt curr = first; + SFL_TRY + { + while (n > 0) + { + sfl::dtl::construct_at(std::addressof(*curr), value); + ++curr; + --n; + } + return curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy(first, curr); + SFL_RETHROW; + } +} + +template +ForwardIt uninitialized_copy(InputIt first, InputIt last, ForwardIt d_first) +{ + ForwardIt d_curr = d_first; + SFL_TRY + { + while (first != last) + { + sfl::dtl::construct_at(std::addressof(*d_curr), *first); + ++d_curr; + ++first; + } + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy(d_first, d_curr); + SFL_RETHROW; + } +} + +template +ForwardIt uninitialized_move(InputIt first, InputIt last, ForwardIt d_first) +{ + ForwardIt d_curr = d_first; + SFL_TRY + { + while (first != last) + { + sfl::dtl::construct_at(std::addressof(*d_curr), std::move(*first)); + ++d_curr; + ++first; + } + return d_curr; + } + SFL_CATCH (...) + { + sfl::dtl::destroy(d_first, d_curr); + SFL_RETHROW; + } +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// EXCEPTIONS +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +[[noreturn]] +inline void throw_length_error(const char* msg) +{ + #ifdef SFL_NO_EXCEPTIONS + sfl::dtl::ignore_unused(msg); + SFL_ASSERT(!"std::length_error thrown"); + std::abort(); + #else + throw std::length_error(msg); + #endif +} + +[[noreturn]] +inline void throw_out_of_range(const char* msg) +{ + #ifdef SFL_NO_EXCEPTIONS + sfl::dtl::ignore_unused(msg); + SFL_ASSERT(!"std::out_of_range thrown"); + std::abort(); + #else + throw std::out_of_range(msg); + #endif +} + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// INDEX SEQUENCE +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +template +struct index_sequence +{ + using type = index_sequence; +}; + +template +struct index_sequence_concat; + +template +struct index_sequence_concat< sfl::dtl::index_sequence, + sfl::dtl::index_sequence > + : sfl::dtl::index_sequence +{}; + +template +struct make_index_sequence + : sfl::dtl::index_sequence_concat< typename sfl::dtl::make_index_sequence::type, + typename sfl::dtl::make_index_sequence::type >::type +{}; + +template <> +struct make_index_sequence<0> : sfl::dtl::index_sequence<> +{}; + +template <> +struct make_index_sequence<1> : sfl::dtl::index_sequence<0> +{}; + +template +using index_sequence_for = sfl::dtl::make_index_sequence; + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// SCOPE GUARD +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +template +class scope_guard +{ +private: + + mutable bool dismissed_; + + Lambda lambda_; + +public: + + scope_guard(Lambda&& lambda) + : dismissed_(false) + , lambda_(std::forward(lambda)) + {} + + scope_guard(const scope_guard& other) = delete; + + scope_guard(scope_guard&& other) + : dismissed_(other.dismissed_) + , lambda_(std::move(other.lambda_)) + { + other.dismissed_ = true; + } + + scope_guard& operator=(const scope_guard& other) = delete; + + scope_guard& operator=(scope_guard&& other) + { + dismissed_ = other.dismissed_; + lambda_ = std::move(other.lambda_); + other.dismissed_ = true; + } + + ~scope_guard() + { + if (!dismissed_) + { + lambda_(); + } + } + + void dismiss() const noexcept + { + dismissed_ = true; + } +}; + +template +scope_guard make_scope_guard(Lambda&& lambda) +{ + return scope_guard(std::forward(lambda)); +} + +} // namespace dtl + +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// DEFAULT INIT TAG +/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// + +// Type used to tag that the inserted values should be default initialized. +struct default_init_t { }; + +} // namespace sfl + +#endif // SFL_PRIVATE_HPP_INCLUDED diff --git a/src/thirdparty/sfl/segmented_devector.hpp b/src/thirdparty/sfl/segmented_devector.hpp new file mode 100644 index 0000000000..45cd92e0f2 --- /dev/null +++ b/src/thirdparty/sfl/segmented_devector.hpp @@ -0,0 +1,2589 @@ +// +// Copyright (c) 2022 Slaven Falandys +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef SFL_SEGMENTED_DEVECTOR_HPP_INCLUDED +#define SFL_SEGMENTED_DEVECTOR_HPP_INCLUDED + +#include "private.hpp" + +#include // copy, move, swap, swap_ranges +#include // size_t +#include // initializer_list +#include // distance, next, reverse_iterator +#include // numeric_limits +#include // allocator, allocator_traits, pointer_traits +#include // is_same, is_nothrow_xxxxx +#include // forward, move, pair + +namespace sfl +{ + +template < typename T, + std::size_t N, + typename Allocator = std::allocator > +class segmented_devector +{ + static_assert(N > 0, "N must be greater than zero."); + +public: + + using allocator_type = Allocator; + using allocator_traits = std::allocator_traits; + using value_type = T; + using size_type = typename allocator_traits::size_type; + using difference_type = typename allocator_traits::difference_type; + using reference = T&; + using const_reference = const T&; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + +private: + + using segment_allocator = typename std::allocator_traits::template rebind_alloc; + using segment_pointer = typename std::allocator_traits::pointer; + +public: + + using iterator = sfl::dtl::segmented_iterator; + using const_iterator = sfl::dtl::segmented_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static_assert + ( + std::is_same::value, + "Allocator::value_type must be same as sfl::segmented_devector::value_type." + ); + +public: + + static constexpr size_type segment_capacity = N; + +private: + + class data_base + { + public: + + // ---- TABLE (OF SEGMENTS) ---- + + segment_pointer table_bos_; // Begin of storage + segment_pointer table_eos_; // End of storage + segment_pointer table_first_; // First element in table + segment_pointer table_last_; // One-past-last element in table + + // ---- ELEMENTS IN VECTOR ---- + + iterator bos_; // Begin of storage + iterator eos_; // End of storage + iterator first_; // First element in vector + iterator last_; // One-past-last element in vector + }; + + class data : public data_base, public allocator_type + { + public: + + data() noexcept(std::is_nothrow_default_constructible::value) + : allocator_type() + {} + + data(const allocator_type& alloc) noexcept(std::is_nothrow_copy_constructible::value) + : allocator_type(alloc) + {} + + data(allocator_type&& other) noexcept(std::is_nothrow_move_constructible::value) + : allocator_type(std::move(other)) + {} + + allocator_type& ref_to_alloc() noexcept + { + return *this; + } + + const allocator_type& ref_to_alloc() const noexcept + { + return *this; + } + }; + + data data_; + +public: + + // + // ---- CONSTRUCTION AND DESTRUCTION -------------------------------------- + // + + segmented_devector() + : data_() + { + initialize_empty(); + } + + explicit segmented_devector(const Allocator& alloc) + : data_(alloc) + { + initialize_empty(); + } + + segmented_devector(size_type n) + : data_() + { + initialize_default_n(n); + } + + explicit segmented_devector(size_type n, const Allocator& alloc) + : data_(alloc) + { + initialize_default_n(n); + } + + segmented_devector(size_type n, const T& value) + : data_() + { + initialize_fill_n(n, value); + } + + segmented_devector(size_type n, const T& value, const Allocator& alloc) + : data_(alloc) + { + initialize_fill_n(n, value); + } + + template ::value>* = nullptr> + segmented_devector(InputIt first, InputIt last) + : data_() + { + initialize_range(first, last); + } + + template ::value>* = nullptr> + segmented_devector(InputIt first, InputIt last, const Allocator& alloc) + : data_(alloc) + { + initialize_range(first, last); + } + + segmented_devector(std::initializer_list ilist) + : segmented_devector(ilist.begin(), ilist.end()) + {} + + segmented_devector(std::initializer_list ilist, const Allocator& alloc) + : segmented_devector(ilist.begin(), ilist.end(), alloc) + {} + + segmented_devector(const segmented_devector& other) + : data_ + ( + allocator_traits::select_on_container_copy_construction + ( + other.data_.ref_to_alloc() + ) + ) + { + initialize_copy(other); + } + + segmented_devector(const segmented_devector& other, const Allocator& alloc) + : data_(alloc) + { + initialize_copy(other); + } + + segmented_devector(segmented_devector&& other) + : data_(std::move(other.data_.ref_to_alloc())) + { + initialize_move(other); + } + + segmented_devector(segmented_devector&& other, const Allocator& alloc) + : data_(alloc) + { + initialize_move(other); + } + + ~segmented_devector() + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + deallocate_storage(); + } + + // + // ---- ASSIGNMENT -------------------------------------------------------- + // + + void assign(size_type n, const T& value) + { + assign_fill_n(n, value); + } + + template ::value>* = nullptr> + void assign(InputIt first, InputIt last) + { + assign_range(first, last); + } + + void assign(std::initializer_list ilist) + { + assign_range(ilist.begin(), ilist.end()); + } + + segmented_devector& operator=(const segmented_devector& other) + { + assign_copy(other); + return *this; + } + + segmented_devector& operator=(segmented_devector&& other) + { + assign_move(other); + return *this; + } + + segmented_devector& operator=(std::initializer_list ilist) + { + assign_range(ilist.begin(), ilist.end()); + return *this; + } + + // + // ---- ALLOCATOR --------------------------------------------------------- + // + + SFL_NODISCARD + allocator_type get_allocator() const noexcept + { + return data_.ref_to_alloc(); + } + + // + // ---- ITERATORS --------------------------------------------------------- + // + + SFL_NODISCARD + iterator begin() noexcept + { + return data_.first_; + } + + SFL_NODISCARD + const_iterator begin() const noexcept + { + return data_.first_; + } + + SFL_NODISCARD + const_iterator cbegin() const noexcept + { + return data_.first_; + } + + SFL_NODISCARD + iterator end() noexcept + { + return data_.last_; + } + + SFL_NODISCARD + const_iterator end() const noexcept + { + return data_.last_; + } + + SFL_NODISCARD + const_iterator cend() const noexcept + { + return data_.last_; + } + + SFL_NODISCARD + reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + iterator nth(size_type pos) noexcept + { + SFL_ASSERT(pos <= size()); + return begin() + pos; + } + + SFL_NODISCARD + const_iterator nth(size_type pos) const noexcept + { + SFL_ASSERT(pos <= size()); + return cbegin() + pos; + } + + SFL_NODISCARD + size_type index_of(const_iterator pos) const noexcept + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return std::distance(cbegin(), pos); + } + + // + // ---- SIZE AND CAPACITY ------------------------------------------------- + // + + SFL_NODISCARD + bool empty() const noexcept + { + return data_.last_ == data_.first_; + } + + SFL_NODISCARD + size_type size() const noexcept + { + return std::distance(data_.first_, data_.last_); + } + + SFL_NODISCARD + size_type max_size() const noexcept + { + return std::min + ( + allocator_traits::max_size(data_.ref_to_alloc()), + std::numeric_limits::max() / sizeof(value_type) + ); + } + + SFL_NODISCARD + size_type capacity() const noexcept + { + return std::distance(data_.bos_, data_.eos_); + } + + SFL_NODISCARD + size_type available_front() const noexcept + { + return std::distance(data_.bos_, data_.first_); + } + + SFL_NODISCARD + size_type available_back() const noexcept + { + return std::distance(data_.last_, data_.eos_); + } + + void reserve_front(size_type new_capacity) + { + const size_type size = this->size(); + const size_type available_front = this->available_front(); + + if (new_capacity > size + available_front) + { + grow_storage_front(new_capacity - (size + available_front)); + } + } + + void reserve_back(size_type new_capacity) + { + const size_type size = this->size(); + const size_type available_back = this->available_back(); + + if (new_capacity > size + available_back) + { + grow_storage_back(new_capacity - (size + available_back)); + } + } + + void shrink_to_fit() + { + shrink_storage(); + } + + // + // ---- ELEMENT ACCESS ---------------------------------------------------- + // + + SFL_NODISCARD + reference at(size_type pos) + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::segmented_devector::at"); + } + return *(begin() + pos); + } + + SFL_NODISCARD + const_reference at(size_type pos) const + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::segmented_devector::at"); + } + return *(cbegin() + pos); + } + + SFL_NODISCARD + reference operator[](size_type pos) noexcept + { + SFL_ASSERT(pos < size()); + return *(begin() + pos); + } + + SFL_NODISCARD + const_reference operator[](size_type pos) const noexcept + { + SFL_ASSERT(pos < size()); + return *(cbegin() + pos); + } + + SFL_NODISCARD + reference front() noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + const_reference front() const noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + reference back() noexcept + { + SFL_ASSERT(!empty()); + return *(--iterator(data_.last_)); + } + + SFL_NODISCARD + const_reference back() const noexcept + { + SFL_ASSERT(!empty()); + return *(--iterator(data_.last_)); + } + + // + // ---- MODIFIERS --------------------------------------------------------- + // + + void clear() noexcept + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + data_.last_ = data_.first_; + } + + template + iterator emplace(const_iterator pos, Args&&... args) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + + iterator p1 = begin() + std::distance(cbegin(), pos); + + const size_type dist_to_begin = std::distance(cbegin(), pos); + const size_type dist_to_end = std::distance(pos, cend()); + + if (dist_to_begin < dist_to_end) + { + if (data_.first_ == data_.bos_) + { + grow_storage_front(1); + p1 = nth(dist_to_begin); + } + + const iterator p2 = --iterator(p1); + + if (p1 == data_.first_) + { + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*p2), + std::forward(args)... + ); + + data_.first_ = p2; + } + else + { + const iterator p3 = ++iterator(data_.first_); + const iterator p4 = --iterator(data_.first_); + + const iterator old_first = data_.first_; + + // The order of operations is critical. First we will construct + // temporary value because arguments `args...` can contain + // reference to element in this container and after that + // we will move elements and insert new element. + + value_type tmp(std::forward(args)...); + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*p4), + std::move(*data_.first_) + ); + + data_.first_ = p4; + + sfl::dtl::move + ( + p3, + p1, + old_first + ); + + *p2 = std::move(tmp); + } + + return p2; + } + else + { + if (data_.last_ == data_.eos_) + { + grow_storage_back(1); + p1 = nth(dist_to_begin); + } + + if (p1 == data_.last_) + { + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*data_.last_), + std::forward(args)... + ); + + ++data_.last_; + } + else + { + const iterator p2 = --iterator(data_.last_); + + const iterator old_last = data_.last_; + + // The order of operations is critical. First we will construct + // temporary value because arguments `args...` can contain + // reference to element in this container and after that + // we will move elements and insert new element. + + value_type tmp(std::forward(args)...); + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*data_.last_), + std::move(*p2) + ); + + ++data_.last_; + + sfl::dtl::move_backward + ( + p1, + p2, + old_last + ); + + *p1 = std::move(tmp); + } + + return p1; + } + } + + iterator insert(const_iterator pos, const T& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return emplace(pos, value); + } + + iterator insert(const_iterator pos, T&& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return emplace(pos, std::move(value)); + } + + iterator insert(const_iterator pos, size_type n, const T& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_fill_n(pos, n, value); + } + + template ::value>* = nullptr> + iterator insert(const_iterator pos, InputIt first, InputIt last) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_range(pos, first, last); + } + + iterator insert(const_iterator pos, std::initializer_list ilist) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_range(pos, ilist.begin(), ilist.end()); + } + + template + reference emplace_front(Args&&... args) + { + if (data_.first_ == data_.bos_) + { + grow_storage_front(1); + } + + const iterator new_first = --iterator(data_.first_); + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*new_first), + std::forward(args)... + ); + + data_.first_ = new_first; + + return *new_first; + } + + template + reference emplace_back(Args&&... args) + { + if (data_.last_ == data_.eos_) + { + grow_storage_back(1); + } + + const iterator old_last = data_.last_; + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*data_.last_), + std::forward(args)... + ); + + ++data_.last_; + + return *old_last; + } + + void push_front(const T& value) + { + emplace_front(value); + } + + void push_front(T&& value) + { + emplace_front(std::move(value)); + } + + void push_back(const T& value) + { + emplace_back(value); + } + + void push_back(T&& value) + { + emplace_back(std::move(value)); + } + + void pop_front() + { + SFL_ASSERT(!empty()); + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), std::addressof(*data_.first_)); + + ++data_.first_; + } + + void pop_back() + { + SFL_ASSERT(!empty()); + + --data_.last_; + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), std::addressof(*data_.last_)); + } + + iterator erase(const_iterator pos) + { + SFL_ASSERT(cbegin() <= pos && pos < cend()); + + const size_type dist_to_begin = std::distance(cbegin(), pos); + const size_type dist_to_end = std::distance(pos, cend()); + + const iterator p1 = begin() + std::distance(cbegin(), pos); + const iterator p2 = ++iterator(p1); + + if (dist_to_begin < dist_to_end) + { + const iterator old_first = data_.first_; + + data_.first_ = sfl::dtl::move_backward(data_.first_, p1, p2); + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), std::addressof(*old_first)); + + return p2; + } + else + { + data_.last_ = sfl::dtl::move(p2, data_.last_, p1); + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), std::addressof(*data_.last_)); + + return p1; + } + } + + iterator erase(const_iterator first, const_iterator last) + { + SFL_ASSERT(cbegin() <= first && first <= last && last <= cend()); + + if (first == last) + { + return begin() + std::distance(cbegin(), first); + } + + const size_type dist_to_begin = std::distance(cbegin(), first); + const size_type dist_to_end = std::distance(last, cend()); + + if (dist_to_begin < dist_to_end) + { + const iterator p1 = begin() + std::distance(cbegin(), first); + const iterator p2 = begin() + std::distance(cbegin(), last); + + const iterator new_first = sfl::dtl::move_backward(data_.first_, p1, p2); + + sfl::dtl::destroy_a(data_.ref_to_alloc(), data_.first_, new_first); + + data_.first_ = new_first; + + return p2; + } + else + { + const iterator p1 = begin() + std::distance(cbegin(), first); + const iterator p2 = begin() + std::distance(cbegin(), last); + + const iterator new_last = sfl::dtl::move(p2, data_.last_, p1); + + sfl::dtl::destroy_a(data_.ref_to_alloc(), new_last, data_.last_); + + data_.last_ = new_last; + + return p1; + } + } + + void resize(size_type n) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = nth(n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type available_back = this->available_back(); + + if (n <= size + available_back) + { + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - size + ); + } + else + { + const size_type available_front = this->available_front(); + + if (n <= available_front + size + available_back) + { + sfl::dtl::uninitialized_default_construct_a + ( + data_.ref_to_alloc(), + data_.last_, + data_.eos_ + ); + + data_.last_ = data_.eos_; + + const iterator new_first = data_.first_ - (n - (size + available_back)); + + sfl::dtl::uninitialized_default_construct_a + ( + data_.ref_to_alloc(), + new_first, + data_.first_ + ); + + data_.first_ = new_first; + } + else + { + grow_storage_back(n - (available_front + size + available_back)); + + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - (size + available_front) + ); + + sfl::dtl::uninitialized_default_construct_a + ( + data_.ref_to_alloc(), + data_.bos_, + data_.first_ + ); + + data_.first_ = data_.bos_; + } + } + } + } + + void resize(size_type n, const T& value) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = nth(n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type available_back = this->available_back(); + + if (n <= size + available_back) + { + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - size, + value + ); + } + else + { + const size_type available_front = this->available_front(); + + if (n <= available_front + size + available_back) + { + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.last_, + data_.eos_, + value + ); + + data_.last_ = data_.eos_; + + const iterator new_first = data_.first_ - (n - (size + available_back)); + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + new_first, + data_.first_, + value + ); + + data_.first_ = new_first; + } + else + { + grow_storage_back(n - (available_front + size + available_back)); + + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - (size + available_front), + value + ); + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.bos_, + data_.first_, + value + ); + + data_.first_ = data_.bos_; + } + } + } + } + + void resize_front(size_type n) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_first = nth(size - n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + new_first + ); + + data_.first_ = new_first; + } + else + { + const size_type available_front = this->available_front(); + + if (n > size + available_front) + { + grow_storage_front(n - (size + available_front)); + } + + const iterator new_first = data_.first_ - (n - size); + + sfl::dtl::uninitialized_default_construct_a + ( + data_.ref_to_alloc(), + new_first, + data_.first_ + ); + + data_.first_ = new_first; + } + } + + void resize_front(size_type n, const T& value) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_first = nth(size - n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + new_first + ); + + data_.first_ = new_first; + } + else + { + const size_type available_front = this->available_front(); + + if (n > size + available_front) + { + grow_storage_front(n - (size + available_front)); + } + + const iterator new_first = data_.first_ - (n - size); + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + new_first, + data_.first_, + value + ); + + data_.first_ = new_first; + } + } + + void resize_back(size_type n) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = nth(n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type available_back = this->available_back(); + + if (n > size + available_back) + { + grow_storage_back(n - (size + available_back)); + } + + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - size + ); + } + } + + void resize_back(size_type n, const T& value) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = nth(n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type available_back = this->available_back(); + + if (n > size + available_back) + { + grow_storage_back(n - (size + available_back)); + } + + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - size, + value + ); + } + } + + void swap(segmented_devector& other) noexcept + { + SFL_ASSERT + ( + allocator_traits::propagate_on_container_swap::value || + this->data_.ref_to_alloc() == other.data_.ref_to_alloc() + ); + + if (this == &other) + { + return; + } + + using std::swap; + + if (allocator_traits::propagate_on_container_swap::value) + { + swap(this->data_.ref_to_alloc(), other.data_.ref_to_alloc()); + } + + swap(this->data_, other.data_); + } + +private: + + // Allocates table for given number of elements (segments). + // It does not construct any element (segment). + // It only allocates memory for table. + // + segment_pointer allocate_table(size_type n) + { + segment_allocator seg_alloc(data_.ref_to_alloc()); + return sfl::dtl::allocate(seg_alloc, n); + } + + // Deallocates table. + // It does not destroy_a any element (segment). + // It only deallocates memory used by table. + // + void deallocate_table(segment_pointer p, size_type n) noexcept + { + segment_allocator seg_alloc(data_.ref_to_alloc()); + sfl::dtl::deallocate(seg_alloc, p, n); + } + + // Allocates memory for single segment. + // It does not construct any element. + // It only allocates memory for segment. + // + pointer allocate_segment() + { + return sfl::dtl::allocate(data_.ref_to_alloc(), N); + } + + // Deallocates memory used by single segment. + // It does not destroy_a any element. + // It only deallocates memory used by segment. + // + void deallocate_segment(pointer p) noexcept + { + sfl::dtl::deallocate(data_.ref_to_alloc(), p, N); + } + + // Allocates memory for multiple segments. + // It does not construct any element. + // It only allocates memory for segments. + // + void allocate_segments(segment_pointer first, segment_pointer last) + { + segment_pointer curr = first; + + SFL_TRY + { + while (curr != last) + { + *curr = allocate_segment(); + ++curr; + } + } + SFL_CATCH (...) + { + deallocate_segments(first, curr); + SFL_RETHROW; + } + } + + // Deallocates memory used by multiple segments. + // It does not destroy_a any element. + // It only deallocates memory used by segments. + // + void deallocate_segments(segment_pointer first, segment_pointer last) noexcept + { + while (first != last) + { + deallocate_segment(*first); + ++first; + } + } + + static constexpr size_type min_table_capacity() noexcept + { + return 8; + } + + // Allocates storage big enough to keep given number of elements. + // It does not construct any element. + // It only allocates memory. + // + void allocate_storage(size_type num_elements) + { + if (num_elements > max_size()) + { + sfl::dtl::throw_length_error("sfl::segmented_devector::allocate_storage"); + } + + // Required capacity of table + const size_type table_required = + num_elements / N + 1; + + const size_type table_capacity = + std::max(table_required, min_table_capacity()); + + data_.table_bos_ = allocate_table(table_capacity); + data_.table_eos_ = data_.table_bos_ + table_capacity; + data_.table_first_ = data_.table_bos_; + data_.table_last_ = data_.table_bos_ + table_required; + + SFL_TRY + { + allocate_segments(data_.table_first_, data_.table_last_); + + data_.bos_.segment_ = data_.table_first_; + data_.bos_.local_ = *data_.table_first_; + + data_.eos_.segment_ = (data_.table_last_ - 1); + data_.eos_.local_ = *(data_.table_last_ - 1) + (N - 1); + + data_.first_ = data_.bos_; + + data_.last_ = data_.first_; + } + SFL_CATCH (...) + { + deallocate_table(data_.table_bos_, table_capacity); + SFL_RETHROW; + } + } + + // Deallocates storage. + // It does not destroy_a any element. + // It only deallocates memory. + // + void deallocate_storage() noexcept + { + deallocate_segments + ( + data_.table_first_, + data_.table_last_ + ); + + deallocate_table + ( + data_.table_bos_, + std::distance(data_.table_bos_, data_.table_eos_) + ); + } + + // Increases capacity at the front for given number of elements. + // It does not construct any element. + // It only allocates memory. + // + void grow_storage_front(size_type num_additional_elements) + { + if (max_size() - capacity() < num_additional_elements) + { + sfl::dtl::throw_length_error("sfl::segmented_devector::grow_storage_front"); + } + + // Required capacity at the front of table + const size_type table_required_front = + num_additional_elements / N + (num_additional_elements % N == 0 ? 0 : 1); + + // Available capacity at the front of table + const size_type table_available_front = + std::distance(data_.table_bos_, data_.table_first_); + + // Increase table capacity at back if neccessary + if (table_required_front > table_available_front) + { + const size_type table_capacity = + std::distance(data_.table_bos_, data_.table_eos_); + + const size_type new_table_capacity = std::max + ( + table_capacity + table_capacity / 2, + table_capacity - table_available_front + table_required_front + ); + + // Distance (in segments) from BEGIN of storage to FIRST element. + const size_type dist1 = + std::distance(data_.bos_.segment_, data_.first_.segment_); + + // Distance (in segments) from BEGIN of storage to LAST element. + const size_type dist2 = + std::distance(data_.bos_.segment_, data_.last_.segment_); + + // Allocate new table. No effects if allocation fails. + const segment_pointer new_table_bos = + allocate_table(new_table_capacity); + + const segment_pointer new_table_eos = + new_table_bos + new_table_capacity; + + // Initialize LAST element in new table (noexecept). + const segment_pointer new_table_last = + new_table_eos - std::distance(data_.table_last_, data_.table_eos_); + + // Initialize FIRST element in new table (noexecept). + const segment_pointer new_table_first = sfl::dtl::copy_backward + ( + data_.table_first_, + data_.table_last_, + new_table_last + ); + + // Deallocate old table (noexecept). + deallocate_table(data_.table_bos_, table_capacity); + + // Update table (noexcept). + data_.table_bos_ = new_table_bos; + data_.table_eos_ = new_table_eos; + data_.table_first_ = new_table_first; + data_.table_last_ = new_table_last; + + // Update iterators (noexcept). + data_.bos_.segment_ = data_.table_first_; + data_.eos_.segment_ = data_.table_last_ - 1; + data_.first_.segment_ = data_.table_first_ + dist1; + data_.last_.segment_ = data_.table_first_ + dist2; + } + + const segment_pointer new_table_first = + data_.table_first_ - table_required_front; + + // Allocate additional segments. No effects if allocation fails. + allocate_segments(new_table_first, data_.table_first_); + + // Update table (noexcept). + data_.table_first_ = new_table_first; + + // Update iterators (noexcept). + data_.bos_.segment_ = data_.table_first_; + data_.bos_.local_ = *data_.table_first_; + } + + // Increases capacity at the back for given number of elements. + // It does not construct any element. + // It only allocates memory. + // + void grow_storage_back(size_type num_additional_elements) + { + if (max_size() - capacity() < num_additional_elements) + { + sfl::dtl::throw_length_error("sfl::segmented_devector::grow_storage_back"); + } + + // Required capacity at the back of table + const size_type table_required_back = + num_additional_elements / N + 1; + + // Available capacity at the back of table + const size_type table_available_back = + std::distance(data_.table_last_, data_.table_eos_); + + // Increase table capacity at back if neccessary + if (table_required_back > table_available_back) + { + const size_type table_capacity = + std::distance(data_.table_bos_, data_.table_eos_); + + const size_type new_table_capacity = std::max + ( + table_capacity + table_capacity / 2, + table_capacity - table_available_back + table_required_back + ); + + // Distance (in segments) from BEGIN of storage to FIRST element. + const size_type dist1 = + std::distance(data_.bos_.segment_, data_.first_.segment_); + + // Distance (in segments) from BEGIN of storage to LAST element. + const size_type dist2 = + std::distance(data_.bos_.segment_, data_.last_.segment_); + + // Allocate new table. No effects if allocation fails. + const segment_pointer new_table_bos = + allocate_table(new_table_capacity); + + const segment_pointer new_table_eos = + new_table_bos + new_table_capacity; + + // Initialize FIRST element in new table (noexcept). + const segment_pointer new_table_first = + new_table_bos + + std::distance(data_.table_bos_, data_.table_first_); + + // Initialize LAST element in new table (noexecept). + const segment_pointer new_table_last = sfl::dtl::copy + ( + data_.table_first_, + data_.table_last_, + new_table_first + ); + + // Deallocate old table (noexecept). + deallocate_table(data_.table_bos_, table_capacity); + + // Update table (noexcept). + data_.table_bos_ = new_table_bos; + data_.table_eos_ = new_table_eos; + data_.table_first_ = new_table_first; + data_.table_last_ = new_table_last; + + // Update iterators (noexcept). + data_.bos_.segment_ = data_.table_first_; + data_.eos_.segment_ = data_.table_last_ - 1; + data_.first_.segment_ = data_.table_first_ + dist1; + data_.last_.segment_ = data_.table_first_ + dist2; + } + + const segment_pointer new_table_last = + data_.table_last_ + table_required_back; + + // Allocate additional segments. No effects if allocation fails. + allocate_segments(data_.table_last_, new_table_last); + + // Update table (noexcept). + data_.table_last_ = new_table_last; + + // Update iterators (noexcept). + data_.eos_.segment_ = data_.table_last_ - 1; + data_.eos_.local_ = *(data_.table_last_ - 1) + (N - 1); + } + + // Removes unused capacity. + // It does not destroy_a any element. + // It only deallocates memory. + // + void shrink_storage() + { + // Destroy empty segments at front. + { + const segment_pointer new_table_first = data_.first_.segment_; + + deallocate_segments(data_.table_first_, new_table_first); + + data_.table_first_ = new_table_first; + + data_.bos_.segment_ = data_.table_first_; + data_.bos_.local_ = *data_.table_first_; + } + + // Destroy empty segments at back. + { + const segment_pointer new_table_last = data_.last_.segment_ + 1; + + deallocate_segments(new_table_last, data_.table_last_); + + data_.table_last_ = new_table_last; + + data_.eos_.segment_ = (data_.table_last_ - 1); + data_.eos_.local_ = *(data_.table_last_ - 1) + (N - 1); + } + + // Shrink table. + { + const size_type table_capacity = + std::distance(data_.table_bos_, data_.table_eos_); + + const size_type table_size = + std::distance(data_.table_first_, data_.table_last_); + + const size_type new_table_capacity = + std::max(table_size, min_table_capacity()); + + // Distance (in segments) from FIRST element to LAST element. + const size_type dist = + std::distance(data_.first_.segment_, data_.last_.segment_); + + // Allocate new table. No effects if allocation fails. + const segment_pointer new_table_bos = + allocate_table(new_table_capacity); + + const segment_pointer new_table_eos = + new_table_bos + new_table_capacity; + + // Initialize FIRST element in new table (noexcept). + const segment_pointer new_table_first = new_table_bos; + + // Initialize LAST element in new table (noexecept). + const segment_pointer new_table_last = sfl::dtl::copy + ( + data_.table_first_, + data_.table_last_, + new_table_first + ); + + // Deallocate old table (noexecept). + deallocate_table(data_.table_bos_, table_capacity); + + // Update table (noexcept). + data_.table_bos_ = new_table_bos; + data_.table_eos_ = new_table_eos; + data_.table_first_ = new_table_first; + data_.table_last_ = new_table_last; + + // Update iterators (noexcept). + data_.bos_.segment_ = data_.table_first_; + data_.eos_.segment_ = data_.table_last_ - 1; + data_.first_.segment_ = data_.table_first_; + data_.last_.segment_ = data_.table_first_ + dist; + } + } + + void initialize_empty() + { + allocate_storage(0); + } + + void initialize_default_n(size_type n) + { + allocate_storage(n); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.first_, + n + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + void initialize_fill_n(size_type n, const T& value) + { + allocate_storage(n); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.first_, + n, + value + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + template ::value>* = nullptr> + void initialize_range(InputIt first, InputIt last) + { + allocate_storage(0); + + SFL_TRY + { + while (first != last) + { + emplace_back(*first); + ++first; + } + } + SFL_CATCH (...) + { + clear(); + deallocate_storage(); + SFL_RETHROW; + } + } + + template ::value>* = nullptr> + void initialize_range(ForwardIt first, ForwardIt last) + { + allocate_storage(std::distance(first, last)); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + last, + data_.first_ + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + void initialize_copy(const segmented_devector& other) + { + allocate_storage(other.size()); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + data_.first_ + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + void initialize_move(segmented_devector& other) + { + if (data_.ref_to_alloc() == other.data_.ref_to_alloc()) + { + allocate_storage(0); + using std::swap; + swap(data_, other.data_); + } + else + { + allocate_storage(other.size()); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + data_.first_ + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + } + + void assign_fill_n(size_type n, const T& value) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = data_.first_ + n; + + sfl::dtl::fill + ( + data_.first_, + new_last, + value + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type available_back = this->available_back(); + + if (n <= size + available_back) + { + sfl::dtl::fill + ( + data_.first_, + data_.last_, + value + ); + + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - size, + value + ); + } + else + { + const size_type available_front = this->available_front(); + + if (n <= available_front + size + available_back) + { + sfl::dtl::fill + ( + data_.first_, + data_.last_, + value + ); + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.last_, + data_.eos_, + value + ); + + data_.last_ = data_.eos_; + + const iterator new_first = data_.first_ - (n - (size + available_back)); + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + new_first, + data_.first_, + value + ); + + data_.first_ = new_first; + } + else + { + grow_storage_back(n - (available_front + size + available_back)); + + sfl::dtl::fill + ( + data_.first_, + data_.last_, + value + ); + + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - (size + available_front), + value + ); + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.bos_, + data_.first_, + value + ); + + data_.first_ = data_.bos_; + } + } + } + } + + template ::value>* = nullptr> + void assign_range(InputIt first, InputIt last) + { + iterator curr = data_.first_; + + while (first != last && curr != data_.last_) + { + *curr = *first; + ++curr; + ++first; + } + + if (first != last) + { + do + { + emplace_back(*first); + ++first; + } + while (first != last); + } + else if (curr < data_.last_) + { + sfl::dtl::destroy_a(data_.ref_to_alloc(), curr, data_.last_); + data_.last_ = curr; + } + } + + template ::value>* = nullptr> + void assign_range(ForwardIt first, ForwardIt last) + { + const size_type n = std::distance(first, last); + + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = sfl::dtl::copy + ( + first, + last, + data_.first_ + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type available_back = this->available_back(); + + if (n <= size + available_back) + { + const ForwardIt mid = std::next(first, size); + + sfl::dtl::copy + ( + first, + mid, + data_.first_ + ); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid, + last, + data_.last_ + ); + } + else + { + const size_type available_front = this->available_front(); + + if (n <= available_front + size + available_back) + { + const ForwardIt mid1 = std::next(first, n - (size + available_back)); + const ForwardIt mid2 = std::next(mid1, size); + + sfl::dtl::copy + ( + mid1, + mid2, + data_.first_ + ); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid2, + last, + data_.last_ + ); + + const iterator new_first = data_.first_ - (n - (size + available_back)); + + sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + mid1, + new_first + ); + + data_.first_ = new_first; + } + else + { + grow_storage_back(n - (available_front + size + available_back)); + + const ForwardIt mid1 = std::next(first, available_front); + const ForwardIt mid2 = std::next(mid1, size); + + sfl::dtl::copy + ( + mid1, + mid2, + data_.first_ + ); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid2, + last, + data_.last_ + ); + + sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + mid1, + data_.bos_ + ); + + data_.first_ = data_.bos_; + } + } + } + } + + void assign_copy(const segmented_devector& other) + { + if (this != &other) + { + if (allocator_traits::propagate_on_container_copy_assignment::value) + { + if (data_.ref_to_alloc() != other.data_.ref_to_alloc()) + { + // Create temporary vector using other allocator. + // There are no effects if allocation fails. + segmented_devector temp(other.data_.ref_to_alloc()); + + // Clear and destroy_a current storage (noexcept). + clear(); + deallocate_storage(); + + // Set pointers to null (noexcept). + data_.table_bos_ = nullptr; + data_.table_eos_ = nullptr; + data_.table_first_ = nullptr; + data_.table_last_ = nullptr; + + // Swap storage of this and temporary vector (noexcept). + using std::swap; + swap(data_, temp.data_); + + // Temporary vector has no allocated storage (pointers + // are set to null) so destructor of temporary vector + // has nothing to do. + } + + // Propagate allocator (noexcept). + data_.ref_to_alloc() = other.data_.ref_to_alloc(); + } + + assign_range + ( + other.data_.first_, + other.data_.last_ + ); + } + } + + void assign_move(segmented_devector& other) + { + using std::swap; + + if (data_.ref_to_alloc() == other.data_.ref_to_alloc()) + { + // Create temporary container using allocator of "this". + // There are no effects if allocation fails. + // NOTE: We could also use allocator of "other". There are no + // difference since both allocators compare equal. + segmented_devector temp(data_.ref_to_alloc()); + + // Clear storage of "this" (noexcept). + clear(); + + // Destroy storage of "this" (noexcept). + // NOTE: This does not set pointers to null. + deallocate_storage(); + + // Set pointers of "this" to null pointers (noexcept). + data_.table_bos_ = nullptr; + data_.table_eos_ = nullptr; + data_.table_first_ = nullptr; + data_.table_last_ = nullptr; + + // Current state: + // - "this" has no allocated storage (pointers are null). + + // Swap storage of "this" and "other" (noexcept) + swap(data_, other.data_); + + // After swap: + // - "this" owns storage previously owned by "other". + // - "other" has no allocated storage (pointers are null). + + // Swap storage of "other" and "temp" (noexcept) + swap(other.data_, temp.data_); + + // After swap: + // - "other" owns storage previously owned by "temp". + // - "temp" has no allocated storage (pointers are null). + // This is OK in this case. Destructor of "temp" has + // nothing to do. + + if (allocator_traits::propagate_on_container_move_assignment::value) + { + // Propagate allocator (noexcept). + data_.ref_to_alloc() = std::move(other.data_.ref_to_alloc()); + } + } + else if (allocator_traits::propagate_on_container_move_assignment::value) + { + // Create temporary container using allocator of "other". + // There are no effects if allocation fails. + segmented_devector temp(other.data_.ref_to_alloc()); + + // Clear storage of "this" (noexcept). + clear(); + + // Destroy storage of "this" (noexcept). + // NOTE: This does not set pointers to null. + deallocate_storage(); + + // Set pointers of "this" to null pointers (noexcept). + data_.table_bos_ = nullptr; + data_.table_eos_ = nullptr; + data_.table_first_ = nullptr; + data_.table_last_ = nullptr; + + // Current state: + // - "this" has no allocated storage (pointers are null). + + // Swap storage of "this" and "temp" (noexcept) + swap(data_, temp.data_); + + // After swap: + // - "this" owns storage previously owned by "temp". + // That storage was allocated by allocator of "temp" + // (i.e. copy of allocator of "other"). + // "this" cannot deallocate that storage because allocators + // of "this" and "other" does not compare equal. + // - "temp" has no allocated storage (pointers are null). + // This is OK in this case. Destructor of "temp" has + // nothing to do. + + // Propagate allocator (noexcept). + data_.ref_to_alloc() = std::move(other.data_.ref_to_alloc()); + + // After propagation: + // - "this" owns storage previously owned by "temp", but now + // "this" can deallocate that storage. + + // Move elements one-by-one from "other" to "this" (can throw) + assign_range + ( + std::make_move_iterator(other.data_.first_), + std::make_move_iterator(other.data_.last_) + ); + } + else + { + // Move elements one-by-one from "other" to "this" (can throw) + assign_range + ( + std::make_move_iterator(other.data_.first_), + std::make_move_iterator(other.data_.last_) + ); + } + } + + iterator insert_fill_n(const_iterator pos, size_type n, const T& value) + { + if (n == 0) + { + return begin() + std::distance(cbegin(), pos); + } + + const value_type tmp(value); + + const size_type dist_to_begin = std::distance(cbegin(), pos); + const size_type dist_to_end = std::distance(pos, cend()); + + if (dist_to_begin < dist_to_end) + { + const size_type available_front = this->available_front(); + + if (available_front < n) + { + grow_storage_front(n - available_front); + } + + const iterator p1 = data_.first_ + dist_to_begin; + const iterator p2 = p1 - n; + + if (dist_to_begin > n) + { + const iterator p3 = data_.first_ + n; + const iterator p4 = data_.first_ - n; + + const iterator old_first = data_.first_; + + sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + data_.first_, + p3, + p4 + ); + + data_.first_ = p4; + + sfl::dtl::move + ( + p3, + p1, + old_first + ); + + sfl::dtl::fill + ( + p2, + p1, + tmp + ); + } + else + { + const iterator p3 = data_.first_ - n; + + const iterator old_first = data_.first_; + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + p2, + data_.first_, + tmp + ); + + data_.first_ = p2; + + sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + old_first, + p1, + p3 + ); + + data_.first_ = p3; + + sfl::dtl::fill + ( + old_first, + p1, + tmp + ); + } + + return p2; + } + else + { + const size_type available_back = this->available_back(); + + if (available_back < n) + { + grow_storage_back(n - available_back); + } + + const iterator p1 = data_.first_ + dist_to_begin; + const iterator p2 = p1 + n; + + if (dist_to_end > n) + { + const iterator p3 = data_.last_ - n; + + const iterator old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p3, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p3, + old_last + ); + + sfl::dtl::fill + ( + p1, + p2, + tmp + ); + } + else + { + const iterator old_last = data_.last_; + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.last_, + p2, + tmp + ); + + data_.last_ = p2; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p1, + old_last, + data_.last_ + ); + + sfl::dtl::fill + ( + p1, + old_last, + tmp + ); + } + + return p1; + } + } + + template ::value>* = nullptr> + iterator insert_range(const_iterator pos, InputIt first, InputIt last) + { + const size_type offset = std::distance(cbegin(), pos); + + while (first != last) + { + pos = insert(pos, *first); + ++pos; + ++first; + } + + return nth(offset); + } + + template ::value>* = nullptr> + iterator insert_range(const_iterator pos, ForwardIt first, ForwardIt last) + { + if (first == last) + { + return begin() + std::distance(cbegin(), pos); + } + + const size_type n = std::distance(first, last); + + const size_type dist_to_begin = std::distance(cbegin(), pos); + const size_type dist_to_end = std::distance(pos, cend()); + + if (dist_to_begin < dist_to_end) + { + const size_type available_front = this->available_front(); + + if (available_front < n) + { + grow_storage_front(n - available_front); + } + + const iterator p1 = data_.first_ + dist_to_begin; + const iterator p2 = p1 - n; + + if (dist_to_begin > n) + { + const iterator p3 = data_.first_ + n; + const iterator p4 = data_.first_ - n; + + const iterator old_first = data_.first_; + + sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + data_.first_, + p3, + p4 + ); + + data_.first_ = p4; + + sfl::dtl::move + ( + p3, + p1, + old_first + ); + + sfl::dtl::copy + ( + first, + last, + p2 + ); + } + else + { + const iterator p3 = data_.first_ - n; + + const iterator old_first = data_.first_; + + const ForwardIt mid = std::next(first, n - dist_to_begin); + + sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + mid, + p2 + ); + + data_.first_ = p2; + + sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + old_first, + p1, + p3 + ); + + data_.first_ = p3; + + sfl::dtl::copy + ( + mid, + last, + old_first + ); + } + + return p2; + } + else + { + const size_type available_back = this->available_back(); + + if (available_back < n) + { + grow_storage_back(n - available_back); + } + + const iterator p1 = data_.first_ + dist_to_begin; + const iterator p2 = data_.last_ - n; + + if (dist_to_end > n) + { + const iterator old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p2, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p2, + old_last + ); + + sfl::dtl::copy + ( + first, + last, + p1 + ); + } + else + { + const iterator old_last = data_.last_; + + const ForwardIt mid = std::next(first, dist_to_end); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid, + last, + data_.last_ + ); + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p1, + old_last, + data_.last_ + ); + + sfl::dtl::copy + ( + first, + mid, + p1 + ); + } + + return p1; + } + } +}; + +// +// ---- NON-MEMBER FUNCTIONS -------------------------------------------------- +// + +template +SFL_NODISCARD +bool operator== +( + const segmented_devector& x, + const segmented_devector& y +) +{ + return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); +} + +template +SFL_NODISCARD +bool operator!= +( + const segmented_devector& x, + const segmented_devector& y +) +{ + return !(x == y); +} + +template +SFL_NODISCARD +bool operator< +( + const segmented_devector& x, + const segmented_devector& y +) +{ + return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +template +SFL_NODISCARD +bool operator> +( + const segmented_devector& x, + const segmented_devector& y +) +{ + return y < x; +} + +template +SFL_NODISCARD +bool operator<= +( + const segmented_devector& x, + const segmented_devector& y +) +{ + return !(y < x); +} + +template +SFL_NODISCARD +bool operator>= +( + const segmented_devector& x, + const segmented_devector& y +) +{ + return !(x < y); +} + +template +void swap +( + segmented_devector& x, + segmented_devector& y +) +{ + x.swap(y); +} + +template +typename segmented_devector::size_type + erase(segmented_devector& c, const U& value) +{ + auto it = std::remove(c.begin(), c.end(), value); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +template +typename segmented_devector::size_type + erase_if(segmented_devector& c, Predicate pred) +{ + auto it = std::remove_if(c.begin(), c.end(), pred); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +} // namespace sfl + +#endif // SFL_SEGMENTED_DEVECTOR_HPP_INCLUDED diff --git a/src/thirdparty/sfl/segmented_vector.hpp b/src/thirdparty/sfl/segmented_vector.hpp new file mode 100644 index 0000000000..d5c9e50d1f --- /dev/null +++ b/src/thirdparty/sfl/segmented_vector.hpp @@ -0,0 +1,1808 @@ +// +// Copyright (c) 2022 Slaven Falandys +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef SFL_SEGMENTED_VECTOR_HPP_INCLUDED +#define SFL_SEGMENTED_VECTOR_HPP_INCLUDED + +#include "private.hpp" + +#include // copy, move, swap, swap_ranges +#include // size_t +#include // initializer_list +#include // distance, next, reverse_iterator +#include // numeric_limits +#include // allocator, allocator_traits, pointer_traits +#include // is_same, is_nothrow_xxxxx +#include // forward, move, pair + +namespace sfl +{ + +template < typename T, + std::size_t N, + typename Allocator = std::allocator > +class segmented_vector +{ + static_assert(N > 0, "N must be greater than zero."); + +public: + + using allocator_type = Allocator; + using allocator_traits = std::allocator_traits; + using value_type = T; + using size_type = typename allocator_traits::size_type; + using difference_type = typename allocator_traits::difference_type; + using reference = T&; + using const_reference = const T&; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + +private: + + using segment_allocator = typename std::allocator_traits::template rebind_alloc; + using segment_pointer = typename std::allocator_traits::pointer; + +public: + + using iterator = sfl::dtl::segmented_iterator; + using const_iterator = sfl::dtl::segmented_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static_assert + ( + std::is_same::value, + "Allocator::value_type must be same as sfl::segmented_vector::value_type." + ); + +public: + + static constexpr size_type segment_capacity = N; + +private: + + class data_base + { + public: + + // ---- TABLE (OF SEGMENTS) ---- + + segment_pointer table_first_; // First element in table + segment_pointer table_last_; // One-past-last element in table + segment_pointer table_eos_; // End of storage + + // ---- ELEMENTS IN VECTOR ---- + + iterator first_; // First element in vector + iterator last_; // One-past-last element in vector + iterator eos_; // End of storage + }; + + class data : public data_base, public allocator_type + { + public: + + data() noexcept(std::is_nothrow_default_constructible::value) + : allocator_type() + {} + + data(const allocator_type& alloc) noexcept(std::is_nothrow_copy_constructible::value) + : allocator_type(alloc) + {} + + data(allocator_type&& other) noexcept(std::is_nothrow_move_constructible::value) + : allocator_type(std::move(other)) + {} + + allocator_type& ref_to_alloc() noexcept + { + return *this; + } + + const allocator_type& ref_to_alloc() const noexcept + { + return *this; + } + }; + + data data_; + +public: + + // + // ---- CONSTRUCTION AND DESTRUCTION -------------------------------------- + // + + segmented_vector() + : data_() + { + initialize_empty(); + } + + explicit segmented_vector(const Allocator& alloc) + : data_(alloc) + { + initialize_empty(); + } + + segmented_vector(size_type n) + : data_() + { + initialize_default_n(n); + } + + explicit segmented_vector(size_type n, const Allocator& alloc) + : data_(alloc) + { + initialize_default_n(n); + } + + segmented_vector(size_type n, const T& value) + : data_() + { + initialize_fill_n(n, value); + } + + segmented_vector(size_type n, const T& value, const Allocator& alloc) + : data_(alloc) + { + initialize_fill_n(n, value); + } + + template ::value>* = nullptr> + segmented_vector(InputIt first, InputIt last) + : data_() + { + initialize_range(first, last); + } + + template ::value>* = nullptr> + segmented_vector(InputIt first, InputIt last, const Allocator& alloc) + : data_(alloc) + { + initialize_range(first, last); + } + + segmented_vector(std::initializer_list ilist) + : segmented_vector(ilist.begin(), ilist.end()) + {} + + segmented_vector(std::initializer_list ilist, const Allocator& alloc) + : segmented_vector(ilist.begin(), ilist.end(), alloc) + {} + + segmented_vector(const segmented_vector& other) + : data_ + ( + allocator_traits::select_on_container_copy_construction + ( + other.data_.ref_to_alloc() + ) + ) + { + initialize_copy(other); + } + + segmented_vector(const segmented_vector& other, const Allocator& alloc) + : data_(alloc) + { + initialize_copy(other); + } + + segmented_vector(segmented_vector&& other) + : data_(std::move(other.data_.ref_to_alloc())) + { + initialize_move(other); + } + + segmented_vector(segmented_vector&& other, const Allocator& alloc) + : data_(alloc) + { + initialize_move(other); + } + + ~segmented_vector() + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + deallocate_storage(); + } + + // + // ---- ASSIGNMENT -------------------------------------------------------- + // + + void assign(size_type n, const T& value) + { + assign_fill_n(n, value); + } + + template ::value>* = nullptr> + void assign(InputIt first, InputIt last) + { + assign_range(first, last); + } + + void assign(std::initializer_list ilist) + { + assign_range(ilist.begin(), ilist.end()); + } + + segmented_vector& operator=(const segmented_vector& other) + { + assign_copy(other); + return *this; + } + + segmented_vector& operator=(segmented_vector&& other) + { + assign_move(other); + return *this; + } + + segmented_vector& operator=(std::initializer_list ilist) + { + assign_range(ilist.begin(), ilist.end()); + return *this; + } + + // + // ---- ALLOCATOR --------------------------------------------------------- + // + + SFL_NODISCARD + allocator_type get_allocator() const noexcept + { + return data_.ref_to_alloc(); + } + + // + // ---- ITERATORS --------------------------------------------------------- + // + + SFL_NODISCARD + iterator begin() noexcept + { + return data_.first_; + } + + SFL_NODISCARD + const_iterator begin() const noexcept + { + return data_.first_; + } + + SFL_NODISCARD + const_iterator cbegin() const noexcept + { + return data_.first_; + } + + SFL_NODISCARD + iterator end() noexcept + { + return data_.last_; + } + + SFL_NODISCARD + const_iterator end() const noexcept + { + return data_.last_; + } + + SFL_NODISCARD + const_iterator cend() const noexcept + { + return data_.last_; + } + + SFL_NODISCARD + reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + iterator nth(size_type pos) noexcept + { + SFL_ASSERT(pos <= size()); + + const auto i = pos / N; + const auto j = pos - i * N; + + const auto seg = data_.table_first_ + i; + const auto elem = *seg + j; + + return iterator(seg, elem); + } + + SFL_NODISCARD + const_iterator nth(size_type pos) const noexcept + { + SFL_ASSERT(pos <= size()); + + const auto i = pos / N; + const auto j = pos - i * N; + + const auto seg = data_.table_first_ + i; + const auto elem = *seg + j; + + return iterator(seg, elem); + } + + SFL_NODISCARD + size_type index_of(const_iterator pos) const noexcept + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return std::distance(cbegin(), pos); + } + + // + // ---- SIZE AND CAPACITY ------------------------------------------------- + // + + SFL_NODISCARD + bool empty() const noexcept + { + return data_.last_ == data_.first_; + } + + SFL_NODISCARD + size_type size() const noexcept + { + return std::distance(data_.first_, data_.last_); + } + + SFL_NODISCARD + size_type max_size() const noexcept + { + return std::min + ( + allocator_traits::max_size(data_.ref_to_alloc()), + std::numeric_limits::max() / sizeof(value_type) + ); + } + + SFL_NODISCARD + size_type capacity() const noexcept + { + return std::distance(data_.first_, data_.eos_); + } + + SFL_NODISCARD + size_type available() const noexcept + { + return std::distance(data_.last_, data_.eos_); + } + + void reserve(size_type new_capacity) + { + const size_type capacity = this->capacity(); + + if (new_capacity > capacity) + { + grow_storage(new_capacity - capacity); + } + } + + void shrink_to_fit() + { + shrink_storage(); + } + + // + // ---- ELEMENT ACCESS ---------------------------------------------------- + // + + SFL_NODISCARD + reference at(size_type pos) + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::segmented_vector::at"); + } + + const auto i = pos / N; + const auto j = pos - i * N; + + return *(*(data_.table_first_ + i) + j); + } + + SFL_NODISCARD + const_reference at(size_type pos) const + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::segmented_vector::at"); + } + + const auto i = pos / N; + const auto j = pos - i * N; + + return *(*(data_.table_first_ + i) + j); + } + + SFL_NODISCARD + reference operator[](size_type pos) noexcept + { + SFL_ASSERT(pos < size()); + + const auto i = pos / N; + const auto j = pos - i * N; + + return *(*(data_.table_first_ + i) + j); + } + + SFL_NODISCARD + const_reference operator[](size_type pos) const noexcept + { + SFL_ASSERT(pos < size()); + + const auto i = pos / N; + const auto j = pos - i * N; + + return *(*(data_.table_first_ + i) + j); + } + + SFL_NODISCARD + reference front() noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + const_reference front() const noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + reference back() noexcept + { + SFL_ASSERT(!empty()); + return *(--iterator(data_.last_)); + } + + SFL_NODISCARD + const_reference back() const noexcept + { + SFL_ASSERT(!empty()); + return *(--iterator(data_.last_)); + } + + // + // ---- MODIFIERS --------------------------------------------------------- + // + + void clear() noexcept + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + data_.last_ = data_.first_; + } + + template + iterator emplace(const_iterator pos, Args&&... args) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + + iterator p1 = begin() + std::distance(cbegin(), pos); + + if (data_.last_ == data_.eos_) + { + const size_type offset = std::distance(cbegin(), pos); + grow_storage(1); + p1 = nth(offset); + } + + if (p1 == data_.last_) + { + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*data_.last_), + std::forward(args)... + ); + + ++data_.last_; + } + else + { + const iterator p2 = --iterator(data_.last_); + + const iterator old_last = data_.last_; + + // The order of operations is critical. First we will construct + // temporary value because arguments `args...` can contain + // reference to element in this container and after that + // we will move elements and insert new element. + + value_type tmp(std::forward(args)...); + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*old_last), + std::move(*p2) + ); + + ++data_.last_; + + sfl::dtl::move_backward + ( + p1, + p2, + old_last + ); + + *p1 = std::move(tmp); + } + + return p1; + } + + iterator insert(const_iterator pos, const T& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return emplace(pos, value); + } + + iterator insert(const_iterator pos, T&& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return emplace(pos, std::move(value)); + } + + iterator insert(const_iterator pos, size_type n, const T& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_fill_n(pos, n, value); + } + + template ::value>* = nullptr> + iterator insert(const_iterator pos, InputIt first, InputIt last) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_range(pos, first, last); + } + + iterator insert(const_iterator pos, std::initializer_list ilist) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_range(pos, ilist.begin(), ilist.end()); + } + + template + reference emplace_back(Args&&... args) + { + if (data_.last_ == data_.eos_) + { + grow_storage(1); + } + + const iterator old_last = data_.last_; + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + std::addressof(*data_.last_), + std::forward(args)... + ); + + ++data_.last_; + + return *old_last; + } + + void push_back(const T& value) + { + emplace_back(value); + } + + void push_back(T&& value) + { + emplace_back(std::move(value)); + } + + void pop_back() + { + SFL_ASSERT(!empty()); + + --data_.last_; + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), std::addressof(*data_.last_)); + } + + iterator erase(const_iterator pos) + { + SFL_ASSERT(cbegin() <= pos && pos < cend()); + + const iterator p = begin() + std::distance(cbegin(), pos); + + data_.last_ = sfl::dtl::move(p + 1, data_.last_, p); + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), std::addressof(*data_.last_)); + + return p; + } + + iterator erase(const_iterator first, const_iterator last) + { + SFL_ASSERT(cbegin() <= first && first <= last && last <= cend()); + + if (first == last) + { + return begin() + std::distance(cbegin(), first); + } + + const iterator p1 = begin() + std::distance(cbegin(), first); + const iterator p2 = begin() + std::distance(cbegin(), last); + + const iterator new_last = sfl::dtl::move(p2, data_.last_, p1); + + sfl::dtl::destroy_a(data_.ref_to_alloc(), new_last, data_.last_); + + data_.last_ = new_last; + + return p1; + } + + void resize(size_type n) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = nth(n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type delta = n - size; + + const size_type capacity = this->capacity(); + + if (n > capacity) + { + grow_storage(n - capacity); + } + + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.last_, + delta + ); + } + } + + void resize(size_type n, const T& value) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = nth(n); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type delta = n - size; + + const size_type capacity = this->capacity(); + + if (n > capacity) + { + grow_storage(n - capacity); + } + + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + delta, + value + ); + } + } + + void swap(segmented_vector& other) noexcept + { + SFL_ASSERT + ( + allocator_traits::propagate_on_container_swap::value || + this->data_.ref_to_alloc() == other.data_.ref_to_alloc() + ); + + if (this == &other) + { + return; + } + + using std::swap; + + if (allocator_traits::propagate_on_container_swap::value) + { + swap(this->data_.ref_to_alloc(), other.data_.ref_to_alloc()); + } + + swap(this->data_, other.data_); + } + +private: + + // Allocates table for given number of elements (segments). + // It does not construct any element (segment). + // It only allocates memory for table. + // + segment_pointer allocate_table(size_type n) + { + segment_allocator seg_alloc(data_.ref_to_alloc()); + return sfl::dtl::allocate(seg_alloc, n); + } + + // Deallocates table. + // It does not destroy_a any element (segment). + // It only deallocates memory used by table. + // + void deallocate_table(segment_pointer p, size_type n) noexcept + { + segment_allocator seg_alloc(data_.ref_to_alloc()); + sfl::dtl::deallocate(seg_alloc, p, n); + } + + // Allocates memory for single segment. + // It does not construct any element. + // It only allocates memory for segment. + // + pointer allocate_segment() + { + return sfl::dtl::allocate(data_.ref_to_alloc(), N); + } + + // Deallocates memory used by single segment. + // It does not destroy_a any element. + // It only deallocates memory used by segment. + // + void deallocate_segment(pointer p) noexcept + { + sfl::dtl::deallocate(data_.ref_to_alloc(), p, N); + } + + // Allocates memory for multiple segments. + // It does not construct any element. + // It only allocates memory for segments. + // + void allocate_segments(segment_pointer first, segment_pointer last) + { + segment_pointer curr = first; + + SFL_TRY + { + while (curr != last) + { + *curr = allocate_segment(); + ++curr; + } + } + SFL_CATCH (...) + { + deallocate_segments(first, curr); + SFL_RETHROW; + } + } + + // Deallocates memory used by multiple segments. + // It does not destroy_a any element. + // It only deallocates memory used by segments. + // + void deallocate_segments(segment_pointer first, segment_pointer last) noexcept + { + while (first != last) + { + deallocate_segment(*first); + ++first; + } + } + + static constexpr size_type min_table_capacity() noexcept + { + return 8; + } + + // Allocates storage big enough to keep given number of elements. + // It does not construct any element. + // It only allocates memory. + // + void allocate_storage(size_type num_elements) + { + if (num_elements > max_size()) + { + sfl::dtl::throw_length_error("sfl::segmented_vector::allocate_storage"); + } + + // Required capacity of table + const size_type table_required = + num_elements / N + 1; + + const size_type table_capacity = + std::max(table_required, min_table_capacity()); + + data_.table_first_ = allocate_table(table_capacity); + data_.table_last_ = data_.table_first_ + table_required; + data_.table_eos_ = data_.table_first_ + table_capacity; + + SFL_TRY + { + allocate_segments(data_.table_first_, data_.table_last_); + + data_.first_.segment_ = data_.table_first_; + data_.first_.local_ = *data_.table_first_; + + data_.last_ = data_.first_; + + data_.eos_.segment_ = (data_.table_last_ - 1); + data_.eos_.local_ = *(data_.table_last_ - 1) + (N - 1); + } + SFL_CATCH (...) + { + deallocate_table(data_.table_first_, table_capacity); + SFL_RETHROW; + } + } + + // Deallocates storage. + // It does not destroy_a any element. + // It only deallocates memory. + // + void deallocate_storage() noexcept + { + deallocate_segments + ( + data_.table_first_, + data_.table_last_ + ); + + deallocate_table + ( + data_.table_first_, + std::distance(data_.table_first_, data_.table_eos_) + ); + } + + // Increases capacity for given number of elements. + // It does not construct any element. + // It only allocates memory. + // + void grow_storage(size_type num_additional_elements) + { + if (max_size() - capacity() < num_additional_elements) + { + sfl::dtl::throw_length_error("sfl::segmented_vector::grow_storage"); + } + + // Required capacity of table + const size_type table_required = + num_additional_elements / N + 1; + + // Available capacity of table + const size_type table_available = + std::distance(data_.table_last_, data_.table_eos_); + + // Increase table capacity if neccessary + if (table_required > table_available) + { + const size_type table_capacity = + std::distance(data_.table_first_, data_.table_eos_); + + const size_type new_table_capacity = std::max + ( + table_capacity + table_capacity / 2, + table_capacity - table_available + table_required + ); + + // Distance (in segments) from FIRST element to LAST element. + const size_type dist1 = + std::distance(data_.first_.segment_, data_.last_.segment_); + + // Distance (in segments) from FIRST element to END OF STORAGE. + const size_type dist2 = + std::distance(data_.first_.segment_, data_.eos_.segment_); + + // Allocate new table. No effects if allocation fails. + const segment_pointer new_table_first = + allocate_table(new_table_capacity); + + const segment_pointer new_table_eos = + new_table_first + new_table_capacity; + + // Initialize LAST element in new table (noexecept). + const segment_pointer new_table_last = sfl::dtl::copy + ( + data_.table_first_, + data_.table_last_, + new_table_first + ); + + // Deallocate old table (noexcept). + deallocate_table(data_.table_first_, table_capacity); + + // Update pointers (noexcept). + data_.table_first_ = new_table_first; + data_.table_last_ = new_table_last; + data_.table_eos_ = new_table_eos; + + // Update iterators (noexcept). + data_.first_.segment_ = new_table_first; + data_.last_.segment_ = new_table_first + dist1; + data_.eos_.segment_ = new_table_first + dist2; + } + + const segment_pointer new_table_last = + data_.table_last_ + table_required; + + // Allocate additional segments. No effects if allocation fails. + allocate_segments(data_.table_last_, new_table_last); + + // Update table (noexcept). + data_.table_last_ = new_table_last; + + // Update iterators (noexcept). + data_.eos_.segment_ = data_.table_last_ - 1; + data_.eos_.local_ = *(data_.table_last_ - 1) + (N - 1); + } + + // Removes unused capacity. + // It does not destroy_a any element. + // It only deallocates memory. + // + void shrink_storage() + { + // Destroy empty segments. + { + const segment_pointer new_table_last = data_.last_.segment_ + 1; + + deallocate_segments(new_table_last, data_.table_last_); + + data_.table_last_ = new_table_last; + + data_.eos_.segment_ = (data_.table_last_ - 1); + data_.eos_.local_ = *(data_.table_last_ - 1) + (N - 1); + } + + // Shrink table. + { + const size_type table_capacity = + std::distance(data_.table_first_, data_.table_eos_); + + const size_type table_size = + std::distance(data_.table_first_, data_.table_last_); + + const size_type new_table_capacity = + std::max(table_size, min_table_capacity()); + + // Distance (in segments) from FIRST element to LAST element. + const size_type dist = + std::distance(data_.first_.segment_, data_.last_.segment_); + + // Allocate new table. No effects if allocation fails. + const segment_pointer new_table_first = + allocate_table(new_table_capacity); + + const segment_pointer new_table_eos = + new_table_first + new_table_capacity; + + // Initialize LAST element in new table (noexecept). + const segment_pointer new_table_last = sfl::dtl::copy + ( + data_.table_first_, + data_.table_last_, + new_table_first + ); + + // Deallocate old table (noexcept). + deallocate_table(data_.table_first_, table_capacity); + + // Update pointers (noexcept). + data_.table_first_ = new_table_first; + data_.table_last_ = new_table_last; + data_.table_eos_ = new_table_eos; + + // Update iterators (noexcept). + data_.first_.segment_ = data_.table_first_; + data_.last_.segment_ = data_.table_first_ + dist; + data_.eos_.segment_ = data_.table_last_ - 1; + } + } + + void initialize_empty() + { + allocate_storage(0); + } + + void initialize_default_n(size_type n) + { + allocate_storage(n); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.first_, + n + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + void initialize_fill_n(size_type n, const T& value) + { + allocate_storage(n); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.first_, + n, + value + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + template ::value>* = nullptr> + void initialize_range(InputIt first, InputIt last) + { + allocate_storage(0); + + SFL_TRY + { + while (first != last) + { + emplace_back(*first); + ++first; + } + } + SFL_CATCH (...) + { + clear(); + deallocate_storage(); + SFL_RETHROW; + } + } + + template ::value>* = nullptr> + void initialize_range(ForwardIt first, ForwardIt last) + { + allocate_storage(std::distance(first, last)); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + last, + data_.first_ + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + void initialize_copy(const segmented_vector& other) + { + allocate_storage(other.size()); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + data_.first_ + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + + void initialize_move(segmented_vector& other) + { + if (data_.ref_to_alloc() == other.data_.ref_to_alloc()) + { + allocate_storage(0); + using std::swap; + swap(data_, other.data_); + } + else + { + allocate_storage(other.size()); + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + data_.first_ + ); + } + SFL_CATCH (...) + { + deallocate_storage(); + SFL_RETHROW; + } + } + } + + void assign_fill_n(size_type n, const T& value) + { + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = data_.first_ + n; + + sfl::dtl::fill + ( + data_.first_, + new_last, + value + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type capacity = this->capacity(); + + if (n > capacity) + { + grow_storage(n - capacity); + } + + sfl::dtl::fill + ( + data_.first_, + data_.first_ + size, + value + ); + + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + n - size, + value + ); + } + } + + template ::value>* = nullptr> + void assign_range(InputIt first, InputIt last) + { + iterator curr = data_.first_; + + while (first != last && curr != data_.last_) + { + *curr = *first; + ++curr; + ++first; + } + + if (first != last) + { + do + { + emplace_back(*first); + ++first; + } + while (first != last); + } + else if (curr < data_.last_) + { + sfl::dtl::destroy_a(data_.ref_to_alloc(), curr, data_.last_); + data_.last_ = curr; + } + } + + template ::value>* = nullptr> + void assign_range(ForwardIt first, ForwardIt last) + { + const size_type n = std::distance(first, last); + + const size_type size = this->size(); + + if (n <= size) + { + const iterator new_last = sfl::dtl::copy + ( + first, + last, + data_.first_ + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const size_type capacity = this->capacity(); + + if (n > capacity) + { + grow_storage(n - capacity); + } + + const ForwardIt mid = std::next(first, size); + + sfl::dtl::copy + ( + first, + mid, + data_.first_ + ); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid, + last, + data_.last_ + ); + } + } + + void assign_copy(const segmented_vector& other) + { + if (this != &other) + { + if (allocator_traits::propagate_on_container_copy_assignment::value) + { + if (data_.ref_to_alloc() != other.data_.ref_to_alloc()) + { + // Create temporary vector using other allocator. + // There are no effects if allocation fails. + segmented_vector temp(other.data_.ref_to_alloc()); + + // Clear and destroy_a current storage (noexcept). + clear(); + deallocate_storage(); + + // Set pointers to null (noexcept). + data_.table_first_ = nullptr; + data_.table_last_ = nullptr; + data_.table_eos_ = nullptr; + + // Swap storage of this and temporary vector (noexcept). + using std::swap; + swap(data_, temp.data_); + + // Temporary vector has no allocated storage (pointers + // are set to null) so destructor of temporary vector + // has nothing to do. + } + + // Propagate allocator (noexcept). + data_.ref_to_alloc() = other.data_.ref_to_alloc(); + } + + assign_range + ( + other.data_.first_, + other.data_.last_ + ); + } + } + + void assign_move(segmented_vector& other) + { + using std::swap; + + if (data_.ref_to_alloc() == other.data_.ref_to_alloc()) + { + // Create temporary container using allocator of "this". + // There are no effects if allocation fails. + // NOTE: We could also use allocator of "other". There are no + // difference since both allocators compare equal. + segmented_vector temp(data_.ref_to_alloc()); + + // Clear storage of "this" (noexcept). + clear(); + + // Destroy storage of "this" (noexcept). + // NOTE: This does not set pointers to null. + deallocate_storage(); + + // Set pointers of "this" to null pointers (noexcept). + data_.table_first_ = nullptr; + data_.table_last_ = nullptr; + data_.table_eos_ = nullptr; + + // Current state: + // - "this" has no allocated storage (pointers are null). + + // Swap storage of "this" and "other" (noexcept) + swap(data_, other.data_); + + // After swap: + // - "this" owns storage previously owned by "other". + // - "other" has no allocated storage (pointers are null). + + // Swap storage of "other" and "temp" (noexcept) + swap(other.data_, temp.data_); + + // After swap: + // - "other" owns storage previously owned by "temp". + // - "temp" has no allocated storage (pointers are null). + // This is OK in this case. Destructor of "temp" has + // nothing to do. + + if (allocator_traits::propagate_on_container_move_assignment::value) + { + // Propagate allocator (noexcept). + data_.ref_to_alloc() = std::move(other.data_.ref_to_alloc()); + } + } + else if (allocator_traits::propagate_on_container_move_assignment::value) + { + // Create temporary container using allocator of "other". + // There are no effects if allocation fails. + segmented_vector temp(other.data_.ref_to_alloc()); + + // Clear storage of "this" (noexcept). + clear(); + + // Destroy storage of "this" (noexcept). + // NOTE: This does not set pointers to null. + deallocate_storage(); + + // Set pointers of "this" to null pointers (noexcept). + data_.table_first_ = nullptr; + data_.table_last_ = nullptr; + data_.table_eos_ = nullptr; + + // Current state: + // - "this" has no allocated storage (pointers are null). + + // Swap storage of "this" and "temp" (noexcept) + swap(data_, temp.data_); + + // After swap: + // - "this" owns storage previously owned by "temp". + // That storage was allocated by allocator of "temp" + // (i.e. copy of allocator of "other"). + // "this" cannot deallocate that storage because allocators + // of "this" and "other" does not compare equal. + // - "temp" has no allocated storage (pointers are null). + // This is OK in this case. Destructor of "temp" has + // nothing to do. + + // Propagate allocator (noexcept). + data_.ref_to_alloc() = std::move(other.data_.ref_to_alloc()); + + // After propagation: + // - "this" owns storage previously owned by "temp", but now + // "this" can deallocate that storage. + + // Move elements one-by-one from "other" to "this" (can throw) + assign_range + ( + std::make_move_iterator(other.data_.first_), + std::make_move_iterator(other.data_.last_) + ); + } + else + { + // Move elements one-by-one from "other" to "this" (can throw) + assign_range + ( + std::make_move_iterator(other.data_.first_), + std::make_move_iterator(other.data_.last_) + ); + } + } + + iterator insert_fill_n(const_iterator pos, size_type n, const T& value) + { + if (n == 0) + { + return begin() + std::distance(cbegin(), pos); + } + + const value_type tmp(value); + + const size_type dist_to_begin = std::distance(cbegin(), pos); + + const size_type available = this->available(); + + if (available < n) + { + grow_storage(n - available); + } + + const iterator p1 = data_.first_ + dist_to_begin; + const iterator p2 = p1 + n; + + if (p2 <= data_.last_) + { + const iterator p3 = data_.last_ - n; + + const iterator old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p3, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p3, + old_last + ); + + sfl::dtl::fill + ( + p1, + p2, + tmp + ); + } + else + { + const iterator old_last = data_.last_; + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.last_, + p2, + tmp + ); + + data_.last_ = p2; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p1, + old_last, + data_.last_ + ); + + sfl::dtl::fill + ( + p1, + old_last, + tmp + ); + } + + return p1; + } + + template ::value>* = nullptr> + iterator insert_range(const_iterator pos, InputIt first, InputIt last) + { + const size_type offset = std::distance(cbegin(), pos); + + while (first != last) + { + pos = insert(pos, *first); + ++pos; + ++first; + } + + return nth(offset); + } + + template ::value>* = nullptr> + iterator insert_range(const_iterator pos, ForwardIt first, ForwardIt last) + { + if (first == last) + { + return begin() + std::distance(cbegin(), pos); + } + + const size_type n = std::distance(first, last); + + const size_type dist_to_begin = std::distance(cbegin(), pos); + const size_type dist_to_end = std::distance(pos, cend()); + + const size_type available = this->available(); + + if (available < n) + { + grow_storage(n - available); + } + + const iterator p1 = data_.first_ + dist_to_begin; + const iterator p2 = p1 + n; + + if (p2 <= data_.last_) + { + const iterator p3 = data_.last_ - n; + + const iterator old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p3, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p3, + old_last + ); + + sfl::dtl::copy + ( + first, + last, + p1 + ); + } + else + { + const iterator old_last = data_.last_; + + const ForwardIt mid = std::next(first, dist_to_end); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid, + last, + data_.last_ + ); + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p1, + old_last, + data_.last_ + ); + + sfl::dtl::copy + ( + first, + mid, + p1 + ); + } + + return p1; + } +}; + +// +// ---- NON-MEMBER FUNCTIONS -------------------------------------------------- +// + +template +SFL_NODISCARD +bool operator== +( + const segmented_vector& x, + const segmented_vector& y +) +{ + return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); +} + +template +SFL_NODISCARD +bool operator!= +( + const segmented_vector& x, + const segmented_vector& y +) +{ + return !(x == y); +} + +template +SFL_NODISCARD +bool operator< +( + const segmented_vector& x, + const segmented_vector& y +) +{ + return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +template +SFL_NODISCARD +bool operator> +( + const segmented_vector& x, + const segmented_vector& y +) +{ + return y < x; +} + +template +SFL_NODISCARD +bool operator<= +( + const segmented_vector& x, + const segmented_vector& y +) +{ + return !(y < x); +} + +template +SFL_NODISCARD +bool operator>= +( + const segmented_vector& x, + const segmented_vector& y +) +{ + return !(x < y); +} + +template +void swap +( + segmented_vector& x, + segmented_vector& y +) +{ + x.swap(y); +} + +template +typename segmented_vector::size_type + erase(segmented_vector& c, const U& value) +{ + auto it = std::remove(c.begin(), c.end(), value); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +template +typename segmented_vector::size_type + erase_if(segmented_vector& c, Predicate pred) +{ + auto it = std::remove_if(c.begin(), c.end(), pred); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +} // namespace sfl + +#endif // SFL_SEGMENTED_VECTOR_HPP_INCLUDED diff --git a/src/thirdparty/sfl/small_vector.hpp b/src/thirdparty/sfl/small_vector.hpp new file mode 100644 index 0000000000..0d2c6b09ad --- /dev/null +++ b/src/thirdparty/sfl/small_vector.hpp @@ -0,0 +1,2540 @@ +// +// Copyright (c) 2022 Slaven Falandys +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef SFL_SMALL_VECTOR_HPP_INCLUDED +#define SFL_SMALL_VECTOR_HPP_INCLUDED + +#include "private.hpp" + +#include // copy, move, swap, swap_ranges +#include // size_t +#include // initializer_list +#include // distance, next, reverse_iterator +#include // numeric_limits +#include // allocator, allocator_traits, pointer_traits +#include // is_same, is_nothrow_xxxxx +#include // forward, move, pair + +namespace sfl +{ + +template < typename T, + std::size_t N, + typename Allocator = std::allocator > +class small_vector +{ +public: + + using allocator_type = Allocator; + using allocator_traits = std::allocator_traits; + using value_type = T; + using size_type = typename allocator_traits::size_type; + using difference_type = typename allocator_traits::difference_type; + using reference = T&; + using const_reference = const T&; + using pointer = typename allocator_traits::pointer; + using const_pointer = typename allocator_traits::const_pointer; + using iterator = sfl::dtl::normal_iterator; + using const_iterator = sfl::dtl::normal_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static_assert + ( + std::is_same::value, + "Allocator::value_type must be same as sfl::small_vector::value_type." + ); + +public: + + static constexpr size_type static_capacity = N; + +private: + + template + class data_base + { + private: + + union + { + value_type internal_storage_[N]; + }; + + public: + + pointer first_; + pointer last_; + pointer eos_; + + data_base() noexcept + : first_(std::pointer_traits::pointer_to(*internal_storage_)) + , last_(first_) + , eos_(first_ + N) + {} + + ~data_base() noexcept + {} + + pointer internal_storage() noexcept + { + return std::pointer_traits::pointer_to(*internal_storage_); + } + }; + + template + class data_base + { + public: + + pointer first_; + pointer last_; + pointer eos_; + + data_base() noexcept + : first_(nullptr) + , last_(nullptr) + , eos_(nullptr) + {} + + pointer internal_storage() noexcept + { + return nullptr; + } + }; + + class data : public data_base<(N > 0)> , public allocator_type + { + public: + + data() noexcept(std::is_nothrow_default_constructible::value) + : allocator_type() + {} + + data(const allocator_type& alloc) noexcept(std::is_nothrow_copy_constructible::value) + : allocator_type(alloc) + {} + + data(allocator_type&& other) noexcept(std::is_nothrow_move_constructible::value) + : allocator_type(std::move(other)) + {} + + allocator_type& ref_to_alloc() noexcept + { + return *this; + } + + const allocator_type& ref_to_alloc() const noexcept + { + return *this; + } + }; + + data data_; + +public: + + // + // ---- CONSTRUCTION AND DESTRUCTION -------------------------------------- + // + + small_vector() noexcept + ( + std::is_nothrow_default_constructible::value + ) + : data_() + {} + + explicit small_vector(const Allocator& alloc) noexcept + ( + std::is_nothrow_copy_constructible::value + ) + : data_(alloc) + {} + + small_vector(size_type n) + : data_() + { + initialize_default_n(n); + } + + explicit small_vector(size_type n, const Allocator& alloc) + : data_(alloc) + { + initialize_default_n(n); + } + + small_vector(size_type n, const T& value) + : data_() + { + initialize_fill_n(n, value); + } + + small_vector(size_type n, const T& value, const Allocator& alloc) + : data_(alloc) + { + initialize_fill_n(n, value); + } + + template ::value>* = nullptr> + small_vector(InputIt first, InputIt last) + : data_() + { + initialize_range(first, last); + } + + template ::value>* = nullptr> + small_vector(InputIt first, InputIt last, const Allocator& alloc) + : data_(alloc) + { + initialize_range(first, last); + } + + small_vector(std::initializer_list ilist) + : small_vector(ilist.begin(), ilist.end()) + {} + + small_vector(std::initializer_list ilist, const Allocator& alloc) + : small_vector(ilist.begin(), ilist.end(), alloc) + {} + + small_vector(const small_vector& other) + : data_ + ( + allocator_traits::select_on_container_copy_construction + ( + other.data_.ref_to_alloc() + ) + ) + { + initialize_copy(other); + } + + small_vector(const small_vector& other, const Allocator& alloc) + : data_(alloc) + { + initialize_copy(other); + } + + small_vector(small_vector&& other) + : data_(std::move(other.data_.ref_to_alloc())) + { + initialize_move(other); + } + + small_vector(small_vector&& other, const Allocator& alloc) + : data_(alloc) + { + initialize_move(other); + } + + ~small_vector() + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + } + + // + // ---- ASSIGNMENT -------------------------------------------------------- + // + + void assign(size_type n, const T& value) + { + assign_fill_n(n, value); + } + + template ::value>* = nullptr> + void assign(InputIt first, InputIt last) + { + assign_range(first, last); + } + + void assign(std::initializer_list ilist) + { + assign_range(ilist.begin(), ilist.end()); + } + + small_vector& operator=(const small_vector& other) + { + assign_copy(other); + return *this; + } + + small_vector& operator=(small_vector&& other) + { + assign_move(other); + return *this; + } + + small_vector& operator=(std::initializer_list ilist) + { + assign_range(ilist.begin(), ilist.end()); + return *this; + } + + // + // ---- ALLOCATOR --------------------------------------------------------- + // + + SFL_NODISCARD + allocator_type get_allocator() const noexcept + { + return data_.ref_to_alloc(); + } + + // + // ---- ITERATORS --------------------------------------------------------- + // + + SFL_NODISCARD + iterator begin() noexcept + { + return iterator(data_.first_); + } + + SFL_NODISCARD + const_iterator begin() const noexcept + { + return const_iterator(data_.first_); + } + + SFL_NODISCARD + const_iterator cbegin() const noexcept + { + return const_iterator(data_.first_); + } + + SFL_NODISCARD + iterator end() noexcept + { + return iterator(data_.last_); + } + + SFL_NODISCARD + const_iterator end() const noexcept + { + return const_iterator(data_.last_); + } + + SFL_NODISCARD + const_iterator cend() const noexcept + { + return const_iterator(data_.last_); + } + + SFL_NODISCARD + reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + iterator nth(size_type pos) noexcept + { + SFL_ASSERT(pos <= size()); + return iterator(data_.first_ + pos); + } + + SFL_NODISCARD + const_iterator nth(size_type pos) const noexcept + { + SFL_ASSERT(pos <= size()); + return const_iterator(data_.first_ + pos); + } + + SFL_NODISCARD + size_type index_of(const_iterator pos) const noexcept + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return std::distance(cbegin(), pos); + } + + // + // ---- SIZE AND CAPACITY ------------------------------------------------- + // + + SFL_NODISCARD + bool empty() const noexcept + { + return data_.first_ == data_.last_; + } + + SFL_NODISCARD + size_type size() const noexcept + { + return std::distance(data_.first_, data_.last_); + } + + SFL_NODISCARD + size_type max_size() const noexcept + { + return std::min + ( + allocator_traits::max_size(data_.ref_to_alloc()), + std::numeric_limits::max() / sizeof(value_type) + ); + } + + SFL_NODISCARD + size_type capacity() const noexcept + { + return std::distance(data_.first_, data_.eos_); + } + + SFL_NODISCARD + size_type available() const noexcept + { + return std::distance(data_.last_, data_.eos_); + } + + void reserve(size_type new_cap) + { + check_size(new_cap, "sfl::small_vector::reserve"); + + if (new_cap > capacity()) + { + if (new_cap <= N) + { + if (data_.first_ == data_.internal_storage()) + { + // Do nothing. We are already using internal storage. + } + else + { + // We are not using internal storage but new capacity + // can fit in internal storage. + + pointer new_first = data_.internal_storage(); + pointer new_last = new_first; + pointer new_eos = new_first + N; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_, + new_first + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + } + } + else + { + pointer new_first = sfl::dtl::allocate(data_.ref_to_alloc(), new_cap); + pointer new_last = new_first; + pointer new_eos = new_first + new_cap; + + SFL_TRY + { + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_, + new_first + ); + } + SFL_CATCH (...) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + new_cap + ); + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + } + } + } + + void shrink_to_fit() + { + const size_type new_cap = size(); + + if (new_cap < capacity()) + { + if (new_cap <= N) + { + if (data_.first_ == data_.internal_storage()) + { + // Do nothing. We are already using internal storage. + } + else + { + // We are not using internal storage but new capacity + // can fit in internal storage. + + pointer new_first = data_.internal_storage(); + pointer new_last = new_first; + pointer new_eos = new_first + N; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_, + new_first + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + } + } + else + { + pointer new_first = sfl::dtl::allocate(data_.ref_to_alloc(), new_cap); + pointer new_last = new_first; + pointer new_eos = new_first + new_cap; + + SFL_TRY + { + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_, + new_first + ); + } + SFL_CATCH (...) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + new_cap + ); + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + } + } + } + + // + // ---- ELEMENT ACCESS ---------------------------------------------------- + // + + SFL_NODISCARD + reference at(size_type pos) + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::small_vector::at"); + } + + return *(data_.first_ + pos); + } + + SFL_NODISCARD + const_reference at(size_type pos) const + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::small_vector::at"); + } + + return *(data_.first_ + pos); + } + + SFL_NODISCARD + reference operator[](size_type pos) noexcept + { + SFL_ASSERT(pos < size()); + return *(data_.first_ + pos); + } + + SFL_NODISCARD + const_reference operator[](size_type pos) const noexcept + { + SFL_ASSERT(pos < size()); + return *(data_.first_ + pos); + } + + SFL_NODISCARD + reference front() noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + const_reference front() const noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + reference back() noexcept + { + SFL_ASSERT(!empty()); + return *(data_.last_ - 1); + } + + SFL_NODISCARD + const_reference back() const noexcept + { + SFL_ASSERT(!empty()); + return *(data_.last_ - 1); + } + + SFL_NODISCARD + T* data() noexcept + { + return sfl::dtl::to_address(data_.first_); + } + + SFL_NODISCARD + const T* data() const noexcept + { + return sfl::dtl::to_address(data_.first_); + } + + // + // ---- MODIFIERS --------------------------------------------------------- + // + + void clear() noexcept + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + data_.last_ = data_.first_; + } + + template + iterator emplace(const_iterator pos, Args&&... args) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + + if (data_.last_ != data_.eos_) + { + const pointer p1 = data_.first_ + std::distance(cbegin(), pos); + + if (p1 == data_.last_) + { + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + p1, + std::forward(args)... + ); + + ++data_.last_; + } + else + { + // This container can contain duplicates so we must + // create new element now as a temporary value. + value_type tmp(std::forward(args)...); + + const pointer p2 = data_.last_ - 1; + + const pointer old_last = data_.last_; + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + data_.last_, + std::move(*p2) + ); + + ++data_.last_; + + sfl::dtl::move_backward + ( + p1, + p2, + old_last + ); + + *p1 = std::move(tmp); + } + + return iterator(p1); + } + else + { + const difference_type offset = std::distance(cbegin(), pos); + + const size_type new_cap = + calculate_new_capacity(1, "sfl::small_vector::emplace"); + + pointer new_first; + pointer new_last; + pointer new_eos; + + if (new_cap <= N && data_.first_ != data_.internal_storage()) + { + new_first = data_.internal_storage(); + new_last = new_first; + new_eos = new_first + N; + } + else + { + new_first = sfl::dtl::allocate(data_.ref_to_alloc(), new_cap); + new_last = new_first; + new_eos = new_first + new_cap; + } + + const pointer p = new_first + offset; + + SFL_TRY + { + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + p, + std::forward(args)... + ); + + new_last = nullptr; + + const pointer mid = data_.first_ + offset; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + mid, + new_first + ); + + ++new_last; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + mid, + data_.last_, + new_last + ); + } + SFL_CATCH (...) + { + if (new_last == nullptr) + { + sfl::dtl::destroy_at_a + ( + data_.ref_to_alloc(), + p + ); + } + else + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_first, + new_last + ); + } + + if (new_first != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + new_cap + ); + } + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + + return iterator(p); + } + } + + iterator insert(const_iterator pos, const T& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return emplace(pos, value); + } + + iterator insert(const_iterator pos, T&& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return emplace(pos, std::move(value)); + } + + iterator insert(const_iterator pos, size_type n, const T& value) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_fill_n(pos, n, value); + } + + template ::value>* = nullptr> + iterator insert(const_iterator pos, InputIt first, InputIt last) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_range(pos, first, last); + } + + iterator insert(const_iterator pos, std::initializer_list ilist) + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return insert_range(pos, ilist.begin(), ilist.end()); + } + + template + reference emplace_back(Args&&... args) + { + if (data_.last_ != data_.eos_) + { + const pointer old_last = data_.last_; + + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + data_.last_, + std::forward(args)... + ); + + ++data_.last_; + + return *old_last; + } + else + { + const size_type new_cap = + calculate_new_capacity(1, "sfl::small_vector::emplace_back"); + + pointer new_first; + pointer new_last; + pointer new_eos; + + if (new_cap <= N && data_.first_ != data_.internal_storage()) + { + new_first = data_.internal_storage(); + new_last = new_first; + new_eos = new_first + N; + } + else + { + new_first = sfl::dtl::allocate(data_.ref_to_alloc(), new_cap); + new_last = new_first; + new_eos = new_first + new_cap; + } + + const pointer p = new_first + size(); + + SFL_TRY + { + sfl::dtl::construct_at_a + ( + data_.ref_to_alloc(), + p, + std::forward(args)... + ); + + new_last = nullptr; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_, + new_first + ); + + ++new_last; + } + SFL_CATCH (...) + { + if (new_last == nullptr) + { + sfl::dtl::destroy_at_a + ( + data_.ref_to_alloc(), + p + ); + } + else + { + // Nothing to do + } + + if (new_first != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + new_cap + ); + } + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + + return *p; + } + } + + void push_back(const T& value) + { + emplace_back(value); + } + + void push_back(T&& value) + { + emplace_back(std::move(value)); + } + + void pop_back() + { + SFL_ASSERT(!empty()); + + --data_.last_; + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), data_.last_); + } + + iterator erase(const_iterator pos) + { + SFL_ASSERT(cbegin() <= pos && pos < cend()); + + const pointer p = data_.first_ + std::distance(cbegin(), pos); + + data_.last_ = sfl::dtl::move(p + 1, data_.last_, p); + + sfl::dtl::destroy_at_a(data_.ref_to_alloc(), data_.last_); + + return iterator(p); + } + + iterator erase(const_iterator first, const_iterator last) + { + SFL_ASSERT(cbegin() <= first && first <= last && last <= cend()); + + if (first == last) + { + return begin() + std::distance(cbegin(), first); + } + + const pointer p1 = data_.first_ + std::distance(cbegin(), first); + const pointer p2 = data_.first_ + std::distance(cbegin(), last); + + const pointer new_last = sfl::dtl::move(p2, data_.last_, p1); + + sfl::dtl::destroy_a(data_.ref_to_alloc(), new_last, data_.last_); + + data_.last_ = new_last; + + return iterator(p1); + } + + void resize(size_type n) + { + check_size(n, "sfl::small_vector::resize"); + + const size_type size = this->size(); + + if (n < size) + { + const pointer new_last = data_.first_ + n; + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else if (n > size) + { + const size_type delta = n - size; + + if (n > capacity()) + { + pointer new_first; + pointer new_last; + pointer new_eos; + + if (n <= N && data_.first_ != data_.internal_storage()) + { + new_first = data_.internal_storage(); + new_last = new_first; + new_eos = new_first + N; + } + else + { + new_first = sfl::dtl::allocate(data_.ref_to_alloc(), n); + new_last = new_first; + new_eos = new_first + n; + } + + SFL_TRY + { + sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + new_first + size, + delta + ); + + new_last = nullptr; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_, + new_first + ); + + new_last += delta; + } + SFL_CATCH (...) + { + if (new_last == nullptr) + { + sfl::dtl::destroy_n_a + ( + data_.ref_to_alloc(), + new_first + size, + delta + ); + } + else + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_first, + new_last + ); + } + + if (new_first != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + n + ); + } + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + } + else + { + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.last_, + delta + ); + } + } + } + + void resize(size_type n, const T& value) + { + check_size(n, "sfl::small_vector::resize"); + + const size_type size = this->size(); + + if (n < size) + { + const pointer new_last = data_.first_ + n; + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else if (n > size) + { + const size_type delta = n - size; + + if (n > capacity()) + { + pointer new_first; + pointer new_last; + pointer new_eos; + + if (n <= N && data_.first_ != data_.internal_storage()) + { + new_first = data_.internal_storage(); + new_last = new_first; + new_eos = new_first + N; + } + else + { + new_first = sfl::dtl::allocate(data_.ref_to_alloc(), n); + new_last = new_first; + new_eos = new_first + n; + } + + SFL_TRY + { + sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + new_first + size, + delta, + value + ); + + new_last = nullptr; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_, + new_first + ); + + new_last += delta; + } + SFL_CATCH (...) + { + if (new_last == nullptr) + { + sfl::dtl::destroy_n_a + ( + data_.ref_to_alloc(), + new_first + size, + delta + ); + } + else + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_first, + new_last + ); + } + + if (new_first != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + n + ); + } + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + } + else + { + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.last_, + delta, + value + ); + } + } + } + + void swap(small_vector& other) + { + if (this == &other) + { + return; + } + + using std::swap; + + SFL_ASSERT + ( + allocator_traits::propagate_on_container_swap::value || + this->data_.ref_to_alloc() == other.data_.ref_to_alloc() + ); + + // If this and other allocator compares equal then one allocator + // can deallocate memory allocated by another allocator. + // One allocator can safely destroy_a elements constructed by other + // allocator regardless the two allocators compare equal or not. + + if (allocator_traits::propagate_on_container_swap::value) + { + swap(this->data_.ref_to_alloc(), other.data_.ref_to_alloc()); + } + + if + ( + this->data_.first_ == this->data_.internal_storage() && + other.data_.first_ == other.data_.internal_storage() + ) + { + const size_type this_size = this->size(); + const size_type other_size = other.size(); + + if (this_size <= other_size) + { + std::swap_ranges + ( + this->data_.first_, + this->data_.first_ + this_size, + other.data_.first_ + ); + + sfl::dtl::uninitialized_move_a + ( + this->data_.ref_to_alloc(), + other.data_.first_ + this_size, + other.data_.first_ + other_size, + this->data_.first_ + this_size + ); + + sfl::dtl::destroy_a + ( + other.data_.ref_to_alloc(), + other.data_.first_ + this_size, + other.data_.first_ + other_size + ); + } + else + { + std::swap_ranges + ( + other.data_.first_, + other.data_.first_ + other_size, + this->data_.first_ + ); + + sfl::dtl::uninitialized_move_a + ( + other.data_.ref_to_alloc(), + this->data_.first_ + other_size, + this->data_.first_ + this_size, + other.data_.first_ + other_size + ); + + sfl::dtl::destroy_a + ( + this->data_.ref_to_alloc(), + this->data_.first_ + other_size, + this->data_.first_ + this_size + ); + } + + this->data_.last_ = this->data_.first_ + other_size; + other.data_.last_ = other.data_.first_ + this_size; + } + else if + ( + this->data_.first_ == this->data_.internal_storage() && + other.data_.first_ != other.data_.internal_storage() + ) + { + pointer new_other_first = other.data_.internal_storage(); + pointer new_other_last = new_other_first; + pointer new_other_eos = new_other_first + N; + + new_other_last = sfl::dtl::uninitialized_move_a + ( + other.data_.ref_to_alloc(), + this->data_.first_, + this->data_.last_, + new_other_first + ); + + sfl::dtl::destroy_a + ( + this->data_.ref_to_alloc(), + this->data_.first_, + this->data_.last_ + ); + + this->data_.first_ = other.data_.first_; + this->data_.last_ = other.data_.last_; + this->data_.eos_ = other.data_.eos_; + + other.data_.first_ = new_other_first; + other.data_.last_ = new_other_last; + other.data_.eos_ = new_other_eos; + } + else if + ( + this->data_.first_ != this->data_.internal_storage() && + other.data_.first_ == other.data_.internal_storage() + ) + { + pointer new_this_first = this->data_.internal_storage(); + pointer new_this_last = new_this_first; + pointer new_this_eos = new_this_first + N; + + new_this_last = sfl::dtl::uninitialized_move_a + ( + this->data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + new_this_first + ); + + sfl::dtl::destroy_a + ( + other.data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_ + ); + + other.data_.first_ = this->data_.first_; + other.data_.last_ = this->data_.last_; + other.data_.eos_ = this->data_.eos_; + + this->data_.first_ = new_this_first; + this->data_.last_ = new_this_last; + this->data_.eos_ = new_this_eos; + } + else + { + swap(this->data_.first_, other.data_.first_); + swap(this->data_.last_, other.data_.last_); + swap(this->data_.eos_, other.data_.eos_); + } + } + +private: + + void check_size(size_type n, const char* msg) + { + if (n > max_size()) + { + sfl::dtl::throw_length_error(msg); + } + } + + size_type calculate_new_capacity(size_type num_additional_elements, const char* msg) + { + const size_type size = this->size(); + const size_type capacity = this->capacity(); + const size_type max_size = this->max_size(); + + if (max_size - size < num_additional_elements) + { + sfl::dtl::throw_length_error(msg); + } + else if (max_size - capacity < capacity / 2) + { + return max_size; + } + else if (size + num_additional_elements < capacity + capacity / 2) + { + return std::max(N, capacity + capacity / 2); + } + else + { + return std::max(N, size + num_additional_elements); + } + } + + void reset(size_type new_cap = N) + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = data_.internal_storage(); + data_.last_ = data_.first_; + data_.eos_ = data_.first_ + N; + + if (new_cap > N) + { + data_.first_ = sfl::dtl::allocate(data_.ref_to_alloc(), new_cap); + data_.last_ = data_.first_; + data_.eos_ = data_.first_ + new_cap; + + // If allocation throws, first_, last_ and eos_ will be valid + // (they will be pointing to internal_storage). + } + } + + void initialize_default_n(size_type n) + { + check_size(n, "sfl::small_vector::initialize_default_n"); + + if (n > N) + { + data_.first_ = sfl::dtl::allocate(data_.ref_to_alloc(), n); + data_.last_ = data_.first_; + data_.eos_ = data_.first_ + n; + } + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_default_construct_n_a + ( + data_.ref_to_alloc(), + data_.first_, + n + ); + } + SFL_CATCH (...) + { + if (n > N) + { + sfl::dtl::deallocate(data_.ref_to_alloc(), data_.first_, n); + } + + SFL_RETHROW; + } + } + + void initialize_fill_n(size_type n, const T& value) + { + check_size(n, "sfl::small_vector::initialize_fill_n"); + + if (n > N) + { + data_.first_ = sfl::dtl::allocate(data_.ref_to_alloc(), n); + data_.last_ = data_.first_; + data_.eos_ = data_.first_ + n; + } + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.first_, + n, + value + ); + } + SFL_CATCH (...) + { + if (n > N) + { + sfl::dtl::deallocate(data_.ref_to_alloc(), data_.first_, n); + } + + SFL_RETHROW; + } + } + + template ::value>* = nullptr> + void initialize_range(InputIt first, InputIt last) + { + SFL_TRY + { + while (first != last) + { + emplace_back(*first); + ++first; + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + SFL_RETHROW; + } + } + + template ::value>* = nullptr> + void initialize_range(ForwardIt first, ForwardIt last) + { + const size_type n = std::distance(first, last); + + check_size(n, "sfl::small_vector::initialize_range"); + + if (n > N) + { + data_.first_ = sfl::dtl::allocate(data_.ref_to_alloc(), n); + data_.last_ = data_.first_; + data_.eos_ = data_.first_ + n; + } + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + last, + data_.first_ + ); + } + SFL_CATCH (...) + { + if (n > N) + { + sfl::dtl::deallocate(data_.ref_to_alloc(), data_.first_, n); + } + + SFL_RETHROW; + } + } + + void initialize_copy(const small_vector& other) + { + const size_type n = other.size(); + + check_size(n, "sfl::small_vector::initialize_copy"); + + if (n > N) + { + data_.first_ = sfl::dtl::allocate(data_.ref_to_alloc(), n); + data_.last_ = data_.first_; + data_.eos_ = data_.first_ + n; + } + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + data_.first_ + ); + } + SFL_CATCH (...) + { + if (n > N) + { + sfl::dtl::deallocate(data_.ref_to_alloc(), data_.first_, n); + } + + SFL_RETHROW; + } + } + + void initialize_move(small_vector& other) + { + if (other.data_.first_ == other.data_.internal_storage()) + { + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + data_.first_ + ); + } + else if (data_.ref_to_alloc() == other.data_.ref_to_alloc()) + { + data_.first_ = other.data_.first_; + data_.last_ = other.data_.last_; + data_.eos_ = other.data_.eos_; + + other.data_.first_ = nullptr; + other.data_.last_ = nullptr; + other.data_.eos_ = nullptr; + } + else + { + const size_type n = other.size(); + + check_size(n, "sfl::small_vector::initialize_move"); + + if (n > N) + { + data_.first_ = sfl::dtl::allocate(data_.ref_to_alloc(), n); + data_.last_ = data_.first_; + data_.eos_ = data_.first_ + n; + } + + SFL_TRY + { + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + other.data_.first_, + other.data_.last_, + data_.first_ + ); + } + SFL_CATCH (...) + { + if (n > N) + { + sfl::dtl::deallocate(data_.ref_to_alloc(), data_.first_, n); + } + + SFL_RETHROW; + } + } + } + + void assign_fill_n(size_type n, const T& value) + { + check_size(n, "sfl::small_vector::assign_fill_n"); + + if (n <= capacity()) + { + const size_type size = this->size(); + + const pointer new_last = data_.first_ + n; + + if (n <= size) + { + sfl::dtl::fill + ( + data_.first_, + new_last, + value + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + } + else + { + sfl::dtl::fill + ( + data_.first_, + data_.last_, + value + ); + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.last_, + new_last, + value + ); + } + + data_.last_ = new_last; + } + else + { + reset(n); + + data_.last_ = sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + data_.first_, + n, + value + ); + } + } + + template ::value>* = nullptr> + void assign_range(InputIt first, InputIt last) + { + pointer curr = data_.first_; + + while (first != last && curr != data_.last_) + { + *curr = *first; + ++curr; + ++first; + } + + if (first != last) + { + do + { + emplace_back(*first); + ++first; + } + while (first != last); + } + else if (curr < data_.last_) + { + sfl::dtl::destroy_a(data_.ref_to_alloc(), curr, data_.last_); + data_.last_ = curr; + } + } + + template ::value>* = nullptr> + void assign_range(ForwardIt first, ForwardIt last) + { + const size_type n = std::distance(first, last); + + check_size(n, "sfl::small_vector::assign_range"); + + if (n <= capacity()) + { + const size_type size = this->size(); + + if (n <= size) + { + const pointer new_last = sfl::dtl::copy + ( + first, + last, + data_.first_ + ); + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const ForwardIt mid = std::next(first, size); + + sfl::dtl::copy + ( + first, + mid, + data_.first_ + ); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid, + last, + data_.last_ + ); + } + } + else + { + reset(n); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + last, + data_.first_ + ); + } + } + + void assign_copy(const small_vector& other) + { + if (this != &other) + { + if (allocator_traits::propagate_on_container_copy_assignment::value) + { + if (data_.ref_to_alloc() != other.data_.ref_to_alloc()) + { + reset(); + } + + data_.ref_to_alloc() = other.data_.ref_to_alloc(); + } + + assign_range + ( + other.data_.first_, + other.data_.last_ + ); + } + } + + void assign_move(small_vector& other) + { + if (allocator_traits::propagate_on_container_move_assignment::value) + { + if (data_.ref_to_alloc() != other.data_.ref_to_alloc()) + { + reset(); + } + + data_.ref_to_alloc() = std::move(other.data_.ref_to_alloc()); + } + + if (other.data_.first_ == other.data_.internal_storage()) + { + assign_range + ( + std::make_move_iterator(other.data_.first_), + std::make_move_iterator(other.data_.last_) + ); + } + else if (data_.ref_to_alloc() == other.data_.ref_to_alloc()) + { + reset(); + + data_.first_ = other.data_.first_; + data_.last_ = other.data_.last_; + data_.eos_ = other.data_.eos_; + + other.data_.first_ = nullptr; + other.data_.last_ = nullptr; + other.data_.eos_ = nullptr; + } + else + { + assign_range + ( + std::make_move_iterator(other.data_.first_), + std::make_move_iterator(other.data_.last_) + ); + } + } + + iterator insert_fill_n(const_iterator pos, size_type n, const T& value) + { + if (n == 0) + { + return begin() + std::distance(cbegin(), pos); + } + + if (available() >= n) + { + const value_type tmp(value); + + const pointer p1 = data_.first_ + std::distance(cbegin(), pos); + const pointer p2 = p1 + n; + + if (p2 <= data_.last_) + { + const pointer p3 = data_.last_ - n; + + const pointer old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p3, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p3, + old_last + ); + + sfl::dtl::fill + ( + p1, + p2, + tmp + ); + } + else + { + const pointer old_last = data_.last_; + + sfl::dtl::uninitialized_fill_a + ( + data_.ref_to_alloc(), + data_.last_, + p2, + tmp + ); + + data_.last_ = p2; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p1, + old_last, + data_.last_ + ); + + sfl::dtl::fill + ( + p1, + old_last, + tmp + ); + } + + return iterator(p1); + } + else + { + const difference_type offset = std::distance(cbegin(), pos); + + const size_type new_cap = + calculate_new_capacity(n, "sfl::small_vector::insert_fill_n"); + + pointer new_first; + pointer new_last; + pointer new_eos; + + if (new_cap <= N && data_.first_ != data_.internal_storage()) + { + new_first = data_.internal_storage(); + new_last = new_first; + new_eos = new_first + N; + } + else + { + new_first = sfl::dtl::allocate(data_.ref_to_alloc(), new_cap); + new_last = new_first; + new_eos = new_first + new_cap; + } + + const pointer p = new_first + offset; + + SFL_TRY + { + // `value` can be a reference to an element in this + // container. First we will create `n` copies of `value` + // and ffter that we can move elements. + + sfl::dtl::uninitialized_fill_n_a + ( + data_.ref_to_alloc(), + p, + n, + value + ); + + new_last = nullptr; + + const pointer mid = data_.first_ + offset; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + mid, + new_first + ); + + new_last += n; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + mid, + data_.last_, + new_last + ); + } + SFL_CATCH (...) + { + if (new_last == nullptr) + { + sfl::dtl::destroy_n_a + ( + data_.ref_to_alloc(), + p, + n + ); + } + else + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_first, + new_last + ); + } + + if (new_first != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + new_cap + ); + } + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + + return iterator(p); + } + } + + template ::value>* = nullptr> + iterator insert_range(const_iterator pos, InputIt first, InputIt last) + { + const difference_type offset = std::distance(cbegin(), pos); + + while (first != last) + { + pos = insert(pos, *first); + ++pos; + ++first; + } + + return begin() + offset; + } + + template ::value>* = nullptr> + iterator insert_range(const_iterator pos, ForwardIt first, ForwardIt last) + { + if (first == last) + { + return begin() + std::distance(cbegin(), pos); + } + + const size_type n = std::distance(first, last); + + if (available() >= n) + { + const pointer p1 = data_.first_ + std::distance(cbegin(), pos); + const pointer p2 = p1 + n; + + if (p2 <= data_.last_) + { + const pointer p3 = data_.last_ - n; + + const pointer old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p3, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p3, + old_last + ); + + sfl::dtl::copy + ( + first, + last, + p1 + ); + } + else + { + const pointer old_last = data_.last_; + + const ForwardIt mid = std::next(first, std::distance(pos, cend())); + + data_.last_ = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + mid, + last, + data_.last_ + ); + + data_.last_ = sfl::dtl::uninitialized_move_a + ( + data_.ref_to_alloc(), + p1, + old_last, + data_.last_ + ); + + sfl::dtl::copy + ( + first, + mid, + p1 + ); + } + + return iterator(p1); + } + else + { + const difference_type offset = std::distance(cbegin(), pos); + + const size_type new_cap = + calculate_new_capacity(n, "sfl::small_vector::insert_range"); + + pointer new_first; + pointer new_last; + pointer new_eos; + + if (new_cap <= N && data_.first_ != data_.internal_storage()) + { + new_first = data_.internal_storage(); + new_last = new_first; + new_eos = new_first + N; + } + else + { + new_first = sfl::dtl::allocate(data_.ref_to_alloc(), new_cap); + new_last = new_first; + new_eos = new_first + new_cap; + } + + const pointer p = new_first + offset; + + SFL_TRY + { + const pointer mid = data_.first_ + offset; + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + data_.first_, + mid, + new_first + ); + + new_last = sfl::dtl::uninitialized_copy_a + ( + data_.ref_to_alloc(), + first, + last, + new_last + ); + + new_last = sfl::dtl::uninitialized_move_if_noexcept_a + ( + data_.ref_to_alloc(), + mid, + data_.last_, + new_last + ); + } + SFL_CATCH (...) + { + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + new_first, + new_last + ); + + if (new_first != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + new_first, + new_cap + ); + } + + SFL_RETHROW; + } + + sfl::dtl::destroy_a + ( + data_.ref_to_alloc(), + data_.first_, + data_.last_ + ); + + if (data_.first_ != data_.internal_storage()) + { + sfl::dtl::deallocate + ( + data_.ref_to_alloc(), + data_.first_, + std::distance(data_.first_, data_.eos_) + ); + } + + data_.first_ = new_first; + data_.last_ = new_last; + data_.eos_ = new_eos; + + return iterator(p); + } + } +}; + +// +// ---- NON-MEMBER FUNCTIONS -------------------------------------------------- +// + +template +SFL_NODISCARD +bool operator== +( + const small_vector& x, + const small_vector& y +) +{ + return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); +} + +template +SFL_NODISCARD +bool operator!= +( + const small_vector& x, + const small_vector& y +) +{ + return !(x == y); +} + +template +SFL_NODISCARD +bool operator< +( + const small_vector& x, + const small_vector& y +) +{ + return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +template +SFL_NODISCARD +bool operator> +( + const small_vector& x, + const small_vector& y +) +{ + return y < x; +} + +template +SFL_NODISCARD +bool operator<= +( + const small_vector& x, + const small_vector& y +) +{ + return !(y < x); +} + +template +SFL_NODISCARD +bool operator>= +( + const small_vector& x, + const small_vector& y +) +{ + return !(x < y); +} + +template +void swap +( + small_vector& x, + small_vector& y +) +{ + x.swap(y); +} + +template +typename small_vector::size_type + erase(small_vector& c, const U& value) +{ + auto it = std::remove(c.begin(), c.end(), value); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +template +typename small_vector::size_type + erase_if(small_vector& c, Predicate pred) +{ + auto it = std::remove_if(c.begin(), c.end(), pred); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +} // namespace sfl + +#endif // SFL_SMALL_VECTOR_HPP_INCLUDED diff --git a/src/thirdparty/sfl/static_vector.hpp b/src/thirdparty/sfl/static_vector.hpp new file mode 100644 index 0000000000..c993413544 --- /dev/null +++ b/src/thirdparty/sfl/static_vector.hpp @@ -0,0 +1,1119 @@ +// +// Copyright (c) 2022 Slaven Falandys +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#ifndef SFL_STATIC_VECTOR_HPP_INCLUDED +#define SFL_STATIC_VECTOR_HPP_INCLUDED + +#include "private.hpp" + +#include // copy, move, swap, swap_ranges +#include // size_t +#include // initializer_list +#include // distance, next, reverse_iterator +#include // numeric_limits +#include // allocator, allocator_traits, pointer_traits +#include // is_same, is_nothrow_xxxxx +#include // forward, move, pair + +namespace sfl +{ + +template +class static_vector +{ + static_assert(N > 0, "N must be greater than zero."); + +public: + + using value_type = T; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = value_type*; + using const_pointer = const value_type*; + using iterator = sfl::dtl::normal_iterator; + using const_iterator = sfl::dtl::normal_iterator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + +public: + + static constexpr size_type static_capacity = N; + +private: + + struct data + { + union + { + value_type first_[N]; + }; + + pointer last_; + + data() noexcept + : last_(first_) + {} + + ~data() noexcept + {} + }; + + data data_; + +public: + + // + // ---- CONSTRUCTION AND DESTRUCTION -------------------------------------- + // + + static_vector() noexcept + {} + + static_vector(size_type n) + { + SFL_ASSERT(n <= capacity()); + + data_.last_ = sfl::dtl::uninitialized_value_construct_n + ( + data_.first_, + n + ); + } + + static_vector(size_type n, sfl::default_init_t) + { + SFL_ASSERT(n <= capacity()); + + data_.last_ = sfl::dtl::uninitialized_default_construct_n + ( + data_.first_, + n + ); + } + + static_vector(size_type n, const T& value) + { + SFL_ASSERT(n <= capacity()); + + data_.last_ = sfl::dtl::uninitialized_fill_n + ( + data_.first_, + n, + value + ); + } + + template ::value>* = nullptr> + static_vector(InputIt first, InputIt last) + { + SFL_TRY + { + while (first != last) + { + emplace_back(*first); + ++first; + } + } + SFL_CATCH (...) + { + sfl::dtl::destroy(data_.first_, data_.last_); + SFL_RETHROW; + } + } + + template ::value>* = nullptr> + static_vector(ForwardIt first, ForwardIt last) + { + SFL_ASSERT(size_type(std::distance(first, last)) <= capacity()); + + data_.last_ = sfl::dtl::uninitialized_copy + ( + first, + last, + data_.first_ + ); + } + + static_vector(std::initializer_list ilist) + : static_vector(ilist.begin(), ilist.end()) + {} + + static_vector(const static_vector& other) + { + data_.last_ = sfl::dtl::uninitialized_copy + ( + pointer(other.data_.first_), + pointer(other.data_.last_), + data_.first_ + ); + } + + static_vector(static_vector&& other) + { + data_.last_ = sfl::dtl::uninitialized_move + ( + std::make_move_iterator(pointer(other.data_.first_)), + std::make_move_iterator(pointer(other.data_.last_)), + data_.first_ + ); + } + + ~static_vector() noexcept + { + sfl::dtl::destroy(data_.first_, data_.last_); + } + + // + // ---- ASSIGNMENT -------------------------------------------------------- + // + + void assign(size_type n, const T& value) + { + SFL_ASSERT(n <= capacity()); + + const size_type size = this->size(); + + const pointer new_last = data_.first_ + n; + + if (n <= size) + { + sfl::dtl::fill + ( + data_.first_, + new_last, + value + ); + + sfl::dtl::destroy + ( + new_last, + data_.last_ + ); + } + else + { + sfl::dtl::fill + ( + data_.first_, + data_.last_, + value + ); + + sfl::dtl::uninitialized_fill + ( + data_.last_, + new_last, + value + ); + } + + data_.last_ = new_last; + } + + template ::value>* = nullptr> + void assign(InputIt first, InputIt last) + { + pointer curr = data_.first_; + + while (first != last && curr != data_.last_) + { + *curr = *first; + ++curr; + ++first; + } + + if (first != last) + { + do + { + emplace_back(*first); + ++first; + } + while (first != last); + } + else if (curr < data_.last_) + { + sfl::dtl::destroy(curr, data_.last_); + data_.last_ = curr; + } + } + + template ::value>* = nullptr> + void assign(ForwardIt first, ForwardIt last) + { + SFL_ASSERT(size_type(std::distance(first, last)) <= capacity()); + + const size_type n = std::distance(first, last); + + const size_type size = this->size(); + + if (n <= size) + { + const pointer new_last = sfl::dtl::copy + ( + first, + last, + data_.first_ + ); + + sfl::dtl::destroy + ( + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else + { + const ForwardIt mid = std::next(first, size); + + sfl::dtl::copy + ( + first, + mid, + data_.first_ + ); + + data_.last_ = sfl::dtl::uninitialized_copy + ( + mid, + last, + data_.last_ + ); + } + } + + void assign(std::initializer_list ilist) + { + assign(ilist.begin(), ilist.end()); + } + + static_vector& operator=(const static_vector& other) + { + if (this != &other) + { + assign + ( + pointer(other.data_.first_), + pointer(other.data_.last_) + ); + } + return *this; + } + + static_vector& operator=(static_vector&& other) + { + assign + ( + std::make_move_iterator(pointer(other.data_.first_)), + std::make_move_iterator(pointer(other.data_.last_)) + ); + return *this; + } + + static_vector& operator=(std::initializer_list ilist) + { + assign(ilist.begin(), ilist.end()); + return *this; + } + + // + // ---- ITERATORS --------------------------------------------------------- + // + + SFL_NODISCARD + iterator begin() noexcept + { + return iterator(data_.first_); + } + + SFL_NODISCARD + const_iterator begin() const noexcept + { + return const_iterator(data_.first_); + } + + SFL_NODISCARD + const_iterator cbegin() const noexcept + { + return const_iterator(data_.first_); + } + + SFL_NODISCARD + iterator end() noexcept + { + return iterator(data_.last_); + } + + SFL_NODISCARD + const_iterator end() const noexcept + { + return const_iterator(data_.last_); + } + + SFL_NODISCARD + const_iterator cend() const noexcept + { + return const_iterator(data_.last_); + } + + SFL_NODISCARD + reverse_iterator rbegin() noexcept + { + return reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator rbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + const_reverse_iterator crbegin() const noexcept + { + return const_reverse_iterator(end()); + } + + SFL_NODISCARD + reverse_iterator rend() noexcept + { + return reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator rend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + const_reverse_iterator crend() const noexcept + { + return const_reverse_iterator(begin()); + } + + SFL_NODISCARD + iterator nth(size_type pos) noexcept + { + SFL_ASSERT(pos <= size()); + return iterator(data_.first_ + pos); + } + + SFL_NODISCARD + const_iterator nth(size_type pos) const noexcept + { + SFL_ASSERT(pos <= size()); + return const_iterator(data_.first_ + pos); + } + + SFL_NODISCARD + size_type index_of(const_iterator pos) const noexcept + { + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + return std::distance(cbegin(), pos); + } + + // + // ---- SIZE AND CAPACITY ------------------------------------------------- + // + + SFL_NODISCARD + bool empty() const noexcept + { + return data_.first_ == data_.last_; + } + + SFL_NODISCARD + bool full() const noexcept + { + return std::distance(begin(), end()) == N; + } + + SFL_NODISCARD + size_type size() const noexcept + { + return std::distance(begin(), end()); + } + + SFL_NODISCARD + static constexpr size_type max_size() noexcept + { + return N; + } + + SFL_NODISCARD + static constexpr size_type capacity() noexcept + { + return N; + } + + SFL_NODISCARD + size_type available() const noexcept + { + return capacity() - size(); + } + + // + // ---- ELEMENT ACCESS ---------------------------------------------------- + // + + SFL_NODISCARD + reference at(size_type pos) + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::static_vector::at"); + } + + return *(data_.first_ + pos); + } + + SFL_NODISCARD + const_reference at(size_type pos) const + { + if (pos >= size()) + { + sfl::dtl::throw_out_of_range("sfl::static_vector::at"); + } + + return *(data_.first_ + pos); + } + + SFL_NODISCARD + reference operator[](size_type pos) noexcept + { + SFL_ASSERT(pos < size()); + return *(data_.first_ + pos); + } + + SFL_NODISCARD + const_reference operator[](size_type pos) const noexcept + { + SFL_ASSERT(pos < size()); + return *(data_.first_ + pos); + } + + SFL_NODISCARD + reference front() noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + const_reference front() const noexcept + { + SFL_ASSERT(!empty()); + return *data_.first_; + } + + SFL_NODISCARD + reference back() noexcept + { + SFL_ASSERT(!empty()); + return *(data_.last_ - 1); + } + + SFL_NODISCARD + const_reference back() const noexcept + { + SFL_ASSERT(!empty()); + return *(data_.last_ - 1); + } + + SFL_NODISCARD + T* data() noexcept + { + return data_.first_; + } + + SFL_NODISCARD + const T* data() const noexcept + { + return data_.first_; + } + + // + // ---- MODIFIERS --------------------------------------------------------- + // + + void clear() noexcept + { + sfl::dtl::destroy(data_.first_, data_.last_); + data_.last_ = data_.first_; + } + + template + iterator emplace(const_iterator pos, Args&&... args) + { + SFL_ASSERT(!full()); + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + + const pointer p1 = data_.first_ + std::distance(cbegin(), pos); + + if (p1 == data_.last_) + { + sfl::dtl::construct_at + ( + p1, + std::forward(args)... + ); + + ++data_.last_; + } + else + { + // This container can contain duplicates so we must + // create new element now as a temporary value. + value_type tmp(std::forward(args)...); + + const pointer p2 = data_.last_ - 1; + + const pointer old_last = data_.last_; + + sfl::dtl::construct_at + ( + data_.last_, + std::move(*p2) + ); + + ++data_.last_; + + sfl::dtl::move_backward + ( + p1, + p2, + old_last + ); + + *p1 = std::move(tmp); + } + + return iterator(p1); + } + + iterator insert(const_iterator pos, const T& value) + { + return emplace(pos, value); + } + + iterator insert(const_iterator pos, T&& value) + { + return emplace(pos, std::move(value)); + } + + iterator insert(const_iterator pos, size_type n, const T& value) + { + SFL_ASSERT(n <= available()); + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + + if (n == 0) + { + return begin() + std::distance(cbegin(), pos); + } + + const value_type tmp(value); + + const pointer p1 = data_.first_ + std::distance(cbegin(), pos); + const pointer p2 = p1 + n; + + if (p2 <= data_.last_) + { + const pointer p3 = data_.last_ - n; + + const pointer old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move + ( + p3, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p3, + old_last + ); + + sfl::dtl::fill + ( + p1, + p2, + tmp + ); + } + else + { + const pointer old_last = data_.last_; + + sfl::dtl::uninitialized_fill + ( + data_.last_, + p2, + tmp + ); + + data_.last_ = p2; + + data_.last_ = sfl::dtl::uninitialized_move + ( + p1, + old_last, + data_.last_ + ); + + sfl::dtl::fill + ( + p1, + old_last, + tmp + ); + } + + return iterator(p1); + } + + template ::value>* = nullptr> + iterator insert(const_iterator pos, InputIt first, InputIt last) + { + const difference_type offset = std::distance(cbegin(), pos); + + while (first != last) + { + pos = emplace(pos, *first); + ++pos; + ++first; + } + + return begin() + offset; + } + + template ::value>* = nullptr> + iterator insert(const_iterator pos, ForwardIt first, ForwardIt last) + { + SFL_ASSERT(size_type(std::distance(first, last)) <= available()); + SFL_ASSERT(cbegin() <= pos && pos <= cend()); + + if (first == last) + { + return begin() + std::distance(cbegin(), pos); + } + + const size_type n = std::distance(first, last); + + const pointer p1 = data_.first_ + std::distance(cbegin(), pos); + const pointer p2 = p1 + n; + + if (p2 <= data_.last_) + { + const pointer p3 = data_.last_ - n; + + const pointer old_last = data_.last_; + + data_.last_ = sfl::dtl::uninitialized_move + ( + p3, + data_.last_, + data_.last_ + ); + + sfl::dtl::move_backward + ( + p1, + p3, + old_last + ); + + sfl::dtl::copy + ( + first, + last, + p1 + ); + } + else + { + const pointer old_last = data_.last_; + + const ForwardIt mid = std::next(first, std::distance(pos, cend())); + + data_.last_ = sfl::dtl::uninitialized_copy + ( + mid, + last, + data_.last_ + ); + + data_.last_ = sfl::dtl::uninitialized_move + ( + p1, + old_last, + data_.last_ + ); + + sfl::dtl::copy + ( + first, + mid, + p1 + ); + } + + return iterator(p1); + } + + iterator insert(const_iterator pos, std::initializer_list ilist) + { + return insert(pos, ilist.begin(), ilist.end()); + } + + template + reference emplace_back(Args&&... args) + { + SFL_ASSERT(!full()); + + const pointer old_last = data_.last_; + + sfl::dtl::construct_at(data_.last_, std::forward(args)...); + + ++data_.last_; + + return *old_last; + } + + void push_back(const T& value) + { + emplace_back(value); + } + + void push_back(T&& value) + { + emplace_back(std::move(value)); + } + + void pop_back() + { + SFL_ASSERT(!empty()); + + --data_.last_; + + sfl::dtl::destroy_at(data_.last_); + } + + iterator erase(const_iterator pos) + { + SFL_ASSERT(cbegin() <= pos && pos < cend()); + + const pointer p = data_.first_ + std::distance(cbegin(), pos); + + data_.last_ = sfl::dtl::move(p + 1, data_.last_, p); + + sfl::dtl::destroy_at(data_.last_); + + return iterator(p); + } + + iterator erase(const_iterator first, const_iterator last) + { + SFL_ASSERT(cbegin() <= first && first <= last && last <= cend()); + + if (first == last) + { + return begin() + std::distance(cbegin(), first); + } + + const pointer p1 = data_.first_ + std::distance(cbegin(), first); + const pointer p2 = data_.first_ + std::distance(cbegin(), last); + + const pointer new_last = sfl::dtl::move(p2, data_.last_, p1); + + sfl::dtl::destroy(new_last, data_.last_); + + data_.last_ = new_last; + + return iterator(p1); + } + + void resize(size_type n) + { + SFL_ASSERT(n <= capacity()); + + const size_type size = this->size(); + + if (n < size) + { + const pointer new_last = data_.first_ + n; + + sfl::dtl::destroy + ( + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else if (n > size) + { + const size_type delta = n - size; + + data_.last_ = sfl::dtl::uninitialized_value_construct_n + ( + data_.last_, + delta + ); + } + } + + void resize(size_type n, sfl::default_init_t) + { + SFL_ASSERT(n <= capacity()); + + const size_type size = this->size(); + + if (n < size) + { + const pointer new_last = data_.first_ + n; + + sfl::dtl::destroy + ( + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else if (n > size) + { + const size_type delta = n - size; + + data_.last_ = sfl::dtl::uninitialized_default_construct_n + ( + data_.last_, + delta + ); + } + } + + void resize(size_type n, const T& value) + { + SFL_ASSERT(n <= capacity()); + + const size_type size = this->size(); + + if (n < size) + { + const pointer new_last = data_.first_ + n; + + sfl::dtl::destroy + ( + new_last, + data_.last_ + ); + + data_.last_ = new_last; + } + else if (n > size) + { + const size_type delta = n - size; + + data_.last_ = sfl::dtl::uninitialized_fill_n + ( + data_.last_, + delta, + value + ); + } + } + + void swap(static_vector& other) + { + if (this == &other) + { + return; + } + + const size_type this_size = this->size(); + const size_type other_size = other.size(); + + if (this_size <= other_size) + { + std::swap_ranges + ( + this->data_.first_, + this->data_.first_ + this_size, + other.data_.first_ + ); + + sfl::dtl::uninitialized_move + ( + other.data_.first_ + this_size, + other.data_.first_ + other_size, + this->data_.first_ + this_size + ); + + sfl::dtl::destroy + ( + other.data_.first_ + this_size, + other.data_.first_ + other_size + ); + } + else + { + std::swap_ranges + ( + other.data_.first_, + other.data_.first_ + other_size, + this->data_.first_ + ); + + sfl::dtl::uninitialized_move + ( + this->data_.first_ + other_size, + this->data_.first_ + this_size, + other.data_.first_ + other_size + ); + + sfl::dtl::destroy + ( + this->data_.first_ + other_size, + this->data_.first_ + this_size + ); + } + + this->data_.last_ = this->data_.first_ + other_size; + other.data_.last_ = other.data_.first_ + this_size; + } +}; + +// +// ---- NON-MEMBER FUNCTIONS -------------------------------------------------- +// + +template +SFL_NODISCARD +bool operator== +( + const static_vector& x, + const static_vector& y +) +{ + return x.size() == y.size() && std::equal(x.begin(), x.end(), y.begin()); +} + +template +SFL_NODISCARD +bool operator!= +( + const static_vector& x, + const static_vector& y +) +{ + return !(x == y); +} + +template +SFL_NODISCARD +bool operator< +( + const static_vector& x, + const static_vector& y +) +{ + return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); +} + +template +SFL_NODISCARD +bool operator> +( + const static_vector& x, + const static_vector& y +) +{ + return y < x; +} + +template +SFL_NODISCARD +bool operator<= +( + const static_vector& x, + const static_vector& y +) +{ + return !(y < x); +} + +template +SFL_NODISCARD +bool operator>= +( + const static_vector& x, + const static_vector& y +) +{ + return !(x < y); +} + +template +void swap +( + static_vector& x, + static_vector& y +) +{ + x.swap(y); +} + +template +typename static_vector::size_type + erase(static_vector& c, const U& value) +{ + auto it = std::remove(c.begin(), c.end(), value); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +template +typename static_vector::size_type + erase_if(static_vector& c, Predicate pred) +{ + auto it = std::remove_if(c.begin(), c.end(), pred); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return r; +} + +} // namespace sfl + +#endif // SFL_STATIC_VECTOR_HPP_INCLUDED From b0fc76fdd0e5455a77aa95c81d9f500e86d469d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 2 Dec 2024 02:21:52 +0200 Subject: [PATCH 102/139] Replace custom FixedVector with sfl::static_vector --- src/openrct2-ui/ride/VehicleSounds.cpp | 6 +- src/openrct2/core/FixedVector.h | 178 ------------------------- src/openrct2/libopenrct2.vcxproj | 3 +- src/openrct2/ride/Ride.cpp | 2 +- src/openrct2/ride/RideConstruction.cpp | 4 +- 5 files changed, 7 insertions(+), 186 deletions(-) delete mode 100644 src/openrct2/core/FixedVector.h diff --git a/src/openrct2-ui/ride/VehicleSounds.cpp b/src/openrct2-ui/ride/VehicleSounds.cpp index 8530bee3ab..361ff999b6 100644 --- a/src/openrct2-ui/ride/VehicleSounds.cpp +++ b/src/openrct2-ui/ride/VehicleSounds.cpp @@ -11,12 +11,12 @@ #include #include #include -#include #include #include #include #include #include +#include namespace OpenRCT2::Audio { @@ -236,7 +236,7 @@ namespace OpenRCT2::Audio * rct2: 0x006BB9FF */ static void UpdateSoundParams( - const Vehicle& vehicle, FixedVector& vehicleSoundParamsList) + const Vehicle& vehicle, sfl::static_vector& vehicleSoundParamsList) { if (!SoundCanPlay(vehicle)) return; @@ -536,7 +536,7 @@ namespace OpenRCT2::Audio if (!IsAvailable()) return; - FixedVector vehicleSoundParamsList; + sfl::static_vector vehicleSoundParamsList; VehicleSoundsUpdateWindowSetup(); diff --git a/src/openrct2/core/FixedVector.h b/src/openrct2/core/FixedVector.h deleted file mode 100644 index 4b6ebe86e3..0000000000 --- a/src/openrct2/core/FixedVector.h +++ /dev/null @@ -1,178 +0,0 @@ -/***************************************************************************** - * 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 "Guard.hpp" - -#include -#include -#include - -template -class FixedVector -{ -public: - using container = std::array; - using iterator = typename container::iterator; - using const_iterator = typename container::const_iterator; - using reverse_iterator = typename container::reverse_iterator; - using const_reverse_iterator = typename container::const_reverse_iterator; - using value_type = typename container::value_type; - using reference_type = value_type&; - using const_reference_type = const value_type&; - - constexpr iterator begin() - { - if (_count == 0) - return _data.end(); - - return _data.begin(); - } - - constexpr iterator end() - { - if (_count == 0) - return _data.end(); - return begin() + _count; - } - - constexpr const_iterator cbegin() const - { - if (_count == 0) - return _data.cend(); - - return _data.cbegin(); - } - - constexpr const_iterator cend() const - { - if (_count == 0) - return _data.cend(); - return cbegin() + _count; - } - - constexpr reverse_iterator rbegin() - { - if (_count == 0) - return _data.rend(); - return _data.rbegin() + (MAX - _count); - } - - constexpr reverse_iterator rend() - { - return _data.rend(); - } - - constexpr const_reverse_iterator rbegin() const - { - return _data.rbegin() + (MAX - _count); - } - - constexpr const_reverse_iterator rend() const - { - return _data.rend(); - } - - constexpr reference_type back() - { - return _data[_count - 1]; - } - - constexpr const_reference_type back() const - { - return _data[_count - 1]; - } - - constexpr void push_back(const T& val) - { - OpenRCT2::Guard::Assert(_count < MAX); - _data[_count++] = val; - } - - constexpr void push_back(T&& val) - { - OpenRCT2::Guard::Assert(_count < MAX); - _data[_count++] = std::move(val); - } - - constexpr iterator insert(iterator pos, const T& val) - { - // Make sure the end iterator is correct. - auto itCurEnd = end(); - push_back(val); - - // Shift all elements to the right - auto offset = pos - begin(); - std::rotate(_data.begin(), pos, itCurEnd); - - return _data.begin() + offset; - } - - constexpr iterator insert(iterator pos, T&& val) - { - // Make sure the end iterator is correct. - auto itCurEnd = end(); - emplace_back(std::move(val)); - - // Shift all elements to the right - auto offset = pos - begin(); - std::rotate(_data.begin() + offset, itCurEnd, end()); - - return _data.begin() + offset; - } - - template - constexpr reference_type emplace_back(Args&&... args) - { - OpenRCT2::Guard::Assert(_count < MAX); - reference_type res = _data[_count++]; - ::new (&res) T(std::forward(args)...); - return res; - } - - constexpr reference_type operator[](const size_t n) - { - return _data[n]; - } - - constexpr const_reference_type operator[](const size_t n) const - { - return _data[n]; - } - - constexpr void pop_back() - { - _count--; - } - - constexpr void clear() - { - _count = 0; - } - - constexpr size_t size() const - { - return _count; - } - - constexpr size_t capacity() const - { - return _data.size(); - } - - constexpr bool empty() const - { - return _count == 0; - } - -private: - size_t _count = 0; - container _data; -}; diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 81084c84d8..f115df0039 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -203,7 +203,6 @@ - @@ -1135,4 +1134,4 @@ - + \ No newline at end of file diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 9c5b72ae2c..e8755a0230 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -25,7 +25,6 @@ #include "../audio/audio.h" #include "../config/Config.h" #include "../core/BitSet.hpp" -#include "../core/FixedVector.h" #include "../core/Guard.hpp" #include "../core/Numerics.hpp" #include "../entity/EntityRegistry.h" @@ -84,6 +83,7 @@ #include #include #include +#include using namespace OpenRCT2; using namespace OpenRCT2::TrackMetaData; diff --git a/src/openrct2/ride/RideConstruction.cpp b/src/openrct2/ride/RideConstruction.cpp index 1dd7978fb8..3f79d2bd15 100644 --- a/src/openrct2/ride/RideConstruction.cpp +++ b/src/openrct2/ride/RideConstruction.cpp @@ -18,7 +18,6 @@ #include "../actions/RideSetStatusAction.h" #include "../actions/RideSetVehicleAction.h" #include "../actions/TrackRemoveAction.h" -#include "../core/FixedVector.h" #include "../entity/EntityList.h" #include "../entity/EntityRegistry.h" #include "../entity/Staff.h" @@ -50,6 +49,7 @@ #include "Vehicle.h" #include +#include using namespace OpenRCT2; using namespace OpenRCT2::TrackMetaData; @@ -1255,7 +1255,7 @@ void Ride::ValidateStations() } } // determine what entrances and exits exist - FixedVector locations; + sfl::static_vector locations; for (auto& station : stations) { if (!station.Entrance.IsNull()) From 10544ca81b6d58471b43639ac5ed5eb5e58f060c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 2 Dec 2024 02:34:01 +0200 Subject: [PATCH 103/139] Exclude sfl macros from clang-tidy --- .clang-tidy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy b/.clang-tidy index 781e5cde4d..2b7757409e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -7,7 +7,7 @@ Checks: > readability-uppercase-literal-suffix CheckOptions: - key: cppcoreguidelines-macro-usage.AllowedRegexp - value: 'validate_global_widx|NETWORK_STREAM_VERSION' + value: 'validate_global_widx|NETWORK_STREAM_VERSION|SFL_ASSERT|SFL_CATCH' - key: readability-uppercase-literal-suffix.NewSuffixes value: 'u;L;uL;LL;uLL' WarningsAsErrors: true From 61b2bae7b72a04ff4b5b0ac20e5d0e2fbd43e519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Mon, 2 Dec 2024 02:47:01 +0200 Subject: [PATCH 104/139] Use sfl::small_vector for litter removal, avoid 99% of heap allocations --- src/openrct2/entity/Litter.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/openrct2/entity/Litter.cpp b/src/openrct2/entity/Litter.cpp index 34d3f4b7d3..12177c7516 100644 --- a/src/openrct2/entity/Litter.cpp +++ b/src/openrct2/entity/Litter.cpp @@ -13,6 +13,8 @@ #include "EntityList.h" #include "EntityRegistry.h" +#include + using namespace OpenRCT2; template<> @@ -101,7 +103,9 @@ void Litter::Create(const CoordsXYZD& litterPos, Type type) */ void Litter::RemoveAt(const CoordsXYZ& litterPos) { - std::vector removals; + // There can be a lot of litter entities on the same tile, avoid heap allocations + // by having the first 512 stored in a small_vector which is on the stack. + sfl::small_vector removals; for (auto litter : EntityTileList(litterPos)) { if (abs(litter->z - litterPos.z) <= 16) From 979bdcd4caa0d111f7dd6f19b3acdc76f094989f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Mon, 2 Dec 2024 10:22:39 +0100 Subject: [PATCH 105/139] Update sponsor wording for SignPath in readme.md (#23301) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 3ccb38dea8..794c82b5d0 100644 --- a/readme.md +++ b/readme.md @@ -297,4 +297,4 @@ Companies that kindly allow us to use their stuff: | [DigitalOcean](https://www.digitalocean.com/) | [JetBrains](https://www.jetbrains.com/) | [Backtrace](https://backtrace.io/) | [SignPath](https://signpath.org/) | |-------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------| | [![do_logo_vertical_blue svg](https://user-images.githubusercontent.com/550290/36508276-8b572f0e-175c-11e8-8622-9febbce756b2.png)](https://www.digitalocean.com/) | [![jetbrains](https://user-images.githubusercontent.com/550290/36413299-0e0985ea-161e-11e8-8a01-3ef523b5905b.png)](https://www.jetbrains.com/) | [![backtrace](https://user-images.githubusercontent.com/550290/47113259-d0647680-d258-11e8-97c3-1a2c6bde6d11.png)](https://backtrace.io/) | [![Image](https://github.com/user-attachments/assets/2b5679e0-76a4-4ae7-bb37-a6a507a53466)](https://signpath.org/) | -| Hosting of various services | CLion and other products | Minidump uploads and inspection | Code signing | +| Hosting of various services | CLion and other products | Minidump uploads and inspection | Free code signing provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/). | From 5da7d0e4db84cd96f309d659884d5a069fbec216 Mon Sep 17 00:00:00 2001 From: Brendan Heinonen Date: Sun, 3 Nov 2024 20:05:03 -0500 Subject: [PATCH 106/139] Fix #22972: Missing flat footpath in scenarios Scenarios touched: - Alton Towers - Build your own Six Flags Magic Mountain - Mirage Madness - Six Flags Magic Mountain --- data/scenario_patches/2696a05.parkpatch | 17 +++- data/scenario_patches/5c95a4e.parkpatch | 9 +- data/scenario_patches/7f38f1b.parkpatch | 13 ++- data/scenario_patches/7ffdb44.parkpatch | 13 ++- data/scenario_patches/c1d4056.parkpatch | 13 ++- data/scenario_patches/c82272a.parkpatch | 13 ++- src/openrct2/rct12/ScenarioPatcher.cpp | 128 ++++++++++++++++++++++-- 7 files changed, 182 insertions(+), 24 deletions(-) diff --git a/data/scenario_patches/2696a05.parkpatch b/data/scenario_patches/2696a05.parkpatch index 391ddbd0f9..54c597985b 100644 --- a/data/scenario_patches/2696a05.parkpatch +++ b/data/scenario_patches/2696a05.parkpatch @@ -18,5 +18,20 @@ [ 140, 74 ], [ 141, 74 ], [ 142, 74 ], [ 143, 74 ], [ 144, 74 ], [ 145, 74 ], [ 146, 74 ], [ 147, 74 ] ] } - } + }, + "elements_to_delete": [ + { + "element_index": 1, + "coordinates": [ + [ 86, 75 ], [ 86, 77 ], [ 86, 78 ] + ] + } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.bamboo_brown", + "surface": "rct2.footpath_surface.dirt", + "coordinates": [ [ 86, 74, 12 ], [ 86, 75, 12 ], [ 86, 76, 12 ], [ 86, 77, 12 ], [ 86, 78, 12 ] ] + } + ] } diff --git a/data/scenario_patches/5c95a4e.parkpatch b/data/scenario_patches/5c95a4e.parkpatch index 6c30ef46bf..0f7e0a0e03 100644 --- a/data/scenario_patches/5c95a4e.parkpatch +++ b/data/scenario_patches/5c95a4e.parkpatch @@ -7,5 +7,12 @@ [ 11, 31 ], [ 68, 112 ], [ 72, 118 ] ] } - } + }, + "paths": [ + { + "railings": "rct2.footpath_railings.wood", + "surface": "rct1.footpath_surface.crazy_paving", + "coordinates": [ [ 83, 81, 22 ] ] + } + ] } diff --git a/data/scenario_patches/7f38f1b.parkpatch b/data/scenario_patches/7f38f1b.parkpatch index a282000c56..5ab76eb98e 100644 --- a/data/scenario_patches/7f38f1b.parkpatch +++ b/data/scenario_patches/7f38f1b.parkpatch @@ -4,11 +4,11 @@ "land_ownership": { "available": { "coordinates": [ - [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], - [ 75, 167 ], + [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], + [ 75, 167 ], [ 61, 92 ], [ 61, 93 ], [ 61, 94 ], [ 61, 95 ], [ 62, 90 ], [ 62, 91 ], [ 62, 92 ], [ 62, 93 ], [ 62, 94 ], [ 92, 57 ], [ 93, 57 ], - [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], + [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], [ 168, 20 ], [ 169, 20 ], [ 46, 51 ], [ 58, 159 ], [ 71, 201 ], [ 126, 15 ], [ 190, 6 ] ] @@ -21,5 +21,12 @@ [ 103, 76 ], [ 104, 76 ] ] } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.bamboo_brown", + "surface": "rct2.footpath_surface.dirt", + "coordinates": [ [ 144, 100, 34 ] ] + } ] } diff --git a/data/scenario_patches/7ffdb44.parkpatch b/data/scenario_patches/7ffdb44.parkpatch index db6206427e..6fd885f4b6 100644 --- a/data/scenario_patches/7ffdb44.parkpatch +++ b/data/scenario_patches/7ffdb44.parkpatch @@ -4,11 +4,11 @@ "land_ownership": { "available": { "coordinates": [ - [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], - [ 75, 167 ], + [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], + [ 75, 167 ], [ 61, 92 ], [ 61, 93 ], [ 61, 94 ], [ 61, 95 ], [ 62, 90 ], [ 62, 91 ], [ 62, 92 ], [ 62, 93 ], [ 62, 94 ], [ 92, 57 ], [ 93, 57 ], - [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], + [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], [ 168, 20 ], [ 169, 20 ], [ 46, 51 ], [ 58, 159 ], [ 71, 201 ], [ 126, 15 ], [ 190, 6 ] ] @@ -21,5 +21,12 @@ [ 103, 76 ], [ 104, 76 ] ] } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.bamboo_brown", + "surface": "rct2.footpath_surface.dirt", + "coordinates": [ [ 144, 100, 34 ] ] + } ] } diff --git a/data/scenario_patches/c1d4056.parkpatch b/data/scenario_patches/c1d4056.parkpatch index 7f291735a1..96934e447d 100644 --- a/data/scenario_patches/c1d4056.parkpatch +++ b/data/scenario_patches/c1d4056.parkpatch @@ -4,11 +4,11 @@ "land_ownership": { "available": { "coordinates": [ - [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], - [ 75, 167 ], + [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], + [ 75, 167 ], [ 61, 92 ], [ 61, 93 ], [ 61, 94 ], [ 61, 95 ], [ 62, 90 ], [ 62, 91 ], [ 62, 92 ], [ 62, 93 ], [ 62, 94 ], [ 92, 57 ], [ 93, 57 ], - [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], + [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], [ 168, 20 ], [ 169, 20 ], [ 46, 51 ], [ 58, 159 ], [ 71, 201 ], [ 126, 15 ], [ 190, 6 ] ] @@ -21,5 +21,12 @@ [ 103, 76 ], [ 104, 76 ] ] } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.bamboo_brown", + "surface": "rct2.footpath_surface.dirt", + "coordinates": [ [ 144, 100, 34 ] ] + } ] } diff --git a/data/scenario_patches/c82272a.parkpatch b/data/scenario_patches/c82272a.parkpatch index a75e9e8fef..e220c663c5 100644 --- a/data/scenario_patches/c82272a.parkpatch +++ b/data/scenario_patches/c82272a.parkpatch @@ -4,11 +4,11 @@ "land_ownership": { "available": { "coordinates": [ - [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], - [ 75, 167 ], + [ 104, 190 ], [ 105, 190 ], [ 108, 197 ], + [ 75, 167 ], [ 61, 92 ], [ 61, 93 ], [ 61, 94 ], [ 61, 95 ], [ 62, 90 ], [ 62, 91 ], [ 62, 92 ], [ 62, 93 ], [ 62, 94 ], [ 92, 57 ], [ 93, 57 ], - [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], + [ 89, 40 ], [ 89, 41 ], [ 89, 42 ], [ 88, 42 ], [ 168, 20 ], [ 169, 20 ], [ 46, 51 ], [ 58, 159 ], [ 71, 201 ], [ 126, 15 ], [ 190, 6 ] ] @@ -21,5 +21,12 @@ [ 103, 76 ], [ 104, 76 ] ] } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.bamboo_brown", + "surface": "rct2.footpath_surface.dirt", + "coordinates": [ [ 144, 100, 34 ] ] + } ] } diff --git a/src/openrct2/rct12/ScenarioPatcher.cpp b/src/openrct2/rct12/ScenarioPatcher.cpp index 359d6eba8b..16dfb057d1 100644 --- a/src/openrct2/rct12/ScenarioPatcher.cpp +++ b/src/openrct2/rct12/ScenarioPatcher.cpp @@ -27,6 +27,7 @@ #include "../world/Location.hpp" #include "../world/Map.h" #include "../world/tile_element/EntranceElement.h" +#include "../world/tile_element/PathElement.h" #include "../world/tile_element/SurfaceElement.h" #include "../world/tile_element/TileElement.h" #include "../world/tile_element/TileElementType.h" @@ -74,6 +75,11 @@ static const std::string _ridesKey = "rides"; static const std::string _rideIdKey = "id"; static const std::string _operationKey = "operation"; +// Path fix keys +static const std::string _pathsKey = "paths"; +static const std::string _railingsKey = "railings"; +static const std::string _surfaceKey = "surface"; + static u8string ToOwnershipJsonKey(int ownershipType) { switch (ownershipType) @@ -93,7 +99,33 @@ static u8string ToOwnershipJsonKey(int ownershipType) return {}; } -static std::vector getCoordinates(const json_t& parameters) +static void readCoordinate(std::vector& out, const json_t& coordinatesArray) +{ + if (coordinatesArray.size() != 2) + { + OpenRCT2::Guard::Assert(0, "Fix coordinates sub array should have 2 elements"); + return; + } + + out.emplace_back( + OpenRCT2::Json::GetNumber(coordinatesArray[0]), OpenRCT2::Json::GetNumber(coordinatesArray[1])); +} + +static void readCoordinate(std::vector& out, const json_t& coordinatesArray) +{ + if (coordinatesArray.size() != 3) + { + OpenRCT2::Guard::Assert(0, "Fix coordinates sub array should have 3 elements"); + return; + } + + out.emplace_back( + OpenRCT2::Json::GetNumber(coordinatesArray[0]), OpenRCT2::Json::GetNumber(coordinatesArray[1]), + OpenRCT2::Json::GetNumber(coordinatesArray[2])); +} + +template +static std::vector getCoordinates(const json_t& parameters) { if (!parameters.contains(_coordinatesKey)) { @@ -113,7 +145,7 @@ static std::vector getCoordinates(const json_t& parameters) return {}; } - std::vector parsedCoordinates; + std::vector parsedCoordinates; parsedCoordinates.reserve(coords.size()); for (size_t i = 0; i < coords.size(); ++i) { @@ -123,14 +155,8 @@ static std::vector getCoordinates(const json_t& parameters) return {}; } - auto coordinatesPair = OpenRCT2::Json::AsArray(coords[i]); - if (coordinatesPair.size() != 2) - { - OpenRCT2::Guard::Assert(0, "Fix coordinates sub array should have 2 elements"); - return {}; - } - parsedCoordinates.emplace_back( - OpenRCT2::Json::GetNumber(coordinatesPair[0]), OpenRCT2::Json::GetNumber(coordinatesPair[1])); + auto coordinatesArray = OpenRCT2::Json::AsArray(coords[i]); + readCoordinate(parsedCoordinates, coordinatesArray); } return parsedCoordinates; } @@ -517,6 +543,87 @@ static void ApplyRideFixes(const json_t& scenarioPatch) } } +static void ApplyPathFixes(const json_t& scenarioPatch) +{ + if (!scenarioPatch.contains(_pathsKey)) + { + return; + } + + if (!scenarioPatch[_pathsKey].is_array()) + { + OpenRCT2::Guard::Assert(0, "Path fixes should be an array of arrays"); + return; + } + + auto pathFixes = OpenRCT2::Json::AsArray(scenarioPatch[_pathsKey]); + if (pathFixes.empty()) + { + OpenRCT2::Guard::Assert(0, "Path fixes should not be an empty array"); + return; + } + + for (size_t i = 0; i < pathFixes.size(); ++i) + { + auto pathFix = pathFixes[i]; + + if (!pathFix.contains(_railingsKey)) + { + OpenRCT2::Guard::Assert(0, "Path fixes should have railings"); + return; + } + + if (!pathFix.contains(_surfaceKey)) + { + OpenRCT2::Guard::Assert(0, "Path fixes should have a surface"); + return; + } + + auto railings = OpenRCT2::Json::GetString(pathFix[_railingsKey]); + auto surface = OpenRCT2::Json::GetString(pathFix[_surfaceKey]); + + if (_dryRun) + { + continue; + } + + auto& objectManager = OpenRCT2::GetContext()->GetObjectManager(); + auto railingsObjIndex = objectManager.GetLoadedObjectEntryIndex(railings); + auto surfaceObjIndex = objectManager.GetLoadedObjectEntryIndex(surface); + + if (railingsObjIndex == OBJECT_ENTRY_INDEX_NULL) + { + OpenRCT2::Guard::Assert(0, "Railings object not found"); + return; + } + + if (surfaceObjIndex == OBJECT_ENTRY_INDEX_NULL) + { + OpenRCT2::Guard::Assert(0, "Surface object not found"); + return; + } + + auto coordinates = getCoordinates(pathFix); + + for (auto coordinate : coordinates) + { + auto* pathElement = TileElementInsert(coordinate.ToCoordsXYZ(), 0b1111); + OpenRCT2::Guard::Assert(pathElement != nullptr); + + pathElement->SetSurfaceEntryIndex(surfaceObjIndex); + pathElement->SetRailingsEntryIndex(railingsObjIndex); + + FootpathQueueChainReset(); + FootpathConnectEdges( + coordinate.ToCoordsXY(), pathElement->as(), + GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); + FootpathUpdateQueueChains(); + + MapInvalidateTileFull(coordinate.ToCoordsXY()); + } + } +} + static u8string getScenarioSHA256(u8string_view scenarioPath) { auto env = OpenRCT2::GetContext()->GetPlatformEnvironment(); @@ -581,6 +688,7 @@ void OpenRCT2::RCT12::ApplyScenarioPatch(u8string_view scenarioPatchFile, u8stri ApplySurfaceFixes(scenarioPatch); RemoveTileElements(scenarioPatch); ApplyRideFixes(scenarioPatch); + ApplyPathFixes(scenarioPatch); } void OpenRCT2::RCT12::FetchAndApplyScenarioPatch(u8string_view scenarioPath) From 7d958e63dfe32ba6a8a7ace7004223f2a5c7de22 Mon Sep 17 00:00:00 2001 From: Brendan Heinonen Date: Mon, 4 Nov 2024 17:46:52 -0500 Subject: [PATCH 107/139] Part of #20070: missing sloped footpath in scenarios Scenarios amended: - Alton Towers - Rollercoaster Heaven --- data/scenario_patches/0b8cc95.parkpatch | 31 +++++++++++++++++++++++++ data/scenario_patches/5c95a4e.parkpatch | 6 +++++ data/scenario_patches/eabcb3d.parkpatch | 31 +++++++++++++++++++++++++ data/scenario_patches/scenario_to_hash | 6 ++++- src/openrct2/rct12/ScenarioPatcher.cpp | 30 ++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 data/scenario_patches/0b8cc95.parkpatch create mode 100644 data/scenario_patches/eabcb3d.parkpatch diff --git a/data/scenario_patches/0b8cc95.parkpatch b/data/scenario_patches/0b8cc95.parkpatch new file mode 100644 index 0000000000..bfbf52c33e --- /dev/null +++ b/data/scenario_patches/0b8cc95.parkpatch @@ -0,0 +1,31 @@ +{ + "scenario_name": "Rollercoaster Heaven", + "sha256": "0b8cc952c399e1515546a4ababe5ba2f7aace83915a7e51c56ee901568c9ef56", + "elements_to_delete": [ + { + "element_index": 0, + "coordinates": [ + [ 23, 79 ], [ 24, 79 ] + ] + }, + { + "element_index": 1, + "coordinates": [ + [ 87, 13 ] + ] + } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.crazy_paving", + "coordinates": [ [ 24, 79, 14 ], [ 87, 13, 18 ] ] + }, + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.crazy_paving", + "coordinates": [ [ 23, 79, 12 ] ], + "slope_direction": 2 + } + ] +} diff --git a/data/scenario_patches/5c95a4e.parkpatch b/data/scenario_patches/5c95a4e.parkpatch index 0f7e0a0e03..67b6961874 100644 --- a/data/scenario_patches/5c95a4e.parkpatch +++ b/data/scenario_patches/5c95a4e.parkpatch @@ -13,6 +13,12 @@ "railings": "rct2.footpath_railings.wood", "surface": "rct1.footpath_surface.crazy_paving", "coordinates": [ [ 83, 81, 22 ] ] + }, + { + "railings": "rct2.footpath_railings.wood", + "surface": "rct1.footpath_surface.crazy_paving", + "coordinates": [ [ 85, 77, 22 ] ], + "slope_direction": 2 } ] } diff --git a/data/scenario_patches/eabcb3d.parkpatch b/data/scenario_patches/eabcb3d.parkpatch new file mode 100644 index 0000000000..e266f8fc1b --- /dev/null +++ b/data/scenario_patches/eabcb3d.parkpatch @@ -0,0 +1,31 @@ +{ + "scenario_name": "Rollercoaster Heaven (.sea)", + "sha256": "eabcb3d924e8e3438bfd90f6758a723c89df4136a817533d34985598d58ba38f", + "elements_to_delete": [ + { + "element_index": 0, + "coordinates": [ + [ 23, 79 ], [ 24, 79 ] + ] + }, + { + "element_index": 1, + "coordinates": [ + [ 87, 13 ] + ] + } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.crazy_paving", + "coordinates": [ [ 24, 79, 14 ], [ 87, 13, 18 ] ] + }, + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.crazy_paving", + "coordinates": [ [ 23, 79, 12 ] ], + "slope_direction": 2 + } + ] +} diff --git a/data/scenario_patches/scenario_to_hash b/data/scenario_patches/scenario_to_hash index 6d352dc211..7d2b9985fb 100644 --- a/data/scenario_patches/scenario_to_hash +++ b/data/scenario_patches/scenario_to_hash @@ -51,6 +51,8 @@ '33bac63d13aa7513ac8536d865cbc6fa4a2189c79e3943869e6380072e71bce7'], 'Rock ‘n’ Roll Revival': ['d48bbfe', 'd48bbfe4833347dfbf5befe63eb3795df3bce36cdc9152048ee7851e36d45ad9'], + 'Rollercoaster Heaven': ['0b8cc95', + '0b8cc952c399e1515546a4ababe5ba2f7aace83915a7e51c56ee901568c9ef56'], 'Schneider Shores': ['e57112f', 'e57112f58a7710d3e80242e867fb65d720e0cd3b67bebfd6b7df8b404fc7ea2b'], 'Sherwood Forest': ['825134a', @@ -207,6 +209,8 @@ 'b43b07e47f2e6cb762a86760ac0242595617aa59bfd9811cec7e2dcc121ae367'], 'Rock ‘n’ Roll Revival': ['f71c978', 'f71c9788ab40ac591d5c96397fad8b12d9d3ac7830eac53f6ee5dc024c8c2bcf'], + 'Rollercoaster Heaven': ['eabcb3d', + 'eabcb3d924e8e3438bfd90f6758a723c89df4136a817533d34985598d58ba38f'], 'Schneider Shores': ['0d53bdc', '0d53bdc076d75d86b31b6b3e6948e3d45671cf5aeff6b2b3c07a7618923223f5'], 'Sherwood Forest': ['a04b536', @@ -220,4 +224,4 @@ 'Six Flags over Texas': ['6226822', '62268223a1539c92b7494973263457c9e9bf386c1e68eef21d377854f0ac0e38'], 'Wacky Waikiki': ['72cf3d2', - '72cf3d220740fd64f7681d3533320598cf6d3b71dff484bc43045e8d9d7a1a4b'], \ No newline at end of file + '72cf3d220740fd64f7681d3533320598cf6d3b71dff484bc43045e8d9d7a1a4b'], diff --git a/src/openrct2/rct12/ScenarioPatcher.cpp b/src/openrct2/rct12/ScenarioPatcher.cpp index 16dfb057d1..11e23c0ff6 100644 --- a/src/openrct2/rct12/ScenarioPatcher.cpp +++ b/src/openrct2/rct12/ScenarioPatcher.cpp @@ -79,6 +79,7 @@ static const std::string _operationKey = "operation"; static const std::string _pathsKey = "paths"; static const std::string _railingsKey = "railings"; static const std::string _surfaceKey = "surface"; +static const std::string _directionKey = "slope_direction"; static u8string ToOwnershipJsonKey(int ownershipType) { @@ -161,6 +162,29 @@ static std::vector getCoordinates(const json_t& parameters) return parsedCoordinates; } +static Direction GetDirection(const json_t& parameters) +{ + if (!parameters.contains(_directionKey)) + { + return INVALID_DIRECTION; + } + else if (!parameters[_directionKey].is_number()) + { + OpenRCT2::Guard::Assert(0, "Fix direction must be a number"); + return INVALID_DIRECTION; + } + + Direction direction = OpenRCT2::Json::GetNumber(parameters[_directionKey]); + + if (direction > 3) + { + OpenRCT2::Guard::Assert(0, "Direction must be between 0 and 3"); + return INVALID_DIRECTION; + } + + return direction; +} + static void ApplyLandOwnershipFixes(const json_t& landOwnershipFixes, int ownershipType) { auto ownershipTypeKey = ToOwnershipJsonKey(ownershipType); @@ -604,6 +628,7 @@ static void ApplyPathFixes(const json_t& scenarioPatch) } auto coordinates = getCoordinates(pathFix); + Direction direction = GetDirection(pathFix); for (auto coordinate : coordinates) { @@ -612,6 +637,11 @@ static void ApplyPathFixes(const json_t& scenarioPatch) pathElement->SetSurfaceEntryIndex(surfaceObjIndex); pathElement->SetRailingsEntryIndex(railingsObjIndex); + if (direction != INVALID_DIRECTION) + { + pathElement->SetSloped(true); + pathElement->SetSlopeDirection(direction); + } FootpathQueueChainReset(); FootpathConnectEdges( From 47c8970d712623e731a7b8b506112bab638d5d7e Mon Sep 17 00:00:00 2001 From: Tulio Leao Date: Wed, 13 Nov 2024 08:03:31 -0300 Subject: [PATCH 108/139] Part of #20070: Allow fixing paths with queues Fixes Mines of Africa --- data/scenario_patches/2980c28.parkpatch | 21 ++++++++++++ data/scenario_patches/4a762ae.parkpatch | 40 ++++++++++++++++++++++ data/scenario_patches/b080197.parkpatch | 21 ++++++++++++ data/scenario_patches/b20bd80.parkpatch | 40 ++++++++++++++++++++++ data/scenario_patches/scenario_to_hash | 10 +++++- src/openrct2/rct12/ScenarioPatcher.cpp | 44 ++++++++++++++++--------- 6 files changed, 159 insertions(+), 17 deletions(-) create mode 100644 data/scenario_patches/2980c28.parkpatch create mode 100644 data/scenario_patches/4a762ae.parkpatch create mode 100644 data/scenario_patches/b080197.parkpatch create mode 100644 data/scenario_patches/b20bd80.parkpatch diff --git a/data/scenario_patches/2980c28.parkpatch b/data/scenario_patches/2980c28.parkpatch new file mode 100644 index 0000000000..e16ab06d8f --- /dev/null +++ b/data/scenario_patches/2980c28.parkpatch @@ -0,0 +1,21 @@ +{ + "scenario_name": "Mines of Africa", + "sha256": "2980c287d81e4e96a46db30d1a80e6bfa0caace6a14488dddc6f20ac71676cff", + "elements_to_delete": [ + { + "element_index": 1, + "coordinates": [ + [ 43, 46 ] + ] + } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.queue_yellow", + "coordinates": [ [ 43, 46, 6 ] ], + "slope_direction": 3, + "queue": true + } + ] +} diff --git a/data/scenario_patches/4a762ae.parkpatch b/data/scenario_patches/4a762ae.parkpatch new file mode 100644 index 0000000000..01986fc1c2 --- /dev/null +++ b/data/scenario_patches/4a762ae.parkpatch @@ -0,0 +1,40 @@ +{ + "scenario_name": "Iceberg Islands", + "sha256": "4a762ae89bf279dbcaead9e457c21014a9e39eb4a46cf1cbf63304450f9ed050", + "elements_to_delete": [ + { + "element_index": 2, + "coordinates": [ + [ 49, 43 ], [ 50, 43 ], [ 51, 43 ], [ 44, 55 ] + ] + }, + { + "element_index": 1, + "coordinates": [ + [ 44, 54 ], [ 44, 53 ] + ] + } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct1.footpath_surface.queue_blue", + "coordinates": [ [ 51, 43, 24 ], [ 44, 55, 20 ] ], + "queue": true + }, + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct1.footpath_surface.queue_blue", + "coordinates": [ [ 50, 43, 24 ], [ 49, 43, 26 ] ], + "slope_direction": 0, + "queue": true + }, + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct1.footpath_surface.queue_blue", + "coordinates": [ [ 44, 54, 18 ], [ 44, 53, 16 ] ], + "slope_direction": 1, + "queue": true + } + ] +} diff --git a/data/scenario_patches/b080197.parkpatch b/data/scenario_patches/b080197.parkpatch new file mode 100644 index 0000000000..642e69bf10 --- /dev/null +++ b/data/scenario_patches/b080197.parkpatch @@ -0,0 +1,21 @@ +{ + "scenario_name": "Mines of Africa (.sea)", + "sha256": "b080197d430a6ded46945035a95c8f2d9e3064637e9119e68270554eda48e747", + "elements_to_delete": [ + { + "element_index": 1, + "coordinates": [ + [ 43, 46 ] + ] + } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.queue_yellow", + "coordinates": [ [ 43, 46, 6 ] ], + "slope_direction": 3, + "queue": true + } + ] +} diff --git a/data/scenario_patches/b20bd80.parkpatch b/data/scenario_patches/b20bd80.parkpatch new file mode 100644 index 0000000000..973c8e350e --- /dev/null +++ b/data/scenario_patches/b20bd80.parkpatch @@ -0,0 +1,40 @@ +{ + "scenario_name": "Iceberg Islands (.sea)", + "sha256": "b20bd803c0a99c8748b48688501ba6ef8a5ce5d746540a486617e0564aa407d5", + "elements_to_delete": [ + { + "element_index": 2, + "coordinates": [ + [ 49, 43 ], [ 50, 43 ], [ 51, 43 ], [ 44, 55 ] + ] + }, + { + "element_index": 1, + "coordinates": [ + [ 44, 54 ], [ 44, 53 ] + ] + } + ], + "paths": [ + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.queue_yellow", + "coordinates": [ [ 51, 43, 24 ], [ 44, 55, 20 ] ], + "queue": true + }, + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.queue_yellow", + "coordinates": [ [ 50, 43, 24 ], [ 49, 43, 26 ] ], + "slope_direction": 0, + "queue": true + }, + { + "railings": "rct2.footpath_railings.concrete", + "surface": "rct2.footpath_surface.queue_yellow", + "coordinates": [ [ 44, 54, 18 ], [ 44, 53, 16 ] ], + "slope_direction": 1, + "queue": true + } + ] +} diff --git a/data/scenario_patches/scenario_to_hash b/data/scenario_patches/scenario_to_hash index 7d2b9985fb..3ffa3ec789 100644 --- a/data/scenario_patches/scenario_to_hash +++ b/data/scenario_patches/scenario_to_hash @@ -39,6 +39,8 @@ 'fcc15f9c9b42bdd4aa8761c3a6df17c1293aa616780bc4aadd348d191e275112'], 'Lost City Founder': ['13e81f2', '13e81f23ab1a7051b5465e4a7bb214b4188f2264d499f8f7e106372c3a984331'], + 'Mines of Africa': ['2980c28', + '2980c287d81e4e96a46db30d1a80e6bfa0caace6a14488dddc6f20ac71676cff'], 'Mirage Madness': ['2696a05', '2696a059c2c1b23c60cbfcc293fd29cfec45d7e3da7f3b38bc2b52aff834fd34'], 'Mythological Madness': ['ef0c020', @@ -89,6 +91,8 @@ '102a1c52853e77b6efd448a44572a862fa440615b4ea9ae5d7fb31c48c96aac9'], 'Hydro Hills': ['bfbd61f', 'bfbd61f6d22cdc5f2e017935f4e9e5969dece159218a08c695bfd727382cc717'], + 'Iceberg Islands': ['4a762ae', + '4a762ae89bf279dbcaead9e457c21014a9e39eb4a46cf1cbf63304450f9ed050'], 'katie\'s dreamland': ['73d0921', '73d0921f1d49388ffb4deb300c6ebb3920564410c2239580a7d1145fa54c2d4a'], 'Leafy Lake': ['83bd798', @@ -132,7 +136,9 @@ 'Haunted Harbour': ['b2cebe1', 'b2cebe149b2330e071a028d079f6632af144fb44e076a5eca89780eb4007e136'], 'hydro hills': ['ce24961', - 'ce249614e735c560c5019318bc6fa8603ba6630576f7fb038def0bdac3e143ef'] + 'ce249614e735c560c5019318bc6fa8603ba6630576f7fb038def0bdac3e143ef'], + 'Iceberg Islands': ['b20bd80', + 'b20bd803c0a99c8748b48688501ba6ef8a5ce5d746540a486617e0564aa407d5'], 'katie\'s dreamland': ['b8b572d', 'b8b572d394b145535cdb20f66b0bee9a497683a5885e4d78af6773c5bc0323ff'], 'mel\'s world': ['bfaf504', @@ -197,6 +203,8 @@ 'adffe2ff1e06ebeb821bbf01263125dc40311a8350722c62908be8d1c8852259'], 'Lost City Founder': ['70ce3e1', '70ce3e11f1dd59929a6d82d0f6f88897c95b94d1f9d4efd6ef3a0c6c449f966f'], + 'Mines of Africa': ['b080197', + 'b080197d430a6ded46945035a95c8f2d9e3064637e9119e68270554eda48e747'], 'Mirage Madness': ['82aeaf6', '82aeaf6bd628bf26dabd1ca87455b667f3081598bcf4d4c7751e2bdfbd266ac2'], 'Mythological Madness': ['6633d17', diff --git a/src/openrct2/rct12/ScenarioPatcher.cpp b/src/openrct2/rct12/ScenarioPatcher.cpp index 11e23c0ff6..bb334a3072 100644 --- a/src/openrct2/rct12/ScenarioPatcher.cpp +++ b/src/openrct2/rct12/ScenarioPatcher.cpp @@ -12,6 +12,8 @@ #include "../Context.h" #include "../Game.h" #include "../PlatformEnvironment.h" +#include "../actions/FootpathPlaceAction.h" +#include "../actions/GameActionResult.h" #include "../core/File.h" #include "../core/Guard.hpp" #include "../core/Json.hpp" @@ -28,6 +30,7 @@ #include "../world/Map.h" #include "../world/tile_element/EntranceElement.h" #include "../world/tile_element/PathElement.h" +#include "../world/tile_element/Slope.h" #include "../world/tile_element/SurfaceElement.h" #include "../world/tile_element/TileElement.h" #include "../world/tile_element/TileElementType.h" @@ -80,6 +83,7 @@ static const std::string _pathsKey = "paths"; static const std::string _railingsKey = "railings"; static const std::string _surfaceKey = "surface"; static const std::string _directionKey = "slope_direction"; +static const std::string _isQueue = "queue"; static u8string ToOwnershipJsonKey(int ownershipType) { @@ -185,6 +189,23 @@ static Direction GetDirection(const json_t& parameters) return direction; } +static bool IsQueue(const json_t& parameters) +{ + if (!parameters.contains(_isQueue)) + { + return false; + } + else if (!parameters[_isQueue].is_boolean()) + { + OpenRCT2::Guard::Assert(0, "queue must be a boolean"); + return false; + } + else + { + return OpenRCT2::Json::GetBoolean(parameters[_isQueue]); + } +} + static void ApplyLandOwnershipFixes(const json_t& landOwnershipFixes, int ownershipType) { auto ownershipTypeKey = ToOwnershipJsonKey(ownershipType); @@ -629,27 +650,18 @@ static void ApplyPathFixes(const json_t& scenarioPatch) auto coordinates = getCoordinates(pathFix); Direction direction = GetDirection(pathFix); + PathConstructFlags constructionFlags = IsQueue(pathFix) ? OpenRCT2::PathConstructFlag::IsQueue : 0; for (auto coordinate : coordinates) { - auto* pathElement = TileElementInsert(coordinate.ToCoordsXYZ(), 0b1111); - OpenRCT2::Guard::Assert(pathElement != nullptr); - - pathElement->SetSurfaceEntryIndex(surfaceObjIndex); - pathElement->SetRailingsEntryIndex(railingsObjIndex); - if (direction != INVALID_DIRECTION) + auto slope = direction != INVALID_DIRECTION ? direction + 4 : 0; + auto footpathPlaceAction = FootpathPlaceAction( + coordinate.ToCoordsXYZ(), slope, surfaceObjIndex, railingsObjIndex, direction, constructionFlags); + auto result = footpathPlaceAction.Execute(); + if (result.Error != OpenRCT2::GameActions::Status::Ok) { - pathElement->SetSloped(true); - pathElement->SetSlopeDirection(direction); + OpenRCT2::Guard::Assert(0, "Could not patch path"); } - - FootpathQueueChainReset(); - FootpathConnectEdges( - coordinate.ToCoordsXY(), pathElement->as(), - GAME_COMMAND_FLAG_APPLY | GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED); - FootpathUpdateQueueChains(); - - MapInvalidateTileFull(coordinate.ToCoordsXY()); } } } From 7e30d8e4f5a682eef4453b5d48f7590082925fed Mon Sep 17 00:00:00 2001 From: Tulio Leao Date: Tue, 12 Nov 2024 08:08:54 -0300 Subject: [PATCH 109/139] Add changelog and bump network version --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 65caffd754..627598ac12 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -6,6 +6,7 @@ - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). - Improved: [#23233] Add diagonal booster to LSM Launched Coaster. +- Fix: [#20070, #22972] Missing and mismatched flat and sloped footpaths on several scenarios. - Fix: [#22726] ‘Force park rating’ cheat is not saved with the park. - Fix: [#23064] Stand-Up Roller Coaster unbanked to banked track pieces are misaligned. - Fix: [#23066] Stand-Up Roller Coaster has many supports that don't join up to the track. From 38943d5ba4b7bafa8e17280d99d4d319e527a7a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:21:17 +0200 Subject: [PATCH 110/139] Add sfl license in readme.txt --- distribution/readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/readme.txt b/distribution/readme.txt index e71efd79e2..c423d4be13 100644 --- a/distribution/readme.txt +++ b/distribution/readme.txt @@ -154,6 +154,7 @@ SDL2 | zlib licence. zlib | zlib licence. Google Test | BSD 3 clause licence. Google Benchmark | Apache 2.0 licence. +sfl | zlib licence. Licences for sub-libraries used by the above may vary. For more information, visit the libraries' respective official websites. From f9fdac27693c8848240426d2ca4d4dd9dcf2e3b9 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 4 Dec 2024 00:00:54 +0100 Subject: [PATCH 111/139] Infer peep animation sprite bounds at runtime (#23235) --- src/openrct2/Context.cpp | 3 + src/openrct2/peep/PeepAnimationData.cpp | 732 ++++++++++++++---------- src/openrct2/peep/PeepAnimationData.h | 12 +- 3 files changed, 438 insertions(+), 309 deletions(-) diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 7ba3a94b47..031e9aa9e0 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -57,6 +57,7 @@ #include "object/ObjectRepository.h" #include "paint/Painter.h" #include "park/ParkFile.h" +#include "peep/PeepAnimationData.h" #include "platform/Crash.h" #include "platform/Platform.h" #include "profiling/Profiling.h" @@ -1006,6 +1007,7 @@ namespace OpenRCT2 return result; } + // TODO: move function elsewhere? bool LoadBaseGraphics() { if (!GfxLoadG1(*_env)) @@ -1015,6 +1017,7 @@ namespace OpenRCT2 GfxLoadG2(); GfxLoadCsg(); FontSpriteInitialiseCharacters(); + inferMaxPeepSpriteDimensions(); return true; } diff --git a/src/openrct2/peep/PeepAnimationData.cpp b/src/openrct2/peep/PeepAnimationData.cpp index 042f3baa99..9b90f883f5 100644 --- a/src/openrct2/peep/PeepAnimationData.cpp +++ b/src/openrct2/peep/PeepAnimationData.cpp @@ -9,12 +9,110 @@ #include "PeepAnimationData.h" +#include "../drawing/Drawing.h" #include "PeepSpriteIds.h" +#include #include namespace OpenRCT2 { + // Adapted from CarEntry.cpp + static SpriteBounds inferMaxAnimationDimensions(const PeepAnimation& anim) + { + constexpr uint8_t kWidth = 200; + constexpr uint8_t kHeight = 200; + constexpr uint8_t kCentreX = kWidth / 2; + constexpr uint8_t kCentreY = kHeight / 2; + + uint8_t bitmap[kHeight][kWidth] = { 0 }; + + DrawPixelInfo dpi = { + .bits = reinterpret_cast(bitmap), + .x = -(kWidth / 2), + .y = -(kHeight / 2), + .width = kWidth, + .height = kHeight, + .pitch = 0, + .zoom_level = ZoomLevel{ 0 }, + }; + + const auto numImages = *(std::max_element(anim.frame_offsets.begin(), anim.frame_offsets.end())) + 1; + for (int32_t i = 0; i < numImages; ++i) + { + GfxDrawSpriteSoftware(dpi, ImageId(anim.base_image + i), { 0, 0 }); + } + + int32_t spriteWidth = -1; + for (int32_t i = kCentreX - 1; i != 0; --i) + { + for (int32_t j = 0; j < kWidth; j++) + { + if (bitmap[j][kCentreX - i] != 0) + { + spriteWidth = i; + break; + } + } + + if (spriteWidth != -1) + break; + + for (int32_t j = 0; j < kWidth; j++) + { + if (bitmap[j][kCentreX + i] != 0) + { + spriteWidth = i; + break; + } + } + + if (spriteWidth != -1) + break; + } + spriteWidth++; + + int32_t spriteHeightNegative = -1; + for (int32_t i = kCentreY - 1; i != 0; --i) + { + for (int32_t j = 0; j < kWidth; j++) + { + if (bitmap[kCentreY - i][j] != 0) + { + spriteHeightNegative = i; + break; + } + } + + if (spriteHeightNegative != -1) + break; + } + spriteHeightNegative++; + + int32_t spriteHeightPositive = -1; + for (int32_t i = kCentreY - 1; i != 0; --i) + { + for (int32_t j = 0; j < kWidth; j++) + { + if (bitmap[kCentreY + i][j] != 0) + { + spriteHeightPositive = i; + break; + } + } + + if (spriteHeightPositive != -1) + break; + } + spriteHeightPositive++; + + return { + .sprite_width = static_cast(spriteWidth), + .sprite_height_negative = static_cast(spriteHeightNegative), + .sprite_height_positive = static_cast(spriteHeightPositive), + }; + } + // clang-format off // Define animation sequences for Normal sprites @@ -46,34 +144,34 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceNormalWithdrawMoney = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11, 12, 11, 12, 11, 12, 11, 12, 11, 11, 11, 11, 11, 13, 14, 15 }; // Define animation group for Normal sequences - static constexpr PeepAnimations kPeepAnimationsNormal = []() { + static PeepAnimations kPeepAnimationsNormal = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kPeepSpriteNormalStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceNormalNone }; - pag[PeepAnimationType::CheckTime] = { kPeepSpriteNormalStateCheckTimeId, { 8, 16, 5 }, kPeepAnimationSequenceNormalCheckTime }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteNormalStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceNormalWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteNormalStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceNormalEatFood }; - pag[PeepAnimationType::ShakeHead] = { kPeepSpriteNormalStateShakeHeadId, { 8, 16, 5 }, kPeepAnimationSequenceNormalShakeHead }; - pag[PeepAnimationType::EmptyPockets] = { kPeepSpriteNormalStateEmptyPocketsId, { 8, 16, 5 }, kPeepAnimationSequenceNormalEmptyPockets }; - pag[PeepAnimationType::HoldMat] = { kPeepSpriteNormalStateHoldMatId, { 9, 16, 5 }, kPeepAnimationSequenceNormalHoldMat }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteNormalStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceNormalSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteNormalStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceNormalSittingEatFood }; - pag[PeepAnimationType::SittingLookAroundLeft] = { kPeepSpriteNormalStateSittingLookAroundLeftId, { 9, 16, 6 }, kPeepAnimationSequenceNormalSittingLookAroundLeft }; - pag[PeepAnimationType::SittingLookAroundRight] = { kPeepSpriteNormalStateSittingLookAroundRightId, { 9, 16, 6 }, kPeepAnimationSequenceNormalSittingLookAroundRight }; - pag[PeepAnimationType::Hanging] = { kPeepSpriteNormalStateHangingId, { 8, 16, 5 }, kPeepAnimationSequenceNormalHanging }; - pag[PeepAnimationType::Wow] = { kPeepSpriteNormalStateWowId, { 12, 22, 5 }, kPeepAnimationSequenceNormalWow }; - pag[PeepAnimationType::ThrowUp] = { kPeepSpriteNormalStateThrowUpId, { 9, 16, 7 }, kPeepAnimationSequenceNormalThrowUp }; - pag[PeepAnimationType::Jump] = { kPeepSpriteNormalStateJumpId, { 10, 22, 5 }, kPeepAnimationSequenceNormalJump }; - pag[PeepAnimationType::Drowning] = { kPeepSpriteNormalStateDrowningId, { 9, 15, 6 }, kPeepAnimationSequenceNormalDrowning }; - pag[PeepAnimationType::Joy] = { kPeepSpriteNormalStateJoyId, { 11, 24, 6 }, kPeepAnimationSequenceNormalJoy }; - pag[PeepAnimationType::ReadMap] = { kPeepSpriteNormalStateReadMapId, { 11, 16, 5 }, kPeepAnimationSequenceNormalReadMap }; - pag[PeepAnimationType::Wave] = { kPeepSpriteNormalStateWaveId, { 11, 16, 5 }, kPeepAnimationSequenceNormalWave }; - pag[PeepAnimationType::Wave2] = { kPeepSpriteNormalStateWave2Id, { 11, 16, 5 }, kPeepAnimationSequenceNormalWave2 }; - pag[PeepAnimationType::TakePhoto] = { kPeepSpriteNormalStateTakePhotoId, { 8, 16, 5 }, kPeepAnimationSequenceNormalTakePhoto }; - pag[PeepAnimationType::Clap] = { kPeepSpriteNormalStateClapId, { 9, 17, 6 }, kPeepAnimationSequenceNormalClap }; - pag[PeepAnimationType::Disgust] = { kPeepSpriteNormalStateDisgustId, { 9, 16, 5 }, kPeepAnimationSequenceNormalDisgust }; - pag[PeepAnimationType::DrawPicture] = { kPeepSpriteNormalStateDrawPictureId, { 9, 22, 7 }, kPeepAnimationSequenceNormalDrawPicture }; - pag[PeepAnimationType::BeingWatched] = { kPeepSpriteNormalStateBeingWatchedId, { 9, 22, 7 }, kPeepAnimationSequenceNormalBeingWatched }; - pag[PeepAnimationType::WithdrawMoney] = { kPeepSpriteNormalStateWithdrawMoneyId, { 9, 22, 7 }, kPeepAnimationSequenceNormalWithdrawMoney }; + pag[PeepAnimationType::None] = { kPeepSpriteNormalStateNoneId, kPeepAnimationSequenceNormalNone }; + pag[PeepAnimationType::CheckTime] = { kPeepSpriteNormalStateCheckTimeId, kPeepAnimationSequenceNormalCheckTime }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteNormalStateWatchRideId, kPeepAnimationSequenceNormalWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteNormalStateEatFoodId, kPeepAnimationSequenceNormalEatFood }; + pag[PeepAnimationType::ShakeHead] = { kPeepSpriteNormalStateShakeHeadId, kPeepAnimationSequenceNormalShakeHead }; + pag[PeepAnimationType::EmptyPockets] = { kPeepSpriteNormalStateEmptyPocketsId, kPeepAnimationSequenceNormalEmptyPockets }; + pag[PeepAnimationType::HoldMat] = { kPeepSpriteNormalStateHoldMatId, kPeepAnimationSequenceNormalHoldMat }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteNormalStateSittingIdleId, kPeepAnimationSequenceNormalSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteNormalStateSittingEatFoodId, kPeepAnimationSequenceNormalSittingEatFood }; + pag[PeepAnimationType::SittingLookAroundLeft] = { kPeepSpriteNormalStateSittingLookAroundLeftId, kPeepAnimationSequenceNormalSittingLookAroundLeft }; + pag[PeepAnimationType::SittingLookAroundRight] = { kPeepSpriteNormalStateSittingLookAroundRightId, kPeepAnimationSequenceNormalSittingLookAroundRight }; + pag[PeepAnimationType::Hanging] = { kPeepSpriteNormalStateHangingId, kPeepAnimationSequenceNormalHanging }; + pag[PeepAnimationType::Wow] = { kPeepSpriteNormalStateWowId, kPeepAnimationSequenceNormalWow }; + pag[PeepAnimationType::ThrowUp] = { kPeepSpriteNormalStateThrowUpId, kPeepAnimationSequenceNormalThrowUp }; + pag[PeepAnimationType::Jump] = { kPeepSpriteNormalStateJumpId, kPeepAnimationSequenceNormalJump }; + pag[PeepAnimationType::Drowning] = { kPeepSpriteNormalStateDrowningId, kPeepAnimationSequenceNormalDrowning }; + pag[PeepAnimationType::Joy] = { kPeepSpriteNormalStateJoyId, kPeepAnimationSequenceNormalJoy }; + pag[PeepAnimationType::ReadMap] = { kPeepSpriteNormalStateReadMapId, kPeepAnimationSequenceNormalReadMap }; + pag[PeepAnimationType::Wave] = { kPeepSpriteNormalStateWaveId, kPeepAnimationSequenceNormalWave }; + pag[PeepAnimationType::Wave2] = { kPeepSpriteNormalStateWave2Id, kPeepAnimationSequenceNormalWave2 }; + pag[PeepAnimationType::TakePhoto] = { kPeepSpriteNormalStateTakePhotoId, kPeepAnimationSequenceNormalTakePhoto }; + pag[PeepAnimationType::Clap] = { kPeepSpriteNormalStateClapId, kPeepAnimationSequenceNormalClap }; + pag[PeepAnimationType::Disgust] = { kPeepSpriteNormalStateDisgustId, kPeepAnimationSequenceNormalDisgust }; + pag[PeepAnimationType::DrawPicture] = { kPeepSpriteNormalStateDrawPictureId, kPeepAnimationSequenceNormalDrawPicture }; + pag[PeepAnimationType::BeingWatched] = { kPeepSpriteNormalStateBeingWatchedId, kPeepAnimationSequenceNormalBeingWatched }; + pag[PeepAnimationType::WithdrawMoney] = { kPeepSpriteNormalStateWithdrawMoneyId, kPeepAnimationSequenceNormalWithdrawMoney }; return pag; }(); @@ -88,16 +186,16 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceHandymanStaffEmptyBin = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; // Define animation group for Handyman sequences - static constexpr PeepAnimations kPeepAnimationsHandyman = []() { + static PeepAnimations kPeepAnimationsHandyman = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kHandymanSpriteStateNoneId, { 12, 16, 6 }, kPeepAnimationSequenceHandymanNone }; - pag[PeepAnimationType::WatchRide] = { kHandymanSpriteStateWatchRideId, { 9, 16, 6 }, kPeepAnimationSequenceHandymanWatchRide }; - pag[PeepAnimationType::Hanging] = { kHandymanSpriteStateHangingId, { 15, 16, 5 }, kPeepAnimationSequenceHandymanHanging }; - pag[PeepAnimationType::StaffMower] = { kHandymanSpriteStateStaffMowerId, { 18, 16, 11 }, kPeepAnimationSequenceHandymanStaffMower }; - pag[PeepAnimationType::StaffSweep] = { kHandymanSpriteStateStaffSweepId, { 17, 16, 9 }, kPeepAnimationSequenceHandymanStaffSweep }; - pag[PeepAnimationType::Drowning] = { kHandymanSpriteStateDrowningId, { 9, 15, 6 }, kPeepAnimationSequenceHandymanDrowning }; - pag[PeepAnimationType::StaffWatering] = { kHandymanSpriteStateStaffWateringId, { 17, 16, 9 }, kPeepAnimationSequenceHandymanStaffWatering }; - pag[PeepAnimationType::StaffEmptyBin] = { kHandymanSpriteStateStaffEmptyBinId, { 17, 16, 9 }, kPeepAnimationSequenceHandymanStaffEmptyBin }; + pag[PeepAnimationType::None] = { kHandymanSpriteStateNoneId, kPeepAnimationSequenceHandymanNone }; + pag[PeepAnimationType::WatchRide] = { kHandymanSpriteStateWatchRideId, kPeepAnimationSequenceHandymanWatchRide }; + pag[PeepAnimationType::Hanging] = { kHandymanSpriteStateHangingId, kPeepAnimationSequenceHandymanHanging }; + pag[PeepAnimationType::StaffMower] = { kHandymanSpriteStateStaffMowerId, kPeepAnimationSequenceHandymanStaffMower }; + pag[PeepAnimationType::StaffSweep] = { kHandymanSpriteStateStaffSweepId, kPeepAnimationSequenceHandymanStaffSweep }; + pag[PeepAnimationType::Drowning] = { kHandymanSpriteStateDrowningId, kPeepAnimationSequenceHandymanDrowning }; + pag[PeepAnimationType::StaffWatering] = { kHandymanSpriteStateStaffWateringId, kPeepAnimationSequenceHandymanStaffWatering }; + pag[PeepAnimationType::StaffEmptyBin] = { kHandymanSpriteStateStaffEmptyBinId, kPeepAnimationSequenceHandymanStaffEmptyBin }; return pag; }(); @@ -115,19 +213,19 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceMechanicStaffFix3 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 16, 15, 14, 15, 16, 17, 16, 15, 14, 15, 16, 17, 16, 15, 14, 13, 12, 11, 11, 12, 13, 14, 15, 16, 17, 16, 15, 14, 15, 16, 17, 16, 15, 14, 15, 16, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 18, 19, 20, 21, 22, 21, 20, 21, 22, 21, 20, 21, 22, 20, 19, 18, 0, 0, 23, 24, 25, 26, 27, 28, 28, 26, 24, 0, 0, 0, 0, 0, 0 }; // Define animation group for Mechanic sequences - static constexpr PeepAnimations kPeepAnimationsMechanic = []() { + static PeepAnimations kPeepAnimationsMechanic = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kMechanicSpriteStateNoneId, { 10, 16, 5 }, kPeepAnimationSequenceMechanicNone }; - pag[PeepAnimationType::WatchRide] = { kMechanicSpriteStateWatchRideId, { 10, 16, 5 }, kPeepAnimationSequenceMechanicWatchRide }; - pag[PeepAnimationType::Hanging] = { kMechanicSpriteStateHangingId, { 10, 16, 5 }, kPeepAnimationSequenceMechanicHanging }; - pag[PeepAnimationType::Drowning] = { kMechanicSpriteStateDrowningId, { 9, 15, 6 }, kPeepAnimationSequenceMechanicDrowning }; - pag[PeepAnimationType::StaffAnswerCall] = { kMechanicSpriteStateStaffAnswerCallId, { 13, 22, 7 }, kPeepAnimationSequenceMechanicStaffAnswerCall }; - pag[PeepAnimationType::StaffAnswerCall2] = { kMechanicSpriteStateStaffAnswerCallId, { 13, 22, 7 }, kPeepAnimationSequenceMechanicStaffAnswerCall2 }; - pag[PeepAnimationType::StaffCheckBoard] = { kMechanicSpriteStateStaffCheckBoardId, { 13, 22, 7 }, kPeepAnimationSequenceMechanicStaffCheckBoard }; - pag[PeepAnimationType::StaffFix] = { kMechanicSpriteStateStaffFixId, { 13, 22, 7 }, kPeepAnimationSequenceMechanicStaffFix }; - pag[PeepAnimationType::StaffFix2] = { kMechanicSpriteStateStaffFixId, { 13, 22, 7 }, kPeepAnimationSequenceMechanicStaffFix2 }; - pag[PeepAnimationType::StaffFixGround] = { kMechanicSpriteStateStaffFixGroundId, { 19, 16, 16 }, kPeepAnimationSequenceMechanicStaffFixGround }; - pag[PeepAnimationType::StaffFix3] = { kMechanicSpriteStateStaffFixId, { 13, 22, 7 }, kPeepAnimationSequenceMechanicStaffFix3 }; + pag[PeepAnimationType::None] = { kMechanicSpriteStateNoneId, kPeepAnimationSequenceMechanicNone }; + pag[PeepAnimationType::WatchRide] = { kMechanicSpriteStateWatchRideId, kPeepAnimationSequenceMechanicWatchRide }; + pag[PeepAnimationType::Hanging] = { kMechanicSpriteStateHangingId, kPeepAnimationSequenceMechanicHanging }; + pag[PeepAnimationType::Drowning] = { kMechanicSpriteStateDrowningId, kPeepAnimationSequenceMechanicDrowning }; + pag[PeepAnimationType::StaffAnswerCall] = { kMechanicSpriteStateStaffAnswerCallId, kPeepAnimationSequenceMechanicStaffAnswerCall }; + pag[PeepAnimationType::StaffAnswerCall2] = { kMechanicSpriteStateStaffAnswerCallId, kPeepAnimationSequenceMechanicStaffAnswerCall2 }; + pag[PeepAnimationType::StaffCheckBoard] = { kMechanicSpriteStateStaffCheckBoardId, kPeepAnimationSequenceMechanicStaffCheckBoard }; + pag[PeepAnimationType::StaffFix] = { kMechanicSpriteStateStaffFixId, kPeepAnimationSequenceMechanicStaffFix }; + pag[PeepAnimationType::StaffFix2] = { kMechanicSpriteStateStaffFixId, kPeepAnimationSequenceMechanicStaffFix2 }; + pag[PeepAnimationType::StaffFixGround] = { kMechanicSpriteStateStaffFixGroundId, kPeepAnimationSequenceMechanicStaffFixGround }; + pag[PeepAnimationType::StaffFix3] = { kMechanicSpriteStateStaffFixId, kPeepAnimationSequenceMechanicStaffFix3 }; return pag; }(); @@ -138,12 +236,12 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceSecurityDrowning = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 4, 5, 6 }; // Define animation group for Security sequences - static constexpr PeepAnimations kPeepAnimationsSecurity = []() { + static PeepAnimations kPeepAnimationsSecurity = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kSecuritySpriteStateNoneId, { 8, 18, 5 }, kPeepAnimationSequenceSecurityNone }; - pag[PeepAnimationType::WatchRide] = { kSecuritySpriteStateWatchRideId, { 8, 17, 5 }, kPeepAnimationSequenceSecurityWatchRide }; - pag[PeepAnimationType::Hanging] = { kSecuritySpriteStateHangingId, { 15, 19, 6 }, kPeepAnimationSequenceSecurityHanging }; - pag[PeepAnimationType::Drowning] = { kSecuritySpriteStateDrowningId, { 9, 15, 6 }, kPeepAnimationSequenceSecurityDrowning }; + pag[PeepAnimationType::None] = { kSecuritySpriteStateNoneId, kPeepAnimationSequenceSecurityNone }; + pag[PeepAnimationType::WatchRide] = { kSecuritySpriteStateWatchRideId, kPeepAnimationSequenceSecurityWatchRide }; + pag[PeepAnimationType::Hanging] = { kSecuritySpriteStateHangingId, kPeepAnimationSequenceSecurityHanging }; + pag[PeepAnimationType::Drowning] = { kSecuritySpriteStateDrowningId, kPeepAnimationSequenceSecurityDrowning }; return pag; }(); @@ -157,15 +255,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerPandaWave2 = { 0, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 1, 0 }; // Define animation group for EntertainerPanda sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerPanda = []() { + static PeepAnimations kPeepAnimationsEntertainerPanda = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpritePandaStateNoneId, { 13, 24, 8 }, kPeepAnimationSequenceEntertainerPandaNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpritePandaStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerPandaWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpritePandaStateWaveId, { 14, 24, 7 }, kPeepAnimationSequenceEntertainerPandaEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpritePandaStateHangingId, { 19, 30, 8 }, kPeepAnimationSequenceEntertainerPandaHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpritePandaStateDrowningId, { 13, 15, 6 }, kPeepAnimationSequenceEntertainerPandaDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpritePandaStateJoyId, { 14, 25, 8 }, kPeepAnimationSequenceEntertainerPandaJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpritePandaStateWaveId, { 14, 24, 7 }, kPeepAnimationSequenceEntertainerPandaWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpritePandaStateNoneId, kPeepAnimationSequenceEntertainerPandaNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpritePandaStateWatchRideId, kPeepAnimationSequenceEntertainerPandaWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpritePandaStateWaveId, kPeepAnimationSequenceEntertainerPandaEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpritePandaStateHangingId, kPeepAnimationSequenceEntertainerPandaHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpritePandaStateDrowningId, kPeepAnimationSequenceEntertainerPandaDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpritePandaStateJoyId, kPeepAnimationSequenceEntertainerPandaJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpritePandaStateWaveId, kPeepAnimationSequenceEntertainerPandaWave2 }; return pag; }(); @@ -179,15 +277,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerTigerWave2 = { 0, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 1, 0 }; // Define animation group for EntertainerTiger sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerTiger = []() { + static PeepAnimations kPeepAnimationsEntertainerTiger = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteTigerStateNoneId, { 13, 24, 8 }, kPeepAnimationSequenceEntertainerTigerNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteTigerStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerTigerWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteTigerStateWaveId, { 16, 24, 8 }, kPeepAnimationSequenceEntertainerTigerEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteTigerStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerTigerHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteTigerStateDrowningId, { 13, 15, 6 }, kPeepAnimationSequenceEntertainerTigerDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteTigerStateJoyId, { 16, 28, 9 }, kPeepAnimationSequenceEntertainerTigerJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteTigerStateWaveId, { 16, 24, 8 }, kPeepAnimationSequenceEntertainerTigerWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteTigerStateNoneId, kPeepAnimationSequenceEntertainerTigerNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteTigerStateWatchRideId, kPeepAnimationSequenceEntertainerTigerWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteTigerStateWaveId, kPeepAnimationSequenceEntertainerTigerEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteTigerStateHangingId, kPeepAnimationSequenceEntertainerTigerHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteTigerStateDrowningId, kPeepAnimationSequenceEntertainerTigerDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteTigerStateJoyId, kPeepAnimationSequenceEntertainerTigerJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteTigerStateWaveId, kPeepAnimationSequenceEntertainerTigerWave2 }; return pag; }(); @@ -201,15 +299,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerElephantWave2 = { 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0 }; // Define animation group for EntertainerElephant sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerElephant = []() { + static PeepAnimations kPeepAnimationsEntertainerElephant = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteElephantStateNoneId, { 13, 24, 8 }, kPeepAnimationSequenceEntertainerElephantNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteElephantStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerElephantWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteElephantStateWaveId, { 17, 24, 8 }, kPeepAnimationSequenceEntertainerElephantEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteElephantStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerElephantHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteElephantStateDrowningId, { 17, 15, 6 }, kPeepAnimationSequenceEntertainerElephantDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteElephantStateJoyId, { 18, 25, 9 }, kPeepAnimationSequenceEntertainerElephantJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteElephantStateWaveId, { 17, 24, 8 }, kPeepAnimationSequenceEntertainerElephantWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteElephantStateNoneId, kPeepAnimationSequenceEntertainerElephantNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteElephantStateWatchRideId, kPeepAnimationSequenceEntertainerElephantWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteElephantStateWaveId, kPeepAnimationSequenceEntertainerElephantEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteElephantStateHangingId, kPeepAnimationSequenceEntertainerElephantHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteElephantStateDrowningId, kPeepAnimationSequenceEntertainerElephantDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteElephantStateJoyId, kPeepAnimationSequenceEntertainerElephantJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteElephantStateWaveId, kPeepAnimationSequenceEntertainerElephantWave2 }; return pag; }(); @@ -223,15 +321,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerRomanWave2 = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0 }; // Define animation group for EntertainerRoman sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerRoman = []() { + static PeepAnimations kPeepAnimationsEntertainerRoman = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteRomanStateNoneId, { 13, 24, 8 }, kPeepAnimationSequenceEntertainerRomanNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteRomanStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerRomanWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteRomanStateWaveId, { 17, 24, 8 }, kPeepAnimationSequenceEntertainerRomanEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteRomanStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerRomanHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteRomanStateDrowningId, { 17, 15, 6 }, kPeepAnimationSequenceEntertainerRomanDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteRomanStateJoyId, { 18, 25, 9 }, kPeepAnimationSequenceEntertainerRomanJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteRomanStateWaveId, { 17, 24, 8 }, kPeepAnimationSequenceEntertainerRomanWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteRomanStateNoneId, kPeepAnimationSequenceEntertainerRomanNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteRomanStateWatchRideId, kPeepAnimationSequenceEntertainerRomanWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteRomanStateWaveId, kPeepAnimationSequenceEntertainerRomanEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteRomanStateHangingId, kPeepAnimationSequenceEntertainerRomanHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteRomanStateDrowningId, kPeepAnimationSequenceEntertainerRomanDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteRomanStateJoyId, kPeepAnimationSequenceEntertainerRomanJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteRomanStateWaveId, kPeepAnimationSequenceEntertainerRomanWave2 }; return pag; }(); @@ -245,15 +343,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerGorillaWave2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 8, 9, 10, 9, 8, 7, 8, 9, 10, 9, 8, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; // Define animation group for EntertainerGorilla sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerGorilla = []() { + static PeepAnimations kPeepAnimationsEntertainerGorilla = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteGorillaStateNoneId, { 13, 24, 8 }, kPeepAnimationSequenceEntertainerGorillaNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteGorillaStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerGorillaWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteGorillaStateWaveId, { 17, 24, 8 }, kPeepAnimationSequenceEntertainerGorillaEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteGorillaStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerGorillaHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteGorillaStateDrowningId, { 17, 15, 6 }, kPeepAnimationSequenceEntertainerGorillaDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteGorillaStateWaveId, { 18, 25, 9 }, kPeepAnimationSequenceEntertainerGorillaJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteGorillaStateWaveId, { 17, 24, 8 }, kPeepAnimationSequenceEntertainerGorillaWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteGorillaStateNoneId, kPeepAnimationSequenceEntertainerGorillaNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteGorillaStateWatchRideId, kPeepAnimationSequenceEntertainerGorillaWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteGorillaStateWaveId, kPeepAnimationSequenceEntertainerGorillaEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteGorillaStateHangingId, kPeepAnimationSequenceEntertainerGorillaHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteGorillaStateDrowningId, kPeepAnimationSequenceEntertainerGorillaDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteGorillaStateWaveId, kPeepAnimationSequenceEntertainerGorillaJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteGorillaStateWaveId, kPeepAnimationSequenceEntertainerGorillaWave2 }; return pag; }(); @@ -267,15 +365,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerSnowmanWave2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 31, 31, 31, 32, 33 }; // Define animation group for EntertainerSnowman sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerSnowman = []() { + static PeepAnimations kPeepAnimationsEntertainerSnowman = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteSnowmanStateNoneId, { 13, 24, 8 }, kPeepAnimationSequenceEntertainerSnowmanNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteSnowmanStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerSnowmanWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteSnowmanStateWaveId, { 17, 28, 9 }, kPeepAnimationSequenceEntertainerSnowmanEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteSnowmanStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerSnowmanHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteSnowmanStateDrowningId, { 17, 15, 9 }, kPeepAnimationSequenceEntertainerSnowmanDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteSnowmanStateWaveId, { 18, 28, 9 }, kPeepAnimationSequenceEntertainerSnowmanJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteSnowmanStateWaveId, { 17, 28, 9 }, kPeepAnimationSequenceEntertainerSnowmanWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteSnowmanStateNoneId, kPeepAnimationSequenceEntertainerSnowmanNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteSnowmanStateWatchRideId, kPeepAnimationSequenceEntertainerSnowmanWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteSnowmanStateWaveId, kPeepAnimationSequenceEntertainerSnowmanEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteSnowmanStateHangingId, kPeepAnimationSequenceEntertainerSnowmanHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteSnowmanStateDrowningId, kPeepAnimationSequenceEntertainerSnowmanDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteSnowmanStateWaveId, kPeepAnimationSequenceEntertainerSnowmanJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteSnowmanStateWaveId, kPeepAnimationSequenceEntertainerSnowmanWave2 }; return pag; }(); @@ -289,15 +387,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerKnightWave2 = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 12, 12, 12, 12, 13, 14, 15, 16, 17, 17, 17, 17, 17, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23, 24, 25, 26, 27 }; // Define animation group for EntertainerKnight sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerKnight = []() { + static PeepAnimations kPeepAnimationsEntertainerKnight = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteKnightStateNoneId, { 16, 32, 8 }, kPeepAnimationSequenceEntertainerKnightNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteKnightStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerKnightWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteKnightStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerKnightEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteKnightStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerKnightHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteKnightStateDrowningId, { 21, 32, 9 }, kPeepAnimationSequenceEntertainerKnightDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteKnightStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerKnightJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteKnightStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerKnightWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteKnightStateNoneId, kPeepAnimationSequenceEntertainerKnightNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteKnightStateWatchRideId, kPeepAnimationSequenceEntertainerKnightWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteKnightStateWaveId, kPeepAnimationSequenceEntertainerKnightEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteKnightStateHangingId, kPeepAnimationSequenceEntertainerKnightHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteKnightStateDrowningId, kPeepAnimationSequenceEntertainerKnightDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteKnightStateWaveId, kPeepAnimationSequenceEntertainerKnightJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteKnightStateWaveId, kPeepAnimationSequenceEntertainerKnightWave2 }; return pag; }(); @@ -311,15 +409,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerAstronautWave2 = { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 0 }; // Define animation group for EntertainerAstronaut sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerAstronaut = []() { + static PeepAnimations kPeepAnimationsEntertainerAstronaut = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteAstronautStateNoneId, { 16, 32, 8 }, kPeepAnimationSequenceEntertainerAstronautNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteAstronautStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerAstronautWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteAstronautStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerAstronautEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteAstronautStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerAstronautHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteAstronautStateDrowningId, { 21, 32, 9 }, kPeepAnimationSequenceEntertainerAstronautDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteAstronautStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerAstronautJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteAstronautStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerAstronautWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteAstronautStateNoneId, kPeepAnimationSequenceEntertainerAstronautNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteAstronautStateWatchRideId, kPeepAnimationSequenceEntertainerAstronautWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteAstronautStateWaveId, kPeepAnimationSequenceEntertainerAstronautEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteAstronautStateHangingId, kPeepAnimationSequenceEntertainerAstronautHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteAstronautStateDrowningId, kPeepAnimationSequenceEntertainerAstronautDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteAstronautStateWaveId, kPeepAnimationSequenceEntertainerAstronautJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteAstronautStateWaveId, kPeepAnimationSequenceEntertainerAstronautWave2 }; return pag; }(); @@ -333,15 +431,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerBanditWave2 = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 12, 13, 13, 13, 13, 13, 14, 15, 16, 17, 17, 17, 17, 17, 18, 19, 20, 21, 22, 21, 20, 19, 20, 21, 22, 21, 20, 19, 20, 21, 22, 21, 20, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41 }; // Define animation group for EntertainerBandit sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerBandit = []() { + static PeepAnimations kPeepAnimationsEntertainerBandit = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteBanditStateNoneId, { 16, 32, 8 }, kPeepAnimationSequenceEntertainerBanditNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteBanditStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerBanditWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteBanditStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerBanditEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteBanditStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerBanditHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteBanditStateDrowningId, { 21, 32, 9 }, kPeepAnimationSequenceEntertainerBanditDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteBanditStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerBanditJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteBanditStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerBanditWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteBanditStateNoneId, kPeepAnimationSequenceEntertainerBanditNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteBanditStateWatchRideId, kPeepAnimationSequenceEntertainerBanditWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteBanditStateWaveId, kPeepAnimationSequenceEntertainerBanditEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteBanditStateHangingId, kPeepAnimationSequenceEntertainerBanditHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteBanditStateDrowningId, kPeepAnimationSequenceEntertainerBanditDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteBanditStateWaveId, kPeepAnimationSequenceEntertainerBanditJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteBanditStateWaveId, kPeepAnimationSequenceEntertainerBanditWave2 }; return pag; }(); @@ -355,15 +453,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerSheriffWave2 = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; // Define animation group for EntertainerSheriff sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerSheriff = []() { + static PeepAnimations kPeepAnimationsEntertainerSheriff = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteSheriffStateNoneId, { 16, 32, 8 }, kPeepAnimationSequenceEntertainerSheriffNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteSheriffStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerSheriffWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpriteSheriffStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerSheriffEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpriteSheriffStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerSheriffHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpriteSheriffStateDrowningId, { 21, 32, 9 }, kPeepAnimationSequenceEntertainerSheriffDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpriteSheriffStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerSheriffJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpriteSheriffStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerSheriffWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpriteSheriffStateNoneId, kPeepAnimationSequenceEntertainerSheriffNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteSheriffStateWatchRideId, kPeepAnimationSequenceEntertainerSheriffWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpriteSheriffStateWaveId, kPeepAnimationSequenceEntertainerSheriffEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpriteSheriffStateHangingId, kPeepAnimationSequenceEntertainerSheriffHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpriteSheriffStateDrowningId, kPeepAnimationSequenceEntertainerSheriffDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpriteSheriffStateWaveId, kPeepAnimationSequenceEntertainerSheriffJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpriteSheriffStateWaveId, kPeepAnimationSequenceEntertainerSheriffWave2 }; return pag; }(); @@ -377,15 +475,15 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceEntertainerPirateWave2 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 9, 10, 11, 12, 13, 14, 15, 16, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 21, 21, 21, 21, 21, 22, 23, 23, 23, 23, 24, 25, 26, 27, 27, 27, 27, 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31 }; // Define animation group for EntertainerPirate sequences - static constexpr PeepAnimations kPeepAnimationsEntertainerPirate = []() { + static PeepAnimations kPeepAnimationsEntertainerPirate = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpritePirateStateNoneId, { 16, 32, 8 }, kPeepAnimationSequenceEntertainerPirateNone }; - pag[PeepAnimationType::WatchRide] = { kEntertainerSpritePirateStateWatchRideId, { 10, 23, 7 }, kPeepAnimationSequenceEntertainerPirateWatchRide }; - pag[PeepAnimationType::EatFood] = { kEntertainerSpritePirateStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerPirateEatFood }; - pag[PeepAnimationType::Hanging] = { kEntertainerSpritePirateStateHangingId, { 23, 30, 8 }, kPeepAnimationSequenceEntertainerPirateHanging }; - pag[PeepAnimationType::Drowning] = { kEntertainerSpritePirateStateDrowningId, { 21, 32, 9 }, kPeepAnimationSequenceEntertainerPirateDrowning }; - pag[PeepAnimationType::Joy] = { kEntertainerSpritePirateStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerPirateJoy }; - pag[PeepAnimationType::Wave2] = { kEntertainerSpritePirateStateWaveId, { 23, 30, 15 }, kPeepAnimationSequenceEntertainerPirateWave2 }; + pag[PeepAnimationType::None] = { kEntertainerSpritePirateStateNoneId, kPeepAnimationSequenceEntertainerPirateNone }; + pag[PeepAnimationType::WatchRide] = { kEntertainerSpritePirateStateWatchRideId, kPeepAnimationSequenceEntertainerPirateWatchRide }; + pag[PeepAnimationType::EatFood] = { kEntertainerSpritePirateStateWaveId, kPeepAnimationSequenceEntertainerPirateEatFood }; + pag[PeepAnimationType::Hanging] = { kEntertainerSpritePirateStateHangingId, kPeepAnimationSequenceEntertainerPirateHanging }; + pag[PeepAnimationType::Drowning] = { kEntertainerSpritePirateStateDrowningId, kPeepAnimationSequenceEntertainerPirateDrowning }; + pag[PeepAnimationType::Joy] = { kEntertainerSpritePirateStateWaveId, kPeepAnimationSequenceEntertainerPirateJoy }; + pag[PeepAnimationType::Wave2] = { kEntertainerSpritePirateStateWaveId, kPeepAnimationSequenceEntertainerPirateWave2 }; return pag; }(); @@ -397,13 +495,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceIceCreamSittingEatFood = { 0, 1, 2, 3, 4, 5 }; // Define animation group for IceCream sequences - static constexpr PeepAnimations kPeepAnimationsIceCream = []() { + static PeepAnimations kPeepAnimationsIceCream = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteIceCreamStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceIceCreamNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteIceCreamStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceIceCreamWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteIceCreamStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceIceCreamEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteIceCreamStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceIceCreamSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteIceCreamStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceIceCreamSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteIceCreamStateNoneId, kPeepAnimationSequenceIceCreamNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteIceCreamStateWatchRideId, kPeepAnimationSequenceIceCreamWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteIceCreamStateEatFoodId, kPeepAnimationSequenceIceCreamEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteIceCreamStateSittingIdleId, kPeepAnimationSequenceIceCreamSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteIceCreamStateSittingEatFoodId, kPeepAnimationSequenceIceCreamSittingEatFood }; return pag; }(); @@ -415,13 +513,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceChipsSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Chips sequences - static constexpr PeepAnimations kPeepAnimationsChips = []() { + static PeepAnimations kPeepAnimationsChips = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteChipsStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceChipsNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteChipsStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceChipsWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteChipsStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceChipsEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteChipsStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceChipsSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteChipsStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceChipsSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteChipsStateNoneId, kPeepAnimationSequenceChipsNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteChipsStateWatchRideId, kPeepAnimationSequenceChipsWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteChipsStateEatFoodId, kPeepAnimationSequenceChipsEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteChipsStateSittingIdleId, kPeepAnimationSequenceChipsSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteChipsStateSittingEatFoodId, kPeepAnimationSequenceChipsSittingEatFood }; return pag; }(); @@ -433,13 +531,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceBurgerSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Burger sequences - static constexpr PeepAnimations kPeepAnimationsBurger = []() { + static PeepAnimations kPeepAnimationsBurger = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteBurgerStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceBurgerNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteBurgerStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceBurgerWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteBurgerStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceBurgerEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteBurgerStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceBurgerSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteBurgerStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceBurgerSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteBurgerStateNoneId, kPeepAnimationSequenceBurgerNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteBurgerStateWatchRideId, kPeepAnimationSequenceBurgerWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteBurgerStateEatFoodId, kPeepAnimationSequenceBurgerEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteBurgerStateSittingIdleId, kPeepAnimationSequenceBurgerSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteBurgerStateSittingEatFoodId, kPeepAnimationSequenceBurgerSittingEatFood }; return pag; }(); @@ -451,13 +549,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceDrinkSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Drink sequences - static constexpr PeepAnimations kPeepAnimationsDrink = []() { + static PeepAnimations kPeepAnimationsDrink = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteDrinkStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceDrinkNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteDrinkStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceDrinkWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteDrinkStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceDrinkEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteDrinkStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceDrinkSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteDrinkStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceDrinkSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteDrinkStateNoneId, kPeepAnimationSequenceDrinkNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteDrinkStateWatchRideId, kPeepAnimationSequenceDrinkWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteDrinkStateEatFoodId, kPeepAnimationSequenceDrinkEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteDrinkStateSittingIdleId, kPeepAnimationSequenceDrinkSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteDrinkStateSittingEatFoodId, kPeepAnimationSequenceDrinkSittingEatFood }; return pag; }(); @@ -467,11 +565,11 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceBalloonSittingIdle = { 0 }; // Define animation group for Balloon sequences - static constexpr PeepAnimations kPeepAnimationsBalloon = []() { + static PeepAnimations kPeepAnimationsBalloon = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteBalloonStateNoneId, { 11, 28, 5 }, kPeepAnimationSequenceBalloonNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteBalloonStateWatchRideId, { 11, 28, 5 }, kPeepAnimationSequenceBalloonWatchRide }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteBalloonStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceBalloonSittingIdle }; + pag[PeepAnimationType::None] = { kPeepSpriteBalloonStateNoneId, kPeepAnimationSequenceBalloonNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteBalloonStateWatchRideId, kPeepAnimationSequenceBalloonWatchRide }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteBalloonStateSittingIdleId, kPeepAnimationSequenceBalloonSittingIdle }; return pag; }(); @@ -483,13 +581,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceCandyflossSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Candyfloss sequences - static constexpr PeepAnimations kPeepAnimationsCandyfloss = []() { + static PeepAnimations kPeepAnimationsCandyfloss = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteCandyflossStateNoneId, { 11, 19, 5 }, kPeepAnimationSequenceCandyflossNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteCandyflossStateWatchRideId, { 11, 19, 5 }, kPeepAnimationSequenceCandyflossWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteCandyflossStateEatFoodId, { 11, 19, 5 }, kPeepAnimationSequenceCandyflossEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteCandyflossStateSittingIdleId, { 13, 16, 6 }, kPeepAnimationSequenceCandyflossSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteCandyflossStateSittingEatFoodId, { 13, 16, 6 }, kPeepAnimationSequenceCandyflossSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteCandyflossStateNoneId, kPeepAnimationSequenceCandyflossNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteCandyflossStateWatchRideId, kPeepAnimationSequenceCandyflossWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteCandyflossStateEatFoodId, kPeepAnimationSequenceCandyflossEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteCandyflossStateSittingIdleId, kPeepAnimationSequenceCandyflossSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteCandyflossStateSittingEatFoodId, kPeepAnimationSequenceCandyflossSittingEatFood }; return pag; }(); @@ -499,11 +597,11 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceUmbrellaSittingIdle = { 0 }; // Define animation group for Umbrella sequences - static constexpr PeepAnimations kPeepAnimationsUmbrella = []() { + static PeepAnimations kPeepAnimationsUmbrella = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteUmbrellaStateNoneId, { 14, 21, 5 }, kPeepAnimationSequenceUmbrellaNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteUmbrellaStateWatchRideId, { 14, 21, 5 }, kPeepAnimationSequenceUmbrellaWatchRide }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteUmbrellaStateSittingIdleId, { 14, 19, 6 }, kPeepAnimationSequenceUmbrellaSittingIdle }; + pag[PeepAnimationType::None] = { kPeepSpriteUmbrellaStateNoneId, kPeepAnimationSequenceUmbrellaNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteUmbrellaStateWatchRideId, kPeepAnimationSequenceUmbrellaWatchRide }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteUmbrellaStateSittingIdleId, kPeepAnimationSequenceUmbrellaSittingIdle }; return pag; }(); @@ -515,13 +613,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequencePizzaSittingEatFood = { 0, 1, 2, 3, 4, 5 }; // Define animation group for Pizza sequences - static constexpr PeepAnimations kPeepAnimationsPizza = []() { + static PeepAnimations kPeepAnimationsPizza = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpritePizzaStateNoneId, { 8, 16, 5 }, kPeepAnimationSequencePizzaNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpritePizzaStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequencePizzaWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpritePizzaStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequencePizzaEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpritePizzaStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequencePizzaSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpritePizzaStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequencePizzaSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpritePizzaStateNoneId, kPeepAnimationSequencePizzaNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpritePizzaStateWatchRideId, kPeepAnimationSequencePizzaWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpritePizzaStateEatFoodId, kPeepAnimationSequencePizzaEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpritePizzaStateSittingIdleId, kPeepAnimationSequencePizzaSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpritePizzaStateSittingEatFoodId, kPeepAnimationSequencePizzaSittingEatFood }; return pag; }(); @@ -532,12 +630,12 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceSecurityAltDrowning = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 4, 5, 6 }; // Define animation group for SecurityAlt sequences - static constexpr PeepAnimations kPeepAnimationsSecurityAlt = []() { + static PeepAnimations kPeepAnimationsSecurityAlt = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kSecurityStaffSpriteAltStateNoneId, { 8, 18, 5 }, kPeepAnimationSequenceSecurityAltNone }; - pag[PeepAnimationType::WatchRide] = { kSecuritySpriteStateWatchRideId, { 8, 17, 5 }, kPeepAnimationSequenceSecurityAltWatchRide }; - pag[PeepAnimationType::Hanging] = { kSecuritySpriteStateHangingId, { 15, 19, 6 }, kPeepAnimationSequenceSecurityAltHanging }; - pag[PeepAnimationType::Drowning] = { kSecuritySpriteStateDrowningId, { 9, 15, 6 }, kPeepAnimationSequenceSecurityAltDrowning }; + pag[PeepAnimationType::None] = { kSecurityStaffSpriteAltStateNoneId, kPeepAnimationSequenceSecurityAltNone }; + pag[PeepAnimationType::WatchRide] = { kSecuritySpriteStateWatchRideId, kPeepAnimationSequenceSecurityAltWatchRide }; + pag[PeepAnimationType::Hanging] = { kSecuritySpriteStateHangingId, kPeepAnimationSequenceSecurityAltHanging }; + pag[PeepAnimationType::Drowning] = { kSecuritySpriteStateDrowningId, kPeepAnimationSequenceSecurityAltDrowning }; return pag; }(); @@ -549,13 +647,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequencePopcornSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Popcorn sequences - static constexpr PeepAnimations kPeepAnimationsPopcorn = []() { + static PeepAnimations kPeepAnimationsPopcorn = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpritePopcornStateNoneId, { 11, 19, 5 }, kPeepAnimationSequencePopcornNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpritePopcornStateWatchRideId, { 11, 19, 5 }, kPeepAnimationSequencePopcornWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpritePopcornStateEatFoodId, { 11, 19, 5 }, kPeepAnimationSequencePopcornEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpritePopcornStateSittingIdleId, { 13, 16, 6 }, kPeepAnimationSequencePopcornSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpritePopcornStateSittingEatFoodId, { 13, 16, 6 }, kPeepAnimationSequencePopcornSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpritePopcornStateNoneId, kPeepAnimationSequencePopcornNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpritePopcornStateWatchRideId, kPeepAnimationSequencePopcornWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpritePopcornStateEatFoodId, kPeepAnimationSequencePopcornEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpritePopcornStateSittingIdleId, kPeepAnimationSequencePopcornSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpritePopcornStateSittingEatFoodId, kPeepAnimationSequencePopcornSittingEatFood }; return pag; }(); @@ -563,9 +661,9 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceArmsCrossedNone = { 0, 1, 2, 3, 4, 5 }; // Define animation group for ArmsCrossed sequences - static constexpr PeepAnimations kPeepAnimationsArmsCrossed = []() { + static PeepAnimations kPeepAnimationsArmsCrossed = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteArmsCrossedStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceArmsCrossedNone }; + pag[PeepAnimationType::None] = { kPeepSpriteArmsCrossedStateNoneId, kPeepAnimationSequenceArmsCrossedNone }; return pag; }(); @@ -573,9 +671,9 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceHeadDownNone = { 0, 1, 2, 3, 4, 5 }; // Define animation group for HeadDown sequences - static constexpr PeepAnimations kPeepAnimationsHeadDown = []() { + static PeepAnimations kPeepAnimationsHeadDown = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteHeadDownStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceHeadDownNone }; + pag[PeepAnimationType::None] = { kPeepSpriteHeadDownStateNoneId, kPeepAnimationSequenceHeadDownNone }; return pag; }(); @@ -583,9 +681,9 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceNauseousNone = { 0, 1, 2, 3, 4, 5 }; // Define animation group for Nauseous sequences - static constexpr PeepAnimations kPeepAnimationsNauseous = []() { + static PeepAnimations kPeepAnimationsNauseous = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteNauseousStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceNauseousNone }; + pag[PeepAnimationType::None] = { kPeepSpriteNauseousStateNoneId, kPeepAnimationSequenceNauseousNone }; return pag; }(); @@ -595,11 +693,11 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceVeryNauseousSittingIdle = { 0 }; // Define animation group for VeryNauseous sequences - static constexpr PeepAnimations kPeepAnimationsVeryNauseous = []() { + static PeepAnimations kPeepAnimationsVeryNauseous = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteVeryNauseousStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceVeryNauseousNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteVeryNauseousStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceVeryNauseousWatchRide }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteVeryNauseousStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceVeryNauseousSittingIdle }; + pag[PeepAnimationType::None] = { kPeepSpriteVeryNauseousStateNoneId, kPeepAnimationSequenceVeryNauseousNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteVeryNauseousStateWatchRideId, kPeepAnimationSequenceVeryNauseousWatchRide }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteVeryNauseousStateSittingIdleId, kPeepAnimationSequenceVeryNauseousSittingIdle }; return pag; }(); @@ -607,9 +705,9 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceRequireToiletNone = { 0, 1, 2, 3, 4, 5 }; // Define animation group for RequireToilet sequences - static constexpr PeepAnimations kPeepAnimationsRequireToilet = []() { + static PeepAnimations kPeepAnimationsRequireToilet = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteRequireToiletStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceRequireToiletNone }; + pag[PeepAnimationType::None] = { kPeepSpriteRequireToiletStateNoneId, kPeepAnimationSequenceRequireToiletNone }; return pag; }(); @@ -619,11 +717,11 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceHatSittingIdle = { 0 }; // Define animation group for Hat sequences - static constexpr PeepAnimations kPeepAnimationsHat = []() { + static PeepAnimations kPeepAnimationsHat = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteHatStateNoneId, { 12, 32, 5 }, kPeepAnimationSequenceHatNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteHatStateWatchRideId, { 12, 32, 5 }, kPeepAnimationSequenceHatWatchRide }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteHatStateSittingIdleId, { 10, 20, 6 }, kPeepAnimationSequenceHatSittingIdle }; + pag[PeepAnimationType::None] = { kPeepSpriteHatStateNoneId, kPeepAnimationSequenceHatNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteHatStateWatchRideId, kPeepAnimationSequenceHatWatchRide }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteHatStateSittingIdleId, kPeepAnimationSequenceHatSittingIdle }; return pag; }(); @@ -635,13 +733,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceHotDogSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for HotDog sequences - static constexpr PeepAnimations kPeepAnimationsHotDog = []() { + static PeepAnimations kPeepAnimationsHotDog = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteHotDogStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceHotDogNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteHotDogStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceHotDogWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteHotDogStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceHotDogEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteHotDogStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceHotDogSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteHotDogStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceHotDogSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteHotDogStateNoneId, kPeepAnimationSequenceHotDogNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteHotDogStateWatchRideId, kPeepAnimationSequenceHotDogWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteHotDogStateEatFoodId, kPeepAnimationSequenceHotDogEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteHotDogStateSittingIdleId, kPeepAnimationSequenceHotDogSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteHotDogStateSittingEatFoodId, kPeepAnimationSequenceHotDogSittingEatFood }; return pag; }(); @@ -653,13 +751,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceTentacleSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; // Define animation group for Tentacle sequences - static constexpr PeepAnimations kPeepAnimationsTentacle = []() { + static PeepAnimations kPeepAnimationsTentacle = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteTentacleStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceTentacleNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteTentacleStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceTentacleWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteTentacleStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceTentacleEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteTentacleStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceTentacleSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteTentacleStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceTentacleSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteTentacleStateNoneId, kPeepAnimationSequenceTentacleNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteTentacleStateWatchRideId, kPeepAnimationSequenceTentacleWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteTentacleStateEatFoodId, kPeepAnimationSequenceTentacleEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteTentacleStateSittingIdleId, kPeepAnimationSequenceTentacleSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteTentacleStateSittingEatFoodId, kPeepAnimationSequenceTentacleSittingEatFood }; return pag; }(); @@ -671,13 +769,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceToffeeAppleSittingEatFood = { 0, 1, 2, 3, 4, 5 }; // Define animation group for ToffeeApple sequences - static constexpr PeepAnimations kPeepAnimationsToffeeApple = []() { + static PeepAnimations kPeepAnimationsToffeeApple = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteToffeeAppleStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceToffeeAppleNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteToffeeAppleStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceToffeeAppleWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteToffeeAppleStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceToffeeAppleEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteToffeeAppleStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceToffeeAppleSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteToffeeAppleStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceToffeeAppleSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteToffeeAppleStateNoneId, kPeepAnimationSequenceToffeeAppleNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteToffeeAppleStateWatchRideId, kPeepAnimationSequenceToffeeAppleWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteToffeeAppleStateEatFoodId, kPeepAnimationSequenceToffeeAppleEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteToffeeAppleStateSittingIdleId, kPeepAnimationSequenceToffeeAppleSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteToffeeAppleStateSittingEatFoodId, kPeepAnimationSequenceToffeeAppleSittingEatFood }; return pag; }(); @@ -689,13 +787,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceDonutSittingEatFood = { 0, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5 }; // Define animation group for Donut sequences - static constexpr PeepAnimations kPeepAnimationsDonut = []() { + static PeepAnimations kPeepAnimationsDonut = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteDonutStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceDonutNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteDonutStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceDonutWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteDonutStateEatFoodId, { 8, 16, 5 }, kPeepAnimationSequenceDonutEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteDonutStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceDonutSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteDonutStateSittingEatFoodId, { 9, 16, 6 }, kPeepAnimationSequenceDonutSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteDonutStateNoneId, kPeepAnimationSequenceDonutNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteDonutStateWatchRideId, kPeepAnimationSequenceDonutWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteDonutStateEatFoodId, kPeepAnimationSequenceDonutEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteDonutStateSittingIdleId, kPeepAnimationSequenceDonutSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteDonutStateSittingEatFoodId, kPeepAnimationSequenceDonutSittingEatFood }; return pag; }(); @@ -707,13 +805,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceCoffeeSittingEatFood = { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1 }; // Define animation group for Coffee sequences - static constexpr PeepAnimations kPeepAnimationsCoffee = []() { + static PeepAnimations kPeepAnimationsCoffee = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteCoffeeStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceCoffeeNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteCoffeeStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceCoffeeWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteCoffeeStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceCoffeeEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteCoffeeStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceCoffeeSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteCoffeeStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceCoffeeSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteCoffeeStateNoneId, kPeepAnimationSequenceCoffeeNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteCoffeeStateWatchRideId, kPeepAnimationSequenceCoffeeWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteCoffeeStateWatchRideId, kPeepAnimationSequenceCoffeeEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteCoffeeStateSittingIdleId, kPeepAnimationSequenceCoffeeSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteCoffeeStateSittingIdleId, kPeepAnimationSequenceCoffeeSittingEatFood }; return pag; }(); @@ -725,13 +823,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceChickenSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Chicken sequences - static constexpr PeepAnimations kPeepAnimationsChicken = []() { + static PeepAnimations kPeepAnimationsChicken = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteChickenStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceChickenNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteChickenStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceChickenWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteChickenStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceChickenEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteChickenStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceChickenSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteChickenStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceChickenSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteChickenStateNoneId, kPeepAnimationSequenceChickenNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteChickenStateWatchRideId, kPeepAnimationSequenceChickenWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteChickenStateWatchRideId, kPeepAnimationSequenceChickenEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteChickenStateSittingIdleId, kPeepAnimationSequenceChickenSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteChickenStateSittingIdleId, kPeepAnimationSequenceChickenSittingEatFood }; return pag; }(); @@ -743,13 +841,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceLemonadeSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Lemonade sequences - static constexpr PeepAnimations kPeepAnimationsLemonade = []() { + static PeepAnimations kPeepAnimationsLemonade = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteLemonadeStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceLemonadeNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteLemonadeStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceLemonadeWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteLemonadeStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceLemonadeEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteLemonadeStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceLemonadeSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteLemonadeStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceLemonadeSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteLemonadeStateNoneId, kPeepAnimationSequenceLemonadeNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteLemonadeStateWatchRideId, kPeepAnimationSequenceLemonadeWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteLemonadeStateWatchRideId, kPeepAnimationSequenceLemonadeEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteLemonadeStateSittingIdleId, kPeepAnimationSequenceLemonadeSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteLemonadeStateSittingIdleId, kPeepAnimationSequenceLemonadeSittingEatFood }; return pag; }(); @@ -757,9 +855,9 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceWatchingWatchRide = { 0 }; // Define animation group for Watching sequences - static constexpr PeepAnimations kPeepAnimationsWatching = []() { + static PeepAnimations kPeepAnimationsWatching = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteWatchingStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceWatchingWatchRide }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteWatchingStateWatchRideId, kPeepAnimationSequenceWatchingWatchRide }; return pag; }(); @@ -771,13 +869,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequencePretzelSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Pretzel sequences - static constexpr PeepAnimations kPeepAnimationsPretzel = []() { + static PeepAnimations kPeepAnimationsPretzel = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpritePretzelStateNoneId, { 8, 16, 5 }, kPeepAnimationSequencePretzelNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpritePretzelStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequencePretzelWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpritePretzelStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequencePretzelEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpritePretzelStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequencePretzelSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpritePretzelStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequencePretzelSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpritePretzelStateNoneId, kPeepAnimationSequencePretzelNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpritePretzelStateWatchRideId, kPeepAnimationSequencePretzelWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpritePretzelStateWatchRideId, kPeepAnimationSequencePretzelEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpritePretzelStateSittingIdleId, kPeepAnimationSequencePretzelSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpritePretzelStateSittingIdleId, kPeepAnimationSequencePretzelSittingEatFood }; return pag; }(); @@ -787,11 +885,11 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceSunglassesSittingIdle = { 0 }; // Define animation group for Sunglasses sequences - static constexpr PeepAnimations kPeepAnimationsSunglasses = []() { + static PeepAnimations kPeepAnimationsSunglasses = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSunglassesStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceSunglassesNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteSunglassesStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSunglassesWatchRide }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSunglassesStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSunglassesSittingIdle }; + pag[PeepAnimationType::None] = { kPeepSpriteSunglassesStateNoneId, kPeepAnimationSequenceSunglassesNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteSunglassesStateWatchRideId, kPeepAnimationSequenceSunglassesWatchRide }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSunglassesStateSittingIdleId, kPeepAnimationSequenceSunglassesSittingIdle }; return pag; }(); @@ -803,13 +901,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceSuJongkwaSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for SuJongkwa sequences - static constexpr PeepAnimations kPeepAnimationsSuJongkwa = []() { + static PeepAnimations kPeepAnimationsSuJongkwa = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSuJongkwaStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceSuJongkwaNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteSuJongkwaStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSuJongkwaWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteSuJongkwaStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSuJongkwaEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSuJongkwaStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSuJongkwaSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSuJongkwaStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSuJongkwaSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteSuJongkwaStateNoneId, kPeepAnimationSequenceSuJongkwaNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteSuJongkwaStateWatchRideId, kPeepAnimationSequenceSuJongkwaWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteSuJongkwaStateWatchRideId, kPeepAnimationSequenceSuJongkwaEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSuJongkwaStateSittingIdleId, kPeepAnimationSequenceSuJongkwaSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSuJongkwaStateSittingIdleId, kPeepAnimationSequenceSuJongkwaSittingEatFood }; return pag; }(); @@ -821,13 +919,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceJuiceSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Juice sequences - static constexpr PeepAnimations kPeepAnimationsJuice = []() { + static PeepAnimations kPeepAnimationsJuice = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteJuiceStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceJuiceNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteJuiceStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceJuiceWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteJuiceStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceJuiceEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteJuiceStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceJuiceSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteJuiceStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceJuiceSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteJuiceStateNoneId, kPeepAnimationSequenceJuiceNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteJuiceStateWatchRideId, kPeepAnimationSequenceJuiceWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteJuiceStateWatchRideId, kPeepAnimationSequenceJuiceEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteJuiceStateSittingIdleId, kPeepAnimationSequenceJuiceSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteJuiceStateSittingIdleId, kPeepAnimationSequenceJuiceSittingEatFood }; return pag; }(); @@ -839,13 +937,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceFunnelCakeSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for FunnelCake sequences - static constexpr PeepAnimations kPeepAnimationsFunnelCake = []() { + static PeepAnimations kPeepAnimationsFunnelCake = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteFunnelCakeStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceFunnelCakeNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteFunnelCakeStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceFunnelCakeWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteFunnelCakeStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceFunnelCakeEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteFunnelCakeStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceFunnelCakeSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteFunnelCakeStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceFunnelCakeSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteFunnelCakeStateNoneId, kPeepAnimationSequenceFunnelCakeNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteFunnelCakeStateWatchRideId, kPeepAnimationSequenceFunnelCakeWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteFunnelCakeStateWatchRideId, kPeepAnimationSequenceFunnelCakeEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteFunnelCakeStateSittingIdleId, kPeepAnimationSequenceFunnelCakeSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteFunnelCakeStateSittingIdleId, kPeepAnimationSequenceFunnelCakeSittingEatFood }; return pag; }(); @@ -857,13 +955,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceNoodlesSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Noodles sequences - static constexpr PeepAnimations kPeepAnimationsNoodles = []() { + static PeepAnimations kPeepAnimationsNoodles = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteNoodlesStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceNoodlesNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteNoodlesStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceNoodlesWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteNoodlesStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceNoodlesEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteNoodlesStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceNoodlesSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteNoodlesStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceNoodlesSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteNoodlesStateNoneId, kPeepAnimationSequenceNoodlesNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteNoodlesStateWatchRideId, kPeepAnimationSequenceNoodlesWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteNoodlesStateWatchRideId, kPeepAnimationSequenceNoodlesEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteNoodlesStateSittingIdleId, kPeepAnimationSequenceNoodlesSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteNoodlesStateSittingIdleId, kPeepAnimationSequenceNoodlesSittingEatFood }; return pag; }(); @@ -875,13 +973,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceSausageSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Sausage sequences - static constexpr PeepAnimations kPeepAnimationsSausage = []() { + static PeepAnimations kPeepAnimationsSausage = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSausageStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceSausageNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteSausageStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSausageWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteSausageStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSausageEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSausageStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSausageSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSausageStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSausageSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteSausageStateNoneId, kPeepAnimationSequenceSausageNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteSausageStateWatchRideId, kPeepAnimationSequenceSausageWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteSausageStateWatchRideId, kPeepAnimationSequenceSausageEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSausageStateSittingIdleId, kPeepAnimationSequenceSausageSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSausageStateSittingIdleId, kPeepAnimationSequenceSausageSittingEatFood }; return pag; }(); @@ -893,13 +991,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceSoupSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Soup sequences - static constexpr PeepAnimations kPeepAnimationsSoup = []() { + static PeepAnimations kPeepAnimationsSoup = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSoupStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceSoupNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteSoupStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSoupWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteSoupStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSoupEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSoupStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSoupSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSoupStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSoupSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteSoupStateNoneId, kPeepAnimationSequenceSoupNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteSoupStateWatchRideId, kPeepAnimationSequenceSoupWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteSoupStateWatchRideId, kPeepAnimationSequenceSoupEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSoupStateSittingIdleId, kPeepAnimationSequenceSoupSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSoupStateSittingIdleId, kPeepAnimationSequenceSoupSittingEatFood }; return pag; }(); @@ -911,13 +1009,13 @@ namespace OpenRCT2 static constexpr std::array kPeepAnimationSequenceSandwichSittingEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; // Define animation group for Sandwich sequences - static constexpr PeepAnimations kPeepAnimationsSandwich = []() { + static PeepAnimations kPeepAnimationsSandwich = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSandwichStateNoneId, { 8, 16, 5 }, kPeepAnimationSequenceSandwichNone }; - pag[PeepAnimationType::WatchRide] = { kPeepSpriteSandwichStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSandwichWatchRide }; - pag[PeepAnimationType::EatFood] = { kPeepSpriteSandwichStateWatchRideId, { 8, 16, 5 }, kPeepAnimationSequenceSandwichEatFood }; - pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSandwichStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSandwichSittingIdle }; - pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSandwichStateSittingIdleId, { 9, 16, 6 }, kPeepAnimationSequenceSandwichSittingEatFood }; + pag[PeepAnimationType::None] = { kPeepSpriteSandwichStateNoneId, kPeepAnimationSequenceSandwichNone }; + pag[PeepAnimationType::WatchRide] = { kPeepSpriteSandwichStateWatchRideId, kPeepAnimationSequenceSandwichWatchRide }; + pag[PeepAnimationType::EatFood] = { kPeepSpriteSandwichStateWatchRideId, kPeepAnimationSequenceSandwichEatFood }; + pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSandwichStateSittingIdleId, kPeepAnimationSequenceSandwichSittingIdle }; + pag[PeepAnimationType::SittingEatFood] = { kPeepSpriteSandwichStateSittingIdleId, kPeepAnimationSequenceSandwichSittingEatFood }; return pag; }(); @@ -983,4 +1081,22 @@ namespace OpenRCT2 { return kPeepAnimationEntries[EnumValue(spriteType)][actionAnimationGroup].bounds; } + + void inferMaxPeepSpriteDimensions() + { + for (auto groupKey = EnumValue(PeepAnimationGroup::Normal); groupKey < EnumValue(PeepAnimationGroup::Count); groupKey++) + { + auto& group = kPeepAnimationEntries[groupKey]; + + for (auto type = EnumValue(PeepAnimationType::None); type <= EnumValue(PeepAnimationType::WithdrawMoney); type++) + { + auto& anim = group[PeepAnimationType(type)]; + if (anim.frame_offsets.empty()) + continue; + + anim.bounds = inferMaxAnimationDimensions(anim); + } + } + } + } // namespace OpenRCT2 diff --git a/src/openrct2/peep/PeepAnimationData.h b/src/openrct2/peep/PeepAnimationData.h index 3dadeb678d..1210a43c0d 100644 --- a/src/openrct2/peep/PeepAnimationData.h +++ b/src/openrct2/peep/PeepAnimationData.h @@ -17,8 +17,16 @@ namespace OpenRCT2 struct PeepAnimation { uint32_t base_image; - SpriteBounds bounds; std::span frame_offsets; + SpriteBounds bounds{}; + + constexpr PeepAnimation() = default; + + PeepAnimation(uint32_t baseImage, std::span frameOffsets) + : base_image(baseImage) + , frame_offsets(frameOffsets) + { + } }; struct PeepAnimations @@ -41,4 +49,6 @@ namespace OpenRCT2 PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::None); const SpriteBounds& GetSpriteBounds( PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::None); + + void inferMaxPeepSpriteDimensions(); } // namespace OpenRCT2 From 2f450212a5b3fa9c082ec784874641430a15a61b Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 4 Dec 2024 07:38:30 +0100 Subject: [PATCH 112/139] ImageTable: make parsing ranges more robust (#23316) --- src/openrct2/object/ImageTable.cpp | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/openrct2/object/ImageTable.cpp b/src/openrct2/object/ImageTable.cpp index 184a18b96f..4984016e15 100644 --- a/src/openrct2/object/ImageTable.cpp +++ b/src/openrct2/object/ImageTable.cpp @@ -92,9 +92,12 @@ std::vector> ImageTable::ParseImages( } else if (String::StartsWith(s, "$CSG")) { - auto range = ParseRange(s.substr(4)); - if (!range.empty()) + auto rangeStart = s.find('['); + auto rangeEnd = s.find(']'); + if (rangeStart != std::string::npos && rangeEnd != std::string::npos) { + auto rangeString = s.substr(rangeStart, rangeEnd - rangeStart + 1); + auto range = ParseRange(rangeString); if (IsCsgLoaded()) { for (auto i : range) @@ -118,9 +121,12 @@ std::vector> ImageTable::ParseImages( } else if (String::StartsWith(s, "$G1")) { - auto range = ParseRange(s.substr(3)); - if (!range.empty()) + auto rangeStart = s.find('['); + auto rangeEnd = s.find(']'); + if (rangeStart != std::string::npos && rangeEnd != std::string::npos) { + auto rangeString = s.substr(rangeStart, rangeEnd - rangeStart + 1); + auto range = ParseRange(rangeString); for (auto i : range) { result.push_back(std::make_unique( @@ -132,10 +138,11 @@ std::vector> ImageTable::ParseImages( { auto name = s.substr(14); auto rangeStart = name.find('['); - if (rangeStart != std::string::npos) + auto rangeEnd = name.find(']'); + if (rangeStart != std::string::npos && rangeEnd != std::string::npos) { - auto rangeString = name.substr(rangeStart); - auto range = ParseRange(name.substr(rangeStart)); + auto rangeString = name.substr(rangeStart, rangeEnd - rangeStart + 1); + auto range = ParseRange(rangeString); name = name.substr(0, rangeStart); result = LoadObjectImages(context, name, range); } @@ -144,10 +151,11 @@ std::vector> ImageTable::ParseImages( { auto name = s.substr(5); auto rangeStart = name.find('['); - if (rangeStart != std::string::npos) + auto rangeEnd = name.find(']'); + if (rangeStart != std::string::npos && rangeEnd != std::string::npos) { - auto rangeString = name.substr(rangeStart); - auto range = ParseRange(name.substr(rangeStart)); + auto rangeString = name.substr(rangeStart, rangeEnd - rangeStart + 1); + auto range = ParseRange(rangeString); name = name.substr(0, rangeStart); result = LoadImageArchiveImages(context, name, range); } From a55a690db3155431961d832f435db946758edd70 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 4 Dec 2024 09:50:48 +0100 Subject: [PATCH 113/139] Introduce const ObjectList::FindLegacy (#23315) --- src/openrct2/object/ObjectList.cpp | 19 +++++++++++++++++-- src/openrct2/object/ObjectList.h | 3 ++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/openrct2/object/ObjectList.cpp b/src/openrct2/object/ObjectList.cpp index 27ebb3c8d9..858cdbbac0 100644 --- a/src/openrct2/object/ObjectList.cpp +++ b/src/openrct2/object/ObjectList.cpp @@ -170,12 +170,27 @@ void ObjectList::SetObject(ObjectType type, ObjectEntryIndex index, std::string_ SetObject(index, entry); } -ObjectEntryIndex ObjectList::Find(ObjectType type, std::string_view identifier) +ObjectEntryIndex ObjectList::Find(ObjectType type, std::string_view identifier) const { auto& subList = GetList(type); for (size_t i = 0; i < subList.size(); i++) { - if (subList[i].Identifier == identifier) + if (subList[i].Generation == ObjectGeneration::JSON && subList[i].Identifier == identifier) + { + return static_cast(i); + } + } + return OBJECT_ENTRY_INDEX_NULL; +} + +// Intended to be used to find non-custom legacy objects. For internal use only. +ObjectEntryIndex ObjectList::FindLegacy(ObjectType type, std::string_view identifier) const +{ + auto& subList = GetList(type); + for (size_t i = 0; i < subList.size(); i++) + { + if (subList[i].Generation == ObjectGeneration::DAT && subList[i].Entry.GetName() == identifier + && subList[i].Entry.GetSourceGame() != ObjectSourceGame::Custom) { return static_cast(i); } diff --git a/src/openrct2/object/ObjectList.h b/src/openrct2/object/ObjectList.h index 3cc725cf10..476c694e4e 100644 --- a/src/openrct2/object/ObjectList.h +++ b/src/openrct2/object/ObjectList.h @@ -25,7 +25,8 @@ public: const ObjectEntryDescriptor& GetObject(ObjectType type, ObjectEntryIndex index) const; void SetObject(ObjectEntryIndex index, const ObjectEntryDescriptor& entry); void SetObject(ObjectType type, ObjectEntryIndex index, std::string_view identifier); - ObjectEntryIndex Find(ObjectType type, std::string_view identifier); + ObjectEntryIndex Find(ObjectType type, std::string_view identifier) const; + ObjectEntryIndex FindLegacy(ObjectType type, std::string_view identifier) const; struct const_iterator { From d4352bd65af3565307d97f04088ce1eb5c96ea88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:32:48 +0200 Subject: [PATCH 114/139] Use std::variant for Intent data --- src/openrct2/windows/Intent.cpp | 55 ++++++++++++--------------------- src/openrct2/windows/Intent.h | 24 ++------------ 2 files changed, 23 insertions(+), 56 deletions(-) diff --git a/src/openrct2/windows/Intent.cpp b/src/openrct2/windows/Intent.cpp index 04d38a6f21..74432d8eec 100644 --- a/src/openrct2/windows/Intent.cpp +++ b/src/openrct2/windows/Intent.cpp @@ -32,55 +32,35 @@ Intent::Intent(IntentAction intentAction) Intent* Intent::PutExtra(uint32_t key, uint32_t value) { - IntentData data = {}; - data.intVal.unsignedInt = value; - data.type = IntentData::DataType::Int; - - _Data.insert(std::make_pair(key, data)); + _Data.emplace(key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, void* value) { - IntentData data = {}; - data.pointerVal = value; - data.type = IntentData::DataType::Pointer; - - _Data.insert(std::make_pair(key, data)); + _Data.emplace(key, value); return this; } Intent* Intent::PutExtra(uint32_t key, int32_t value) { - IntentData data = {}; - data.intVal.signedInt = value; - data.type = IntentData::DataType::Int; - - _Data.insert(std::make_pair(key, data)); + _Data.emplace(key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, std::string value) { - IntentData data = {}; - data.stringVal = std::move(value); - data.type = IntentData::DataType::String; - - _Data.insert(std::make_pair(key, data)); + _Data.emplace(key, value); return this; } Intent* Intent::PutExtra(uint32_t key, close_callback value) { - IntentData data = {}; - data.closeCallbackVal = value; - data.type = IntentData::DataType::CloseCallback; - - _Data.insert(std::make_pair(key, data)); + _Data.emplace(key, value); return this; } @@ -108,8 +88,9 @@ void* Intent::GetPointerExtra(uint32_t key) const } auto data = _Data.at(key); - Guard::Assert(data.type == IntentData::DataType::Pointer, "Actual type doesn't match requested type"); - return static_cast(data.pointerVal); + + assert(std::holds_alternative(data)); + return std::get(data); } uint32_t Intent::GetUIntExtra(uint32_t key) const @@ -120,8 +101,9 @@ uint32_t Intent::GetUIntExtra(uint32_t key) const } auto data = _Data.at(key); - Guard::Assert(data.type == IntentData::DataType::Int, "Actual type doesn't match requested type"); - return data.intVal.unsignedInt; + + assert(std::holds_alternative(data)); + return static_cast(std::get(data)); } int32_t Intent::GetSIntExtra(uint32_t key) const @@ -132,8 +114,9 @@ int32_t Intent::GetSIntExtra(uint32_t key) const } auto data = _Data.at(key); - Guard::Assert(data.type == IntentData::DataType::Int, "Actual type doesn't match requested type"); - return data.intVal.signedInt; + + assert(std::holds_alternative(data)); + return static_cast(std::get(data)); } std::string Intent::GetStringExtra(uint32_t key) const @@ -144,8 +127,9 @@ std::string Intent::GetStringExtra(uint32_t key) const } auto data = _Data.at(key); - Guard::Assert(data.type == IntentData::DataType::String, "Actual type doesn't match requested type"); - return data.stringVal; + + assert(std::holds_alternative(data)); + return std::get(data); } close_callback Intent::GetCloseCallbackExtra(uint32_t key) const @@ -156,6 +140,7 @@ close_callback Intent::GetCloseCallbackExtra(uint32_t key) const } auto data = _Data.at(key); - Guard::Assert(data.type == IntentData::DataType::CloseCallback, "Actual type doesn't match requested type"); - return data.closeCallbackVal; + + assert(std::holds_alternative(data)); + return std::get(data); } diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index ed0ffa0715..f859bf1b2a 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -14,6 +14,7 @@ #include #include +#include enum IntentAction { @@ -57,29 +58,10 @@ enum IntentAction INTENT_ACTION_NULL = 255, }; -struct IntentData -{ - enum class DataType - { - Int, - String, - Pointer, - CloseCallback - } type; - - union - { - uint32_t unsignedInt; - int32_t signedInt; - } intVal; - std::string stringVal; - close_callback closeCallbackVal; - void* pointerVal; -}; - class Intent { -private: + using IntentData = std::variant; + WindowClass _Class{ WindowClass::Null }; WindowDetail _WindowDetail{ WD_NULL }; IntentAction _Action{ INTENT_ACTION_NULL }; From e86618e8354d23d4daf1c4c40ed54f73525c52da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:46:35 +0200 Subject: [PATCH 115/139] Make sure the callback is not converted to void* --- src/openrct2-ui/windows/MapGen.cpp | 2 +- src/openrct2-ui/windows/Ride.cpp | 2 +- src/openrct2-ui/windows/SavePrompt.cpp | 2 +- src/openrct2-ui/windows/ServerStart.cpp | 2 +- src/openrct2/Game.cpp | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index 0fd661cb60..7efcea20e2 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -942,7 +942,7 @@ namespace OpenRCT2::Ui::Windows { auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_HEIGHTMAP); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(HeightmapLoadsaveCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(HeightmapLoadsaveCallback)); ContextOpenIntent(&intent); return; } diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index e07b24c4f0..e364906851 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -5456,7 +5456,7 @@ namespace OpenRCT2::Ui::Windows intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_SAVE | LOADSAVETYPE_TRACK); intent.PutExtra(INTENT_EXTRA_TRACK_DESIGN, _trackDesign.get()); intent.PutExtra(INTENT_EXTRA_PATH, trackName); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(&TrackDesignCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(&TrackDesignCallback)); ContextOpenIntent(&intent); } diff --git a/src/openrct2-ui/windows/SavePrompt.cpp b/src/openrct2-ui/windows/SavePrompt.cpp index 57d525c114..b286a59adf 100644 --- a/src/openrct2-ui/windows/SavePrompt.cpp +++ b/src/openrct2-ui/windows/SavePrompt.cpp @@ -173,7 +173,7 @@ namespace OpenRCT2::Ui::Windows intent = CreateSaveGameAsIntent(); } Close(); - intent->PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(WindowSavePromptCallback)); + intent->PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(WindowSavePromptCallback)); ContextOpenIntent(intent.get()); break; } diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index 93988b3710..d38a4cfd6a 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -139,7 +139,7 @@ namespace OpenRCT2::Ui::Windows NetworkSetPassword(_password); auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(LoadSaveCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(LoadSaveCallback)); ContextOpenIntent(&intent); break; } diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 8940bfca52..f77124cc5c 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -654,7 +654,7 @@ void GameLoadOrQuitNoSavePrompt() { auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(GameLoadOrQuitNoSavePromptCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(GameLoadOrQuitNoSavePromptCallback)); ContextOpenIntent(&intent); } break; @@ -683,7 +683,7 @@ void GameLoadOrQuitNoSavePrompt() GameActions::Execute(&loadOrQuitAction); ToolCancel(); auto intent = Intent(WindowClass::ScenarioSelect); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(NewGameWindowCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(NewGameWindowCallback)); ContextOpenIntent(&intent); break; } From 116cb2d712ba68c335f09034be4e684ee317edfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:58:56 +0200 Subject: [PATCH 116/139] Use static storage for Intent data, no more allocations --- src/openrct2/windows/Intent.cpp | 51 +++++++++++++++++++++++---------- src/openrct2/windows/Intent.h | 8 +++++- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/openrct2/windows/Intent.cpp b/src/openrct2/windows/Intent.cpp index 74432d8eec..61fe133c27 100644 --- a/src/openrct2/windows/Intent.cpp +++ b/src/openrct2/windows/Intent.cpp @@ -11,6 +11,7 @@ #include "../core/Guard.hpp" +#include #include using namespace OpenRCT2; @@ -32,35 +33,50 @@ Intent::Intent(IntentAction intentAction) Intent* Intent::PutExtra(uint32_t key, uint32_t value) { - _Data.emplace(key, static_cast(value)); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, void* value) { - _Data.emplace(key, value); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, value); return this; } Intent* Intent::PutExtra(uint32_t key, int32_t value) { - _Data.emplace(key, static_cast(value)); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, std::string value) { - _Data.emplace(key, value); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, std::move(value)); return this; } Intent* Intent::PutExtra(uint32_t key, close_callback value) { - _Data.emplace(key, value); + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + assert(it == _Data.end() || it->first != key); + + _Data.emplace(it, key, value); return this; } @@ -82,12 +98,13 @@ IntentAction Intent::GetAction() const void* Intent::GetPointerExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return nullptr; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return std::get(data); @@ -95,12 +112,13 @@ void* Intent::GetPointerExtra(uint32_t key) const uint32_t Intent::GetUIntExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return 0; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return static_cast(std::get(data)); @@ -108,12 +126,13 @@ uint32_t Intent::GetUIntExtra(uint32_t key) const int32_t Intent::GetSIntExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return 0; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return static_cast(std::get(data)); @@ -121,12 +140,13 @@ int32_t Intent::GetSIntExtra(uint32_t key) const std::string Intent::GetStringExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return std::string{}; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return std::get(data); @@ -134,12 +154,13 @@ std::string Intent::GetStringExtra(uint32_t key) const close_callback Intent::GetCloseCallbackExtra(uint32_t key) const { - if (_Data.count(key) == 0) + auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); + if (it == _Data.end() || it->first != key) { return nullptr; } - auto data = _Data.at(key); + const auto& [_, data] = *it; assert(std::holds_alternative(data)); return std::get(data); diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index f859bf1b2a..7b71b1954d 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -13,6 +13,7 @@ #include "../interface/Window.h" #include +#include #include #include @@ -60,12 +61,17 @@ enum IntentAction class Intent { + // The maximum amount of data the Intent can hold, 8 should be sufficient, raise this if needed. + static constexpr size_t kMaxDataSlots = 8; + using IntentData = std::variant; WindowClass _Class{ WindowClass::Null }; WindowDetail _WindowDetail{ WD_NULL }; IntentAction _Action{ INTENT_ACTION_NULL }; - std::map _Data; + + using DataEntry = std::pair; + sfl::static_vector _Data; public: explicit Intent(WindowClass windowClass); From dd78366a4c236ab63a9dcf5aeedb8446c06ba966 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:14:02 +0200 Subject: [PATCH 117/139] Deduplicate the code, add more safety checks --- src/openrct2/windows/Intent.cpp | 114 +++++++++++--------------------- src/openrct2/windows/Intent.h | 19 +++--- 2 files changed, 50 insertions(+), 83 deletions(-) diff --git a/src/openrct2/windows/Intent.cpp b/src/openrct2/windows/Intent.cpp index 61fe133c27..0430cac15e 100644 --- a/src/openrct2/windows/Intent.cpp +++ b/src/openrct2/windows/Intent.cpp @@ -16,6 +16,35 @@ using namespace OpenRCT2; +template +static void putExtraImpl(IntentDataStorage& storage, uint32_t key, T&& value) +{ + auto it = std::ranges::lower_bound(storage, key, {}, &IntentDataEntry::first); + + // Key should not already exist. + assert(it == storage.end() || it->first != key); + + storage.emplace(it, key, std::forward(value)); +} + +template +static auto getExtraImpl(const IntentDataStorage& storage, uint32_t key) +{ + auto it = std::ranges::lower_bound(storage, key, {}, &IntentDataEntry::first); + if (it == storage.end() || it->first != key) + { + // If key does not exist then the usage of Intent is incorrect. + assert(false); + + return T{}; + } + + const auto& [_, data] = *it; + assert(std::holds_alternative(data)); + + return std::get(data); +} + Intent::Intent(WindowClass windowClass) : _Class(windowClass) { @@ -33,51 +62,31 @@ Intent::Intent(IntentAction intentAction) Intent* Intent::PutExtra(uint32_t key, uint32_t value) { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - assert(it == _Data.end() || it->first != key); - - _Data.emplace(it, key, static_cast(value)); - + putExtraImpl(_Data, key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, void* value) { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - assert(it == _Data.end() || it->first != key); - - _Data.emplace(it, key, value); - + putExtraImpl(_Data, key, value); return this; } Intent* Intent::PutExtra(uint32_t key, int32_t value) { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - assert(it == _Data.end() || it->first != key); - - _Data.emplace(it, key, static_cast(value)); - + putExtraImpl(_Data, key, static_cast(value)); return this; } Intent* Intent::PutExtra(uint32_t key, std::string value) { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - assert(it == _Data.end() || it->first != key); - - _Data.emplace(it, key, std::move(value)); - + putExtraImpl(_Data, key, std::move(value)); return this; } Intent* Intent::PutExtra(uint32_t key, close_callback value) { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - assert(it == _Data.end() || it->first != key); - - _Data.emplace(it, key, value); - + putExtraImpl(_Data, key, value); return this; } @@ -98,70 +107,25 @@ IntentAction Intent::GetAction() const void* Intent::GetPointerExtra(uint32_t key) const { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - if (it == _Data.end() || it->first != key) - { - return nullptr; - } - - const auto& [_, data] = *it; - - assert(std::holds_alternative(data)); - return std::get(data); + return getExtraImpl(_Data, key); } uint32_t Intent::GetUIntExtra(uint32_t key) const { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - if (it == _Data.end() || it->first != key) - { - return 0; - } - - const auto& [_, data] = *it; - - assert(std::holds_alternative(data)); - return static_cast(std::get(data)); + return static_cast(getExtraImpl(_Data, key)); } int32_t Intent::GetSIntExtra(uint32_t key) const { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - if (it == _Data.end() || it->first != key) - { - return 0; - } - - const auto& [_, data] = *it; - - assert(std::holds_alternative(data)); - return static_cast(std::get(data)); + return static_cast(getExtraImpl(_Data, key)); } std::string Intent::GetStringExtra(uint32_t key) const { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - if (it == _Data.end() || it->first != key) - { - return std::string{}; - } - - const auto& [_, data] = *it; - - assert(std::holds_alternative(data)); - return std::get(data); + return getExtraImpl(_Data, key); } close_callback Intent::GetCloseCallbackExtra(uint32_t key) const { - auto it = std::ranges::lower_bound(_Data, key, {}, &DataEntry::first); - if (it == _Data.end() || it->first != key) - { - return nullptr; - } - - const auto& [_, data] = *it; - - assert(std::holds_alternative(data)); - return std::get(data); + return getExtraImpl(_Data, key); } diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index 7b71b1954d..6983010a97 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -59,32 +59,35 @@ enum IntentAction INTENT_ACTION_NULL = 255, }; +// The maximum amount of data the Intent can hold, 8 should be sufficient, raise this if needed. +static constexpr size_t kIntentMaxDataSlots = 8; + +using IntentData = std::variant; +using IntentDataEntry = std::pair; +using IntentDataStorage = sfl::static_vector; + class Intent { - // The maximum amount of data the Intent can hold, 8 should be sufficient, raise this if needed. - static constexpr size_t kMaxDataSlots = 8; - - using IntentData = std::variant; - WindowClass _Class{ WindowClass::Null }; WindowDetail _WindowDetail{ WD_NULL }; IntentAction _Action{ INTENT_ACTION_NULL }; - - using DataEntry = std::pair; - sfl::static_vector _Data; + IntentDataStorage _Data; public: explicit Intent(WindowClass windowClass); explicit Intent(WindowDetail windowDetail); explicit Intent(IntentAction windowclass); + WindowClass GetWindowClass() const; WindowDetail GetWindowDetail() const; IntentAction GetAction() const; + void* GetPointerExtra(uint32_t key) const; std::string GetStringExtra(uint32_t key) const; uint32_t GetUIntExtra(uint32_t key) const; int32_t GetSIntExtra(uint32_t key) const; close_callback GetCloseCallbackExtra(uint32_t key) const; + Intent* PutExtra(uint32_t key, uint32_t value); Intent* PutExtra(uint32_t key, void* value); Intent* PutExtra(uint32_t key, int32_t value); From 0ff522de311120e8cd8ef745ca08d54f1806e07a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:26:13 +0200 Subject: [PATCH 118/139] Remove the assertion, code currently expects this behavior --- src/openrct2/windows/Intent.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/openrct2/windows/Intent.cpp b/src/openrct2/windows/Intent.cpp index 0430cac15e..2dd7e6aa3e 100644 --- a/src/openrct2/windows/Intent.cpp +++ b/src/openrct2/windows/Intent.cpp @@ -33,9 +33,7 @@ static auto getExtraImpl(const IntentDataStorage& storage, uint32_t key) auto it = std::ranges::lower_bound(storage, key, {}, &IntentDataEntry::first); if (it == storage.end() || it->first != key) { - // If key does not exist then the usage of Intent is incorrect. - assert(false); - + // TODO: The code currently assumes that some things are optional, we need to handle this better. return T{}; } From f65ef672604f40afeaae002fd8082edd05e2dd96 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 4 Dec 2024 17:09:17 +0100 Subject: [PATCH 119/139] Rename PeepAnimationType::None to PeepAnimationType::Walking (#23317) --- src/openrct2-ui/windows/GameBottomToolbar.cpp | 2 +- src/openrct2-ui/windows/Guest.cpp | 2 +- src/openrct2/actions/StaffHireNewAction.cpp | 2 +- src/openrct2/entity/Guest.cpp | 2 +- src/openrct2/entity/Peep.cpp | 10 +- src/openrct2/entity/Peep.h | 2 +- src/openrct2/peep/PeepAnimationData.cpp | 196 +++++++++--------- src/openrct2/peep/PeepAnimationData.h | 4 +- src/openrct2/peep/PeepSpriteIds.h | 94 ++++----- .../scripting/bindings/entity/ScGuest.cpp | 4 +- .../scripting/bindings/entity/ScStaff.cpp | 10 +- 11 files changed, 164 insertions(+), 164 deletions(-) diff --git a/src/openrct2-ui/windows/GameBottomToolbar.cpp b/src/openrct2-ui/windows/GameBottomToolbar.cpp index 6b2d74fd8f..0f31d5418e 100644 --- a/src/openrct2-ui/windows/GameBottomToolbar.cpp +++ b/src/openrct2-ui/windows/GameBottomToolbar.cpp @@ -300,7 +300,7 @@ namespace OpenRCT2::Ui::Windows { GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->BalloonColour), clipCoords); } - if (image_id_base >= kPeepSpriteUmbrellaStateNoneId + if (image_id_base >= kPeepSpriteUmbrellaStateWalkingId && image_id_base < kPeepSpriteUmbrellaStateSittingIdleId + 4) { GfxDrawSprite(cliped_dpi, ImageId(image_id_base + 32, guest->UmbrellaColour), clipCoords); diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index 3a0242438a..3d1ad43415 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -580,7 +580,7 @@ namespace OpenRCT2::Ui::Windows } // If holding umbrella - if (animationFrame >= kPeepSpriteUmbrellaStateNoneId + if (animationFrame >= kPeepSpriteUmbrellaStateWalkingId && animationFrame < kPeepSpriteUmbrellaStateSittingIdleId + 4) { GfxDrawSprite(clipDpi, ImageId(animationFrame + 32, guest->UmbrellaColour), screenCoords); diff --git a/src/openrct2/actions/StaffHireNewAction.cpp b/src/openrct2/actions/StaffHireNewAction.cpp index fb2bf4e8d5..e29db45b1b 100644 --- a/src/openrct2/actions/StaffHireNewAction.cpp +++ b/src/openrct2/actions/StaffHireNewAction.cpp @@ -134,7 +134,7 @@ GameActions::Result StaffHireNewAction::QueryExecute(bool execute) const newPeep->SpecialSprite = 0; newPeep->AnimationImageIdOffset = 0; newPeep->WalkingAnimationFrameNum = 0; - newPeep->AnimationType = PeepAnimationType::None; + newPeep->AnimationType = PeepAnimationType::Walking; newPeep->PathCheckOptimisation = 0; newPeep->PeepFlags = 0; newPeep->StaffLawnsMown = 0; diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index ee4dde5ec8..f18d52fd81 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -7145,7 +7145,7 @@ Guest* Guest::Generate(const CoordsXYZ& coords) peep->SpecialSprite = 0; peep->AnimationImageIdOffset = 0; peep->WalkingAnimationFrameNum = 0; - peep->AnimationType = PeepAnimationType::None; + peep->AnimationType = PeepAnimationType::Walking; peep->PeepFlags = 0; peep->FavouriteRide = RideId::GetNull(); peep->FavouriteRideRating = 0; diff --git a/src/openrct2/entity/Peep.cpp b/src/openrct2/entity/Peep.cpp index f60602f70f..c9e12c506d 100644 --- a/src/openrct2/entity/Peep.cpp +++ b/src/openrct2/entity/Peep.cpp @@ -80,7 +80,7 @@ static std::shared_ptr _crowdSoundChannel = nullptr; static void GuestReleaseBalloon(Guest* peep, int16_t spawn_height); static PeepAnimationType PeepSpecialSpriteToAnimationGroupMap[] = { - PeepAnimationType::None, + PeepAnimationType::Walking, PeepAnimationType::HoldMat, PeepAnimationType::StaffMower, }; @@ -332,7 +332,7 @@ PeepAnimationType Peep::GetAnimationType() Guard::Assert( EnumValue(Action) >= std::size(PeepActionToAnimationGroupMap) && Action < PeepActionType::Idle, "Invalid peep action %u", EnumValue(Action)); - return PeepAnimationType::None; + return PeepAnimationType::Walking; } /* @@ -625,7 +625,7 @@ void Peep::PickupAbort(int32_t old_x) Action = PeepActionType::Walking; SpecialSprite = 0; AnimationImageIdOffset = 0; - AnimationType = PeepAnimationType::None; + AnimationType = PeepAnimationType::Walking; PathCheckOptimisation = 0; } @@ -674,7 +674,7 @@ GameActions::Result Peep::Place(const TileCoordsXYZ& location, bool apply) Action = PeepActionType::Walking; SpecialSprite = 0; AnimationImageIdOffset = 0; - AnimationType = PeepAnimationType::None; + AnimationType = PeepAnimationType::Walking; PathCheckOptimisation = 0; EntityTweener::Get().Reset(); auto* guest = As(); @@ -2911,7 +2911,7 @@ void Peep::Paint(PaintSession& session, int32_t imageDirection) const return; } - if (baseImageId >= kPeepSpriteUmbrellaStateNoneId && baseImageId < (kPeepSpriteUmbrellaStateSittingIdleId + 4)) + if (baseImageId >= kPeepSpriteUmbrellaStateWalkingId && baseImageId < (kPeepSpriteUmbrellaStateSittingIdleId + 4)) { imageId = ImageId(baseImageId + 32, guest->UmbrellaColour); PaintAddImageAsChild(session, imageId, offset, bb); diff --git a/src/openrct2/entity/Peep.h b/src/openrct2/entity/Peep.h index 517961c5ca..3663aa3cbf 100644 --- a/src/openrct2/entity/Peep.h +++ b/src/openrct2/entity/Peep.h @@ -153,7 +153,7 @@ enum class PeepActionType : uint8_t enum class PeepAnimationType : uint8_t { - None = 0, + Walking = 0, CheckTime = 1, WatchRide = 2, EatFood = 3, diff --git a/src/openrct2/peep/PeepAnimationData.cpp b/src/openrct2/peep/PeepAnimationData.cpp index 9b90f883f5..5b6daeb00d 100644 --- a/src/openrct2/peep/PeepAnimationData.cpp +++ b/src/openrct2/peep/PeepAnimationData.cpp @@ -116,7 +116,7 @@ namespace OpenRCT2 // clang-format off // Define animation sequences for Normal sprites - static constexpr std::array kPeepAnimationSequenceNormalNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceNormalWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceNormalCheckTime = { 0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8 }; static constexpr std::array kPeepAnimationSequenceNormalWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceNormalEatFood = { 0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 9, 10 }; @@ -146,7 +146,7 @@ namespace OpenRCT2 // Define animation group for Normal sequences static PeepAnimations kPeepAnimationsNormal = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kPeepSpriteNormalStateNoneId, kPeepAnimationSequenceNormalNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteNormalStateWalkingId, kPeepAnimationSequenceNormalWalking }; pag[PeepAnimationType::CheckTime] = { kPeepSpriteNormalStateCheckTimeId, kPeepAnimationSequenceNormalCheckTime }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteNormalStateWatchRideId, kPeepAnimationSequenceNormalWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteNormalStateEatFoodId, kPeepAnimationSequenceNormalEatFood }; @@ -176,7 +176,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Handyman sprites - static constexpr std::array kPeepAnimationSequenceHandymanNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceHandymanWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceHandymanWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceHandymanHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceHandymanStaffMower = { 0, 1, 2, 3, 4, 5 }; @@ -188,7 +188,7 @@ namespace OpenRCT2 // Define animation group for Handyman sequences static PeepAnimations kPeepAnimationsHandyman = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kHandymanSpriteStateNoneId, kPeepAnimationSequenceHandymanNone }; + pag[PeepAnimationType::Walking] = { kHandymanSpriteStateWalkingId, kPeepAnimationSequenceHandymanWalking }; pag[PeepAnimationType::WatchRide] = { kHandymanSpriteStateWatchRideId, kPeepAnimationSequenceHandymanWatchRide }; pag[PeepAnimationType::Hanging] = { kHandymanSpriteStateHangingId, kPeepAnimationSequenceHandymanHanging }; pag[PeepAnimationType::StaffMower] = { kHandymanSpriteStateStaffMowerId, kPeepAnimationSequenceHandymanStaffMower }; @@ -200,7 +200,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Mechanic sprites - static constexpr std::array kPeepAnimationSequenceMechanicNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceMechanicWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceMechanicWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceMechanicHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceMechanicDrowning = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 4, 5, 6, 7 }; @@ -215,7 +215,7 @@ namespace OpenRCT2 // Define animation group for Mechanic sequences static PeepAnimations kPeepAnimationsMechanic = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kMechanicSpriteStateNoneId, kPeepAnimationSequenceMechanicNone }; + pag[PeepAnimationType::Walking] = { kMechanicSpriteStateWalkingId, kPeepAnimationSequenceMechanicWalking }; pag[PeepAnimationType::WatchRide] = { kMechanicSpriteStateWatchRideId, kPeepAnimationSequenceMechanicWatchRide }; pag[PeepAnimationType::Hanging] = { kMechanicSpriteStateHangingId, kPeepAnimationSequenceMechanicHanging }; pag[PeepAnimationType::Drowning] = { kMechanicSpriteStateDrowningId, kPeepAnimationSequenceMechanicDrowning }; @@ -230,7 +230,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Security sprites - static constexpr std::array kPeepAnimationSequenceSecurityNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceSecurityWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceSecurityWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceSecurityHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceSecurityDrowning = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 4, 5, 6 }; @@ -238,7 +238,7 @@ namespace OpenRCT2 // Define animation group for Security sequences static PeepAnimations kPeepAnimationsSecurity = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kSecuritySpriteStateNoneId, kPeepAnimationSequenceSecurityNone }; + pag[PeepAnimationType::Walking] = { kSecuritySpriteStateWalkingId, kPeepAnimationSequenceSecurityWalking }; pag[PeepAnimationType::WatchRide] = { kSecuritySpriteStateWatchRideId, kPeepAnimationSequenceSecurityWatchRide }; pag[PeepAnimationType::Hanging] = { kSecuritySpriteStateHangingId, kPeepAnimationSequenceSecurityHanging }; pag[PeepAnimationType::Drowning] = { kSecuritySpriteStateDrowningId, kPeepAnimationSequenceSecurityDrowning }; @@ -246,7 +246,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerPanda sprites - static constexpr std::array kPeepAnimationSequenceEntertainerPandaNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerPandaWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerPandaWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerPandaEatFood = { 0, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 1, 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerPandaHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -257,7 +257,7 @@ namespace OpenRCT2 // Define animation group for EntertainerPanda sequences static PeepAnimations kPeepAnimationsEntertainerPanda = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpritePandaStateNoneId, kPeepAnimationSequenceEntertainerPandaNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpritePandaStateWalkingId, kPeepAnimationSequenceEntertainerPandaWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpritePandaStateWatchRideId, kPeepAnimationSequenceEntertainerPandaWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpritePandaStateWaveId, kPeepAnimationSequenceEntertainerPandaEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpritePandaStateHangingId, kPeepAnimationSequenceEntertainerPandaHanging }; @@ -268,7 +268,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerTiger sprites - static constexpr std::array kPeepAnimationSequenceEntertainerTigerNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerTigerWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerTigerWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerTigerEatFood = { 0, 1, 2, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 4, 5, 4, 3, 2, 1, 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerTigerHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -279,7 +279,7 @@ namespace OpenRCT2 // Define animation group for EntertainerTiger sequences static PeepAnimations kPeepAnimationsEntertainerTiger = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteTigerStateNoneId, kPeepAnimationSequenceEntertainerTigerNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteTigerStateWalkingId, kPeepAnimationSequenceEntertainerTigerWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteTigerStateWatchRideId, kPeepAnimationSequenceEntertainerTigerWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteTigerStateWaveId, kPeepAnimationSequenceEntertainerTigerEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteTigerStateHangingId, kPeepAnimationSequenceEntertainerTigerHanging }; @@ -290,7 +290,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerElephant sprites - static constexpr std::array kPeepAnimationSequenceEntertainerElephantNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerElephantWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerElephantWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerElephantEatFood = { 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 5, 4, 3, 4, 5, 6, 5, 4, 3, 2, 1, 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerElephantHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -301,7 +301,7 @@ namespace OpenRCT2 // Define animation group for EntertainerElephant sequences static PeepAnimations kPeepAnimationsEntertainerElephant = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteElephantStateNoneId, kPeepAnimationSequenceEntertainerElephantNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteElephantStateWalkingId, kPeepAnimationSequenceEntertainerElephantWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteElephantStateWatchRideId, kPeepAnimationSequenceEntertainerElephantWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteElephantStateWaveId, kPeepAnimationSequenceEntertainerElephantEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteElephantStateHangingId, kPeepAnimationSequenceEntertainerElephantHanging }; @@ -312,7 +312,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerRoman sprites - static constexpr std::array kPeepAnimationSequenceEntertainerRomanNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerRomanWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerRomanWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerRomanEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerRomanHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -323,7 +323,7 @@ namespace OpenRCT2 // Define animation group for EntertainerRoman sequences static PeepAnimations kPeepAnimationsEntertainerRoman = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteRomanStateNoneId, kPeepAnimationSequenceEntertainerRomanNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteRomanStateWalkingId, kPeepAnimationSequenceEntertainerRomanWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteRomanStateWatchRideId, kPeepAnimationSequenceEntertainerRomanWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteRomanStateWaveId, kPeepAnimationSequenceEntertainerRomanEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteRomanStateHangingId, kPeepAnimationSequenceEntertainerRomanHanging }; @@ -334,7 +334,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerGorilla sprites - static constexpr std::array kPeepAnimationSequenceEntertainerGorillaNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerGorillaWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerGorillaWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerGorillaEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 8, 9, 10, 9, 8, 7, 8, 9, 10, 9, 8, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerGorillaHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -345,7 +345,7 @@ namespace OpenRCT2 // Define animation group for EntertainerGorilla sequences static PeepAnimations kPeepAnimationsEntertainerGorilla = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteGorillaStateNoneId, kPeepAnimationSequenceEntertainerGorillaNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteGorillaStateWalkingId, kPeepAnimationSequenceEntertainerGorillaWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteGorillaStateWatchRideId, kPeepAnimationSequenceEntertainerGorillaWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteGorillaStateWaveId, kPeepAnimationSequenceEntertainerGorillaEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteGorillaStateHangingId, kPeepAnimationSequenceEntertainerGorillaHanging }; @@ -356,7 +356,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerSnowman sprites - static constexpr std::array kPeepAnimationSequenceEntertainerSnowmanNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerSnowmanWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerSnowmanWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerSnowmanEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 31, 31, 31, 32, 33 }; static constexpr std::array kPeepAnimationSequenceEntertainerSnowmanHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -367,7 +367,7 @@ namespace OpenRCT2 // Define animation group for EntertainerSnowman sequences static PeepAnimations kPeepAnimationsEntertainerSnowman = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteSnowmanStateNoneId, kPeepAnimationSequenceEntertainerSnowmanNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteSnowmanStateWalkingId, kPeepAnimationSequenceEntertainerSnowmanWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteSnowmanStateWatchRideId, kPeepAnimationSequenceEntertainerSnowmanWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteSnowmanStateWaveId, kPeepAnimationSequenceEntertainerSnowmanEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteSnowmanStateHangingId, kPeepAnimationSequenceEntertainerSnowmanHanging }; @@ -378,7 +378,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerKnight sprites - static constexpr std::array kPeepAnimationSequenceEntertainerKnightNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerKnightWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerKnightWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerKnightEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 12, 12, 12, 12, 13, 14, 15, 16, 17, 17, 17, 17, 17, 18, 19, 20, 21, 22, 23, 23, 23, 23, 23, 24, 25, 26, 27 }; static constexpr std::array kPeepAnimationSequenceEntertainerKnightHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -389,7 +389,7 @@ namespace OpenRCT2 // Define animation group for EntertainerKnight sequences static PeepAnimations kPeepAnimationsEntertainerKnight = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteKnightStateNoneId, kPeepAnimationSequenceEntertainerKnightNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteKnightStateWalkingId, kPeepAnimationSequenceEntertainerKnightWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteKnightStateWatchRideId, kPeepAnimationSequenceEntertainerKnightWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteKnightStateWaveId, kPeepAnimationSequenceEntertainerKnightEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteKnightStateHangingId, kPeepAnimationSequenceEntertainerKnightHanging }; @@ -400,7 +400,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerAstronaut sprites - static constexpr std::array kPeepAnimationSequenceEntertainerAstronautNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerAstronautWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerAstronautWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerAstronautEatFood = { 0, 1, 2, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 9, 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerAstronautHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -411,7 +411,7 @@ namespace OpenRCT2 // Define animation group for EntertainerAstronaut sequences static PeepAnimations kPeepAnimationsEntertainerAstronaut = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteAstronautStateNoneId, kPeepAnimationSequenceEntertainerAstronautNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteAstronautStateWalkingId, kPeepAnimationSequenceEntertainerAstronautWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteAstronautStateWatchRideId, kPeepAnimationSequenceEntertainerAstronautWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteAstronautStateWaveId, kPeepAnimationSequenceEntertainerAstronautEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteAstronautStateHangingId, kPeepAnimationSequenceEntertainerAstronautHanging }; @@ -422,7 +422,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerBandit sprites - static constexpr std::array kPeepAnimationSequenceEntertainerBanditNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerBanditWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerBanditWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerBanditEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 8, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 12, 13, 13, 13, 13, 13, 14, 15, 16, 17, 17, 17, 17, 17, 18, 19, 20, 21, 22, 21, 20, 19, 20, 21, 22, 21, 20, 19, 20, 21, 22, 21, 20, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41 }; static constexpr std::array kPeepAnimationSequenceEntertainerBanditHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -433,7 +433,7 @@ namespace OpenRCT2 // Define animation group for EntertainerBandit sequences static PeepAnimations kPeepAnimationsEntertainerBandit = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteBanditStateNoneId, kPeepAnimationSequenceEntertainerBanditNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteBanditStateWalkingId, kPeepAnimationSequenceEntertainerBanditWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteBanditStateWatchRideId, kPeepAnimationSequenceEntertainerBanditWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteBanditStateWaveId, kPeepAnimationSequenceEntertainerBanditEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteBanditStateHangingId, kPeepAnimationSequenceEntertainerBanditHanging }; @@ -444,7 +444,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerSheriff sprites - static constexpr std::array kPeepAnimationSequenceEntertainerSheriffNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerSheriffWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerSheriffWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerSheriffEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 8, 9, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 10, 11, 12, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerSheriffHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -455,7 +455,7 @@ namespace OpenRCT2 // Define animation group for EntertainerSheriff sequences static PeepAnimations kPeepAnimationsEntertainerSheriff = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpriteSheriffStateNoneId, kPeepAnimationSequenceEntertainerSheriffNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpriteSheriffStateWalkingId, kPeepAnimationSequenceEntertainerSheriffWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpriteSheriffStateWatchRideId, kPeepAnimationSequenceEntertainerSheriffWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpriteSheriffStateWaveId, kPeepAnimationSequenceEntertainerSheriffEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpriteSheriffStateHangingId, kPeepAnimationSequenceEntertainerSheriffHanging }; @@ -466,7 +466,7 @@ namespace OpenRCT2 }(); // Define animation sequences for EntertainerPirate sprites - static constexpr std::array kPeepAnimationSequenceEntertainerPirateNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceEntertainerPirateWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceEntertainerPirateWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceEntertainerPirateEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 9, 10, 11, 12, 13, 14, 15, 16, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 21, 21, 21, 21, 21, 22, 23, 23, 23, 23, 24, 25, 26, 27, 27, 27, 27, 28, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31 }; static constexpr std::array kPeepAnimationSequenceEntertainerPirateHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; @@ -477,7 +477,7 @@ namespace OpenRCT2 // Define animation group for EntertainerPirate sequences static PeepAnimations kPeepAnimationsEntertainerPirate = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kEntertainerSpritePirateStateNoneId, kPeepAnimationSequenceEntertainerPirateNone }; + pag[PeepAnimationType::Walking] = { kEntertainerSpritePirateStateWalkingId, kPeepAnimationSequenceEntertainerPirateWalking }; pag[PeepAnimationType::WatchRide] = { kEntertainerSpritePirateStateWatchRideId, kPeepAnimationSequenceEntertainerPirateWatchRide }; pag[PeepAnimationType::EatFood] = { kEntertainerSpritePirateStateWaveId, kPeepAnimationSequenceEntertainerPirateEatFood }; pag[PeepAnimationType::Hanging] = { kEntertainerSpritePirateStateHangingId, kPeepAnimationSequenceEntertainerPirateHanging }; @@ -488,7 +488,7 @@ namespace OpenRCT2 }(); // Define animation sequences for IceCream sprites - static constexpr std::array kPeepAnimationSequenceIceCreamNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + static constexpr std::array kPeepAnimationSequenceIceCreamWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceIceCreamWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceIceCreamEatFood = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceIceCreamSittingIdle = { 0 }; @@ -497,7 +497,7 @@ namespace OpenRCT2 // Define animation group for IceCream sequences static PeepAnimations kPeepAnimationsIceCream = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteIceCreamStateNoneId, kPeepAnimationSequenceIceCreamNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteIceCreamStateWalkingId, kPeepAnimationSequenceIceCreamWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteIceCreamStateWatchRideId, kPeepAnimationSequenceIceCreamWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteIceCreamStateEatFoodId, kPeepAnimationSequenceIceCreamEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteIceCreamStateSittingIdleId, kPeepAnimationSequenceIceCreamSittingIdle }; @@ -506,7 +506,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Chips sprites - static constexpr std::array kPeepAnimationSequenceChipsNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceChipsWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceChipsWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceChipsEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceChipsSittingIdle = { 0 }; @@ -515,7 +515,7 @@ namespace OpenRCT2 // Define animation group for Chips sequences static PeepAnimations kPeepAnimationsChips = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteChipsStateNoneId, kPeepAnimationSequenceChipsNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteChipsStateWalkingId, kPeepAnimationSequenceChipsWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteChipsStateWatchRideId, kPeepAnimationSequenceChipsWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteChipsStateEatFoodId, kPeepAnimationSequenceChipsEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteChipsStateSittingIdleId, kPeepAnimationSequenceChipsSittingIdle }; @@ -524,7 +524,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Burger sprites - static constexpr std::array kPeepAnimationSequenceBurgerNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceBurgerWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceBurgerWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceBurgerEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceBurgerSittingIdle = { 0 }; @@ -533,7 +533,7 @@ namespace OpenRCT2 // Define animation group for Burger sequences static PeepAnimations kPeepAnimationsBurger = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteBurgerStateNoneId, kPeepAnimationSequenceBurgerNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteBurgerStateWalkingId, kPeepAnimationSequenceBurgerWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteBurgerStateWatchRideId, kPeepAnimationSequenceBurgerWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteBurgerStateEatFoodId, kPeepAnimationSequenceBurgerEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteBurgerStateSittingIdleId, kPeepAnimationSequenceBurgerSittingIdle }; @@ -542,7 +542,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Drink sprites - static constexpr std::array kPeepAnimationSequenceDrinkNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceDrinkWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceDrinkWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceDrinkEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceDrinkSittingIdle = { 0 }; @@ -551,7 +551,7 @@ namespace OpenRCT2 // Define animation group for Drink sequences static PeepAnimations kPeepAnimationsDrink = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteDrinkStateNoneId, kPeepAnimationSequenceDrinkNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteDrinkStateWalkingId, kPeepAnimationSequenceDrinkWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteDrinkStateWatchRideId, kPeepAnimationSequenceDrinkWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteDrinkStateEatFoodId, kPeepAnimationSequenceDrinkEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteDrinkStateSittingIdleId, kPeepAnimationSequenceDrinkSittingIdle }; @@ -560,21 +560,21 @@ namespace OpenRCT2 }(); // Define animation sequences for Balloon sprites - static constexpr std::array kPeepAnimationSequenceBalloonNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceBalloonWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceBalloonWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceBalloonSittingIdle = { 0 }; // Define animation group for Balloon sequences static PeepAnimations kPeepAnimationsBalloon = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteBalloonStateNoneId, kPeepAnimationSequenceBalloonNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteBalloonStateWalkingId, kPeepAnimationSequenceBalloonWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteBalloonStateWatchRideId, kPeepAnimationSequenceBalloonWatchRide }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteBalloonStateSittingIdleId, kPeepAnimationSequenceBalloonSittingIdle }; return pag; }(); // Define animation sequences for Candyfloss sprites - static constexpr std::array kPeepAnimationSequenceCandyflossNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceCandyflossWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceCandyflossWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceCandyflossEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceCandyflossSittingIdle = { 0 }; @@ -583,7 +583,7 @@ namespace OpenRCT2 // Define animation group for Candyfloss sequences static PeepAnimations kPeepAnimationsCandyfloss = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteCandyflossStateNoneId, kPeepAnimationSequenceCandyflossNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteCandyflossStateWalkingId, kPeepAnimationSequenceCandyflossWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteCandyflossStateWatchRideId, kPeepAnimationSequenceCandyflossWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteCandyflossStateEatFoodId, kPeepAnimationSequenceCandyflossEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteCandyflossStateSittingIdleId, kPeepAnimationSequenceCandyflossSittingIdle }; @@ -592,21 +592,21 @@ namespace OpenRCT2 }(); // Define animation sequences for Umbrella sprites - static constexpr std::array kPeepAnimationSequenceUmbrellaNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceUmbrellaWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceUmbrellaWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceUmbrellaSittingIdle = { 0 }; // Define animation group for Umbrella sequences static PeepAnimations kPeepAnimationsUmbrella = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteUmbrellaStateNoneId, kPeepAnimationSequenceUmbrellaNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteUmbrellaStateWalkingId, kPeepAnimationSequenceUmbrellaWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteUmbrellaStateWatchRideId, kPeepAnimationSequenceUmbrellaWatchRide }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteUmbrellaStateSittingIdleId, kPeepAnimationSequenceUmbrellaSittingIdle }; return pag; }(); // Define animation sequences for Pizza sprites - static constexpr std::array kPeepAnimationSequencePizzaNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + static constexpr std::array kPeepAnimationSequencePizzaWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequencePizzaWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequencePizzaEatFood = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequencePizzaSittingIdle = { 0 }; @@ -615,7 +615,7 @@ namespace OpenRCT2 // Define animation group for Pizza sequences static PeepAnimations kPeepAnimationsPizza = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpritePizzaStateNoneId, kPeepAnimationSequencePizzaNone }; + pag[PeepAnimationType::Walking] = { kPeepSpritePizzaStateWalkingId, kPeepAnimationSequencePizzaWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpritePizzaStateWatchRideId, kPeepAnimationSequencePizzaWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpritePizzaStateEatFoodId, kPeepAnimationSequencePizzaEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpritePizzaStateSittingIdleId, kPeepAnimationSequencePizzaSittingIdle }; @@ -624,7 +624,7 @@ namespace OpenRCT2 }(); // Define animation sequences for SecurityAlt sprites - static constexpr std::array kPeepAnimationSequenceSecurityAltNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceSecurityAltWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceSecurityAltWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceSecurityAltHanging = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceSecurityAltDrowning = { 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 0, 4, 5, 6 }; @@ -632,15 +632,15 @@ namespace OpenRCT2 // Define animation group for SecurityAlt sequences static PeepAnimations kPeepAnimationsSecurityAlt = []() { PeepAnimations pag; - pag[PeepAnimationType::None] = { kSecurityStaffSpriteAltStateNoneId, kPeepAnimationSequenceSecurityAltNone }; - pag[PeepAnimationType::WatchRide] = { kSecuritySpriteStateWatchRideId, kPeepAnimationSequenceSecurityAltWatchRide }; - pag[PeepAnimationType::Hanging] = { kSecuritySpriteStateHangingId, kPeepAnimationSequenceSecurityAltHanging }; - pag[PeepAnimationType::Drowning] = { kSecuritySpriteStateDrowningId, kPeepAnimationSequenceSecurityAltDrowning }; + pag[PeepAnimationType::Walking] = { kSecurityStaffSpriteAltStateWalkingId, kPeepAnimationSequenceSecurityAltWalking }; + pag[PeepAnimationType::WatchRide] = { kSecuritySpriteStateWatchRideId, kPeepAnimationSequenceSecurityAltWatchRide }; + pag[PeepAnimationType::Hanging] = { kSecuritySpriteStateHangingId, kPeepAnimationSequenceSecurityAltHanging }; + pag[PeepAnimationType::Drowning] = { kSecuritySpriteStateDrowningId, kPeepAnimationSequenceSecurityAltDrowning }; return pag; }(); // Define animation sequences for Popcorn sprites - static constexpr std::array kPeepAnimationSequencePopcornNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequencePopcornWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequencePopcornWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequencePopcornEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequencePopcornSittingIdle = { 0 }; @@ -649,7 +649,7 @@ namespace OpenRCT2 // Define animation group for Popcorn sequences static PeepAnimations kPeepAnimationsPopcorn = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpritePopcornStateNoneId, kPeepAnimationSequencePopcornNone }; + pag[PeepAnimationType::Walking] = { kPeepSpritePopcornStateWalkingId, kPeepAnimationSequencePopcornWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpritePopcornStateWatchRideId, kPeepAnimationSequencePopcornWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpritePopcornStateEatFoodId, kPeepAnimationSequencePopcornEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpritePopcornStateSittingIdleId, kPeepAnimationSequencePopcornSittingIdle }; @@ -658,75 +658,75 @@ namespace OpenRCT2 }(); // Define animation sequences for ArmsCrossed sprites - static constexpr std::array kPeepAnimationSequenceArmsCrossedNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceArmsCrossedWalking = { 0, 1, 2, 3, 4, 5 }; // Define animation group for ArmsCrossed sequences static PeepAnimations kPeepAnimationsArmsCrossed = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteArmsCrossedStateNoneId, kPeepAnimationSequenceArmsCrossedNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteArmsCrossedStateWalkingId, kPeepAnimationSequenceArmsCrossedWalking }; return pag; }(); // Define animation sequences for HeadDown sprites - static constexpr std::array kPeepAnimationSequenceHeadDownNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceHeadDownWalking = { 0, 1, 2, 3, 4, 5 }; // Define animation group for HeadDown sequences static PeepAnimations kPeepAnimationsHeadDown = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteHeadDownStateNoneId, kPeepAnimationSequenceHeadDownNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteHeadDownStateWalkingId, kPeepAnimationSequenceHeadDownWalking }; return pag; }(); // Define animation sequences for Nauseous sprites - static constexpr std::array kPeepAnimationSequenceNauseousNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceNauseousWalking = { 0, 1, 2, 3, 4, 5 }; // Define animation group for Nauseous sequences static PeepAnimations kPeepAnimationsNauseous = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteNauseousStateNoneId, kPeepAnimationSequenceNauseousNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteNauseousStateWalkingId, kPeepAnimationSequenceNauseousWalking }; return pag; }(); // Define animation sequences for VeryNauseous sprites - static constexpr std::array kPeepAnimationSequenceVeryNauseousNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceVeryNauseousWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceVeryNauseousWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceVeryNauseousSittingIdle = { 0 }; // Define animation group for VeryNauseous sequences static PeepAnimations kPeepAnimationsVeryNauseous = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteVeryNauseousStateNoneId, kPeepAnimationSequenceVeryNauseousNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteVeryNauseousStateWalkingId, kPeepAnimationSequenceVeryNauseousWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteVeryNauseousStateWatchRideId, kPeepAnimationSequenceVeryNauseousWatchRide }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteVeryNauseousStateSittingIdleId, kPeepAnimationSequenceVeryNauseousSittingIdle }; return pag; }(); // Define animation sequences for RequireToilet sprites - static constexpr std::array kPeepAnimationSequenceRequireToiletNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceRequireToiletWalking = { 0, 1, 2, 3, 4, 5 }; // Define animation group for RequireToilet sequences static PeepAnimations kPeepAnimationsRequireToilet = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteRequireToiletStateNoneId, kPeepAnimationSequenceRequireToiletNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteRequireToiletStateWalkingId, kPeepAnimationSequenceRequireToiletWalking }; return pag; }(); // Define animation sequences for Hat sprites - static constexpr std::array kPeepAnimationSequenceHatNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceHatWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceHatWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceHatSittingIdle = { 0 }; // Define animation group for Hat sequences static PeepAnimations kPeepAnimationsHat = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteHatStateNoneId, kPeepAnimationSequenceHatNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteHatStateWalkingId, kPeepAnimationSequenceHatWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteHatStateWatchRideId, kPeepAnimationSequenceHatWatchRide }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteHatStateSittingIdleId, kPeepAnimationSequenceHatSittingIdle }; return pag; }(); // Define animation sequences for HotDog sprites - static constexpr std::array kPeepAnimationSequenceHotDogNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceHotDogWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceHotDogWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceHotDogEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceHotDogSittingIdle = { 0 }; @@ -735,7 +735,7 @@ namespace OpenRCT2 // Define animation group for HotDog sequences static PeepAnimations kPeepAnimationsHotDog = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteHotDogStateNoneId, kPeepAnimationSequenceHotDogNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteHotDogStateWalkingId, kPeepAnimationSequenceHotDogWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteHotDogStateWatchRideId, kPeepAnimationSequenceHotDogWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteHotDogStateEatFoodId, kPeepAnimationSequenceHotDogEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteHotDogStateSittingIdleId, kPeepAnimationSequenceHotDogSittingIdle }; @@ -744,7 +744,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Tentacle sprites - static constexpr std::array kPeepAnimationSequenceTentacleNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }; + static constexpr std::array kPeepAnimationSequenceTentacleWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }; static constexpr std::array kPeepAnimationSequenceTentacleWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceTentacleEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; static constexpr std::array kPeepAnimationSequenceTentacleSittingIdle = { 0 }; @@ -753,7 +753,7 @@ namespace OpenRCT2 // Define animation group for Tentacle sequences static PeepAnimations kPeepAnimationsTentacle = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteTentacleStateNoneId, kPeepAnimationSequenceTentacleNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteTentacleStateWalkingId, kPeepAnimationSequenceTentacleWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteTentacleStateWatchRideId, kPeepAnimationSequenceTentacleWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteTentacleStateEatFoodId, kPeepAnimationSequenceTentacleEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteTentacleStateSittingIdleId, kPeepAnimationSequenceTentacleSittingIdle }; @@ -762,7 +762,7 @@ namespace OpenRCT2 }(); // Define animation sequences for ToffeeApple sprites - static constexpr std::array kPeepAnimationSequenceToffeeAppleNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + static constexpr std::array kPeepAnimationSequenceToffeeAppleWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceToffeeAppleWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceToffeeAppleEatFood = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceToffeeAppleSittingIdle = { 0 }; @@ -771,7 +771,7 @@ namespace OpenRCT2 // Define animation group for ToffeeApple sequences static PeepAnimations kPeepAnimationsToffeeApple = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteToffeeAppleStateNoneId, kPeepAnimationSequenceToffeeAppleNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteToffeeAppleStateWalkingId, kPeepAnimationSequenceToffeeAppleWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteToffeeAppleStateWatchRideId, kPeepAnimationSequenceToffeeAppleWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteToffeeAppleStateEatFoodId, kPeepAnimationSequenceToffeeAppleEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteToffeeAppleStateSittingIdleId, kPeepAnimationSequenceToffeeAppleSittingIdle }; @@ -780,7 +780,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Donut sprites - static constexpr std::array kPeepAnimationSequenceDonutNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceDonutWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceDonutWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceDonutEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceDonutSittingIdle = { 0 }; @@ -789,7 +789,7 @@ namespace OpenRCT2 // Define animation group for Donut sequences static PeepAnimations kPeepAnimationsDonut = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteDonutStateNoneId, kPeepAnimationSequenceDonutNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteDonutStateWalkingId, kPeepAnimationSequenceDonutWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteDonutStateWatchRideId, kPeepAnimationSequenceDonutWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteDonutStateEatFoodId, kPeepAnimationSequenceDonutEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteDonutStateSittingIdleId, kPeepAnimationSequenceDonutSittingIdle }; @@ -798,7 +798,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Coffee sprites - static constexpr std::array kPeepAnimationSequenceCoffeeNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceCoffeeWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceCoffeeWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceCoffeeEatFood = { 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 1 }; static constexpr std::array kPeepAnimationSequenceCoffeeSittingIdle = { 0 }; @@ -807,7 +807,7 @@ namespace OpenRCT2 // Define animation group for Coffee sequences static PeepAnimations kPeepAnimationsCoffee = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteCoffeeStateNoneId, kPeepAnimationSequenceCoffeeNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteCoffeeStateWalkingId, kPeepAnimationSequenceCoffeeWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteCoffeeStateWatchRideId, kPeepAnimationSequenceCoffeeWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteCoffeeStateWatchRideId, kPeepAnimationSequenceCoffeeEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteCoffeeStateSittingIdleId, kPeepAnimationSequenceCoffeeSittingIdle }; @@ -816,7 +816,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Chicken sprites - static constexpr std::array kPeepAnimationSequenceChickenNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceChickenWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceChickenWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceChickenEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceChickenSittingIdle = { 0 }; @@ -825,7 +825,7 @@ namespace OpenRCT2 // Define animation group for Chicken sequences static PeepAnimations kPeepAnimationsChicken = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteChickenStateNoneId, kPeepAnimationSequenceChickenNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteChickenStateWalkingId, kPeepAnimationSequenceChickenWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteChickenStateWatchRideId, kPeepAnimationSequenceChickenWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteChickenStateWatchRideId, kPeepAnimationSequenceChickenEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteChickenStateSittingIdleId, kPeepAnimationSequenceChickenSittingIdle }; @@ -834,7 +834,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Lemonade sprites - static constexpr std::array kPeepAnimationSequenceLemonadeNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceLemonadeWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceLemonadeWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceLemonadeEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceLemonadeSittingIdle = { 0 }; @@ -843,7 +843,7 @@ namespace OpenRCT2 // Define animation group for Lemonade sequences static PeepAnimations kPeepAnimationsLemonade = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteLemonadeStateNoneId, kPeepAnimationSequenceLemonadeNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteLemonadeStateWalkingId, kPeepAnimationSequenceLemonadeWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteLemonadeStateWatchRideId, kPeepAnimationSequenceLemonadeWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteLemonadeStateWatchRideId, kPeepAnimationSequenceLemonadeEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteLemonadeStateSittingIdleId, kPeepAnimationSequenceLemonadeSittingIdle }; @@ -862,7 +862,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Pretzel sprites - static constexpr std::array kPeepAnimationSequencePretzelNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequencePretzelWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequencePretzelWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequencePretzelEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequencePretzelSittingIdle = { 0 }; @@ -871,7 +871,7 @@ namespace OpenRCT2 // Define animation group for Pretzel sequences static PeepAnimations kPeepAnimationsPretzel = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpritePretzelStateNoneId, kPeepAnimationSequencePretzelNone }; + pag[PeepAnimationType::Walking] = { kPeepSpritePretzelStateWalkingId, kPeepAnimationSequencePretzelWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpritePretzelStateWatchRideId, kPeepAnimationSequencePretzelWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpritePretzelStateWatchRideId, kPeepAnimationSequencePretzelEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpritePretzelStateSittingIdleId, kPeepAnimationSequencePretzelSittingIdle }; @@ -880,21 +880,21 @@ namespace OpenRCT2 }(); // Define animation sequences for Sunglasses sprites - static constexpr std::array kPeepAnimationSequenceSunglassesNone = { 0, 1, 2, 3, 4, 5 }; + static constexpr std::array kPeepAnimationSequenceSunglassesWalking = { 0, 1, 2, 3, 4, 5 }; static constexpr std::array kPeepAnimationSequenceSunglassesWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceSunglassesSittingIdle = { 0 }; // Define animation group for Sunglasses sequences static PeepAnimations kPeepAnimationsSunglasses = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSunglassesStateNoneId, kPeepAnimationSequenceSunglassesNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteSunglassesStateWalkingId, kPeepAnimationSequenceSunglassesWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteSunglassesStateWatchRideId, kPeepAnimationSequenceSunglassesWatchRide }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSunglassesStateSittingIdleId, kPeepAnimationSequenceSunglassesSittingIdle }; return pag; }(); // Define animation sequences for SuJongkwa sprites - static constexpr std::array kPeepAnimationSequenceSuJongkwaNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceSuJongkwaWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceSuJongkwaWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceSuJongkwaEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceSuJongkwaSittingIdle = { 0 }; @@ -903,7 +903,7 @@ namespace OpenRCT2 // Define animation group for SuJongkwa sequences static PeepAnimations kPeepAnimationsSuJongkwa = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSuJongkwaStateNoneId, kPeepAnimationSequenceSuJongkwaNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteSuJongkwaStateWalkingId, kPeepAnimationSequenceSuJongkwaWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteSuJongkwaStateWatchRideId, kPeepAnimationSequenceSuJongkwaWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteSuJongkwaStateWatchRideId, kPeepAnimationSequenceSuJongkwaEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSuJongkwaStateSittingIdleId, kPeepAnimationSequenceSuJongkwaSittingIdle }; @@ -912,7 +912,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Juice sprites - static constexpr std::array kPeepAnimationSequenceJuiceNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceJuiceWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceJuiceWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceJuiceEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceJuiceSittingIdle = { 0 }; @@ -921,7 +921,7 @@ namespace OpenRCT2 // Define animation group for Juice sequences static PeepAnimations kPeepAnimationsJuice = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteJuiceStateNoneId, kPeepAnimationSequenceJuiceNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteJuiceStateWalkingId, kPeepAnimationSequenceJuiceWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteJuiceStateWatchRideId, kPeepAnimationSequenceJuiceWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteJuiceStateWatchRideId, kPeepAnimationSequenceJuiceEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteJuiceStateSittingIdleId, kPeepAnimationSequenceJuiceSittingIdle }; @@ -930,7 +930,7 @@ namespace OpenRCT2 }(); // Define animation sequences for FunnelCake sprites - static constexpr std::array kPeepAnimationSequenceFunnelCakeNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceFunnelCakeWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceFunnelCakeWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceFunnelCakeEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceFunnelCakeSittingIdle = { 0 }; @@ -939,7 +939,7 @@ namespace OpenRCT2 // Define animation group for FunnelCake sequences static PeepAnimations kPeepAnimationsFunnelCake = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteFunnelCakeStateNoneId, kPeepAnimationSequenceFunnelCakeNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteFunnelCakeStateWalkingId, kPeepAnimationSequenceFunnelCakeWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteFunnelCakeStateWatchRideId, kPeepAnimationSequenceFunnelCakeWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteFunnelCakeStateWatchRideId, kPeepAnimationSequenceFunnelCakeEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteFunnelCakeStateSittingIdleId, kPeepAnimationSequenceFunnelCakeSittingIdle }; @@ -948,7 +948,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Noodles sprites - static constexpr std::array kPeepAnimationSequenceNoodlesNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceNoodlesWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceNoodlesWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceNoodlesEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceNoodlesSittingIdle = { 0 }; @@ -957,7 +957,7 @@ namespace OpenRCT2 // Define animation group for Noodles sequences static PeepAnimations kPeepAnimationsNoodles = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteNoodlesStateNoneId, kPeepAnimationSequenceNoodlesNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteNoodlesStateWalkingId, kPeepAnimationSequenceNoodlesWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteNoodlesStateWatchRideId, kPeepAnimationSequenceNoodlesWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteNoodlesStateWatchRideId, kPeepAnimationSequenceNoodlesEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteNoodlesStateSittingIdleId, kPeepAnimationSequenceNoodlesSittingIdle }; @@ -966,7 +966,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Sausage sprites - static constexpr std::array kPeepAnimationSequenceSausageNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceSausageWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceSausageWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceSausageEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceSausageSittingIdle = { 0 }; @@ -975,7 +975,7 @@ namespace OpenRCT2 // Define animation group for Sausage sequences static PeepAnimations kPeepAnimationsSausage = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSausageStateNoneId, kPeepAnimationSequenceSausageNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteSausageStateWalkingId, kPeepAnimationSequenceSausageWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteSausageStateWatchRideId, kPeepAnimationSequenceSausageWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteSausageStateWatchRideId, kPeepAnimationSequenceSausageEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSausageStateSittingIdleId, kPeepAnimationSequenceSausageSittingIdle }; @@ -984,7 +984,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Soup sprites - static constexpr std::array kPeepAnimationSequenceSoupNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceSoupWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceSoupWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceSoupEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceSoupSittingIdle = { 0 }; @@ -993,7 +993,7 @@ namespace OpenRCT2 // Define animation group for Soup sequences static PeepAnimations kPeepAnimationsSoup = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSoupStateNoneId, kPeepAnimationSequenceSoupNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteSoupStateWalkingId, kPeepAnimationSequenceSoupWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteSoupStateWatchRideId, kPeepAnimationSequenceSoupWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteSoupStateWatchRideId, kPeepAnimationSequenceSoupEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSoupStateSittingIdleId, kPeepAnimationSequenceSoupSittingIdle }; @@ -1002,7 +1002,7 @@ namespace OpenRCT2 }(); // Define animation sequences for Sandwich sprites - static constexpr std::array kPeepAnimationSequenceSandwichNone = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; + static constexpr std::array kPeepAnimationSequenceSandwichWalking = { 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }; static constexpr std::array kPeepAnimationSequenceSandwichWatchRide = { 0 }; static constexpr std::array kPeepAnimationSequenceSandwichEatFood = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; static constexpr std::array kPeepAnimationSequenceSandwichSittingIdle = { 0 }; @@ -1011,7 +1011,7 @@ namespace OpenRCT2 // Define animation group for Sandwich sequences static PeepAnimations kPeepAnimationsSandwich = []() { PeepAnimations pag = kPeepAnimationsNormal; - pag[PeepAnimationType::None] = { kPeepSpriteSandwichStateNoneId, kPeepAnimationSequenceSandwichNone }; + pag[PeepAnimationType::Walking] = { kPeepSpriteSandwichStateWalkingId, kPeepAnimationSequenceSandwichWalking }; pag[PeepAnimationType::WatchRide] = { kPeepSpriteSandwichStateWatchRideId, kPeepAnimationSequenceSandwichWatchRide }; pag[PeepAnimationType::EatFood] = { kPeepSpriteSandwichStateWatchRideId, kPeepAnimationSequenceSandwichEatFood }; pag[PeepAnimationType::SittingIdle] = { kPeepSpriteSandwichStateSittingIdleId, kPeepAnimationSequenceSandwichSittingIdle }; @@ -1088,7 +1088,7 @@ namespace OpenRCT2 { auto& group = kPeepAnimationEntries[groupKey]; - for (auto type = EnumValue(PeepAnimationType::None); type <= EnumValue(PeepAnimationType::WithdrawMoney); type++) + for (auto type = EnumValue(PeepAnimationType::Walking); type <= EnumValue(PeepAnimationType::WithdrawMoney); type++) { auto& anim = group[PeepAnimationType(type)]; if (anim.frame_offsets.empty()) diff --git a/src/openrct2/peep/PeepAnimationData.h b/src/openrct2/peep/PeepAnimationData.h index 1210a43c0d..7a826d92e5 100644 --- a/src/openrct2/peep/PeepAnimationData.h +++ b/src/openrct2/peep/PeepAnimationData.h @@ -46,9 +46,9 @@ namespace OpenRCT2 }; const PeepAnimation& GetPeepAnimation( - PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::None); + PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::Walking); const SpriteBounds& GetSpriteBounds( - PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::None); + PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::Walking); void inferMaxPeepSpriteDimensions(); } // namespace OpenRCT2 diff --git a/src/openrct2/peep/PeepSpriteIds.h b/src/openrct2/peep/PeepSpriteIds.h index 7eacf53779..ca7f0ded4e 100644 --- a/src/openrct2/peep/PeepSpriteIds.h +++ b/src/openrct2/peep/PeepSpriteIds.h @@ -11,7 +11,7 @@ namespace OpenRCT2 { enum { - kPeepSpriteNormalStateNoneId = 6409, + kPeepSpriteNormalStateWalkingId = 6409, kPeepSpriteNormalStateCheckTimeId = 6585, kPeepSpriteNormalStateWatchRideId = 6621, kPeepSpriteNormalStateEatFoodId = 6653, @@ -38,7 +38,7 @@ namespace OpenRCT2 kPeepSpriteNormalStateBeingWatchedId = 7285, kPeepSpriteNormalStateWithdrawMoneyId = 7181, - kHandymanSpriteStateNoneId = 11261, + kHandymanSpriteStateWalkingId = 11261, kHandymanSpriteStateWatchRideId = 11285, kHandymanSpriteStateHangingId = 11289, kHandymanSpriteStateStaffMowerId = 11301, @@ -47,7 +47,7 @@ namespace OpenRCT2 kHandymanSpriteStateStaffWateringId = 11377, kHandymanSpriteStateStaffEmptyBinId = 11401, - kMechanicSpriteStateNoneId = 11441, + kMechanicSpriteStateWalkingId = 11441, kMechanicSpriteStateWatchRideId = 11465, kMechanicSpriteStateHangingId = 11469, kMechanicSpriteStateDrowningId = 11481, @@ -56,219 +56,219 @@ namespace OpenRCT2 kMechanicSpriteStateStaffFixId = 11669, kMechanicSpriteStateStaffFixGroundId = 11801, - kSecuritySpriteStateNoneId = 11881, + kSecuritySpriteStateWalkingId = 11881, kSecuritySpriteStateWatchRideId = 11905, kSecuritySpriteStateHangingId = 11909, kSecuritySpriteStateDrowningId = 11921, - kEntertainerSpritePandaStateNoneId = 11973, + kEntertainerSpritePandaStateWalkingId = 11973, kEntertainerSpritePandaStateWatchRideId = 11997, kEntertainerSpritePandaStateWaveId = 12041, kEntertainerSpritePandaStateHangingId = 12001, kEntertainerSpritePandaStateDrowningId = 12013, kEntertainerSpritePandaStateJoyId = 12065, - kEntertainerSpriteTigerStateNoneId = 12129, + kEntertainerSpriteTigerStateWalkingId = 12129, kEntertainerSpriteTigerStateWatchRideId = 12153, kEntertainerSpriteTigerStateWaveId = 12197, kEntertainerSpriteTigerStateHangingId = 12157, kEntertainerSpriteTigerStateDrowningId = 12169, kEntertainerSpriteTigerStateJoyId = 12221, - kEntertainerSpriteElephantStateNoneId = 12325, + kEntertainerSpriteElephantStateWalkingId = 12325, kEntertainerSpriteElephantStateWatchRideId = 12349, kEntertainerSpriteElephantStateWaveId = 12365, kEntertainerSpriteElephantStateHangingId = 12353, kEntertainerSpriteElephantStateDrowningId = 12393, kEntertainerSpriteElephantStateJoyId = 12433, - kEntertainerSpriteRomanStateNoneId = 13897, + kEntertainerSpriteRomanStateWalkingId = 13897, kEntertainerSpriteRomanStateWatchRideId = 13921, kEntertainerSpriteRomanStateWaveId = 13937, kEntertainerSpriteRomanStateHangingId = 13925, kEntertainerSpriteRomanStateDrowningId = 13969, kEntertainerSpriteRomanStateJoyId = 14029, - kEntertainerSpriteGorillaStateNoneId = 12549, + kEntertainerSpriteGorillaStateWalkingId = 12549, kEntertainerSpriteGorillaStateWatchRideId = 12545, kEntertainerSpriteGorillaStateWaveId = 12573, kEntertainerSpriteGorillaStateHangingId = 12665, kEntertainerSpriteGorillaStateDrowningId = 12617, - kEntertainerSpriteSnowmanStateNoneId = 12681, + kEntertainerSpriteSnowmanStateWalkingId = 12681, kEntertainerSpriteSnowmanStateWatchRideId = 12677, kEntertainerSpriteSnowmanStateWaveId = 12705, kEntertainerSpriteSnowmanStateHangingId = 12881, kEntertainerSpriteSnowmanStateDrowningId = 12841, - kEntertainerSpriteKnightStateNoneId = 12897, + kEntertainerSpriteKnightStateWalkingId = 12897, kEntertainerSpriteKnightStateWatchRideId = 12893, kEntertainerSpriteKnightStateWaveId = 12993, kEntertainerSpriteKnightStateHangingId = 12981, kEntertainerSpriteKnightStateDrowningId = 12921, - kEntertainerSpriteAstronautStateNoneId = 13769, + kEntertainerSpriteAstronautStateWalkingId = 13769, kEntertainerSpriteAstronautStateWatchRideId = 13765, kEntertainerSpriteAstronautStateWaveId = 13857, kEntertainerSpriteAstronautStateHangingId = 13845, kEntertainerSpriteAstronautStateDrowningId = 13793, - kEntertainerSpriteBanditStateNoneId = 13109, + kEntertainerSpriteBanditStateWalkingId = 13109, kEntertainerSpriteBanditStateWatchRideId = 13105, kEntertainerSpriteBanditStateWaveId = 13209, kEntertainerSpriteBanditStateHangingId = 13197, kEntertainerSpriteBanditStateDrowningId = 13133, - kEntertainerSpriteSheriffStateNoneId = 13613, + kEntertainerSpriteSheriffStateWalkingId = 13613, kEntertainerSpriteSheriffStateWatchRideId = 13609, kEntertainerSpriteSheriffStateWaveId = 13713, kEntertainerSpriteSheriffStateHangingId = 13701, kEntertainerSpriteSheriffStateDrowningId = 13637, - kEntertainerSpritePirateStateNoneId = 13381, + kEntertainerSpritePirateStateWalkingId = 13381, kEntertainerSpritePirateStateWatchRideId = 13377, kEntertainerSpritePirateStateWaveId = 13481, kEntertainerSpritePirateStateHangingId = 13469, kEntertainerSpritePirateStateDrowningId = 13405, - kPeepSpriteIceCreamStateNoneId = 7505, + kPeepSpriteIceCreamStateWalkingId = 7505, kPeepSpriteIceCreamStateWatchRideId = 7501, kPeepSpriteIceCreamStateEatFoodId = 7581, kPeepSpriteIceCreamStateSittingIdleId = 7553, kPeepSpriteIceCreamStateSittingEatFoodId = 7557, - kPeepSpriteChipsStateNoneId = 7609, + kPeepSpriteChipsStateWalkingId = 7609, kPeepSpriteChipsStateWatchRideId = 7605, kPeepSpriteChipsStateEatFoodId = 7733, kPeepSpriteChipsStateSittingIdleId = 7681, kPeepSpriteChipsStateSittingEatFoodId = 7685, - kPeepSpriteBurgerStateNoneId = 8385, + kPeepSpriteBurgerStateWalkingId = 8385, kPeepSpriteBurgerStateWatchRideId = 8381, kPeepSpriteBurgerStateEatFoodId = 8509, kPeepSpriteBurgerStateSittingIdleId = 8457, kPeepSpriteBurgerStateSittingEatFoodId = 8461, - kPeepSpriteDrinkStateNoneId = 8713, + kPeepSpriteDrinkStateWalkingId = 8713, kPeepSpriteDrinkStateWatchRideId = 8709, kPeepSpriteDrinkStateEatFoodId = 8837, kPeepSpriteDrinkStateSittingIdleId = 8785, kPeepSpriteDrinkStateSittingEatFoodId = 8789, - kPeepSpriteBalloonStateNoneId = 10785, + kPeepSpriteBalloonStateWalkingId = 10785, kPeepSpriteBalloonStateWatchRideId = 10781, kPeepSpriteBalloonStateSittingIdleId = 10809, - kPeepSpriteCandyflossStateNoneId = 10849, + kPeepSpriteCandyflossStateWalkingId = 10849, kPeepSpriteCandyflossStateWatchRideId = 10845, kPeepSpriteCandyflossStateEatFoodId = 10973, kPeepSpriteCandyflossStateSittingIdleId = 10921, kPeepSpriteCandyflossStateSittingEatFoodId = 10925, - kPeepSpriteUmbrellaStateNoneId = 11197, + kPeepSpriteUmbrellaStateWalkingId = 11197, kPeepSpriteUmbrellaStateWatchRideId = 11221, kPeepSpriteUmbrellaStateSittingIdleId = 11225, - kPeepSpritePizzaStateNoneId = 7785, + kPeepSpritePizzaStateWalkingId = 7785, kPeepSpritePizzaStateWatchRideId = 7781, kPeepSpritePizzaStateEatFoodId = 7861, kPeepSpritePizzaStateSittingIdleId = 7833, kPeepSpritePizzaStateSittingEatFoodId = 7837, - kSecurityStaffSpriteAltStateNoneId = 11949, + kSecurityStaffSpriteAltStateWalkingId = 11949, - kPeepSpritePopcornStateNoneId = 11025, + kPeepSpritePopcornStateWalkingId = 11025, kPeepSpritePopcornStateWatchRideId = 11021, kPeepSpritePopcornStateEatFoodId = 11149, kPeepSpritePopcornStateSittingIdleId = 11097, kPeepSpritePopcornStateSittingEatFoodId = 11101, - kPeepSpriteArmsCrossedStateNoneId = 6433, + kPeepSpriteArmsCrossedStateWalkingId = 6433, - kPeepSpriteHeadDownStateNoneId = 6457, + kPeepSpriteHeadDownStateWalkingId = 6457, - kPeepSpriteNauseousStateNoneId = 6481, + kPeepSpriteNauseousStateWalkingId = 6481, - kPeepSpriteVeryNauseousStateNoneId = 6505, + kPeepSpriteVeryNauseousStateWalkingId = 6505, kPeepSpriteVeryNauseousStateWatchRideId = 6529, kPeepSpriteVeryNauseousStateSittingIdleId = 6533, - kPeepSpriteRequireToiletStateNoneId = 6537, + kPeepSpriteRequireToiletStateWalkingId = 6537, - kPeepSpriteHatStateNoneId = 10721, + kPeepSpriteHatStateWalkingId = 10721, kPeepSpriteHatStateWatchRideId = 10717, kPeepSpriteHatStateSittingIdleId = 10745, - kPeepSpriteHotDogStateNoneId = 7889, + kPeepSpriteHotDogStateWalkingId = 7889, kPeepSpriteHotDogStateWatchRideId = 7885, kPeepSpriteHotDogStateEatFoodId = 8013, kPeepSpriteHotDogStateSittingIdleId = 7961, kPeepSpriteHotDogStateSittingEatFoodId = 7965, - kPeepSpriteTentacleStateNoneId = 8065, + kPeepSpriteTentacleStateWalkingId = 8065, kPeepSpriteTentacleStateWatchRideId = 8061, kPeepSpriteTentacleStateEatFoodId = 8285, kPeepSpriteTentacleStateSittingIdleId = 8185, kPeepSpriteTentacleStateSittingEatFoodId = 8189, - kPeepSpriteToffeeAppleStateNoneId = 7401, + kPeepSpriteToffeeAppleStateWalkingId = 7401, kPeepSpriteToffeeAppleStateWatchRideId = 7397, kPeepSpriteToffeeAppleStateEatFoodId = 7477, kPeepSpriteToffeeAppleStateSittingIdleId = 7449, kPeepSpriteToffeeAppleStateSittingEatFoodId = 7453, - kPeepSpriteDonutStateNoneId = 8561, + kPeepSpriteDonutStateWalkingId = 8561, kPeepSpriteDonutStateWatchRideId = 8557, kPeepSpriteDonutStateEatFoodId = 8661, kPeepSpriteDonutStateSittingIdleId = 8633, kPeepSpriteDonutStateSittingEatFoodId = 8637, - kPeepSpriteCoffeeStateNoneId = 8885, + kPeepSpriteCoffeeStateWalkingId = 8885, kPeepSpriteCoffeeStateWatchRideId = 8981, kPeepSpriteCoffeeStateSittingIdleId = 8957, - kPeepSpriteChickenStateNoneId = 9005, + kPeepSpriteChickenStateWalkingId = 9005, kPeepSpriteChickenStateWatchRideId = 9125, kPeepSpriteChickenStateSittingIdleId = 9077, - kPeepSpriteLemonadeStateNoneId = 9173, + kPeepSpriteLemonadeStateWalkingId = 9173, kPeepSpriteLemonadeStateWatchRideId = 9293, kPeepSpriteLemonadeStateSittingIdleId = 9245, kPeepSpriteWatchingStateWatchRideId = 7245, - kPeepSpritePretzelStateNoneId = 9341, + kPeepSpritePretzelStateWalkingId = 9341, kPeepSpritePretzelStateWatchRideId = 9461, kPeepSpritePretzelStateSittingIdleId = 9413, - kPeepSpriteSunglassesStateNoneId = 10685, + kPeepSpriteSunglassesStateWalkingId = 10685, kPeepSpriteSunglassesStateWatchRideId = 10713, kPeepSpriteSunglassesStateSittingIdleId = 10709, - kPeepSpriteSuJongkwaStateNoneId = 9509, + kPeepSpriteSuJongkwaStateWalkingId = 9509, kPeepSpriteSuJongkwaStateWatchRideId = 9629, kPeepSpriteSuJongkwaStateSittingIdleId = 9581, - kPeepSpriteJuiceStateNoneId = 9677, + kPeepSpriteJuiceStateWalkingId = 9677, kPeepSpriteJuiceStateWatchRideId = 9797, kPeepSpriteJuiceStateSittingIdleId = 9749, - kPeepSpriteFunnelCakeStateNoneId = 9845, + kPeepSpriteFunnelCakeStateWalkingId = 9845, kPeepSpriteFunnelCakeStateWatchRideId = 9965, kPeepSpriteFunnelCakeStateSittingIdleId = 9917, - kPeepSpriteNoodlesStateNoneId = 10013, + kPeepSpriteNoodlesStateWalkingId = 10013, kPeepSpriteNoodlesStateWatchRideId = 10133, kPeepSpriteNoodlesStateSittingIdleId = 10085, - kPeepSpriteSausageStateNoneId = 10181, + kPeepSpriteSausageStateWalkingId = 10181, kPeepSpriteSausageStateWatchRideId = 10301, kPeepSpriteSausageStateSittingIdleId = 10253, - kPeepSpriteSoupStateNoneId = 10349, + kPeepSpriteSoupStateWalkingId = 10349, kPeepSpriteSoupStateWatchRideId = 10469, kPeepSpriteSoupStateSittingIdleId = 10421, - kPeepSpriteSandwichStateNoneId = 10517, + kPeepSpriteSandwichStateWalkingId = 10517, kPeepSpriteSandwichStateWatchRideId = 10637, kPeepSpriteSandwichStateSittingIdleId = 10589, }; diff --git a/src/openrct2/scripting/bindings/entity/ScGuest.cpp b/src/openrct2/scripting/bindings/entity/ScGuest.cpp index fec22eebc9..4e7a451fca 100644 --- a/src/openrct2/scripting/bindings/entity/ScGuest.cpp +++ b/src/openrct2/scripting/bindings/entity/ScGuest.cpp @@ -148,7 +148,7 @@ namespace OpenRCT2::Scripting }); static const DukEnumMap availableGuestAnimations({ - { "walking", PeepAnimationType::None }, + { "walking", PeepAnimationType::Walking }, { "checkTime", PeepAnimationType::CheckTime }, { "watchRide", PeepAnimationType::WatchRide }, { "eatFood", PeepAnimationType::EatFood }, @@ -921,7 +921,7 @@ namespace OpenRCT2::Scripting // Special consideration for sitting peeps // TODO: something funky going on in the state machine - if (peep->AnimationType == PeepAnimationType::None && peep->State == PeepState::Sitting) + if (peep->AnimationType == PeepAnimationType::Walking && peep->State == PeepState::Sitting) action = availableGuestAnimations[PeepAnimationType::SittingIdle]; return std::string(action); diff --git a/src/openrct2/scripting/bindings/entity/ScStaff.cpp b/src/openrct2/scripting/bindings/entity/ScStaff.cpp index 8123de9f37..6df3274d85 100644 --- a/src/openrct2/scripting/bindings/entity/ScStaff.cpp +++ b/src/openrct2/scripting/bindings/entity/ScStaff.cpp @@ -18,7 +18,7 @@ namespace OpenRCT2::Scripting { static const DukEnumMap availableHandymanAnimations({ - { "walking", PeepAnimationType::None }, + { "walking", PeepAnimationType::Walking }, { "watchRide", PeepAnimationType::WatchRide }, { "hanging", PeepAnimationType::Hanging }, { "staffMower", PeepAnimationType::StaffMower }, @@ -29,7 +29,7 @@ namespace OpenRCT2::Scripting }); static const DukEnumMap availableMechanicAnimations({ - { "walking", PeepAnimationType::None }, + { "walking", PeepAnimationType::Walking }, { "watchRide", PeepAnimationType::WatchRide }, { "hanging", PeepAnimationType::Hanging }, { "drowning", PeepAnimationType::Drowning }, @@ -43,14 +43,14 @@ namespace OpenRCT2::Scripting }); static const DukEnumMap availableSecurityAnimations({ - { "walking", PeepAnimationType::None }, + { "walking", PeepAnimationType::Walking }, { "watchRide", PeepAnimationType::WatchRide }, { "hanging", PeepAnimationType::Hanging }, { "drowning", PeepAnimationType::Drowning }, }); static const DukEnumMap availableEntertainerAnimations({ - { "walking", PeepAnimationType::None }, + { "walking", PeepAnimationType::Walking }, { "watchRide", PeepAnimationType::WatchRide }, { "wave", PeepAnimationType::EatFood }, // NB: this not a typo { "hanging", PeepAnimationType::Hanging }, @@ -136,7 +136,7 @@ namespace OpenRCT2::Scripting // Reset state to walking to prevent invalid actions from carrying over peep->Action = PeepActionType::Walking; - peep->AnimationType = peep->NextAnimationType = PeepAnimationType::None; + peep->AnimationType = peep->NextAnimationType = PeepAnimationType::Walking; } } From 53d1c27771ad2161330ab43399ae7783a9b234d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:46:44 +0200 Subject: [PATCH 120/139] Fix a few more missing callback misuses --- src/openrct2-ui/WindowManager.cpp | 4 ++-- src/openrct2/Editor.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 07e85644d9..4c9fc87aa3 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -247,7 +247,7 @@ public: uint32_t type = intent->GetUIntExtra(INTENT_EXTRA_LOADSAVE_TYPE); std::string defaultName = intent->GetStringExtra(INTENT_EXTRA_PATH); loadsave_callback callback = reinterpret_cast( - intent->GetPointerExtra(INTENT_EXTRA_CALLBACK)); + intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK)); TrackDesign* trackDesign = static_cast(intent->GetPointerExtra(INTENT_EXTRA_TRACK_DESIGN)); auto* w = LoadsaveOpen( type, defaultName, @@ -294,7 +294,7 @@ public: } case WindowClass::ScenarioSelect: return ScenarioselectOpen( - reinterpret_cast(intent->GetPointerExtra(INTENT_EXTRA_CALLBACK))); + reinterpret_cast(intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK))); case WindowClass::Null: // Intent does not hold a window class diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 58ab763afc..8e05fd3d61 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -128,7 +128,7 @@ namespace OpenRCT2::Editor ToolCancel(); auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(ConvertSaveToScenarioCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(ConvertSaveToScenarioCallback)); ContextOpenIntent(&intent); } From 9dfd4f3b1935852650d6b2d9f3d3c09394975d2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 20:43:55 +0200 Subject: [PATCH 121/139] Rename the callback types --- src/openrct2-ui/WindowManager.cpp | 8 ++++---- src/openrct2-ui/windows/MapGen.cpp | 2 +- src/openrct2-ui/windows/NetworkStatus.cpp | 6 +++--- src/openrct2-ui/windows/ProgressWindow.cpp | 6 +++--- src/openrct2-ui/windows/Ride.cpp | 2 +- src/openrct2-ui/windows/SavePrompt.cpp | 2 +- src/openrct2-ui/windows/ScenarioSelect.cpp | 2 +- src/openrct2-ui/windows/ServerStart.cpp | 2 +- src/openrct2-ui/windows/Window.h | 10 +++++----- src/openrct2/Editor.cpp | 2 +- src/openrct2/Game.cpp | 4 ++-- src/openrct2/interface/Window.h | 2 +- src/openrct2/windows/Intent.cpp | 6 +++--- src/openrct2/windows/Intent.h | 6 +++--- 14 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/openrct2-ui/WindowManager.cpp b/src/openrct2-ui/WindowManager.cpp index 4c9fc87aa3..dfdf3684dd 100644 --- a/src/openrct2-ui/WindowManager.cpp +++ b/src/openrct2-ui/WindowManager.cpp @@ -246,7 +246,7 @@ public: { uint32_t type = intent->GetUIntExtra(INTENT_EXTRA_LOADSAVE_TYPE); std::string defaultName = intent->GetStringExtra(INTENT_EXTRA_PATH); - loadsave_callback callback = reinterpret_cast( + LoadSaveCallback callback = reinterpret_cast( intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK)); TrackDesign* trackDesign = static_cast(intent->GetPointerExtra(INTENT_EXTRA_TRACK_DESIGN)); auto* w = LoadsaveOpen( @@ -265,7 +265,7 @@ public: case WindowClass::NetworkStatus: { std::string message = intent->GetStringExtra(INTENT_EXTRA_MESSAGE); - close_callback callback = intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK); + CloseCallback callback = intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK); return NetworkStatusOpen(message, callback); } case WindowClass::ObjectLoadError: @@ -294,7 +294,7 @@ public: } case WindowClass::ScenarioSelect: return ScenarioselectOpen( - reinterpret_cast(intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK))); + reinterpret_cast(intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK))); case WindowClass::Null: // Intent does not hold a window class @@ -335,7 +335,7 @@ public: case INTENT_ACTION_PROGRESS_OPEN: { std::string message = intent->GetStringExtra(INTENT_EXTRA_MESSAGE); - close_callback callback = intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK); + CloseCallback callback = intent->GetCloseCallbackExtra(INTENT_EXTRA_CALLBACK); return ProgressWindowOpen(message, callback); } diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index 7efcea20e2..5f9160fe1d 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -942,7 +942,7 @@ namespace OpenRCT2::Ui::Windows { auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_HEIGHTMAP); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(HeightmapLoadsaveCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(HeightmapLoadsaveCallback)); ContextOpenIntent(&intent); return; } diff --git a/src/openrct2-ui/windows/NetworkStatus.cpp b/src/openrct2-ui/windows/NetworkStatus.cpp index a42c262512..50255cd6b5 100644 --- a/src/openrct2-ui/windows/NetworkStatus.cpp +++ b/src/openrct2-ui/windows/NetworkStatus.cpp @@ -110,7 +110,7 @@ namespace OpenRCT2::Ui::Windows DrawText(dpi, screenCoords, { COLOUR_BLACK }, _buffer.c_str()); } - void SetCloseCallBack(close_callback onClose) + void SetCloseCallBack(CloseCallback onClose) { _onClose = onClose; } @@ -127,12 +127,12 @@ namespace OpenRCT2::Ui::Windows } private: - close_callback _onClose = nullptr; + CloseCallback _onClose = nullptr; std::string _windowNetworkStatusText; std::string _password; }; - WindowBase* NetworkStatusOpen(const std::string& text, close_callback onClose) + WindowBase* NetworkStatusOpen(const std::string& text, CloseCallback onClose) { ContextForceCloseWindowByClass(WindowClass::ProgressWindow); diff --git a/src/openrct2-ui/windows/ProgressWindow.cpp b/src/openrct2-ui/windows/ProgressWindow.cpp index 0ca872e532..2866eddc16 100644 --- a/src/openrct2-ui/windows/ProgressWindow.cpp +++ b/src/openrct2-ui/windows/ProgressWindow.cpp @@ -70,7 +70,7 @@ namespace OpenRCT2::Ui::Windows class ProgressWindow final : public Window { private: - close_callback _onClose = nullptr; + CloseCallback _onClose = nullptr; StringId _progressFormat; std::string _progressTitle; @@ -213,7 +213,7 @@ namespace OpenRCT2::Ui::Windows Invalidate(); } - void SetCloseCallback(close_callback onClose) + void SetCloseCallback(CloseCallback onClose) { _onClose = onClose; } @@ -231,7 +231,7 @@ namespace OpenRCT2::Ui::Windows } }; - WindowBase* ProgressWindowOpen(const std::string& text, close_callback onClose) + WindowBase* ProgressWindowOpen(const std::string& text, CloseCallback onClose) { ContextForceCloseWindowByClass(WindowClass::NetworkStatus); diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index e364906851..4e89347cd3 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -5456,7 +5456,7 @@ namespace OpenRCT2::Ui::Windows intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_SAVE | LOADSAVETYPE_TRACK); intent.PutExtra(INTENT_EXTRA_TRACK_DESIGN, _trackDesign.get()); intent.PutExtra(INTENT_EXTRA_PATH, trackName); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(&TrackDesignCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(&TrackDesignCallback)); ContextOpenIntent(&intent); } diff --git a/src/openrct2-ui/windows/SavePrompt.cpp b/src/openrct2-ui/windows/SavePrompt.cpp index b286a59adf..c268854c97 100644 --- a/src/openrct2-ui/windows/SavePrompt.cpp +++ b/src/openrct2-ui/windows/SavePrompt.cpp @@ -173,7 +173,7 @@ namespace OpenRCT2::Ui::Windows intent = CreateSaveGameAsIntent(); } Close(); - intent->PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(WindowSavePromptCallback)); + intent->PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(WindowSavePromptCallback)); ContextOpenIntent(intent.get()); break; } diff --git a/src/openrct2-ui/windows/ScenarioSelect.cpp b/src/openrct2-ui/windows/ScenarioSelect.cpp index 8c4ab4d378..1b7aa88986 100644 --- a/src/openrct2-ui/windows/ScenarioSelect.cpp +++ b/src/openrct2-ui/windows/ScenarioSelect.cpp @@ -761,7 +761,7 @@ namespace OpenRCT2::Ui::Windows } }; - WindowBase* ScenarioselectOpen(scenarioselect_callback callback) + WindowBase* ScenarioselectOpen(ScenarioSelectCallback callback) { return ScenarioselectOpen([callback](std::string_view scenario) { callback(std::string(scenario).c_str()); }); } diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index d38a4cfd6a..dc851cb5ea 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -139,7 +139,7 @@ namespace OpenRCT2::Ui::Windows NetworkSetPassword(_password); auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(LoadSaveCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(LoadSaveCallback)); ContextOpenIntent(&intent); break; } diff --git a/src/openrct2-ui/windows/Window.h b/src/openrct2-ui/windows/Window.h index aaf44d7a81..75b39767ca 100644 --- a/src/openrct2-ui/windows/Window.h +++ b/src/openrct2-ui/windows/Window.h @@ -24,8 +24,8 @@ struct Vehicle; enum class GuestListFilterType : int32_t; enum class ScatterToolDensity : uint8_t; -using loadsave_callback = void (*)(int32_t result, const utf8* path); -using scenarioselect_callback = void (*)(const utf8* path); +using LoadSaveCallback = void (*)(int32_t result, const utf8* path); +using ScenarioSelectCallback = void (*)(const utf8* path); namespace OpenRCT2::Ui::Windows { @@ -118,7 +118,7 @@ namespace OpenRCT2::Ui::Windows WindowBase* GuestListOpen(); WindowBase* GuestListOpenWithFilter(GuestListFilterType type, int32_t index); WindowBase* StaffFirePromptOpen(Peep* peep); - WindowBase* ScenarioselectOpen(scenarioselect_callback callback); + WindowBase* ScenarioselectOpen(ScenarioSelectCallback callback); WindowBase* ScenarioselectOpen(std::function callback); WindowBase* ErrorOpen(StringId title, StringId message, const class Formatter& formatter, bool autoClose = false); @@ -174,11 +174,11 @@ namespace OpenRCT2::Ui::Windows WindowBase* MazeConstructionOpen(); void WindowMazeConstructionUpdatePressedWidgets(); - WindowBase* NetworkStatusOpen(const std::string& text, close_callback onClose); + WindowBase* NetworkStatusOpen(const std::string& text, CloseCallback onClose); WindowBase* NetworkStatusOpenPassword(); void WindowNetworkStatusClose(); - WindowBase* ProgressWindowOpen(const std::string& text, close_callback onClose = nullptr); + WindowBase* ProgressWindowOpen(const std::string& text, CloseCallback onClose = nullptr); void ProgressWindowSet(uint32_t currentProgress, uint32_t totalCount, StringId format = STR_NONE); void ProgressWindowClose(); diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 8e05fd3d61..80560a2a2d 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -128,7 +128,7 @@ namespace OpenRCT2::Editor ToolCancel(); auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(ConvertSaveToScenarioCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(ConvertSaveToScenarioCallback)); ContextOpenIntent(&intent); } diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index f77124cc5c..444b9b3890 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -654,7 +654,7 @@ void GameLoadOrQuitNoSavePrompt() { auto intent = Intent(WindowClass::Loadsave); intent.PutExtra(INTENT_EXTRA_LOADSAVE_TYPE, LOADSAVETYPE_LOAD | LOADSAVETYPE_GAME); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(GameLoadOrQuitNoSavePromptCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(GameLoadOrQuitNoSavePromptCallback)); ContextOpenIntent(&intent); } break; @@ -683,7 +683,7 @@ void GameLoadOrQuitNoSavePrompt() GameActions::Execute(&loadOrQuitAction); ToolCancel(); auto intent = Intent(WindowClass::ScenarioSelect); - intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(NewGameWindowCallback)); + intent.PutExtra(INTENT_EXTRA_CALLBACK, reinterpret_cast(NewGameWindowCallback)); ContextOpenIntent(&intent); break; } diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 7595214fe3..e01bb155e3 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -445,7 +445,7 @@ extern Tool gCurrentToolId; extern WidgetRef gCurrentToolWidget; using modal_callback = void (*)(int32_t result); -using close_callback = void (*)(); +using CloseCallback = void (*)(); constexpr int8_t kWindowLimitMin = 4; constexpr int8_t kWindowLimitMax = 64; diff --git a/src/openrct2/windows/Intent.cpp b/src/openrct2/windows/Intent.cpp index 2dd7e6aa3e..81c70ce823 100644 --- a/src/openrct2/windows/Intent.cpp +++ b/src/openrct2/windows/Intent.cpp @@ -82,7 +82,7 @@ Intent* Intent::PutExtra(uint32_t key, std::string value) return this; } -Intent* Intent::PutExtra(uint32_t key, close_callback value) +Intent* Intent::PutExtra(uint32_t key, CloseCallback value) { putExtraImpl(_Data, key, value); return this; @@ -123,7 +123,7 @@ std::string Intent::GetStringExtra(uint32_t key) const return getExtraImpl(_Data, key); } -close_callback Intent::GetCloseCallbackExtra(uint32_t key) const +CloseCallback Intent::GetCloseCallbackExtra(uint32_t key) const { - return getExtraImpl(_Data, key); + return getExtraImpl(_Data, key); } diff --git a/src/openrct2/windows/Intent.h b/src/openrct2/windows/Intent.h index 6983010a97..bafa710594 100644 --- a/src/openrct2/windows/Intent.h +++ b/src/openrct2/windows/Intent.h @@ -62,7 +62,7 @@ enum IntentAction // The maximum amount of data the Intent can hold, 8 should be sufficient, raise this if needed. static constexpr size_t kIntentMaxDataSlots = 8; -using IntentData = std::variant; +using IntentData = std::variant; using IntentDataEntry = std::pair; using IntentDataStorage = sfl::static_vector; @@ -86,13 +86,13 @@ public: std::string GetStringExtra(uint32_t key) const; uint32_t GetUIntExtra(uint32_t key) const; int32_t GetSIntExtra(uint32_t key) const; - close_callback GetCloseCallbackExtra(uint32_t key) const; + CloseCallback GetCloseCallbackExtra(uint32_t key) const; Intent* PutExtra(uint32_t key, uint32_t value); Intent* PutExtra(uint32_t key, void* value); Intent* PutExtra(uint32_t key, int32_t value); Intent* PutExtra(uint32_t key, std::string value); - Intent* PutExtra(uint32_t key, close_callback value); + Intent* PutExtra(uint32_t key, CloseCallback value); template Intent* PutExtra(uint32_t key, const TIdentifier& value) From 0cb81e4dcb805bbd6313aced562df688a7126a29 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 4 Dec 2024 20:16:56 +0100 Subject: [PATCH 122/139] Rename util/Prefetch.h to platform/Memory.h (#23320) --- src/openrct2/libopenrct2.vcxproj | 2 +- src/openrct2/paint/Paint.cpp | 2 +- src/openrct2/{util/Prefetch.h => platform/Memory.h} | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) rename src/openrct2/{util/Prefetch.h => platform/Memory.h} (99%) diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index f115df0039..597f07f2ec 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -396,6 +396,7 @@ + @@ -598,7 +599,6 @@ - diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index b52aa7a68e..3a60893a02 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -19,9 +19,9 @@ #include "../localisation/Formatting.h" #include "../localisation/LocalisationService.h" #include "../paint/Painter.h" +#include "../platform/Memory.h" #include "../profiling/Profiling.h" #include "../util/Math.hpp" -#include "../util/Prefetch.h" #include "Boundbox.h" #include "Paint.Entity.h" #include "tile_element/Paint.TileElement.h" diff --git a/src/openrct2/util/Prefetch.h b/src/openrct2/platform/Memory.h similarity index 99% rename from src/openrct2/util/Prefetch.h rename to src/openrct2/platform/Memory.h index 146c0800e1..37b2c9016f 100644 --- a/src/openrct2/util/Prefetch.h +++ b/src/openrct2/platform/Memory.h @@ -7,6 +7,8 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#pragma once + #if defined(__amd64__) || defined(_M_AMD64) || defined(__i386__) || defined(_M_IX86) // Don't bother checking for CPUID, prefetch is available since Pentium 4 #include From 2c6c1161edf3be3265b99c03c8706a56e0e806f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 21:16:59 +0200 Subject: [PATCH 123/139] Remove copying the list of windows, no longer required --- src/openrct2/interface/Window.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index cbc7a730f4..9522898e41 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -94,8 +94,7 @@ std::list>::iterator WindowGetIterator(const WindowB void WindowVisitEach(std::function func) { - auto windowList = g_window_list; - for (auto& w : windowList) + for (auto& w : g_window_list) { if (w->flags & WF_DEAD) continue; From ba30f781f4fcc931a2287ca2363e68ff2675dbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Wed, 4 Dec 2024 21:18:25 +0200 Subject: [PATCH 124/139] Remove WindowFlushDead, shouldn't be used directly --- src/openrct2/interface/Window.cpp | 9 ++------- src/openrct2/interface/Window.h | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index 9522898e41..300ac9a1db 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -141,7 +141,8 @@ void WindowUpdateAllViewports() */ void WindowUpdateAll() { - WindowFlushDead(); + // Remove all windows in g_window_list that have the WF_DEAD flag + g_window_list.remove_if([](auto&& w) -> bool { return w->flags & WF_DEAD; }); // Periodic update happens every second so 40 ticks. if (gCurrentRealTimeTicks >= gWindowUpdateTicks) @@ -237,12 +238,6 @@ void WindowClose(WindowBase& w) w.flags |= WF_DEAD; } -void WindowFlushDead() -{ - // Remove all windows in g_window_list that have the WF_DEAD flag - g_window_list.remove_if([](auto&& w) -> bool { return w->flags & WF_DEAD; }); -} - template static void WindowCloseByCondition(TPred pred, uint32_t flags = WindowCloseFlags::None) { diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index e01bb155e3..f9d38390b7 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -475,7 +475,6 @@ WindowBase* WindowBringToFrontByClassWithFlags(WindowClass cls, uint16_t flags); WindowBase* WindowBringToFrontByNumber(WindowClass cls, rct_windownumber number); void WindowClose(WindowBase& window); -void WindowFlushDead(); void WindowCloseByClass(WindowClass cls); void WindowCloseByNumber(WindowClass cls, rct_windownumber number); void WindowCloseByNumber(WindowClass cls, EntityId number); From b3aa852a8d91be0a5d56a4ea3c86fe97e9193697 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Wed, 4 Dec 2024 22:00:26 +0100 Subject: [PATCH 125/139] Consolidate util/Math.hpp into core/Numerics.hpp (#23319) * Consolidate util/Math.hpp into core/Numerics.hpp * Remove branching; replace isPowerOf2 with std::has_single_bit * Add templated types to floor2 and ceil2 --- src/openrct2-ui/windows/Footpath.cpp | 8 ++-- src/openrct2-ui/windows/GuestList.cpp | 8 ++-- src/openrct2-ui/windows/RideConstruction.cpp | 9 +++-- src/openrct2-ui/windows/Scenery.cpp | 4 +- src/openrct2-ui/windows/Staff.cpp | 9 +++-- src/openrct2-ui/windows/TopToolbar.cpp | 4 +- src/openrct2-ui/windows/TrackDesignPlace.cpp | 9 +++-- src/openrct2/actions/LandSetRightsAction.cpp | 5 ++- .../actions/SmallSceneryPlaceAction.cpp | 5 ++- src/openrct2/actions/TrackPlaceAction.cpp | 10 ++--- src/openrct2/core/Numerics.hpp | 19 ++++++++++ src/openrct2/entity/EntityRegistry.h | 1 + src/openrct2/entity/Guest.cpp | 10 ++--- src/openrct2/entity/MoneyEffect.h | 2 + src/openrct2/interface/Viewport.cpp | 5 ++- src/openrct2/libopenrct2.vcxproj | 1 - src/openrct2/object/RideObject.cpp | 3 +- src/openrct2/paint/Paint.cpp | 13 ++++--- src/openrct2/paint/support/MetalSupports.cpp | 7 ++-- src/openrct2/paint/support/WoodenSupports.cpp | 3 +- .../paint/tile_element/Paint.LargeScenery.cpp | 3 +- .../paint/tile_element/Paint.SmallScenery.cpp | 3 +- .../paint/track/thrill/Enterprise.cpp | 3 +- src/openrct2/util/Math.hpp | 37 ------------------- src/openrct2/util/Util.h | 5 --- src/openrct2/world/Location.hpp | 14 +++++-- 26 files changed, 103 insertions(+), 97 deletions(-) delete mode 100644 src/openrct2/util/Math.hpp diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 45e8ec2bd4..6b4a28726e 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -44,6 +44,8 @@ #include #include +using namespace OpenRCT2::Numerics; + namespace OpenRCT2::Ui::Windows { static money64 FootpathProvisionalSet( @@ -824,7 +826,7 @@ namespace OpenRCT2::Ui::Windows const bool allowInvalidHeights = GetGameState().Cheats.allowTrackPlaceInvalidHeights; const auto heightStep = kCoordsZStep * (!allowInvalidHeights ? 2 : 1); - _footpathPlaceCtrlZ = Floor2(info.Element->GetBaseZ(), heightStep); + _footpathPlaceCtrlZ = floor2(info.Element->GetBaseZ(), heightStep); _footpathPlaceCtrlState = true; } } @@ -856,7 +858,7 @@ namespace OpenRCT2::Ui::Windows const bool allowInvalidHeights = GetGameState().Cheats.allowTrackPlaceInvalidHeights; const auto heightStep = kCoordsZStep * (!allowInvalidHeights ? 2 : 1); - _footpathPlaceShiftZ = Floor2(_footpathPlaceShiftZ, heightStep); + _footpathPlaceShiftZ = floor2(_footpathPlaceShiftZ, heightStep); // Clamp to maximum possible value of BaseHeight can offer. _footpathPlaceShiftZ = std::min(_footpathPlaceShiftZ, maxHeight); @@ -886,7 +888,7 @@ namespace OpenRCT2::Ui::Windows if (surfaceElement == nullptr) return std::nullopt; - auto mapZ = Floor2(surfaceElement->GetBaseZ(), 16); + auto mapZ = floor2(surfaceElement->GetBaseZ(), 16); mapZ += _footpathPlaceShiftZ; mapZ = std::max(mapZ, 16); _footpathPlaceZ = mapZ; diff --git a/src/openrct2-ui/windows/GuestList.cpp b/src/openrct2-ui/windows/GuestList.cpp index e873bbf185..aa288bae2f 100644 --- a/src/openrct2-ui/windows/GuestList.cpp +++ b/src/openrct2-ui/windows/GuestList.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,11 +26,12 @@ #include #include #include -#include #include #include #include +using namespace OpenRCT2::Numerics; + namespace OpenRCT2::Ui::Windows { static constexpr StringId WINDOW_TITLE = STR_GUESTS; @@ -815,7 +817,7 @@ namespace OpenRCT2::Ui::Windows bool IsRefreshOfGroupsRequired() { - uint32_t tick256 = Floor2(GetGameState().CurrentTicks, 256); + uint32_t tick256 = floor2(GetGameState().CurrentTicks, 256); if (_selectedView == _lastFindGroupsSelectedView) { if (_lastFindGroupsWait != 0 || _lastFindGroupsTick == tick256) @@ -843,7 +845,7 @@ namespace OpenRCT2::Ui::Windows void RefreshGroups() { - _lastFindGroupsTick = Floor2(GetGameState().CurrentTicks, 256); + _lastFindGroupsTick = floor2(GetGameState().CurrentTicks, 256); _lastFindGroupsSelectedView = _selectedView; _lastFindGroupsWait = 320; _groups.clear(); diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 40fd197018..b69fc7834c 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -58,6 +58,7 @@ constexpr int8_t kDefaultSpeedIncrement = 2; constexpr int8_t kDefaultMinimumSpeed = 2; +using namespace OpenRCT2::Numerics; using namespace OpenRCT2::TrackMetaData; namespace OpenRCT2::Ui::Windows @@ -2994,7 +2995,7 @@ namespace OpenRCT2::Ui::Windows { _trackPlaceShiftZ = mainWnd->viewport->zoom.ApplyTo(_trackPlaceShiftZ); } - _trackPlaceShiftZ = Floor2(_trackPlaceShiftZ, 8); + _trackPlaceShiftZ = floor2(_trackPlaceShiftZ, 8); // Clamp to maximum possible value of BaseHeight can offer. _trackPlaceShiftZ = std::min(_trackPlaceShiftZ, maxHeight); @@ -3019,7 +3020,7 @@ namespace OpenRCT2::Ui::Windows auto surfaceElement = MapGetSurfaceElementAt(mapCoords); if (surfaceElement == nullptr) return std::nullopt; - auto mapZ = Floor2(surfaceElement->GetBaseZ(), 16); + auto mapZ = floor2(surfaceElement->GetBaseZ(), 16); mapZ += _trackPlaceShiftZ; mapZ = std::max(mapZ, 16); _trackPlaceZ = mapZ; @@ -4600,7 +4601,7 @@ namespace OpenRCT2::Ui::Windows { if (_gotoStartPlacementMode) { - _currentTrackBegin.z = Floor2(piecePos.z, kCoordsZStep); + _currentTrackBegin.z = floor2(piecePos.z, kCoordsZStep); _rideConstructionState = RideConstructionState::Front; _currentTrackSelectionFlags = 0; _currentTrackPieceDirection = piecePos.direction & 3; diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index 958a14e3b8..3804434ac6 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -60,6 +60,8 @@ #include #include +using namespace OpenRCT2::Numerics; + namespace OpenRCT2::Ui::Windows { static constexpr StringId WINDOW_TITLE = STR_NONE; @@ -2422,7 +2424,7 @@ namespace OpenRCT2::Ui::Windows { gSceneryShiftPressZOffset = mainWnd->viewport->zoom.ApplyTo(gSceneryShiftPressZOffset); } - gSceneryShiftPressZOffset = Floor2(gSceneryShiftPressZOffset, 8); + gSceneryShiftPressZOffset = floor2(gSceneryShiftPressZOffset, 8); screenPos.x = gSceneryShiftPressX; screenPos.y = gSceneryShiftPressY; diff --git a/src/openrct2-ui/windows/Staff.cpp b/src/openrct2-ui/windows/Staff.cpp index 62ea364b92..6558fda86d 100644 --- a/src/openrct2-ui/windows/Staff.cpp +++ b/src/openrct2-ui/windows/Staff.cpp @@ -7,11 +7,10 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#include "../interface/Theme.h" -#include "../interface/ViewportQuery.h" - #include +#include #include +#include #include #include #include @@ -36,6 +35,8 @@ #include #include +using namespace OpenRCT2::Numerics; + namespace OpenRCT2::Ui::Windows { static constexpr StringId WINDOW_TITLE = STR_STRINGID; @@ -582,7 +583,7 @@ namespace OpenRCT2::Ui::Windows if (page == WINDOW_STAFF_OVERVIEW) { offset = _tabAnimationOffset; - offset = Floor2(offset, 4); + offset = floor2(offset, 4); } imageIndex += offset; diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 2641aecd93..998f69f2e7 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -43,13 +44,14 @@ #include #include #include -#include #include #include #include #include #include +using namespace OpenRCT2::Numerics; + namespace OpenRCT2::Ui::Windows { enum diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index a4dad85240..02db21bcf3 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -37,6 +37,7 @@ #include #include +using namespace OpenRCT2::Numerics; using namespace OpenRCT2::TrackMetaData; namespace OpenRCT2::Ui::Windows @@ -466,7 +467,7 @@ namespace OpenRCT2::Ui::Windows auto info = GetMapCoordinatesFromPos(screenCoords, interactionFlags); if (info.interactionType == ViewportInteractionItem::Terrain) { - _trackPlaceCtrlZ = Floor2(surfaceElement->GetBaseZ(), kCoordsZStep); + _trackPlaceCtrlZ = floor2(surfaceElement->GetBaseZ(), kCoordsZStep); // Increase Z above water if (surfaceElement->GetWaterHeight() > 0) @@ -474,7 +475,7 @@ namespace OpenRCT2::Ui::Windows } else { - _trackPlaceCtrlZ = Floor2(info.Element->GetBaseZ(), kCoordsZStep); + _trackPlaceCtrlZ = floor2(info.Element->GetBaseZ(), kCoordsZStep); } _trackPlaceCtrlState = true; @@ -504,7 +505,7 @@ namespace OpenRCT2::Ui::Windows _trackPlaceShiftZ = mainWnd->viewport->zoom.ApplyTo(_trackPlaceShiftZ); // Floor to closest kCoordsZStep - _trackPlaceShiftZ = Floor2(_trackPlaceShiftZ, kCoordsZStep); + _trackPlaceShiftZ = floor2(_trackPlaceShiftZ, kCoordsZStep); // Clamp to maximum possible value of BaseHeight can offer. _trackPlaceShiftZ = std::min(_trackPlaceShiftZ, maxHeight); @@ -517,7 +518,7 @@ namespace OpenRCT2::Ui::Windows if (!_trackPlaceCtrlState) { - _trackPlaceZ = Floor2(surfaceElement->GetBaseZ(), kCoordsZStep); + _trackPlaceZ = floor2(surfaceElement->GetBaseZ(), kCoordsZStep); // Increase Z above water if (surfaceElement->GetWaterHeight() > 0) diff --git a/src/openrct2/actions/LandSetRightsAction.cpp b/src/openrct2/actions/LandSetRightsAction.cpp index 152b9d6f75..5a2a82e6f6 100644 --- a/src/openrct2/actions/LandSetRightsAction.cpp +++ b/src/openrct2/actions/LandSetRightsAction.cpp @@ -15,11 +15,11 @@ #include "../OpenRCT2.h" #include "../actions/LandSetHeightAction.h" #include "../audio/audio.h" +#include "../core/Numerics.hpp" #include "../interface/Window.h" #include "../localisation/StringIds.h" #include "../management/Finance.h" #include "../ride/RideData.h" -#include "../util/Math.hpp" #include "../windows/Intent.h" #include "../world/Park.h" #include "../world/Scenery.h" @@ -28,6 +28,7 @@ #include "../world/tile_element/SurfaceElement.h" using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; LandSetRightsAction::LandSetRightsAction(const MapRange& range, LandSetRightSetting setting, uint8_t ownership) : _range(range) @@ -220,7 +221,7 @@ GameActions::Result LandSetRightsAction::MapBuyLandRightsForTile(const CoordsXY& std::remove_if( gameState.PeepSpawns.begin(), gameState.PeepSpawns.end(), [x = loc.x, y = loc.y](const auto& spawn) { - return Floor2(spawn.x, 32) == x && Floor2(spawn.y, 32) == y; + return floor2(spawn.x, 32) == x && floor2(spawn.y, 32) == y; }), gameState.PeepSpawns.end()); } diff --git a/src/openrct2/actions/SmallSceneryPlaceAction.cpp b/src/openrct2/actions/SmallSceneryPlaceAction.cpp index a552a43860..176d054fb7 100644 --- a/src/openrct2/actions/SmallSceneryPlaceAction.cpp +++ b/src/openrct2/actions/SmallSceneryPlaceAction.cpp @@ -35,6 +35,7 @@ #include "SmallSceneryRemoveAction.h" using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; SmallSceneryPlaceAction::SmallSceneryPlaceAction( const CoordsXYZD& loc, uint8_t quadrant, ObjectEntryIndex sceneryType, uint8_t primaryColour, uint8_t secondaryColour, @@ -235,7 +236,7 @@ GameActions::Result SmallSceneryPlaceAction::Query() const } int32_t zLow = targetHeight; - int32_t zHigh = zLow + Ceil2(sceneryEntry->height, kCoordsZStep); + int32_t zHigh = zLow + ceil2(sceneryEntry->height, kCoordsZStep); uint8_t collisionQuadrants = 0b1111; auto quadRotation{ 0 }; if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))) @@ -374,7 +375,7 @@ GameActions::Result SmallSceneryPlaceAction::Execute() const } int32_t zLow = targetHeight; - int32_t zHigh = zLow + Ceil2(sceneryEntry->height, 8); + int32_t zHigh = zLow + ceil2(sceneryEntry->height, 8); uint8_t collisionQuadrants = 0b1111; auto quadRotation{ 0 }; if (!(sceneryEntry->HasFlag(SMALL_SCENERY_FLAG_FULL_TILE))) diff --git a/src/openrct2/actions/TrackPlaceAction.cpp b/src/openrct2/actions/TrackPlaceAction.cpp index cbb5ea7ed2..9562536028 100644 --- a/src/openrct2/actions/TrackPlaceAction.cpp +++ b/src/openrct2/actions/TrackPlaceAction.cpp @@ -17,7 +17,6 @@ #include "../ride/Track.h" #include "../ride/TrackData.h" #include "../ride/TrackDesign.h" -#include "../util/Math.hpp" #include "../world/ConstructionClearance.h" #include "../world/Footpath.h" #include "../world/MapAnimation.h" @@ -30,6 +29,7 @@ #include "RideSetSettingAction.h" using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; using namespace OpenRCT2::TrackMetaData; TrackPlaceAction::TrackPlaceAction( @@ -247,7 +247,7 @@ GameActions::Result TrackPlaceAction::Query() const GameActions::Status::InvalidParameters, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_TOO_LOW); } - int32_t baseZ = Floor2(mapLoc.z, kCoordsZStep); + int32_t baseZ = floor2(mapLoc.z, kCoordsZStep); int32_t clearanceZ = trackBlock.clearanceZ; if (trackBlock.flags & RCT_PREVIEW_TRACK_FLAG_IS_VERTICAL && clearanceHeight > 24) @@ -259,7 +259,7 @@ GameActions::Result TrackPlaceAction::Query() const clearanceZ += clearanceHeight; } - clearanceZ = Floor2(clearanceZ, kCoordsZStep) + baseZ; + clearanceZ = floor2(clearanceZ, kCoordsZStep) + baseZ; if (clearanceZ > MAX_TRACK_HEIGHT) { @@ -467,7 +467,7 @@ GameActions::Result TrackPlaceAction::Execute() const auto quarterTile = trackBlock.quarterTile.Rotate(_origin.direction); - int32_t baseZ = Floor2(mapLoc.z, kCoordsZStep); + int32_t baseZ = floor2(mapLoc.z, kCoordsZStep); int32_t clearanceZ = trackBlock.clearanceZ; if (trackBlock.flags & RCT_PREVIEW_TRACK_FLAG_IS_VERTICAL && clearanceHeight > 24) { @@ -478,7 +478,7 @@ GameActions::Result TrackPlaceAction::Execute() const clearanceZ += clearanceHeight; } - clearanceZ = Floor2(clearanceZ, kCoordsZStep) + baseZ; + clearanceZ = floor2(clearanceZ, kCoordsZStep) + baseZ; const auto mapLocWithClearance = CoordsXYRangedZ(mapLoc, baseZ, clearanceZ); auto crossingMode = (rtd.HasFlag(RtdFlag::supportsLevelCrossings) && _trackType == TrackElemType::Flat) diff --git a/src/openrct2/core/Numerics.hpp b/src/openrct2/core/Numerics.hpp index 6eac9b37b6..2064ca0b5e 100644 --- a/src/openrct2/core/Numerics.hpp +++ b/src/openrct2/core/Numerics.hpp @@ -9,6 +9,8 @@ #pragma once +#include +#include #include #include #include @@ -64,6 +66,23 @@ namespace OpenRCT2::Numerics #endif } + // Rounds an integer down to the given power of 2. Alignment must be a power of 2. + template + constexpr T floor2(T value, size_t alignment) + { + // Ensure alignment is power of two or 0. + assert(alignment > 0 && std::has_single_bit(alignment)); + + return value & ~(alignment - 1); + } + + // Rounds an integer up to the given power of 2. Alignment must be a power of 2. + template + constexpr T ceil2(T value, size_t alignment) + { + return floor2(static_cast(value + alignment - 1), alignment); + } + /** * Bitwise left rotate * @tparam _UIntType unsigned integral type diff --git a/src/openrct2/entity/EntityRegistry.h b/src/openrct2/entity/EntityRegistry.h index a370f38f44..e3330c4cc4 100644 --- a/src/openrct2/entity/EntityRegistry.h +++ b/src/openrct2/entity/EntityRegistry.h @@ -12,6 +12,7 @@ #include "EntityBase.h" #include +#include namespace OpenRCT2 { diff --git a/src/openrct2/entity/Guest.cpp b/src/openrct2/entity/Guest.cpp index f18d52fd81..2aaa2d58ed 100644 --- a/src/openrct2/entity/Guest.cpp +++ b/src/openrct2/entity/Guest.cpp @@ -50,7 +50,6 @@ #include "../scripting/HookEngine.h" #include "../scripting/ScriptEngine.h" #include "../sprites.h" -#include "../util/Math.hpp" #include "../windows/Intent.h" #include "../world/Climate.h" #include "../world/Footpath.h" @@ -75,6 +74,7 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; // Locations of the spiral slide platform that a peep walks from the entrance of the ride to the // entrance of the slide. Up to 4 waypoints for each 4 sides that an ride entrance can be located @@ -1906,8 +1906,8 @@ OpenRCT2::BitSet Guest::FindRidesToGoOn() { // Take nearby rides into consideration constexpr auto radius = 10 * 32; - int32_t cx = Floor2(x, 32); - int32_t cy = Floor2(y, 32); + int32_t cx = floor2(x, 32); + int32_t cy = floor2(y, 32); for (int32_t tileX = cx - radius; tileX <= cx + radius; tileX += kCoordsXYStep) { for (int32_t tileY = cy - radius; tileY <= cy + radius; tileY += kCoordsXYStep) @@ -3182,8 +3182,8 @@ static void PeepHeadForNearestRide(Guest* peep, bool considerOnlyCloseRides, T p { // Take nearby rides into consideration constexpr auto searchRadius = 10 * 32; - int32_t cx = Floor2(peep->x, 32); - int32_t cy = Floor2(peep->y, 32); + int32_t cx = floor2(peep->x, 32); + int32_t cy = floor2(peep->y, 32); for (auto x = cx - searchRadius; x <= cx + searchRadius; x += kCoordsXYStep) { for (auto y = cy - searchRadius; y <= cy + searchRadius; y += kCoordsXYStep) diff --git a/src/openrct2/entity/MoneyEffect.h b/src/openrct2/entity/MoneyEffect.h index 1888d8f1d9..a083dbfd68 100644 --- a/src/openrct2/entity/MoneyEffect.h +++ b/src/openrct2/entity/MoneyEffect.h @@ -13,6 +13,8 @@ #include "../localisation/StringIdType.h" #include "EntityBase.h" +#include + class DataSerialiser; struct CoordsXYZ; struct PaintSession; diff --git a/src/openrct2/interface/Viewport.cpp b/src/openrct2/interface/Viewport.cpp index 067b939d35..1c388ce69d 100644 --- a/src/openrct2/interface/Viewport.cpp +++ b/src/openrct2/interface/Viewport.cpp @@ -18,6 +18,7 @@ #include "../config/Config.h" #include "../core/Guard.hpp" #include "../core/JobPool.h" +#include "../core/Numerics.hpp" #include "../drawing/Drawing.h" #include "../drawing/IDrawingEngine.h" #include "../entity/EntityList.h" @@ -35,7 +36,6 @@ #include "../ride/Vehicle.h" #include "../ui/UiContext.h" #include "../ui/WindowManager.h" -#include "../util/Math.hpp" #include "../world/Climate.h" #include "../world/Map.h" #include "../world/tile_element/LargeSceneryElement.h" @@ -51,6 +51,7 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; enum : uint8_t { @@ -1013,7 +1014,7 @@ static void ViewportPaint(const Viewport* viewport, DrawPixelInfo& dpi) const int32_t columnWidth = worldDpi.zoom_level.ApplyInversedTo(kCoordsXYStep); const int32_t rightBorder = worldDpi.x + worldDpi.width; - const int32_t alignedX = Floor2(worldDpi.x, columnWidth); + const int32_t alignedX = floor2(worldDpi.x, columnWidth); // Generate and sort columns. for (int32_t x = alignedX; x < rightBorder; x += columnWidth) diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 597f07f2ec..36a6b77798 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -598,7 +598,6 @@ - diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 11b734f86a..3b4696cd1c 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -37,6 +37,7 @@ using namespace OpenRCT2; using namespace OpenRCT2::Entity::Yaw; +using namespace OpenRCT2::Numerics; /* * The number of sprites in the sprite group is the specified precision multiplied by this number. General rule is any slope or @@ -878,7 +879,7 @@ CarEntry RideObject::ReadJsonCar([[maybe_unused]] IReadObjectContext* context, j auto numRotationFrames = Json::GetNumber(jRotationCount[SpriteGroupNames[i]], 0); if (numRotationFrames != 0) { - if (!IsPowerOf2(numRotationFrames)) + if (!std::has_single_bit(numRotationFrames)) { context->LogError(ObjectError::InvalidProperty, "spriteGroups values must be powers of 2"); continue; diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index 3a60893a02..dcbd52ef9e 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -13,6 +13,7 @@ #include "../config/Config.h" #include "../core/Guard.hpp" #include "../core/Money.hpp" +#include "../core/Numerics.hpp" #include "../drawing/Drawing.h" #include "../interface/Viewport.h" #include "../localisation/Currency.h" @@ -21,7 +22,6 @@ #include "../paint/Painter.h" #include "../platform/Memory.h" #include "../profiling/Profiling.h" -#include "../util/Math.hpp" #include "Boundbox.h" #include "Paint.Entity.h" #include "tile_element/Paint.TileElement.h" @@ -31,6 +31,7 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; // Globals for paint clipping uint8_t gClipHeight = 128; // Default to middle value @@ -220,7 +221,7 @@ template void PaintSessionGenerateRotate(PaintSession& session) { // Optimised modified version of ViewportPosToMapPos - ScreenCoordsXY screenCoord = { Floor2(session.DPI.WorldX(), 32), Floor2((session.DPI.WorldY() - 16), 32) }; + ScreenCoordsXY screenCoord = { floor2(session.DPI.WorldX(), 32), floor2((session.DPI.WorldY() - 16), 32) }; CoordsXY mapTile = { screenCoord.y - screenCoord.x / 2, screenCoord.y + screenCoord.x / 2 }; mapTile = mapTile.Rotate(direction); @@ -547,12 +548,12 @@ static void PaintDrawStruct(PaintSession& session, PaintStruct* ps) { if (session.DPI.zoom_level >= ZoomLevel{ 1 }) { - screenPos.x = Floor2(screenPos.x, 2); - screenPos.y = Floor2(screenPos.y, 2); + screenPos.x = floor2(screenPos.x, 2); + screenPos.y = floor2(screenPos.y, 2); if (session.DPI.zoom_level >= ZoomLevel{ 2 }) { - screenPos.x = Floor2(screenPos.x, 4); - screenPos.y = Floor2(screenPos.y, 4); + screenPos.x = floor2(screenPos.x, 4); + screenPos.y = floor2(screenPos.y, 4); } } } diff --git a/src/openrct2/paint/support/MetalSupports.cpp b/src/openrct2/paint/support/MetalSupports.cpp index a49be52f02..da0ef6a1f1 100644 --- a/src/openrct2/paint/support/MetalSupports.cpp +++ b/src/openrct2/paint/support/MetalSupports.cpp @@ -18,6 +18,7 @@ #include "../Paint.h" using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; constexpr auto kMetalSupportSkip = 9 * 4 * 2; @@ -385,7 +386,7 @@ static bool MetalASupportsPaintSetup( // Work out if a small support segment required to bring support to normal // size (aka floor2(x, 16)) - int16_t heightDiff = Floor2(height + 16, 16); + int16_t heightDiff = floor2(height + 16, 16); if (heightDiff > si) { heightDiff = si; @@ -598,7 +599,7 @@ static bool MetalBSupportsPaintSetup( baseHeight = supportSegments[segment].height + 6; } - int16_t heightDiff = Floor2(baseHeight + 16, 16); + int16_t heightDiff = floor2(baseHeight + 16, 16); if (heightDiff > si) { heightDiff = si; @@ -782,7 +783,7 @@ bool PathPoleSupportsPaintSetup( // si = height // dx = baseHeight - int16_t heightDiff = Floor2(baseHeight + 16, 16); + int16_t heightDiff = floor2(baseHeight + 16, 16); if (heightDiff > height) { heightDiff = height; diff --git a/src/openrct2/paint/support/WoodenSupports.cpp b/src/openrct2/paint/support/WoodenSupports.cpp index e6fac7d1e6..534347d3ee 100644 --- a/src/openrct2/paint/support/WoodenSupports.cpp +++ b/src/openrct2/paint/support/WoodenSupports.cpp @@ -21,6 +21,7 @@ #include using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; constexpr auto kNumWoodenSupportTypes = 2; constexpr auto kNumWoodenSupportSubTypes = 6; @@ -421,7 +422,7 @@ static inline bool WoodenSupportsPaintSetupCommon( imageTemplate = ImageId().WithTransparency(FilterPaletteID::PaletteDarken1); } - baseHeight = Ceil2(session.Support.height, 16); + baseHeight = ceil2(session.Support.height, 16); int16_t supportLength = height - baseHeight; if (supportLength < 0) diff --git a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp index 1e03888826..74ee372203 100644 --- a/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.LargeScenery.cpp @@ -34,6 +34,7 @@ #include "Segment.h" using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; // clang-format off static constexpr BoundBoxXY LargeSceneryBoundBoxes[] = { @@ -77,7 +78,7 @@ static void PaintLargeScenerySupports( WoodenBSupportsPaintSetupRotated( session, WoodenSupportType::Truss, WoodenSupportSubType::NeSw, direction, supportHeight, imageTemplate, transitionType); - int32_t clearanceHeight = Ceil2(tileElement.GetClearanceZ() + 15, 16); + int32_t clearanceHeight = ceil2(tileElement.GetClearanceZ() + 15, 16); if (tile.allowSupportsAbove) { PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, clearanceHeight, 0x20); diff --git a/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp b/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp index 00cb9be4a4..c00913a02f 100644 --- a/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp +++ b/src/openrct2/paint/tile_element/Paint.SmallScenery.cpp @@ -26,6 +26,7 @@ #include "Segment.h" using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; static constexpr CoordsXY lengths[] = { { 12, 26 }, @@ -74,7 +75,7 @@ static void SetSupportHeights( { height += sceneryEntry.height; - PaintUtilSetGeneralSupportHeight(session, Ceil2(height, 8)); + PaintUtilSetGeneralSupportHeight(session, ceil2(height, 8)); if (sceneryEntry.HasFlag(SMALL_SCENERY_FLAG_BUILD_DIRECTLY_ONTOP)) { if (sceneryEntry.HasFlag(SMALL_SCENERY_FLAG_FULL_TILE)) diff --git a/src/openrct2/paint/track/thrill/Enterprise.cpp b/src/openrct2/paint/track/thrill/Enterprise.cpp index f389b66080..e33d0dd6bd 100644 --- a/src/openrct2/paint/track/thrill/Enterprise.cpp +++ b/src/openrct2/paint/track/thrill/Enterprise.cpp @@ -22,6 +22,7 @@ #include "../../track/Segment.h" using namespace OpenRCT2; +using namespace OpenRCT2::Numerics; static void PaintEnterpriseRiders( PaintSession& session, const RideObjectEntry& rideEntry, Vehicle& vehicle, uint32_t imageOffset, const CoordsXYZ& offset, @@ -39,7 +40,7 @@ static void PaintEnterpriseRiders( break; auto frameOffset1 = ((imageOffset % 4) * 4 + (i * 4) % 15) & 0x0F; - auto frameOffset2 = Floor2(imageOffset, 4) * 4; + auto frameOffset2 = floor2(imageOffset, 4) * 4; auto imageTemplate = ImageId(0, vehicle.peep_tshirt_colours[i]); auto imageId = imageTemplate.WithIndex(baseImageIndex + 196 + frameOffset1 + frameOffset2); PaintAddImageAsChild(session, imageId, offset, bb); diff --git a/src/openrct2/util/Math.hpp b/src/openrct2/util/Math.hpp deleted file mode 100644 index 1621d5d341..0000000000 --- a/src/openrct2/util/Math.hpp +++ /dev/null @@ -1,37 +0,0 @@ - -/***************************************************************************** - * 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 - -namespace -{ - [[maybe_unused]] constexpr bool IsPowerOf2(int v) - { - return v && ((v & (v - 1)) == 0); - } - - // Rounds an integer down to the given power of 2. y must be a power of 2. - [[maybe_unused]] constexpr int Floor2(const int x, const int y) - { - if (!IsPowerOf2(y)) - throw std::logic_error("Floor2 should only operate on power of 2"); - return x & ~(y - 1); - } - - // Rounds an integer up to the given power of 2. y must be a power of 2. - [[maybe_unused]] constexpr int Ceil2(const int x, const int y) - { - if (!IsPowerOf2(y)) - throw std::logic_error("Ceil2 should only operate on power of 2"); - return (x + y - 1) & ~(y - 1); - } -} // namespace diff --git a/src/openrct2/util/Util.h b/src/openrct2/util/Util.h index e4fff3a7bb..8f5ff2c063 100644 --- a/src/openrct2/util/Util.h +++ b/src/openrct2/util/Util.h @@ -9,15 +9,10 @@ #pragma once -#include "../core/CallingConventions.h" #include "../core/Money.hpp" #include "../core/StringTypes.h" -#include #include -#include -#include -#include int32_t StrLogicalCmp(char const* a, char const* b); char* SafeStrCpy(char* destination, const char* source, size_t num); diff --git a/src/openrct2/world/Location.hpp b/src/openrct2/world/Location.hpp index 086495bd77..b60f606075 100644 --- a/src/openrct2/world/Location.hpp +++ b/src/openrct2/world/Location.hpp @@ -9,7 +9,7 @@ #pragma once -#include "../util/Math.hpp" +#include "../core/Numerics.hpp" #include @@ -227,7 +227,9 @@ struct CoordsXY constexpr CoordsXY ToTileStart() const { - return { Floor2(x, kCoordsXYStep), Floor2(y, kCoordsXYStep) }; + using namespace OpenRCT2::Numerics; + + return { floor2(x, kCoordsXYStep), floor2(y, kCoordsXYStep) }; } constexpr bool IsNull() const @@ -276,7 +278,9 @@ struct CoordsXYZ : public CoordsXY constexpr CoordsXYZ ToTileStart() const { - return { Floor2(x, kCoordsXYStep), Floor2(y, kCoordsXYStep), z }; + using namespace OpenRCT2::Numerics; + + return { floor2(x, kCoordsXYStep), floor2(y, kCoordsXYStep), z }; } constexpr CoordsXYZ ToTileCentre() const @@ -661,7 +665,9 @@ struct CoordsXYZD : public CoordsXYZ constexpr CoordsXYZD ToTileStart() const { - return { Floor2(x, kCoordsXYStep), Floor2(y, kCoordsXYStep), z, direction }; + using namespace OpenRCT2::Numerics; + + return { floor2(x, kCoordsXYStep), floor2(y, kCoordsXYStep), z, direction }; } constexpr CoordsXYZD ToTileCentre() const From e73aa548eb5db92b7409765889c13ec9db3c659e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Thu, 5 Dec 2024 12:18:04 +0100 Subject: [PATCH 126/139] Update backtrace.io token in Crash.cpp for upcoming release --- src/openrct2/platform/Crash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/platform/Crash.cpp b/src/openrct2/platform/Crash.cpp index de7a7adf5e..1bd6f7c836 100644 --- a/src/openrct2/platform/Crash.cpp +++ b/src/openrct2/platform/Crash.cpp @@ -57,7 +57,7 @@ static const wchar_t* _wszCommitSha1Short = WSZ(""); static const wchar_t* _wszArchitecture = WSZ(OPENRCT2_ARCHITECTURE); static std::map _uploadFiles; - #define BACKTRACE_TOKEN "1a9becc5de031b0a24ecad5222d2b42820c3710863a0f1dba6ab378b02ca659a" + #define BACKTRACE_TOKEN "024ed66e0e296ab22777d1292e1d945d78584f350c92fc76c2af843a7db002c9" using namespace OpenRCT2; From 9c1a75caef5ed221c340fd018c6f9ab51d7eee91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:50:18 +0200 Subject: [PATCH 127/139] Add missing headers, latest MSVC has build errors --- src/openrct2/entity/Peep.h | 1 + src/openrct2/rct12/RCT12.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/openrct2/entity/Peep.h b/src/openrct2/entity/Peep.h index 3663aa3cbf..90d191df08 100644 --- a/src/openrct2/entity/Peep.h +++ b/src/openrct2/entity/Peep.h @@ -18,6 +18,7 @@ #include #include +#include #include constexpr uint8_t kPeepMinEnergy = 32; diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index ca764e632d..347cb4f764 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -18,6 +18,7 @@ #include "../world/tile_element/TileElementType.h" #include "Limits.h" +#include #include #include #include From e1c39972696e8b2ddda64d83da27e0da40369a7a Mon Sep 17 00:00:00 2001 From: 73 <94884086+733737@users.noreply.github.com> Date: Fri, 6 Dec 2024 04:27:32 -0500 Subject: [PATCH 128/139] Correct copyright years on ZoomLevel.cpp --- src/openrct2/interface/ZoomLevel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2/interface/ZoomLevel.cpp b/src/openrct2/interface/ZoomLevel.cpp index e7ded72fb1..1c52b517ea 100644 --- a/src/openrct2/interface/ZoomLevel.cpp +++ b/src/openrct2/interface/ZoomLevel.cpp @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2020 OpenRCT2 developers + * 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 From 2ac91f79e5cac1a67cc8cbf0559b0e7e204d8f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Janiszewski?= Date: Fri, 6 Dec 2024 11:28:03 +0100 Subject: [PATCH 129/139] Add more descriptive information for renderer faults (#23327) --- .../engines/HardwareDisplayDrawingEngine.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp index f16d14c5bc..fbfb3dc6ea 100644 --- a/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp +++ b/src/openrct2-ui/drawing/engines/HardwareDisplayDrawingEngine.cpp @@ -150,7 +150,9 @@ public: SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); _screenTexture = SDL_CreateTexture(_sdlRenderer, pixelFormat, SDL_TEXTUREACCESS_STREAMING, width, height); - Guard::Assert(_screenTexture != nullptr, "Failed to create screen texture: %s", SDL_GetError()); + Guard::Assert( + _screenTexture != nullptr, "Failed to create unscaled screen texture (%ux%u, pixelFormat = %u): %s", width, + height, pixelFormat, SDL_GetError()); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scaleQualityBuffer); @@ -158,12 +160,17 @@ public: _scaledScreenTexture = SDL_CreateTexture( _sdlRenderer, pixelFormat, SDL_TEXTUREACCESS_TARGET, width * scale, height * scale); - Guard::Assert(_scaledScreenTexture != nullptr, "Failed to create scaled screen texture: %s", SDL_GetError()); + Guard::Assert( + _scaledScreenTexture != nullptr, + "Failed to create scaled screen texture (%ux%u, scale = %u, pixelFormat = %u): %s", width, height, scale, + pixelFormat, SDL_GetError()); } else { _screenTexture = SDL_CreateTexture(_sdlRenderer, pixelFormat, SDL_TEXTUREACCESS_STREAMING, width, height); - Guard::Assert(_screenTexture != nullptr, "Failed to create screen texture: %s", SDL_GetError()); + Guard::Assert( + _screenTexture != nullptr, "Failed to create screen texture (%ux%u, pixelFormat = %u): %s", width, height, + pixelFormat, SDL_GetError()); } uint32_t format; From c2b3f6c54c66a905417a1149806abcd265f42047 Mon Sep 17 00:00:00 2001 From: mrmbernardi Date: Fri, 6 Dec 2024 21:34:20 +1100 Subject: [PATCH 130/139] Avoid pointer arithmetic with null pointer (#23332) --- src/openrct2/drawing/Drawing.Sprite.cpp | 27 ++++++++++++++++++++++--- src/openrct2/object/ImageTable.cpp | 9 ++++++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index dc29987901..27358fe3e8 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -474,7 +474,14 @@ bool GfxLoadG1(const IPlatformEnvironment& env) // Fix entry data offsets for (uint32_t i = 0; i < _g1.header.num_entries; i++) { - _g1.elements[i].offset += reinterpret_cast(_g1.data.get()); + if (_g1.elements[i].offset == nullptr) + { + _g1.elements[i].offset = _g1.data.get(); + } + else + { + _g1.elements[i].offset += reinterpret_cast(_g1.data.get()); + } OverrideElementOffsets(i, _g1.elements[i]); } return true; @@ -554,7 +561,14 @@ bool GfxLoadG2() // Fix entry data offsets for (uint32_t i = 0; i < _g2.header.num_entries; i++) { - _g2.elements[i].offset += reinterpret_cast(_g2.data.get()); + if (_g2.elements[i].offset == nullptr) + { + _g2.elements[i].offset = _g2.data.get(); + } + else + { + _g2.elements[i].offset += reinterpret_cast(_g2.data.get()); + } } return true; } @@ -611,7 +625,14 @@ bool GfxLoadCsg() // Fix entry data offsets for (uint32_t i = 0; i < _csg.header.num_entries; i++) { - _csg.elements[i].offset += reinterpret_cast(_csg.data.get()); + if (_csg.elements[i].offset == nullptr) + { + _csg.elements[i].offset = _csg.data.get(); + } + else + { + _csg.elements[i].offset += reinterpret_cast(_csg.data.get()); + } // RCT1 used zoomed offsets that counted from the beginning of the file, rather than from the current sprite. if (_csg.elements[i].flags & G1_FLAG_HAS_ZOOM_SPRITE) { diff --git a/src/openrct2/object/ImageTable.cpp b/src/openrct2/object/ImageTable.cpp index 4984016e15..2fc66ba645 100644 --- a/src/openrct2/object/ImageTable.cpp +++ b/src/openrct2/object/ImageTable.cpp @@ -232,7 +232,14 @@ std::vector> ImageTable::LoadImageArc // Fix entry data offsets for (uint32_t i = 0; i < gxData->header.num_entries; i++) { - gxData->elements[i].offset += reinterpret_cast(gxData->data.get()); + if (gxData->elements[i].offset == nullptr) + { + gxData->elements[i].offset = gxData->data.get(); + } + else + { + gxData->elements[i].offset += reinterpret_cast(gxData->data.get()); + } } if (range.size() > 0) From c15f6a975f0dfc7706abb8dec87b3a364d0eaa13 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Fri, 6 Dec 2024 11:40:28 +0100 Subject: [PATCH 131/139] Fix swapped labels in heightmap smoothing text input (#23334) Co-authored-by: arekdurlik <72689308+arekdurlik@users.noreply.github.com> --- src/openrct2-ui/UiStringIds.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2-ui/UiStringIds.h b/src/openrct2-ui/UiStringIds.h index 93f1086549..17b5e0adce 100644 --- a/src/openrct2-ui/UiStringIds.h +++ b/src/openrct2-ui/UiStringIds.h @@ -908,7 +908,7 @@ namespace OpenRCT2 STR_ENTER_MIN_LAND = 6691, STR_ENTER_MIN_TREE_ALTITUDE = 6695, STR_ENTER_OCTAVES = 6703, - STR_ENTER_SMOOTH_STRENGTH = 6708, + STR_ENTER_SMOOTH_STRENGTH = 6709, STR_ENTER_TREE_TO_LAND_RATIO = 6699, STR_ENTER_WATER_LEVEL = 5186, STR_HEIGHTMAP_FILE = 6681, @@ -944,7 +944,7 @@ namespace OpenRCT2 STR_MIN_TREE_ALTITUDE = 6694, STR_SIMPLEX_BASE_FREQUENCY = 6700, STR_SIMPLEX_OCTAVES = 6702, - STR_SMOOTH_STRENGTH = 6709, + STR_SMOOTH_STRENGTH = 6708, STR_TERRAIN_LABEL = 2693, STR_TREE_TO_LAND_RATIO = 6694, STR_WATER_LEVEL = 5185, From 4e9765d871140ff67d155dc82cea55653b984bac Mon Sep 17 00:00:00 2001 From: Arek Durlik <72689308+arekdurlik@users.noreply.github.com> Date: Fri, 6 Dec 2024 19:52:59 +0100 Subject: [PATCH 132/139] Fix wrong label in tree to land ratio text input (#23336) --- src/openrct2-ui/UiStringIds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openrct2-ui/UiStringIds.h b/src/openrct2-ui/UiStringIds.h index 17b5e0adce..8cd4d4f85d 100644 --- a/src/openrct2-ui/UiStringIds.h +++ b/src/openrct2-ui/UiStringIds.h @@ -946,7 +946,7 @@ namespace OpenRCT2 STR_SIMPLEX_OCTAVES = 6702, STR_SMOOTH_STRENGTH = 6708, STR_TERRAIN_LABEL = 2693, - STR_TREE_TO_LAND_RATIO = 6694, + STR_TREE_TO_LAND_RATIO = 6698, STR_WATER_LEVEL = 5185, STR_WATER_LEVEL_LABEL = 2692, From 4c56954799866462773538858a37279a38d0baf6 Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sat, 7 Dec 2024 04:02:15 +0000 Subject: [PATCH 133/139] Merge Localisation/master into OpenRCT2/develop --- data/language/pl-PL.txt | 306 ++++++++++++++++++++-------------------- 1 file changed, 153 insertions(+), 153 deletions(-) diff --git a/data/language/pl-PL.txt b/data/language/pl-PL.txt index 8071877878..a256fb116a 100644 --- a/data/language/pl-PL.txt +++ b/data/language/pl-PL.txt @@ -4,7 +4,7 @@ STR_0000 : STR_0001 :{STRINGID} {COMMA16} STR_0002 :Kolejka spiralna -STR_0003 :Stojąca kolejka +STR_0003 :Kolejka stojąca STR_0004 :Kolejka podwieszona STR_0005 :Kolejka odwrotna STR_0006 :Kolejka dla dzieci @@ -60,12 +60,12 @@ STR_0055 :Tarcie boczne STR_0056 :Stalowa szalona mysz STR_0057 :Kolejka wielowymiarowa STR_0058 :Nieznana atrakcja (38) -STR_0059 :Latająca kolejka +STR_0059 :Kolejka latająca STR_0060 :Nieznana atrakcja (3A) STR_0061 :W koło Macieju STR_0062 :Pluskołódki STR_0063 :Minihelikoptery -STR_0064 :Leżąca kolejka +STR_0064 :Kolejka leżąca STR_0065 :Podwieszona jednoszynówka STR_0066 :Nieznana atrakcja (40) STR_0067 :Zawracajka @@ -98,7 +98,7 @@ STR_0093 :Kolejka hybrydowa STR_0094 :Kolejka jednoszynowa STR_0095 :Tor saneczkowy STR_0096 :Klasyczna drewniana jazda -STR_0097 :Klasyczna stojąca kolejka +STR_0097 :Klasyczna kolejka stojąca STR_0098 :Kolejka z napędem synchronicznym liniowym STR_0512 :Zwarta przestrzennie kolejka ze spiralnym podjazdem i gładkimi, zakręconymi zjazdami STR_0513 :Zapętlona kolejka, w której pasażerowie jadą w pozycji stojącej @@ -161,7 +161,7 @@ STR_0574 :Pasażerowie trzymani są przez specjalne uprzęże w pozycji leż STR_0575 :Zasilane pociągi zawieszone na pojedynczej szynie służą jako środek transportu ludzi w parku STR_0577 :Wózki kopalniane jeżdzące po drewnianych torach, zawracające na specjalnych obrotowych sekcjach STR_0578 :Wagoniki jadą po torze otoczonym okrągłymi obręczami, pokonując strome zjazdy i zabójcze obroty -STR_0579 :Spokojna gra w mini golfa +STR_0579 :Spokojna gra w miniaturowego golfa STR_0580 :Wielka stalowa kolejka górska jeżdżąca po łagodnych spadkach i wzniesieniach o wysokości ponad 100 metrów STR_0581 :Pierścień z zamocowanymi fotelami jest wciągany na szczyt wysokiej wieży, obracając się powoli, po czym spada swobodnie, wyhamowując delikatnie u dołu przy użyciu hamulców magnetycznych STR_0582 :Poduszkowce sterowane przez pasażerów @@ -281,7 +281,7 @@ STR_0883 :Zapisz grę STR_0884 :Wczytaj krajobraz STR_0885 :Zapisz krajobraz STR_0887 :Wyjdź z edytora scenariuszy -STR_0888 :Wyjdź z projektanta kolejek +STR_0888 :Wyjdź z projektanta tras STR_0889 :Wyjdź z menedżera projektów tras STR_0891 :Zrzut ekranu STR_0892 :Zrzut ekranu zapisany jako „{STRINGID}” @@ -300,10 +300,10 @@ STR_0904 :Zakręt w lewo (duży promień) STR_0905 :Zakręt w prawo (duży promień) STR_0906 :Prosto STR_0907 :Nachylenie -STR_0908 :Nachylenie boczne +STR_0908 :Przechylenie STR_0909 :Obr. siedzenia -STR_0910 :Nachylenie lewostronne -STR_0911 :Nachylenie prawostronne +STR_0910 :Przechylenie w lewo +STR_0911 :Przechylenie w prawo STR_0912 :Prosto STR_0913 :Przejdź do poprzedniego elementu STR_0914 :Przejdź do następnego elementu @@ -382,7 +382,7 @@ STR_0987 :Zbyt wiele atrakcji STR_0988 :Nie można stworzyć nowej atrakcji… STR_0989 :{STRINGID} STR_0990 :Tryb budowania -STR_0991 :Platforma ze stacją +STR_0991 :Platforma stacji STR_0992 :Zburz całą atrakcję STR_0993 :Zburz atrakcję STR_0994 :Zburz @@ -390,7 +390,7 @@ STR_0995 :{WINDOW_COLOUR_1}Jesteś pewien, że chcesz zburzyć {STRINGID}? STR_0996 :Widok ogólny STR_0997 :Wybór widoku STR_0998 :Nie można utworzyć więcej stacji dla tej atrakcji -STR_0999 :Wymaga platformy ze stacją +STR_0999 :Wymaga platformy stacji STR_1000 :Tor nie jest obwodem zamkniętym STR_1001 :Tor nieodpowiedni dla tego typu kolejki STR_1002 :Nie można otworzyć {STRINGID}… @@ -400,8 +400,8 @@ STR_1005 :Nie można rozpocząć konstrukcji {STRINGID}… STR_1006 :Atrakcja musi najpierw zostać zamknięta STR_1007 :Nie można utworzyć wystarczająco wagonów STR_1008 :Otwórz, zamknij lub testuj atrakcję -STR_1009 :Otwórz / zamknij wszystkie atrakcje -STR_1010 :Otwórz / zamknij park +STR_1009 :Otwórz/zamknij wszystkie atrakcje +STR_1010 :Otwórz/zamknij park STR_1011 :Zamknij wszystkie STR_1012 :Otwórz wszystkie STR_1013 :Zamknij park @@ -445,11 +445,11 @@ STR_1050 :Nie udało się wczytać…{NEWLINE}Plik zawiera błędne dane! STR_1051 :Przezroczyste wsporniki STR_1052 :Przezroczyści goście STR_1053 :Atrakcje w parku -STR_1054 :Nazwy atrakcji -STR_1055 :Nazwy osób -STR_1056 :Nazwy pracowników +STR_1054 :Nazwij atrakcję +STR_1055 :Nazwij gościa +STR_1056 :Nazwij pracownika STR_1057 :Nazwa atrakcji -STR_1058 :Wprowadź nazwę dla tej atrakcji: +STR_1058 :Podaj nową nazwę atrakcji: STR_1059 :Nie można zmienić nazwy atrakcji… STR_1060 :Nieprawidłowa nazwa atrakcji STR_1061 :Tryb normalny @@ -530,8 +530,8 @@ STR_1135 :{STRINGID} {COMMA16} STR_1136 :Wybierz główny kolor STR_1137 :Wybierz dodatkowy kolor nr 1 STR_1138 :Wybierz dodatkowy kolor nr 2 -STR_1139 :Wybierz schemat koloru wsporników -STR_1140 :Wybierz schemat koloru pojazdów +STR_1139 :Wybierz kolor wsporników +STR_1140 :Wybierz schemat kolorów pojazdów STR_1141 :Wybierz pojazd/pociąg do edycji STR_1142 :{MOVE_X}{10}{STRINGID} STR_1143 :»{MOVE_X}{10}{STRINGID} @@ -592,7 +592,7 @@ STR_1197 :Awaria STR_1198 :Katastrofa! STR_1199 :{COMMA16} osoba korzysta STR_1200 :{COMMA16} osób korzysta -STR_1201 :Kolejka pusta +STR_1201 :Pusta kolejka STR_1202 :1 osoba w kolejce STR_1203 :{COMMA16} - liczba osób w kolejce STR_1204 :{COMMA16} min. w kolejce @@ -735,7 +735,7 @@ STR_1340 :{WINDOW_COLOUR_2}Maks. prędkość: {BLACK}{VELOCITY} STR_1341 :{WINDOW_COLOUR_2}Czas przejazdu: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} STR_1342 :{DURATION} STR_1343 :{DURATION} / -STR_1344 :{WINDOW_COLOUR_2}Czas przejazdu: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} +STR_1344 :{WINDOW_COLOUR_2}Długość trasy: {BLACK}{STRINGID}{STRINGID}{STRINGID}{STRINGID} STR_1345 :{LENGTH} STR_1346 :{LENGTH} / STR_1347 :{WINDOW_COLOUR_2}Średnia prędkość: {BLACK}{VELOCITY} @@ -787,7 +787,7 @@ STR_1392 :Podgląd atrakcji STR_1393 :Szczegóły i opcje pojazdów STR_1394 :Opcje operacyjne STR_1395 :Ustawienia konserwacji -STR_1396 :Ustawienia schematu koloru +STR_1396 :Ustawienia schematu kolorów STR_1397 :Ustawienia dźwięku i muzyki STR_1398 :Pomiary i statystyki STR_1399 :Wykresy @@ -844,7 +844,7 @@ STR_1449 :{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) STR_1450 :{INLINE_SPRITE}{09}{20}{00}{00}{SPRITE} {STRINGID}{NEWLINE}({STRINGID}) STR_1451 :{STRINGID}{NEWLINE}({STRINGID}) STR_1452 :Imię gościa -STR_1453 :Nowe imię dla gościa: +STR_1453 :Podaj nowe imię gościa: STR_1454 :Nie można tak nazwać gościa… STR_1455 :Niewłaściwe imię dla gościa STR_1456 :{WINDOW_COLOUR_2}Wydane pieniądze: {BLACK}{CURRENCY2DP} @@ -864,13 +864,13 @@ STR_1469 :Atrakcja musi się zaczynać i kończyć stacją STR_1470 :Stacja jest za krótka STR_1471 :{WINDOW_COLOUR_2}Prędkość: STR_1472 :Prędkość dla przejazdu -STR_1473 :{WINDOW_COLOUR_2}Ocena emocji: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1474 :{WINDOW_COLOUR_2}Ocena emocji: {BLACK}Jeszcze niedostępna -STR_1475 :{WINDOW_COLOUR_2}Ocena intensywności: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1476 :{WINDOW_COLOUR_2}Ocena intensywności: {BLACK}Jeszcze nie dostępna -STR_1477 :{WINDOW_COLOUR_2}Ocena intensywności: {OUTLINE}{RED}{COMMA2DP32} ({STRINGID}) -STR_1478 :{WINDOW_COLOUR_2}Ocena mdłości: {BLACK}{COMMA2DP32} ({STRINGID}) -STR_1479 :{WINDOW_COLOUR_2}Ocena mdłości: {BLACK}Jeszcze nie dostępna +STR_1473 :{WINDOW_COLOUR_2}Emocje: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1474 :{WINDOW_COLOUR_2}Emocje: {BLACK}Jeszcze nieznane +STR_1475 :{WINDOW_COLOUR_2}Intensywność: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1476 :{WINDOW_COLOUR_2}Intensywność: {BLACK}Jeszcze nieznana +STR_1477 :{WINDOW_COLOUR_2}Intensywność: {OUTLINE}{RED}{COMMA2DP32} ({STRINGID}) +STR_1478 :{WINDOW_COLOUR_2}Mdłości: {BLACK}{COMMA2DP32} ({STRINGID}) +STR_1479 :{WINDOW_COLOUR_2}Mdłości: {BLACK}Jeszcze nieznane STR_1480 :„Nie mogę sobie pozwolić na {STRINGID}” STR_1481 :„Wydałem wszystkie swoje pieniądze” STR_1482 :„Niedobrze mi” @@ -1076,7 +1076,7 @@ STR_1683 :Wymiary bazowe 2 × 2 STR_1684 :Wymiary bazowe 4 × 4 STR_1685 :Wymiary bazowe 2 × 4 STR_1686 :Wymiary bazowe 5 × 1 -STR_1687 :Wzburzenie wody +STR_1687 :Przejazd przez wodę STR_1688 :Wymiary bazowe 4 × 1 STR_1689 :Hamulce blokowe STR_1690 :{WINDOW_COLOUR_2}{STRINGID}{NEWLINE}{BLACK}{STRINGID} @@ -1094,7 +1094,7 @@ STR_1701 :Zatrudnij mechanika STR_1702 :Zatrudnij ochroniarza STR_1703 :Zatrudnij komika STR_1704 :Nie można zatrudnić nowych pracowników… -STR_1705 :Zwolnij tego pracownika +STR_1705 :Zwolnij pracownika STR_1706 :Przenieś tę osobę do nowej lokalizacji STR_1707 :Za dużo pracowników w grze STR_1708 :Wyznacz teren patrolowania dla pracownika @@ -1103,12 +1103,12 @@ STR_1710 :Tak STR_1711 :{WINDOW_COLOUR_1}Jesteś pewien, że chcesz zwolnić {STRINGID}? STR_1712 :{INLINE_SPRITE}{247}{19}{00}{00}{WINDOW_COLOUR_2}Zamiatanie ścieżek STR_1713 :{INLINE_SPRITE}{248}{19}{00}{00}{WINDOW_COLOUR_2}Podlewanie kwiatów -STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}Opróżnianie kubłów +STR_1714 :{INLINE_SPRITE}{249}{19}{00}{00}{WINDOW_COLOUR_2}Opróżnianie koszy STR_1715 :{INLINE_SPRITE}{250}{19}{00}{00}{WINDOW_COLOUR_2}Koszenie trawnika STR_1716 :Niewłaściwa nazwa dla parku! STR_1717 :Nie można zmienić nazwy parku… STR_1718 :Nazwa parku -STR_1719 :Podaj nową nazwę parku +STR_1719 :Podaj nową nazwę parku: STR_1720 :Nazwij park STR_1721 :Park zamknięty STR_1722 :Park otwarty @@ -1131,7 +1131,7 @@ STR_1739 :Wyścig wygrany przez gościa {INT32} STR_1740 :Wyścig wygrał {STRINGID} STR_1741 :Jeszcze nie zbudowane! STR_1742 :{WINDOW_COLOUR_2}Maks. ludzi na przejazd: -STR_1743 :Maksymalna ilość osób biorąca jednoczesny udział w wyścigu +STR_1743 :Maksymalna liczba osób, które mogą jednocześnie korzystać z tej atrakcji STR_1744 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} STR_1746 :Nie można tego zmienić… STR_1747 :{WINDOW_COLOUR_2}Limit czasu: @@ -1154,7 +1154,7 @@ STR_1764 :Pniowe odbijaki STR_1765 :Sekcja fotograficzna STR_1766 :Odwrotna obrotnica STR_1767 :Wirujący tunel -STR_1768 :Nie można zmienić ilości huśtań… +STR_1768 :Nie można zmienić liczby huśtań… STR_1769 :{WINDOW_COLOUR_2}Liczba huśtań: STR_1770 :Liczba pełnych huśtań STR_1771 :{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{POP16}{COMMA16} @@ -1175,7 +1175,7 @@ STR_1788 :{INLINE_SPRITE}{07}{20}{00}{00} Kostium szeryfa STR_1789 :{INLINE_SPRITE}{08}{20}{00}{00} Kostium pirata STR_1790 :Wybierz kolor uniformu dla tego typu pracownika STR_1791 :{WINDOW_COLOUR_2}Kolor uniformu: -STR_1792 :Zmierza naprawić atrakcję {STRINGID} +STR_1792 :Zmierza naprawić {STRINGID} STR_1793 :W drodze na inspekcję {STRINGID} STR_1794 :Naprawia {STRINGID} STR_1795 :Odbiera wezwanie telefoniczne @@ -1267,10 +1267,10 @@ STR_1882 :Co 45 minut STR_1883 :Co godzinę STR_1884 :Co dwie godziny STR_1885 :Nigdy -STR_1886 :Inspekcja {STRINGID} +STR_1886 :Dokonuje inspekcji {STRINGID} STR_1887 :{WINDOW_COLOUR_2}Termin ostatniej inspekcji: {BLACK}{COMMA16} minut temu STR_1888 :{WINDOW_COLOUR_2}Termin ostatniej inspekcji: {BLACK} więcej niż 4 godziny temu -STR_1889 :{WINDOW_COLOUR_2}Czas przestoju: {MOVE_X}{255}{BLACK}{COMMA16}% +STR_1889 :{WINDOW_COLOUR_2}Przestoje: {MOVE_X}{255}{BLACK}{COMMA16}% STR_1890 :Określ jak często mechanik ma przeglądać tę atrakcję STR_1891 :Nie ma jeszcze {STRINGID} w parku! STR_1894 :{WINDOW_COLOUR_2}Sprzedane {STRINGID}: {BLACK}{COMMA32} @@ -1582,7 +1582,7 @@ STR_2216 :{WINDOW_COLOUR_2}{COMMA16}°C STR_2217 :{WINDOW_COLOUR_2}{COMMA16}°F STR_2218 :{RED}{STRINGID} na {STRINGID} jeszcze nie powrócił do {STRINGID}!{NEWLINE}Sprawdź czy gdzieś nie utknął. STR_2219 :{RED}{COMMA16} ludzi zginęło w wypadku na atrakcji {STRINGID} -STR_2220 :{WINDOW_COLOUR_2}Ocena parku: {BLACK}{COMMA16} +STR_2220 :{WINDOW_COLOUR_2}Atrakcyjność parku: {BLACK}{COMMA16} STR_2221 :Atrakcyjność Parku: {COMMA16} STR_2222 :{BLACK}{STRINGID} STR_2223 :{WINDOW_COLOUR_2}Liczba gości w parku: {BLACK}{COMMA32} @@ -1668,13 +1668,13 @@ STR_2303 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} pa STR_2304 :{BLACK}Wydał {CURRENCY2DP}{WINDOW_COLOUR_2} na {BLACK}{COMMA16} pamiątki STR_2305 :Plik z projektami tras STR_2306 :Zapisz projekt trasy -STR_2307 :Wybierz projekt {STRINGID} -STR_2308 :{STRINGID} projekty tras +STR_2307 :Wybierz projekt atrakcji {STRINGID} +STR_2308 :Projekty tras atrakcji {STRINGID} STR_2309 :Zainstaluj nowy projekt trasy STR_2310 :Stwórz własny projekt STR_2311 :{WINDOW_COLOUR_2}Emocje: {BLACK}{COMMA2DP32} (około) STR_2312 :{WINDOW_COLOUR_2}Intensywność: {BLACK}{COMMA2DP32} (około) -STR_2313 :{WINDOW_COLOUR_2}Ocena mdłości: {BLACK}{COMMA2DP32} (około) +STR_2313 :{WINDOW_COLOUR_2}Mdłości: {BLACK}{COMMA2DP32} (około) STR_2314 :{WINDOW_COLOUR_2}Długość trasy: {BLACK}{STRINGID} STR_2315 :{WINDOW_COLOUR_2}Koszt: {BLACK}około {CURRENCY} STR_2316 :{WINDOW_COLOUR_2}Zajmowany teren: {BLACK}{COMMA16} × {COMMA16} pól @@ -1923,7 +1923,7 @@ STR_2693 :Teren: STR_2694 :Generuj STR_2695 :Losowy teren STR_2696 :Umieść drzewa -STR_2700 :Częstotliwość autozapisu: +STR_2700 :Autozapis: STR_2701 :Co minutę STR_2702 :Co 5 minut STR_2703 :Co 15 minut @@ -1933,7 +1933,7 @@ STR_2706 :Nigdy STR_2707 :Otwórz nowe okno STR_2708 :{WINDOW_COLOUR_1}Jesteś pewien, że chcesz nadpisać {STRINGID}? STR_2709 :Nadpisz -STR_2710 :Wpisz nazwę pliku +STR_2710 :Wprowadź nazwę pliku: STR_2718 :W górę STR_2719 :Nowy plik STR_2720 :{UINT16}sek @@ -1970,7 +1970,7 @@ STR_2756 :Usuń śmieci STR_2763 :??? STR_2765 :Przypływ gości STR_2766 :Wygraj scenariusz -STR_2767 :Zablokuj zmiany pogody +STR_2767 :Wyłącz zmiany pogody STR_2769 :Otwórz park STR_2770 :Zamknij park STR_2773 :Okno @@ -1998,8 +1998,8 @@ STR_2793 :(Ukończone przez {STRINGID}) STR_2794 :{WINDOW_COLOUR_2}Ukończony przez: {BLACK}{STRINGID}{NEWLINE}{WINDOW_COLOUR_2} z wartością spółki wynoszącą: {BLACK}{CURRENCY} STR_2795 :Sortuj STR_2796 :Sortuj listę atrakcji według wyświetlonych informacji -STR_2797 :Przesuń widok gdy kursor blisko krawędzi -STR_2798 :Włącza przesuwanie widoku, gdy kursor zbliży się do krawędzi ekranu +STR_2797 :Przesuwaj widok, gdy kursor jest na krawędzi okna +STR_2798 :Włącza przesuwanie widoku, gdy kursor myszy jest na krawędzi okna STR_2799 :Przejrzyj lub zmień funkcje przypisane do klawiszy sterujących STR_2800 :{WINDOW_COLOUR_2}Całkowita liczba gości: {BLACK}{COMMA32} STR_2801 :{WINDOW_COLOUR_2}Wpływy z opłat za wstęp: {BLACK}{CURRENCY2DP} @@ -2056,22 +2056,22 @@ STR_2851 :Ten scenariusz jest już zainstalowany STR_2852 :Ten projekt trasy jest już zainstalowany STR_2853 :Zabronione przez władze lokalne! STR_2854 :{RED}Goście nie mogą dotrzeć do wejścia do atrakcji {STRINGID}!{NEWLINE}Zbuduj ścieżkę prowadzącą do wejścia -STR_2855 :Przy wyjściu z atrakcji {RED}{STRINGID} nie ma żadnej dróżki!{NEWLINE}Zbuduj ścieżkę prowadzącą do wyjścia +STR_2855 :{RED}Przy wyjściu z atrakcji {STRINGID} nie ma żadnej dróżki!{NEWLINE}Zbuduj ścieżkę od wyjścia atrakcji STR_2858 :Nie można rozpocząć kampanii reklamowej… STR_2861 :{WINDOW_COLOUR_2}Licencja przyznana Infogrames Interactive Inc. -STR_2971 :Podstawowy schemat koloru +STR_2971 :Podstawowy schemat kolorów STR_2972 :Alternatywny schemat kolorów nr 1 STR_2973 :Alternatywny schemat kolorów nr 2 STR_2974 :Alternatywny schemat kolorów nr 3 STR_2975 :Wybierz schemat kolorów malowania atrakcji -STR_2976 :Pomaluj elementy atrakcji korzystając z indywidualnego schematu koloru +STR_2976 :Pomaluj elementy atrakcji korzystając z indywidualnego schematu kolorów STR_2977 :Nazwa pracownika -STR_2978 :Wprowadź nazwę tego pracownika: +STR_2978 :Podaj nowe imię pracownika: STR_2979 :Nie można zmienić nazwy pracownika… STR_2980 :Za dużo banerów w grze -STR_2981 :{RED}Brak wejścia +STR_2981 :{RED}Brak wejścia STR_2982 :Tekst baneru -STR_2983 :Wprowadź nową treść baneru: +STR_2983 :Podaj nową treść baneru: STR_2984 :Nie można wprowadzić nowej treści baneru… STR_2985 :Baner STR_2986 :Zmień treść baneru @@ -2081,7 +2081,7 @@ STR_2989 :Wybierz główny kolor STR_2990 :Wybierz kolor treści STR_2991 :Znak STR_2992 :Treść znaku -STR_2993 :Wprowadź nową nazwę znaku: +STR_2993 :Podaj nową treść znaku: STR_2994 :Zmień treść znaku STR_2995 :Usuń ten znak STR_2996 :{BLACK}ABC @@ -2143,7 +2143,7 @@ STR_3101 :Wybierz trzeci kolor STR_3102 :Ustaw ponownie kolor scenerii na terenie STR_3103 :Nie można tego przemalować… STR_3104 :Lista przejażdżek -STR_3105 :Lista sklepów i stoisk +STR_3105 :Lista sklepów i kiosków STR_3106 :Lista kiosków informacyjnych i innych obiektów STR_3107 :Zamknij STR_3108 :Testuj @@ -2163,9 +2163,9 @@ STR_3121 :Nie udało się znaleźć mechanika lub wszyscy mechanicy w okolicy STR_3122 :{WINDOW_COLOUR_2}Ulubiona atrakcja: {BLACK}{COMMA32} gości STR_3123 :{WINDOW_COLOUR_2}Ulubiona atrakcja: {BLACK}{COMMA32} gości STR_3124 :Zepsute: {STRINGID} -STR_3125 :{WINDOW_COLOUR_2}Czynnik ekscytacji: {BLACK}+{COMMA16}% -STR_3126 :{WINDOW_COLOUR_2}Czynnik intensywności: {BLACK}+{COMMA16}% -STR_3127 :{WINDOW_COLOUR_2}Czynnik mdłości: {BLACK}+{COMMA16}% +STR_3125 :{WINDOW_COLOUR_2}Emocje: {BLACK}+{COMMA16}% +STR_3126 :{WINDOW_COLOUR_2}Intensywność: {BLACK}+{COMMA16}% +STR_3127 :{WINDOW_COLOUR_2}Mdłości: {BLACK}+{COMMA16}% STR_3128 :Zapisz projekt trasy STR_3129 :Zapisz projekt trasy ze scenerią STR_3130 :Zapisz @@ -2175,7 +2175,7 @@ STR_3133 :Nie można tego zbudować na zboczu STR_3134 :{RED}(Projekt zawiera niedostępne elementy scenerii) STR_3135 :{RED}(Projekt wagoników niedostępny - może mieć to wpływ na atrakcyjność przejażdki) STR_3136 :Uwaga: Ten projekt trasy będzie wybudowany z alternatywnymi wagonami, dlatego może nie działać zgodnie z oczekiwaniami -STR_3137 :Wybierz najbliższą scenerie +STR_3137 :Wybierz najbliższą scenerię STR_3138 :Zresetuj wybór STR_3139 :Wyciągarka nie może działać w tym trybie STR_3140 :Wyciągarka musi znajdować się na początku trasy @@ -2202,7 +2202,7 @@ STR_3180 :Nieprawidłowy wybór obiektów STR_3181 :Wybór obiektów - {STRINGID} STR_3182 :Wejście do parku musi zostać wybrane STR_3183 :Rodzaj wody musi zostać wybrany -STR_3184 :Atrakcje przejazdowe/pojazdy +STR_3184 :Atrakcje/pojazdy STR_3185 :Drobna scenografia STR_3186 :Duża scenografia STR_3187 :Ściany/Ogrodzenia @@ -2242,7 +2242,7 @@ STR_3221 :Przekaż własność terenu parkowi STR_3222 :Przekaż pozwolenie na budowę parkowi STR_3223 :Ustaw teren jako dostępny do nabycia STR_3224 :Ustaw pozwolenie na budowę jako możliwe do nabycia -STR_3225 :Włącz / Wyłącz budowę losowego klastra obiektów wokół wybranej pozycji +STR_3225 :Włącz/Wyłącz budowę losowego klastra obiektów wokół wybranej pozycji STR_3226 :Zbuduj wejście do parku STR_3227 :Za dużo wejść do parku! STR_3228 :Ustaw początkowe rozmieszczenie ludzi @@ -2329,14 +2329,14 @@ STR_3308 :{WINDOW_COLOUR_2}Wskaźnik emocji: STR_3309 :{WINDOW_COLOUR_2}{COMMA32} STR_3310 :{WINDOW_COLOUR_2}{LENGTH} STR_3311 :{WINDOW_COLOUR_2}{COMMA2DP32} -STR_3312 :{WINDOW_COLOUR_2}Przejażdżki/atrakcje według następującej kolejności: +STR_3312 :{WINDOW_COLOUR_2}Atrakcje objęte ochroną konserwatorską: STR_3313 :Nazwa scenariusza STR_3314 :Wprowadź nazwę dla scenariusza: STR_3315 :Szczegóły parku/scenariusza STR_3316 :Wprowadź opis tego scenariusza: STR_3317 :Brak szczegółów STR_3318 :Wybierz w jakich grupach występuje ten scenariusz -STR_3319 :{WINDOW_COLOUR_2}Grupa scenariuszy: +STR_3319 :{WINDOW_COLOUR_2}Gr. scenariuszy: STR_3320 :Nie można zapisać pliku scenariusza… STR_3321 :Nowe elementy zainstalowane pomyślnie STR_3322 :{WINDOW_COLOUR_2}Cel: {BLACK}{STRINGID} @@ -2350,21 +2350,21 @@ STR_3332 :Wejście do parku jest nieprawidłowe lub nie ma ścieżki prowadz STR_3333 :Eksportuj elementy dodatkowe do zapisów gier STR_3334 :Wybierz, czy chcesz zapisać wymagane wtyczki (te, które nie są dołączone do produktu głównego) w zapisanych plikach gry lub scenariuszu, co pozwoli na ich załadowanie przez kogoś, kto nie posiada dodatkowych plików STR_3335 :Projektant tras - Wybierz rodzaj trasy i pojazdu -STR_3336 :Menedżer projektanta tras - Wybierz rodzaj przejazdu +STR_3336 :Menedżer projektów tras - Wybierz rodzaj atrakcji STR_3338 :{BLACK}Własny projekt STR_3339 :{BLACK}{COMMA16} projekt dostępny, możliwość stworzenia własnego STR_3340 :{BLACK}{COMMA16} projekty dostępne, możliwość stworzenia własnego STR_3341 :Narzędzia STR_3342 :Edytor scenariuszy STR_3343 :Przekonwertuj zapisaną grę do scenariusza -STR_3344 :Projektant kolejek +STR_3344 :Projektant tras STR_3345 :Menedżer projektów tras STR_3346 :Nie można zapisać projektu trasy… STR_3347 :Kolejka jest za duża, zawiera za dużo elementów, lub sceneria jest za bardzo rozległa STR_3348 :Zmień nazwę STR_3349 :Usuń STR_3350 :Nazwa projektu trasy -STR_3351 :Podaj nową nazwę dla projektu trasy: +STR_3351 :Podaj nową nazwę projektu trasy: STR_3352 :Nie można zmienić nazwy projektu trasy… STR_3353 :Nowa nazwa zawiera nieprawidłowe znaki STR_3354 :Istnieje plik o takiej nazwie, lub jest on chroniony przed zapisem @@ -2387,8 +2387,8 @@ STR_3372 :{BLACK}= Bankomat STR_3373 :{BLACK}= Toaleta STR_3374 :Uwaga: Zaznaczono zbyt wiele obiektów! STR_3375 :Nie wszystkie elementy w tej grupie scenerii mogą zostać wybrane -STR_3376 :Zainstaluj nowy wygląd tras… -STR_3377 :Zainstaluj nowy wygląd tras z pliku +STR_3376 :Zainstaluj nowy projekt trasy… +STR_3377 :Zainstaluj nowy projekt trasy z pliku STR_3378 :Zainstaluj STR_3379 :Anuluj STR_3380 :Brak możliwości zainstalowania projektu tej trasy… @@ -2413,10 +2413,10 @@ STR_5125 :Wszystko zniszczalne STR_5126 :Losowa muzyka tytułowa STR_5127 :Podczas przeciągania, zmieniaj krajobraz zamiast zmieniać wysokość STR_5128 :Rozmiar zaznaczenia -STR_5129 :Wybierz wielkość zaznaczenia pomiędzy {COMMA16} a {COMMA16} +STR_5129 :Wprowadź rozmiar zaznaczenia pomiędzy {COMMA16} a {COMMA16}: STR_5130 :Rozmiar mapy -STR_5131 :Wprowadź wielkość mapy pomiędzy {COMMA16} a {COMMA16} -STR_5132 :Napraw wszystkie atrakcje +STR_5131 :Wprowadź rozmiar mapy pomiędzy {COMMA16} a {COMMA16}: +STR_5132 :Napraw atrakcje STR_5133 :Ustaw mniejszy obszar praw do ziemi STR_5134 :Ustaw większy obszar praw do ziemi STR_5135 :Zakup ziemi i praw do budowy @@ -2454,9 +2454,9 @@ STR_5180 :Kody związane z parkiem STR_5181 :Kody związane z atrakcjami STR_5182 :{INT32} STR_5183 :Wysokość bazowa -STR_5184 :Wprowadź bazową wysokość pomiędzy {COMMA16} a {COMMA16} +STR_5184 :Wprowadź bazową wysokość pomiędzy {COMMA16} a {COMMA16}: STR_5185 :Poziom wody -STR_5186 :Wprowadź poziom wody pomiędzy {COMMA16} a {COMMA16} +STR_5186 :Wprowadź poziom wody pomiędzy {COMMA16} a {COMMA16}: STR_5187 :Finanse STR_5188 :Nowa kampania STR_5189 :Badania @@ -2510,7 +2510,7 @@ STR_5236 :Okno: STR_5237 :Paleta: STR_5238 :Obecny motyw: STR_5239 :Duplikuj -STR_5240 :Wprowadź nazwę dla motywu +STR_5240 :Wprowadź nazwę dla motywu: STR_5241 :Nie można zmienić tego motywu STR_5242 :Już istnieje taka nazwa motywu STR_5243 :Użyto nieprawidłowego znaku @@ -2524,7 +2524,7 @@ STR_5250 :Tytuł przycisku wyjścia STR_5251 :Tytuł przycisku opcji STR_5252 :Tytuł wyboru scenariusza STR_5253 :Informacje o parku -STR_5256 :Stwórz nowy motyw aby wprowadzić zmiany do +STR_5256 :Stwórz nowy motyw aby wprowadzić zmiany STR_5257 :Stwórz nowy motyw na podstawie bieżącego STR_5258 :Usuń bieżący motyw STR_5259 :Zmień nazwę bieżącego motywu @@ -2543,7 +2543,7 @@ STR_5272 :Mała sceneria STR_5273 :Duża sceneria STR_5274 :Ścieżka STR_5275 :Szukaj obiektu -STR_5276 :Podaj nazwę obiektu który chcesz znaleźć +STR_5276 :Wprowadź nazwę obiektu, który chcesz znaleźć: STR_5277 :Wyczyść STR_5278 :Tryb piaskownicy STR_5279 :Tryb piaskownicy wyłączony @@ -2592,7 +2592,7 @@ STR_5345 :Kody finansowe STR_5346 :Kody związane z gośćmi STR_5347 :Kody związane z parkiem STR_5348 :Kody związane z atrakcjami -STR_5349 :Wszystkie przejażdżki +STR_5349 :Wszystkie atrakcje STR_5350 :Maks. STR_5351 :Min. STR_5352 :{BLACK}Szczęście: @@ -2604,7 +2604,7 @@ STR_5357 :{BLACK}Tolerancja mdłości: STR_5358 :{BLACK}Pęcherz: STR_5359 :Usuń gości STR_5360 :Usuwa wszystkich gości z mapy -STR_5361 :Dodaj do ekwipunku gościa +STR_5361 :Dodaj do ekwipunków gości STR_5362 :{BLACK}Preferowana intensywność atrakcji: STR_5363 :Więcej niż 1 STR_5364 :Mniej niż 15 @@ -2613,7 +2613,7 @@ STR_5366 :Normalnie STR_5367 :Szybko STR_5368 :Zresetuj wypadki STR_5371 :Wybór obiektów -STR_5372 :Odwrócone przesuwanie prawym przyciskiem myszy +STR_5372 :Odwróć przeciąganie prawym przyciskiem myszy STR_5373 :Nazwa {STRINGID} STR_5374 :Data {STRINGID} STR_5375 :▲ @@ -2717,19 +2717,19 @@ STR_5544 :Jasny czerwony STR_5545 :Ciemny różowy STR_5546 :Jasny różowy STR_5547 :Różowy -STR_5548 :Pokaż wszystkie tryby +STR_5548 :Pokaż wszystkie tryby pracy STR_5549 :rok/miesiąc/dzień STR_5550 :{POP16}{POP16}Rok {COMMA16}, {PUSH16}{PUSH16}{MONTH} {PUSH16}{PUSH16}{STRINGID} STR_5551 :rok/dzień/miesiąc STR_5552 :{POP16}{POP16}Rok {COMMA16}, {PUSH16}{PUSH16}{PUSH16}{STRINGID} {MONTH} -STR_5553 :Wstrzymaj grę gdy nakładka Steam jest otwarta +STR_5553 :Wstrzymaj grę, gdy nakładka Steam jest otwarta STR_5554 :Uruchom narzędzie tworzenia gór STR_5555 :Pokaż pojazdy z innych typów torów STR_5556 :Wyrzuć gracza STR_5557 :Nie rozłączaj po desynchronizacji (tryb wieloosobowy) STR_5558 :Wymagany restart dla tej zmiany STR_5559 :10 min. inspekcje -STR_5560 :Ustaw częstotliwość inspekcji na „Co 10 minut” na wszystkich atrakcjach +STR_5560 :Ustawia częstotliwość inspekcji na „Co 10 minut” na wszystkich atrakcjach STR_5561 :Nie udało się załadować języka STR_5562 :UWAGA! STR_5563 :Ta funkcja jest obecnie niestabilna, zachowaj szczególną ostrożność. @@ -2749,12 +2749,12 @@ STR_5578 :Rosyjski rubel (₽) STR_5579 :Współczynnik skali okna: STR_5580 :Korona czeska (Kč) STR_5581 :Pokaż licznik FPS -STR_5582 :Nie pozwól na wyjście kursora poza okno +STR_5582 :Nie pozwalaj na wyjście kursora poza okno STR_5583 :{COMMA1DP16}m/s STR_5584 :SI -STR_5585 :Odblokuj limity w atrakcjach, wpływa to np. na {VELOCITY} wyciągarki -STR_5586 :Automatycznie otwieraj sklepy i stoiska -STR_5587 :Gdy aktywne, sklepy i stoiska będą automatycznie otwierane po zbudowaniu +STR_5585 :Odblokowuje limity w atrakcjach, pozwalając na rzeczy takie jak wyciągarki o prędkości {VELOCITY} +STR_5586 :Automatycznie otwieraj sklepy i kioski +STR_5587 :Gdy aktywne, sklepy i kioski będą automatycznie otwierane po zbudowaniu STR_5588 :Przejdź do rozgrywki wieloosobowej STR_5589 :Ustawienia powiadomień STR_5590 :Nagrody parku @@ -2864,15 +2864,15 @@ STR_5726 :Ustawia aktualną pogodę w parku STR_5734 :Renderowanie STR_5735 :Status sieci STR_5736 :Gracz -STR_5737 :Zamknięte, {COMMA16} gość nadal korzysta z przejażdżki -STR_5738 :Zamknięte, {COMMA16} gości nadal korzysta z przejażdżki +STR_5737 :Zamknięte, {COMMA16} gość nadal korzysta z atrakcji +STR_5738 :Zamknięte, {COMMA16} gości nadal korzysta z atrakcji STR_5739 :{WINDOW_COLOUR_2}Gości na atrakcji: {BLACK}{COMMA16} STR_5740 :Stałe kampanie reklamowe STR_5741 :Nigdy niekończące się kampanie reklamowe STR_5742 :Uwierzytelnianie… STR_5743 :Łączenie… STR_5744 :Szukanie adresu serwera… -STR_5745 :Wykryto desynchronizacje z serwerem +STR_5745 :Wykryto desynchronizację z serwerem STR_5746 :Rozłączono STR_5747 :Rozłączono: {STRING} STR_5748 :Wyrzucono @@ -2908,7 +2908,7 @@ STR_5777 :Zbudowano: w zeszłym roku STR_5778 :Zbudowano: {COMMA16} lat temu STR_5779 :Przychód: {CURRENCY2DP} na godzinę STR_5780 :Koszt: {CURRENCY2DP} na godzinę -STR_5781 :Koszt: nieznane +STR_5781 :Koszt: nieznany STR_5782 :Połączono. Naciśnij „{STRING}” aby pisać na czacie. STR_5783 :{WINDOW_COLOUR_2}Scenariusz zablokowany STR_5784 :{BLACK}Aby odblokować ten scenariusz ukończ poprzedni. @@ -2916,13 +2916,13 @@ STR_5785 :Nie można zmienić nazwy grupy… STR_5786 :Nieprawidłowa nazwa grupy STR_5787 :{COMMA32} graczy online STR_5788 :Domyślny okres inspekcji: -STR_5789 :Wyłącz efekty świetlne +STR_5789 :Wyłącz efekt błyskawic STR_5790 :Mieszany styl płatności RCT1{NEWLINE}(np. jednoczesna odpłatność za wejście i atrakcję) -STR_5791 :Ustaw niezawodność wszystkich atrakcji na 100%{NEWLINE}i zresetuj datę budowy na „w tym roku” +STR_5791 :Ustawia niezawodność wszystkich atrakcji na 100%{NEWLINE}i resetuje datę budowy na „w tym roku” STR_5792 :Naprawia wszystkie uszkodzone atrakcje STR_5793 :Usuwa historię katastrof,{NEWLINE}dzięki czemu goście nie będą narzekać, że atrakcja jest niebezpieczna STR_5794 :Niektóre scenariusze blokują edycję{NEWLINE}istniejących już w parku atrakcji.{NEWLINE}Ta opcja obchodzi tę restrykcję -STR_5795 :Goście korzystają ze wszystkich atrakcji w parku{NEWLINE}nawet jeśli ich intensywność jest ekstremalna +STR_5795 :Goście korzystają ze wszystkich atrakcji{NEWLINE}w parku, nawet jeśli ich intensywność jest ekstremalna STR_5796 :Wymusza zamknięcie/otwarcie parku STR_5797 :Wyłącza zmienność pogody{NEWLINE}i ustawia wybraną pogodę STR_5798 :Pozwala budować atrakcje w trakcie pauzy @@ -2935,10 +2935,10 @@ STR_5804 :Wycisz dźwięk STR_5805 :Jeśli zaznaczone, Twój serwer zostanie dodany{NEWLINE}do listy publicznych serwerów, co umożliwi{NEWLINE}wyszukanie go przez wszystkich STR_5806 :Przełącz tryb okna STR_5807 :{WINDOW_COLOUR_2}Liczba atrakcji: {BLACK}{COMMA16} -STR_5808 :{WINDOW_COLOUR_2}Liczba sklepów i stoisk: {BLACK}{COMMA16} +STR_5808 :{WINDOW_COLOUR_2}Liczba sklepów i kiosków: {BLACK}{COMMA16} STR_5809 :{WINDOW_COLOUR_2}Liczba kiosków informacyjnych i innych obiektów: {BLACK}{COMMA16} STR_5810 :Wyłącz limit pojazdów -STR_5811 :Jeśli zaznaczone, możesz mieć do{NEWLINE}255 wagoników na pociąg i 31{NEWLINE}pociągów na atrakcję +STR_5811 :Umożliwia ustawienie do 255 wagoników na pociąg i 31 pociągów na atrakcję STR_5812 :Pokaż okienko gry sieciowej STR_5813 :„{STRING}” STR_5814 :{WINDOW_COLOUR_1}„{STRING}” @@ -2946,16 +2946,16 @@ STR_5814 :{WINDOW_COLOUR_1}„{STRING}” #Wskazówki STR_5815 :Pokaż licznik FPS w grze STR_5816 :Ustawia stosunek skalowania grafiki.{NEWLINE}Przydatne szczególnie przy grze{NEWLINE}w wysokiej rozdzielczości -STR_5819 :[Wymaga sterownika sprzętowego]{NEWLINE}Zatrzymaj grę jeśli nakładka Steam{NEWLINE} jest otwarta -STR_5820 :Zmniejsz okienko gry w przypadku{NEWLINE}utraty ostrości w trybie pełnoekranowym +STR_5819 :[Wymaga silnika sprzętowego]{NEWLINE}Zatrzymuje grę, jeśli nakładka Steam jest otwarta +STR_5820 :Zmniejsza okno gry w przypadku{NEWLINE}utraty ostrości w trybie pełnoekranowym STR_5822 :Cykl dnia i nocy.{NEWLINE}Pełny cykl trwa jeden miesiąc w grze. STR_5823 :Wyświetlaj banery z dużych liter (zachowanie RCT1) STR_5824 :Wyłącz efekty świetlne{NEWLINE}w trakcie burz -STR_5825 :Zatrzymuj kursor myszki wewnątrz okna -STR_5826 :Odwróć przeciąganie prawym przyciskiem myszki +STR_5825 :Zatrzymuje kursor myszki wewnątrz okna +STR_5826 :Odwraca kierunek przeciągania widoku prawym przyciskiem myszy STR_5827 :Ustawia kolor interfejsu graficznego -STR_5828 :Zmień użyty format jednostki użyty do czasu, prędkość itp. -STR_5829 :Zmień rodzaj użytej waluty. Jedynie w celach wizualnych, nie ma wdrożonego dokładnego kursu wymiany. +STR_5828 :Zmień format jednostek używanych do pomiaru dystansu, prędkości itp. +STR_5829 :Zmień rodzaj używanej waluty. Jedynie w celach wizualnych, nie ma wdrożonego dokładnego kursu wymiany. STR_5830 :Zmień używany język STR_5831 :Zmień używany format{NEWLINE}wyświetlanej temperatury STR_5832 :Pokaż wysokość jako ogólną jednostkę w miejscu formatu jednostki ustawionej w zakładce „Odległość i prędkość” @@ -2978,11 +2978,11 @@ STR_5849 :Automatycznie rozlokuj{NEWLINE}nowo zatrudniony personel STR_5851 :Ustaw domyślną częstotliwość inspekcji{NEWLINE}na nowych atrakcjach STR_5853 :Włącz/Wyłącz efekty dźwiękowe STR_5854 :Włącz/Wyłącz muzykę na atrakcjach -STR_5855 :Ustaw normalny pełny ekran, bezramkowy pełny ekran{NEWLINE}lub tryb okienkowy +STR_5855 :Ustaw normalny pełny ekran, bezramkowy pełny ekran lub tryb okienkowy STR_5856 :Ustaw rozdzielczość ekranu w trybie pełnoekranowym STR_5857 :Ustawienia gry STR_5858 :Użyj do wyświetlania GPU zamiast CPU. Pomoże to w poprawie kompatybilności z oprogramowaniem do przechwytywania ekranu, jednak może wpłynąć negatywnie na wydajność. -STR_5859 :Włącz zmienną ilość klatek dla {NEWLINE}płynniejszej gry. Gdy wyłączone,{NEWLINE}gra będzie używała stałych 40 FPS. +STR_5859 :Włącz zmienną liczbę klatek dla {NEWLINE}płynniejszej gry. Gdy wyłączone,{NEWLINE}gra będzie używała stałych 40 FPS. STR_5860 :Przełącz między oryginalnym/zdekompilowanym rysowaniem trasy STR_5861 :Błąd weryfikacji klucza STR_5862 :Blokuj nieznanych graczy. @@ -2997,9 +2997,9 @@ STR_5870 :Pokaż informacje o serwerze STR_5871 :Wyłącz usychanie kwiatów STR_5872 :Kwiaty się nie starzeją, nie usychają, nie trzeba ich wymieniać STR_5873 :Wyciągarka dozwolona na każdym torze -STR_5874 :Umożliwia przekształcenie dowolnego typu toru w wyciągarkę. +STR_5874 :Umożliwia przekształcenie dowolnego typu toru w wyciągarkę STR_5875 :Silnik graficzny: -STR_5876 :Silnik używany do generowania grafiki. +STR_5876 :Silnik używany do generowania grafiki STR_5877 :Programowy STR_5878 :Programowy (karta graficzna) STR_5879 :OpenGL (eksperymentalne) @@ -3013,11 +3013,11 @@ STR_5886 :{WINDOW_COLOUR_2}Symbol waluty: STR_5887 :Prefiks STR_5888 :Sufiks STR_5889 :Własny symbol waluty -STR_5890 :Wprowadź własny symbol waluty +STR_5890 :Wprowadź własny symbol waluty: STR_5891 :Domyślny STR_5892 :Idź do domyślnego katalogu STR_5893 :Kurs wymiany -STR_5894 :Wprowadź kurs wymiany +STR_5894 :Wprowadź kurs wymiany: STR_5895 :Zapisz trasę STR_5896 :Nieudany zapis trasy! STR_5898 :{BLACK}Nie można załadować trasy, plik może być {newline}uszkodzony lub niedostępny! @@ -3028,10 +3028,10 @@ STR_5902 :Pokaż ścianki ograniczające STR_5903 :Pokaż okno debugowania rysowania STR_5904 :Resetuj datę STR_5905 :Narzędzie do generowania map, które automatycznie tworzy krajobraz -STR_5906 :Przybliż do pozycji kursora -STR_5907 :Jeśli włączone, przybliżanie będzie koncentrować się wokół kursora, a nie na środku ekranu. -STR_5908 :Pozwól zmienić na dowolny typ pojazdu -STR_5909 :Pozwala dowolnie zmienić typ pojazdu. Może powodować wypadki. +STR_5906 :Przybliżaj do pozycji kursora +STR_5907 :Jeśli włączone, przybliżanie będzie koncentrować się wokół kursora, a nie na środku ekranu +STR_5908 :Pozwól na dowolne zmiany typu pojazdu +STR_5909 :Pozwala dowolnie zmienić typ pojazdu. Może powodować wypadki STR_5910 :Zastosuj STR_5911 :Przezroczyste ścieżki STR_5912 :Przełącznik przezroczystych ścieżek @@ -3108,7 +3108,7 @@ STR_5982 :Rodzaj dużej scenerii: {BLACK}{COMMA16} STR_5983 :ID elementu dużej scenerii: {BLACK}{COMMA16} STR_5984 :Zablokowane ścieżki: STR_5985 :Nowy katalog -STR_5986 :Wprowadź nazwę nowego katalogu. +STR_5986 :Wprowadź nazwę nowego katalogu: STR_5987 :Nie można utworzyć katalogu STR_5988 :Nie ma więcej terenu na sprzedaż STR_5989 :Nie ma więcej praw do zabudowy na sprzedaż @@ -3117,13 +3117,13 @@ STR_5991 :Nie można wkleić elementu… STR_5992 :Limit elementów mapy został osiągnięty STR_5993 :Skopiuj wybrany element STR_5994 :Wklej wybrany element -STR_5995 :Przyśpieszenie -STR_5996 :Przyśpieszenie czasu +STR_5995 :Przyspieszenie +STR_5996 :Prędkość przyspieszenia STR_5997 :Dodaj/ustaw pieniądze STR_5998 :Dodaj pieniądze STR_5999 :Ustaw pieniądze -STR_6000 :Wprowadź nową wartość -STR_6001 :Włącz elementy świetlne (eksperymentalne) +STR_6000 :Wprowadź nową wartość: +STR_6001 :Włącz efekty świetlne (eksperymentalne) STR_6002 :Lampy i atrakcje będą świeciły w nocy.{NEWLINE}Wymaga włączenia silnika sprzętowego. STR_6003 :Widok przekroju STR_6004 :Widok przekroju @@ -3146,8 +3146,8 @@ STR_6020 :Konstrukcja - Użyj domyślnej trasy STR_6021 :Konstrukcja - Nachylenie w dół STR_6022 :Konstrukcja - Nachylenie w górę STR_6023 :Konstrukcja - Przełącznik wyciągarki -STR_6024 :Konstrukcja - Nachylenie w lewo -STR_6025 :Konstrukcja - Nachylenie w prawo +STR_6024 :Konstrukcja - Przechylenie w lewo +STR_6025 :Konstrukcja - Przechylenie w prawo STR_6026 :Konstrukcja - Poprzedni element STR_6027 :Konstrukcja - Następny element STR_6028 :Konstrukcja - Wybuduj bieżący @@ -3161,7 +3161,7 @@ STR_6035 :Proszę wybrać katalog z RCT1 STR_6036 :Wyczyść STR_6037 :Proszę wybrać prawidłowy katalog RCT1 STR_6038 :Jeżeli masz zainstalowane RCT1, ustaw tę opcję na ścieżkę do owej gry, aby załadować scenariusze, muzykę itp. -STR_6039 :Szybkie niszczenie atrakcji +STR_6039 :Szybkie burzenie atrakcji STR_6040 :Edytuj opcje scenariusza STR_6041 :{BLACK}Nie masz zatrudnionych mechaników! STR_6042 :Załaduj mapę wysokości @@ -3246,7 +3246,7 @@ STR_6129 :Skopiuj wybrany przedmiot do schowka STR_6130 :Skopiuj listę do schowka STR_6131 :Ścieżka elementu STR_6132 :Ignoruj wyniki badań -STR_6133 :Dostęp do kolejek i scenerii, które nie zostały jeszcze wynalezione +STR_6133 :Umożliwia dostęp do atrakcji i scenerii, które nie zostały jeszcze wynalezione STR_6134 :Wyczyść scenerię STR_6135 :Klient wysłał nieprawidłowe żądanie STR_6136 :Serwer wysłał nieprawidłowe żądanie @@ -3284,7 +3284,7 @@ STR_6169 :Wybór scenariusza STR_6170 :Dostosowanie interfejsu STR_6171 :Szukaj STR_6172 :Szukaj -STR_6173 :Wpisz nazwę której szukasz: +STR_6173 :Podaj imię, którego szukasz: STR_6188 :Wymiociny STR_6189 :Kaczka STR_6191 :Powierzchnia @@ -3302,7 +3302,7 @@ STR_6202 :Styl wirtualnego podłoża: STR_6203 :Gdy włączone, wirtualne podłoże będzie prezentowane przy wciśniętym Ctrl lub Shift, aby ułatwić stawianie elementów w pionie. STR_6215 :Konstrukcja STR_6216 :Operacja -STR_6217 :Dostępność atrakcji / ścieżki +STR_6217 :Dostępność atrakcji/torów STR_6218 :Oficjalne OpenRCT2 STR_6219 :Podświetl problemy na ścieżkach STR_6220 :Przełącz na dostępne @@ -3356,12 +3356,12 @@ STR_6270 :Powierzchnie terenu STR_6271 :Krawędzie terenu STR_6272 :Stacje STR_6273 :Muzyka -STR_6274 :Nie można ustawić schematu koloru… +STR_6274 :Nie można ustawić schematu kolorów… STR_6275 :{WINDOW_COLOUR_2}Styl stacji: STR_6276 :Na {RED}{STRINGID} utykają goście, prawdopodobnie z powodu nieprawidłowego typu atrakcji albo trybu operowania. STR_6277 :Numer stacji: {BLACK}{STRINGID} -STR_6278 :Liczba autozapisów -STR_6279 :Liczba autozapisów powinna zostać zachowana +STR_6278 :Liczba autozapisów: +STR_6279 :Liczba autozapisów, które powinny zostać zachowane STR_6280 :Czat STR_6281 :Pokaż osobny przycisk dla czatu w pasku narzędzi STR_6282 :Czat @@ -3386,11 +3386,11 @@ STR_6309 :Połącz ponownie STR_6310 :{WINDOW_COLOUR_2}Pozycja: {BLACK}{INT32} {INT32} {INT32} STR_6311 :{WINDOW_COLOUR_2}Następna: {BLACK}{INT32} {INT32} {INT32} STR_6312 :(powierzchnia) -STR_6313 :(nechylenie {INT32}) +STR_6313 :(nachylenie {INT32}) STR_6314 :{WINDOW_COLOUR_2}Cel: {BLACK}{INT32}, {INT32} tolerancja {INT32} -STR_6315 :{WINDOW_COLOUR_2}Cel wykrywania ścieżki: {BLACK}{INT32}, {INT32}, {INT32} dir {INT32} -STR_6316 :{WINDOW_COLOUR_2}Historia wykrywania ścieżki: -STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} folder {INT32} +STR_6315 :{WINDOW_COLOUR_2}Cel szukania drogi: {BLACK}{INT32}, {INT32}, {INT32} kier. {INT32} +STR_6316 :{WINDOW_COLOUR_2}Historia szukania drogi: +STR_6317 :{BLACK}{INT32}, {INT32}, {INT32} kier. {INT32} STR_6318 :Desynchronizacja sieci.{NEWLINE}Plik z logami: {STRING} STR_6319 :Hamulec blokowy zamknięty STR_6320 :Niezniszczalne @@ -3432,7 +3432,7 @@ STR_6356 :Przyzywa kaczki jeśli park zawiera wodę STR_6357 :Usuwa wszystkie kaczki z mapy STR_6358 :Strona {UINT16} STR_6359 :{POP16}{POP16}Strona {UINT16} -STR_6361 :Włącz efekty świetlne atrakcji (eksperymentalne) +STR_6361 :Włącz oświetlenie pojazdów STR_6362 :Jeśli włączone, pojazdy będą oświetlone w nocy. STR_6363 :Tekst skopiowany do schowka STR_6364 :{RED}{COMMA16} osoba zmarła w wypadku na {STRINGID} @@ -3532,8 +3532,8 @@ STR_6457 :Zgłoś błąd na GitHubie STR_6458 :Śledź na ekranie głównym STR_6460 :K STR_6461 :Kierunek -STR_6462 :Ekscytacja -STR_6463 :Ekscytacja: {COMMA2DP32} +STR_6462 :Emocje +STR_6463 :Emocje: {COMMA2DP32} STR_6464 :Intensywność STR_6465 :Intensywność: {COMMA2DP32} STR_6466 :Mdłości @@ -3572,7 +3572,7 @@ STR_6498 :Włącz w celu zachowania kwadratowej mapy. STR_6499 :Typ pojazdu nie jest obsługiwany przez format projektu toru STR_6500 :Elementy toru nieobsługiwane przez format projektu toru STR_6501 :Losowy kolor -STR_6502 :Wprowadź wartość pomiędzy {COMMA16} a {COMMA16} +STR_6502 :Wprowadź wartość pomiędzy {COMMA16} a {COMMA16}: STR_6503 :Musi być wybrany przynajmniej jeden obiekt stacji STR_6504 :Należy wybrać co najmniej jeden element powierzchni terenu STR_6505 :Należy wybrać co najmniej jeden element krawędzi terenu @@ -3588,7 +3588,7 @@ STR_6514 :Nieprawidłowa wysokość! STR_6515 :{BLACK}Rollercoaster Tycoon 1 niezaładowany - zostaną użyte grafiki zapasowe. STR_6516 :Jeden lub więcej obiektów wymaga załadowania Rollercoaster Tycoon 1, aby mogły być poprawnie wyświetlane. Zostaną użyte grafiki zapasowe. STR_6517 :Jeden lub więcej obiektów w tym parku wymaga załadowania Rollercoaster Tycoon 1, aby mogły być poprawnie wyświetlane. Zostaną użyte grafiki zapasowe. -STR_6518 :{BLACK}Najedź na scenariusz aby wyświetlić jego opis oraz cel. Kliknij scenariusz aby rozpocząc rozgrywkę. +STR_6518 :{BLACK}Najedź na scenariusz aby wyświetlić jego opis oraz cel. Kliknij scenariusz aby rozpocząć rozgrywkę. STR_6519 :Dodatkowe STR_6520 :Paczki zasobów STR_6521 :Niski priorytet @@ -3599,13 +3599,13 @@ STR_6525 :Przeładuj wszystkie zasoby w grze z włączonymi paczkami zasobów STR_6526 :(podstawowa grafika, muzyka i efekty dźwiękowe) STR_6527 :Zawody STR_6528 :Nieprawidłowe parametry toru! -STR_6529 :Nieprawidłowy parametr schematu koloru! +STR_6529 :Nieprawidłowy parametr schematu kolorów! STR_6530 :User Created Expansion Set STR_6531 :Wehikuł czasu STR_6532 :Kraina Marzeń Katy -STR_6533 :{WINDOW_COLOUR_2}Czynnik ekscytacji: {BLACK}-{COMMA16}% -STR_6534 :{WINDOW_COLOUR_2}Czynnik intensywności: {BLACK}-{COMMA16}% -STR_6535 :{WINDOW_COLOUR_2}Czynnik mdłości: {BLACK}-{COMMA16}% +STR_6533 :{WINDOW_COLOUR_2}Emocje: {BLACK}-{COMMA16}% +STR_6534 :{WINDOW_COLOUR_2}Intensywność: {BLACK}-{COMMA16}% +STR_6535 :{WINDOW_COLOUR_2}Mdłości: {BLACK}-{COMMA16}% STR_6536 :Ten park został zapisany w późniejszej wersji OpenRCT2. Park został zapisany w v{INT32}, a obecnie używasz v{INT32}. STR_6537 :Zezwól na zwykłe chodniki jako kolejki STR_6538 :Pokazuje zwykłe chodniki na liście kolejek do atrakcji w menu chodników. @@ -3660,9 +3660,9 @@ STR_6586 :OpenRCT2 STR_6587 :Motyw tytułowy OpenRCT2 jest dziełem Allistera Brimble’a,{NEWLINE}udostępnionym na licencji Creative Commons Uznanie autorstwa Na tych samych warunkach 4.0. STR_6588 :Dziękujemy Hermanowi Ridderingowi za umożliwienie nam nagrania 35er Voigt. STR_6589 :Umieść przyciski okna po lewej stronie -STR_6590 :Umieść przyciski okna (np. zamknięcie okna) po lewej stronie paska tytułowego zamiast po prawej. +STR_6590 :Umieszcza przyciski okna (np. zamknięcie okna) po lewej stronie paska tytułowego zamiast po prawej. STR_6591 :Pracownik obecnie naprawia atrakcję i nie może zostać zwolniony. -STR_6592 :Pracownik obecnie inspektuje atrakcję i nie może zostać zwolniony. +STR_6592 :Pracownik obecnie dokonuje inspekcji atrakcji i nie może zostać zwolniony. STR_6593 :Usuń ogrodzenia STR_6594 :Inspektor kafelków: Przełącz nachylenie ściany STR_6595 :{WINDOW_COLOUR_2}Autor: {BLACK}{STRING} @@ -3688,7 +3688,7 @@ STR_6614 :Nie można zmienić opłaty za wstęp do parku STR_6615 :Tor na tym kafelku wymaga wody STR_6616 :Działanie niedozwolone dla tego typu pracownika STR_6617 :Nie można zamienić elementu kafelka z samym sobą -STR_6618 :Nie można ograniczyć ani zniesć ograniczeń dla obiektu… +STR_6618 :Nie można ograniczyć ani znieść ograniczeń dla obiektu… STR_6619 :Typ obiektu nie może być ograniczony! STR_6620 :Obiekt nieznaleziony! STR_6621 :Ogranicz @@ -3708,7 +3708,7 @@ STR_6634 :Sprawdzanie plików projektów tras… STR_6635 :Sprawdzanie paczek zasobów… STR_6636 :Sprawdzanie sekwencji tytułowych… STR_6637 :Ładowanie sekwencji tytułowej… -STR_6638 :Powiększony interfejs +STR_6638 :Powiększ interfejs STR_6639 :Modyfikuje interfejs, aby ułatwić obsługę dotykową STR_6640 :Edytuj paczki zasobów… STR_6641 :Okno ładowania/postępu @@ -3756,27 +3756,27 @@ STR_6682 :Generator mapy - Generator STR_6683 :Generator mapy - Teren STR_6684 :Generator mapy - Woda STR_6685 :Generator mapy - Lasy -STR_6686 :Stosunek drzew do powierzchni terenu: +STR_6686 :Stosunek drzew do terenu: STR_6687 :Min. wysokość drzew: STR_6688 :Maks. wysokość drzew: STR_6689 :{UINT16}% STR_6690 :Min. wysokość terenu -STR_6691 :Wprowadź minimalną wysokość terenu pomiędzy {COMMA16} a {COMMA16} +STR_6691 :Wprowadź minimalną wysokość terenu pomiędzy {COMMA16} a {COMMA16}: STR_6692 :Maks. wysokość terenu -STR_6693 :Wprowadź maksymalną wysokość terenu pomiędzy {COMMA16} a {COMMA16} +STR_6693 :Wprowadź maksymalną wysokość terenu pomiędzy {COMMA16} a {COMMA16}: STR_6694 :Min. wysokość drzew -STR_6695 :Wprowadź minimalną wysokość drzew pomiędzy {COMMA16} a {COMMA16} +STR_6695 :Wprowadź minimalną wysokość drzew pomiędzy {COMMA16} a {COMMA16}: STR_6696 :Maks. wysokość drzew -STR_6697 :Wprowadź maksymalną wysokość drzew pomiędzy {COMMA16} a {COMMA16} +STR_6697 :Wprowadź maksymalną wysokość drzew pomiędzy {COMMA16} a {COMMA16}: STR_6698 :Stosunek drzew do powierzchni terenu -STR_6699 :Wprowadź stosunek drzew do powierzchni terenu pomiędzy {COMMA16} a {COMMA16} +STR_6699 :Wprowadź stosunek drzew do powierzchni terenu pomiędzy {COMMA16} a {COMMA16}: STR_6700 :Bazowa częstotliwość szumu Simplex -STR_6701 :Wprowadź bazową częstotliwość pomiędzy {COMMA2DP32} a {COMMA2DP32} +STR_6701 :Wprowadź bazową częstotliwość pomiędzy {COMMA2DP32} a {COMMA2DP32}: STR_6702 :Oktawy szumu Simplex -STR_6703 :Wprowadź oktawy pomiędzy {COMMA16} a {COMMA16} +STR_6703 :Wprowadź oktawy pomiędzy {COMMA16} a {COMMA16}: STR_6704 :{COMMA2DP32} -STR_6705 :Przeglądaj… +STR_6705 :Wczytaj… STR_6706 :{WINDOW_COLOUR_2}Bieżący plik obrazu: {BLACK}{STRING} STR_6707 :(brak) STR_6708 :Siła wygładzania -STR_6709 :Wprowadź siłę wygładzania pomiędzy {COMMA16} a {COMMA16} +STR_6709 :Wprowadź siłę wygładzania pomiędzy {COMMA16} a {COMMA16}: From 03829f9cea401595e5e1461527b7dbf09b1481ff Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Sat, 7 Dec 2024 12:21:50 +0100 Subject: [PATCH 134/139] Fill in the blanks in RCT1::PeepAnimationGroup enum (#23298) --- src/openrct2/rct1/RCT1.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/openrct2/rct1/RCT1.h b/src/openrct2/rct1/RCT1.h index f02760cd8a..349d916890 100644 --- a/src/openrct2/rct1/RCT1.h +++ b/src/openrct2/rct1/RCT1.h @@ -523,12 +523,15 @@ namespace OpenRCT2::RCT1 EntertainerSnowman = 9, EntertainerKnight = 10, EntertainerAstronaut = 11, - + IceCream = 12, + Chips = 13, + Burger = 14, + Drink = 15, Balloon = 16, Candyfloss = 17, Umbrella = 18, - Pizza = 19, // Unsure - SecurityAlt = 20, // Unknown + Pizza = 19, + SecurityAlt = 20, Popcorn = 21, ArmsCrossed = 22, HeadDown = 23, @@ -536,9 +539,13 @@ namespace OpenRCT2::RCT1 VeryNauseous = 25, RequireToilet = 26, Hat = 27, - Burger = 28, + HotDog = 28, Tentacle = 29, - ToffeeApple = 30 + ToffeeApple = 30, + Doughnut = 31, + Coffee = 32, + Chicken = 33, + Lemonade = 34, }; struct Peep : RCT12EntityBase From 7154e85c0ab0fa297f9eb2a756ba8752d0361d23 Mon Sep 17 00:00:00 2001 From: Matt <5415177+ZehMatt@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:08:00 +0200 Subject: [PATCH 135/139] Add stable paint sort (as a debug option) --- data/language/en-GB.txt | 1 + distribution/changelog.txt | 1 + src/openrct2-ui/UiStringIds.h | 1 + src/openrct2-ui/windows/DebugPaint.cpp | 10 ++- src/openrct2/paint/Paint.cpp | 115 ++++++++++++++++++++++--- src/openrct2/paint/Paint.h | 1 + 6 files changed, 117 insertions(+), 12 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index b0a4e3afaf..ccea05dde4 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3785,3 +3785,4 @@ STR_6706 :{WINDOW_COLOUR_2}Current image file: {BLACK}{STRING} STR_6707 :(none selected) STR_6708 :Smooth Strength STR_6709 :Enter Smooth Strength between {COMMA16} and {COMMA16} +STR_6710 :Stable sort diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 627598ac12..f28ee9bdd4 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -5,6 +5,7 @@ - Improved: [#23051] Add large sloped turns and new inversions to the Twister, Vertical Drop, Hyper and Flying Roller Coasters. - Improved: [#23123] Improve sorting of roller coasters in build new ride menu. - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). +- Improved: [#23229] Add debug option for making the sprite sorting algorithm stable. - Improved: [#23233] Add diagonal booster to LSM Launched Coaster. - Fix: [#20070, #22972] Missing and mismatched flat and sloped footpaths on several scenarios. - Fix: [#22726] ‘Force park rating’ cheat is not saved with the park. diff --git a/src/openrct2-ui/UiStringIds.h b/src/openrct2-ui/UiStringIds.h index 8cd4d4f85d..e706b417a4 100644 --- a/src/openrct2-ui/UiStringIds.h +++ b/src/openrct2-ui/UiStringIds.h @@ -455,6 +455,7 @@ namespace OpenRCT2 STR_DEBUG_PAINT_SHOW_DIRTY_VISUALS = 6144, STR_DEBUG_PAINT_SHOW_SEGMENT_HEIGHTS = 5901, STR_DEBUG_PAINT_SHOW_WIDE_PATHS = 6261, + STR_DEBUG_PAINT_STABLE_SORT = 6710, // Window: DemolishRidePrompt STR_DEMOLISH = 994, diff --git a/src/openrct2-ui/windows/DebugPaint.cpp b/src/openrct2-ui/windows/DebugPaint.cpp index c90559fbbc..92b64dac6a 100644 --- a/src/openrct2-ui/windows/DebugPaint.cpp +++ b/src/openrct2-ui/windows/DebugPaint.cpp @@ -27,10 +27,11 @@ namespace OpenRCT2::Ui::Windows WIDX_TOGGLE_SHOW_SEGMENT_HEIGHTS, WIDX_TOGGLE_SHOW_BOUND_BOXES, WIDX_TOGGLE_SHOW_DIRTY_VISUALS, + WIDX_TOGGLE_STABLE_PAINT_SORT, }; constexpr int32_t WINDOW_WIDTH = 200; - constexpr int32_t WINDOW_HEIGHT = 8 + 15 + 15 + 15 + 15 + 11 + 8; + constexpr int32_t WINDOW_HEIGHT = 8 + (15 * 6) + 8; // clang-format off static Widget window_debug_paint_widgets[] = { @@ -40,6 +41,7 @@ namespace OpenRCT2::Ui::Windows MakeWidget({8, 8 + 15 * 2}, { 185, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_DEBUG_PAINT_SHOW_SEGMENT_HEIGHTS), MakeWidget({8, 8 + 15 * 3}, { 185, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_DEBUG_PAINT_SHOW_BOUND_BOXES ), MakeWidget({8, 8 + 15 * 4}, { 185, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_DEBUG_PAINT_SHOW_DIRTY_VISUALS ), + MakeWidget({8, 8 + 15 * 5}, { 185, 12}, WindowWidgetType::Checkbox, WindowColour::Secondary, STR_DEBUG_PAINT_STABLE_SORT ), kWidgetsEnd, }; // clang-format on @@ -91,6 +93,11 @@ namespace OpenRCT2::Ui::Windows gShowDirtyVisuals = !gShowDirtyVisuals; GfxInvalidateScreen(); break; + + case WIDX_TOGGLE_STABLE_PAINT_SORT: + gPaintStableSort = !gPaintStableSort; + GfxInvalidateScreen(); + break; } } @@ -136,6 +143,7 @@ namespace OpenRCT2::Ui::Windows WidgetSetCheckboxValue(*this, WIDX_TOGGLE_SHOW_SEGMENT_HEIGHTS, gShowSupportSegmentHeights); WidgetSetCheckboxValue(*this, WIDX_TOGGLE_SHOW_BOUND_BOXES, gPaintBoundingBoxes); WidgetSetCheckboxValue(*this, WIDX_TOGGLE_SHOW_DIRTY_VISUALS, gShowDirtyVisuals); + WidgetSetCheckboxValue(*this, WIDX_TOGGLE_STABLE_PAINT_SORT, gPaintStableSort); } void OnDraw(DrawPixelInfo& dpi) override diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index dcbd52ef9e..4b466ffab0 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -57,6 +57,7 @@ static constexpr uint8_t BoundBoxDebugColours[] = { bool gShowDirtyVisuals; bool gPaintBoundingBoxes; bool gPaintBlockedTiles; +bool gPaintStableSort; static void PaintAttachedPS(DrawPixelInfo& dpi, PaintStruct* ps, uint32_t viewFlags); static void PaintPSImageWithBoundingBoxes(PaintSession& session, PaintStruct* ps, ImageId imageId, int32_t x, int32_t y); @@ -403,13 +404,14 @@ static std::pair PaintStructsGetNextPending(PaintStr // Re-orders all nodes after the specified child node and marks the child node as traversed. The resulting // order of the children is the depth based on rotation and dimensions of the bounding box. template -static void PaintStructsSortQuadrant(PaintStruct* parent, PaintStruct* child) +static void PaintStructsSortQuadrantLegacy(PaintStruct* parent, PaintStruct* child) { // Mark visited. child->SortFlags &= ~PaintSortFlags::PendingVisit; // Compare all the children below the first child and move them up in the list if they intersect. const PaintStructBoundBox& initialBBox = child->Bounds; + for (;;) { auto* ps = child; @@ -443,7 +445,78 @@ static void PaintStructsSortQuadrant(PaintStruct* parent, PaintStruct* child) } } +// Re-orders all nodes after the specified child node and marks the child node as traversed. The resulting +// order of the children is the depth based on rotation and dimensions of the bounding box. template +static void PaintStructsSortQuadrantStable(PaintStruct* parent, PaintStruct* child) +{ + // Mark visited. + child->SortFlags &= ~PaintSortFlags::PendingVisit; + + // Compare all the children below the first child and move them up in the list if they intersect. + const PaintStructBoundBox& initialBBox = child->Bounds; + + // Create a temporary list to collect sorted nodes in stable order. + PaintStruct* sortedHead = nullptr; + PaintStruct* sortedTail = nullptr; + + // Traverse the list and reorder based on intersection. + for (;;) + { + PaintStruct* next = child->NextQuadrantEntry; + + if (next != nullptr) + { + PREFETCH(&next->Bounds); + } + + // Stop if at the end of the list or outside the quadrant range. + if (next == nullptr || next->SortFlags & PaintSortFlags::OutsideQuadrant) + { + break; + } + + // Ignore nodes that are not neighbors. + if (!(next->SortFlags & PaintSortFlags::Neighbour)) + { + child = next; + continue; + } + + // Detach the current node from the list if it intersects. + if (CheckBoundingBox(initialBBox, next->Bounds)) + { + child->NextQuadrantEntry = next->NextQuadrantEntry; + + if (sortedHead == nullptr) + { + sortedHead = next; + sortedTail = next; + next->NextQuadrantEntry = nullptr; + } + else + { + sortedTail->NextQuadrantEntry = next; + sortedTail = next; + next->NextQuadrantEntry = nullptr; + } + } + else + { + child = next; + } + } + + // Merge the sorted list back into the main list after parent. + if (sortedHead != nullptr) + { + PaintStruct* originalNext = parent->NextQuadrantEntry; + parent->NextQuadrantEntry = sortedHead; + sortedTail->NextQuadrantEntry = originalNext; + } +} + +template static PaintStruct* PaintArrangeStructsHelperRotation(PaintStruct* psQuadrantEntry, uint16_t quadrantIndex, uint8_t flag) { // We keep track of the first node in the quadrant so the next call with a higher quadrant index @@ -464,7 +537,15 @@ static PaintStruct* PaintArrangeStructsHelperRotation(PaintStruct* psQuadrantEnt break; } - PaintStructsSortQuadrant(parent, child); + if constexpr (TStableSort) + { + PaintStructsSortQuadrantStable(parent, child); + } + else + { + PaintStructsSortQuadrantLegacy(parent, child); + } + ps = parent; } @@ -496,7 +577,7 @@ static void PaintStructsLinkQuadrants(PaintSessionCore& session, PaintStruct& ps } while (++quadrantIndex <= session.QuadrantFrontIndex); } -template +template static void PaintSessionArrangeImpl(PaintSessionCore& session) { uint32_t quadrantIndex = session.QuadrantBackIndex; @@ -511,12 +592,13 @@ static void PaintSessionArrangeImpl(PaintSessionCore& session) PaintStruct psHead{}; PaintStructsLinkQuadrants(session, psHead); - PaintStruct* psNextQuadrant = PaintArrangeStructsHelperRotation( + PaintStruct* psNextQuadrant = PaintArrangeStructsHelperRotation( &psHead, session.QuadrantBackIndex, PaintSortFlags::Neighbour); while (++quadrantIndex < session.QuadrantFrontIndex) { - psNextQuadrant = PaintArrangeStructsHelperRotation(psNextQuadrant, quadrantIndex, PaintSortFlags::None); + psNextQuadrant = PaintArrangeStructsHelperRotation( + psNextQuadrant, quadrantIndex, PaintSortFlags::None); } session.PaintHead = psHead.NextQuadrantEntry; @@ -524,11 +606,18 @@ static void PaintSessionArrangeImpl(PaintSessionCore& session) using PaintArrangeWithRotation = void (*)(PaintSessionCore& session); -constexpr std::array _paintArrangeFuncs = { - PaintSessionArrangeImpl<0>, - PaintSessionArrangeImpl<1>, - PaintSessionArrangeImpl<2>, - PaintSessionArrangeImpl<3>, +constexpr std::array _paintArrangeFuncsLegacy = { + PaintSessionArrangeImpl, + PaintSessionArrangeImpl, + PaintSessionArrangeImpl, + PaintSessionArrangeImpl, +}; + +constexpr std::array _paintArrangeFuncsStable = { + PaintSessionArrangeImpl, + PaintSessionArrangeImpl, + PaintSessionArrangeImpl, + PaintSessionArrangeImpl, }; /** @@ -538,7 +627,11 @@ constexpr std::array _paintArrangeFuncs = { void PaintSessionArrange(PaintSessionCore& session) { PROFILED_FUNCTION(); - return _paintArrangeFuncs[session.CurrentRotation](session); + if (gPaintStableSort) + { + return _paintArrangeFuncsStable[session.CurrentRotation](session); + } + return _paintArrangeFuncsLegacy[session.CurrentRotation](session); } static void PaintDrawStruct(PaintSession& session, PaintStruct* ps) diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 250c6b834a..a52b751a71 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -284,6 +284,7 @@ extern bool gShowDirtyVisuals; extern bool gPaintBoundingBoxes; extern bool gPaintBlockedTiles; extern bool gPaintWidePathsAsGhost; +extern bool gPaintStableSort; PaintStruct* PaintAddImageAsParent( PaintSession& session, const ImageId image_id, const CoordsXYZ& offset, const BoundBoxXYZ& boundBox); From 962358974fe7d2c8ed1bcb1dad611c3955d09a4c Mon Sep 17 00:00:00 2001 From: OpenRCT2 git bot Date: Sun, 8 Dec 2024 04:02:07 +0000 Subject: [PATCH 136/139] Merge Localisation/master into OpenRCT2/develop --- data/language/nl-NL.txt | 2 ++ data/language/pl-PL.txt | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/data/language/nl-NL.txt b/data/language/nl-NL.txt index afc0c0d1a8..443dd83e64 100644 --- a/data/language/nl-NL.txt +++ b/data/language/nl-NL.txt @@ -97,6 +97,7 @@ STR_0095 :Rodelachtbaan STR_0096 :Klassieke houten achtbaan STR_0097 :Klassieke staande achtbaan STR_0098 :LSM-lanceringsachtbaan +STR_0099 :Klassieke houten twisterachtbaan STR_0512 :Een compacte achtbaan met een spiraalvormige kettingheuvel en soepele, kronkelende afdalingen. STR_0513 :Een achtbaan met loopings waar de passagiers in de karretjes staan. STR_0514 :Treinen hangen onder de baan en zwaaien naar buiten in de bochten. @@ -182,6 +183,7 @@ STR_0605 :Passagiers rodelen over een kronkelende stalen baan, waarbij ze zel STR_0606 :Een ouder type houten achtbaan met een snelle en ruwe loop, veel airtime, enige zijwaartse G-krachten en het gevoel van controleverlies. STR_0607 :Een intens ouder type achtbaan waarin de passagiers staan. STR_0608 :Achtbaan worden door lineaire synchroonmotoren gelanceerd en razen door een kronkelende baan die vaak over de kop gaat. +STR_0609 :Een ouder type houten achtbaan met een snelle en ruwe loop, veel airtime en een kronkelende baan, waar de passagiers doorheen razen in een gelede trein. STR_0767 :Bezoeker {INT32} STR_0768 :Klusjesman {INT32} STR_0769 :Monteur {INT32} diff --git a/data/language/pl-PL.txt b/data/language/pl-PL.txt index a256fb116a..5f037bbcb9 100644 --- a/data/language/pl-PL.txt +++ b/data/language/pl-PL.txt @@ -100,6 +100,7 @@ STR_0095 :Tor saneczkowy STR_0096 :Klasyczna drewniana jazda STR_0097 :Klasyczna kolejka stojąca STR_0098 :Kolejka z napędem synchronicznym liniowym +STR_0099 :Klasyczna drewniana zwijka STR_0512 :Zwarta przestrzennie kolejka ze spiralnym podjazdem i gładkimi, zakręconymi zjazdami STR_0513 :Zapętlona kolejka, w której pasażerowie jadą w pozycji stojącej STR_0514 :Wagoniki podwieszone pod torem kolejki wychylają się swobodnie na zakrętach @@ -182,9 +183,10 @@ STR_0602 :Wagoniki napędzane liniowymi silnikami indukcyjnymi, mknące przez STR_0603 :Drewniana kolejka górska ze stalowymi torami pozwalającymi na strome zjazdy i mocne inwersje STR_0604 :Pasażerowie jadą pojedynczymi wagonikami po wąskim jednoszynowym torze, pokonując ostre zakręty i mocne inwersje STR_0605 :Pasażerowie zjeżdżają po wijącym się stalowym torze, ręcznie hamując, aby kontrolować prędkość -STR_0606 :Drewniana kolejka górska w starszym stylu, oferująca szybką i twardą jazdę z licznymi wzniesieniami i przeciążeniami bocznymi, co daje poczucie braku kontroli nad przejazdem +STR_0606 :Drewniana kolejka górska w starszym stylu, oferująca szybką i intensywną jazdę z licznymi wzniesieniami i przeciążeniami bocznymi, co daje poczucie braku kontroli nad przejazdem STR_0607 :Intensywna kolejka w starym stylu ze stalowymi torami, w której pasażerowie jadą na stojąco STR_0608 :Wagoniki napędzane synchronicznymi silnikami liniowymi, mknące przez ciasne zakręty i inwersje +STR_0609 :Drewniana kolejka górska w starszym stylu, oferująca szybką i intensywną jazdę w pojedynczych wagonikach, z licznymi wzniesieniami i ostrymi zakrętami STR_0767 :Gość {INT32} STR_0768 :Dozorca {INT32} STR_0769 :Mechanik {INT32} From 2fd52c82bc49a2e022641ec8b2c003b4bb71ce05 Mon Sep 17 00:00:00 2001 From: mix Date: Tue, 26 Nov 2024 12:41:05 +0000 Subject: [PATCH 137/139] Add small medium and large turns, diagonals and s-bends to Boat Hire --- resources/g2/sprites.json | 1002 +++++++++++++++ .../g2/track/boat_hire/flat_diag_1_1.png | Bin 0 -> 939 bytes .../g2/track/boat_hire/flat_diag_1_2.png | Bin 0 -> 945 bytes resources/g2/track/boat_hire/flat_diag_2.png | Bin 0 -> 907 bytes .../boat_hire/large_turn_left_to_diag_1_1.png | Bin 0 -> 967 bytes .../boat_hire/large_turn_left_to_diag_1_2.png | Bin 0 -> 979 bytes .../boat_hire/large_turn_left_to_diag_1_3.png | Bin 0 -> 890 bytes .../boat_hire/large_turn_left_to_diag_1_4.png | Bin 0 -> 990 bytes .../boat_hire/large_turn_left_to_diag_1_5.png | Bin 0 -> 942 bytes .../boat_hire/large_turn_left_to_diag_1_6.png | Bin 0 -> 860 bytes .../boat_hire/large_turn_left_to_diag_1_7.png | Bin 0 -> 892 bytes .../boat_hire/large_turn_left_to_diag_1_8.png | Bin 0 -> 881 bytes .../boat_hire/large_turn_left_to_diag_2_1.png | Bin 0 -> 993 bytes .../large_turn_left_to_diag_2_10.png | Bin 0 -> 928 bytes .../boat_hire/large_turn_left_to_diag_2_2.png | Bin 0 -> 994 bytes .../boat_hire/large_turn_left_to_diag_2_3.png | Bin 0 -> 892 bytes .../boat_hire/large_turn_left_to_diag_2_4.png | Bin 0 -> 978 bytes .../boat_hire/large_turn_left_to_diag_2_5.png | Bin 0 -> 971 bytes .../boat_hire/large_turn_left_to_diag_2_6.png | Bin 0 -> 860 bytes .../boat_hire/large_turn_left_to_diag_2_7.png | Bin 0 -> 860 bytes .../boat_hire/large_turn_left_to_diag_2_8.png | Bin 0 -> 900 bytes .../boat_hire/large_turn_left_to_diag_2_9.png | Bin 0 -> 904 bytes .../boat_hire/large_turn_left_to_diag_3_1.png | Bin 0 -> 964 bytes .../boat_hire/large_turn_left_to_diag_3_2.png | Bin 0 -> 971 bytes .../boat_hire/large_turn_left_to_diag_3_3.png | Bin 0 -> 950 bytes .../boat_hire/large_turn_left_to_diag_3_4.png | Bin 0 -> 902 bytes .../boat_hire/large_turn_left_to_diag_3_5.png | Bin 0 -> 860 bytes .../boat_hire/large_turn_left_to_diag_3_6.png | Bin 0 -> 937 bytes .../boat_hire/large_turn_left_to_diag_3_7.png | Bin 0 -> 897 bytes .../boat_hire/large_turn_left_to_diag_3_8.png | Bin 0 -> 933 bytes .../boat_hire/large_turn_left_to_diag_4_1.png | Bin 0 -> 986 bytes .../boat_hire/large_turn_left_to_diag_4_2.png | Bin 0 -> 988 bytes .../boat_hire/large_turn_left_to_diag_4_3.png | Bin 0 -> 984 bytes .../boat_hire/large_turn_left_to_diag_4_4.png | Bin 0 -> 925 bytes .../boat_hire/large_turn_left_to_diag_4_5.png | Bin 0 -> 860 bytes .../boat_hire/large_turn_left_to_diag_4_6.png | Bin 0 -> 945 bytes .../boat_hire/large_turn_left_to_diag_4_7.png | Bin 0 -> 936 bytes .../boat_hire/large_turn_left_to_diag_4_8.png | Bin 0 -> 919 bytes .../large_turn_right_to_diag_1_1.png | Bin 0 -> 967 bytes .../large_turn_right_to_diag_1_2.png | Bin 0 -> 964 bytes .../large_turn_right_to_diag_1_3.png | Bin 0 -> 993 bytes .../large_turn_right_to_diag_1_4.png | Bin 0 -> 924 bytes .../large_turn_right_to_diag_1_5.png | Bin 0 -> 860 bytes .../large_turn_right_to_diag_1_6.png | Bin 0 -> 953 bytes .../large_turn_right_to_diag_1_7.png | Bin 0 -> 931 bytes .../large_turn_right_to_diag_1_8.png | Bin 0 -> 918 bytes .../large_turn_right_to_diag_2_1.png | Bin 0 -> 981 bytes .../large_turn_right_to_diag_2_2.png | Bin 0 -> 977 bytes .../large_turn_right_to_diag_2_3.png | Bin 0 -> 952 bytes .../large_turn_right_to_diag_2_4.png | Bin 0 -> 898 bytes .../large_turn_right_to_diag_2_5.png | Bin 0 -> 860 bytes .../large_turn_right_to_diag_2_6.png | Bin 0 -> 928 bytes .../large_turn_right_to_diag_2_7.png | Bin 0 -> 898 bytes .../large_turn_right_to_diag_2_8.png | Bin 0 -> 927 bytes .../large_turn_right_to_diag_3_1.png | Bin 0 -> 972 bytes .../large_turn_right_to_diag_3_10.png | Bin 0 -> 925 bytes .../large_turn_right_to_diag_3_2.png | Bin 0 -> 968 bytes .../large_turn_right_to_diag_3_3.png | Bin 0 -> 891 bytes .../large_turn_right_to_diag_3_4.png | Bin 0 -> 982 bytes .../large_turn_right_to_diag_3_5.png | Bin 0 -> 970 bytes .../large_turn_right_to_diag_3_6.png | Bin 0 -> 860 bytes .../large_turn_right_to_diag_3_7.png | Bin 0 -> 860 bytes .../large_turn_right_to_diag_3_8.png | Bin 0 -> 902 bytes .../large_turn_right_to_diag_3_9.png | Bin 0 -> 907 bytes .../large_turn_right_to_diag_4_1.png | Bin 0 -> 978 bytes .../large_turn_right_to_diag_4_2.png | Bin 0 -> 984 bytes .../large_turn_right_to_diag_4_3.png | Bin 0 -> 887 bytes .../large_turn_right_to_diag_4_4.png | Bin 0 -> 985 bytes .../large_turn_right_to_diag_4_5.png | Bin 0 -> 940 bytes .../large_turn_right_to_diag_4_6.png | Bin 0 -> 860 bytes .../large_turn_right_to_diag_4_7.png | Bin 0 -> 894 bytes .../large_turn_right_to_diag_4_8.png | Bin 0 -> 883 bytes .../track/boat_hire/medium_turn_left_1_1.png | Bin 0 -> 960 bytes .../track/boat_hire/medium_turn_left_1_10.png | Bin 0 -> 981 bytes .../track/boat_hire/medium_turn_left_1_2.png | Bin 0 -> 975 bytes .../track/boat_hire/medium_turn_left_1_3.png | Bin 0 -> 866 bytes .../track/boat_hire/medium_turn_left_1_4.png | Bin 0 -> 934 bytes .../track/boat_hire/medium_turn_left_1_5.png | Bin 0 -> 919 bytes .../track/boat_hire/medium_turn_left_1_6.png | Bin 0 -> 924 bytes .../track/boat_hire/medium_turn_left_1_7.png | Bin 0 -> 924 bytes .../track/boat_hire/medium_turn_left_1_8.png | Bin 0 -> 913 bytes .../track/boat_hire/medium_turn_left_1_9.png | Bin 0 -> 981 bytes .../track/boat_hire/medium_turn_left_2_1.png | Bin 0 -> 984 bytes .../track/boat_hire/medium_turn_left_2_10.png | Bin 0 -> 970 bytes .../track/boat_hire/medium_turn_left_2_2.png | Bin 0 -> 989 bytes .../track/boat_hire/medium_turn_left_2_3.png | Bin 0 -> 868 bytes .../track/boat_hire/medium_turn_left_2_4.png | Bin 0 -> 958 bytes .../track/boat_hire/medium_turn_left_2_5.png | Bin 0 -> 1007 bytes .../track/boat_hire/medium_turn_left_2_6.png | Bin 0 -> 913 bytes .../track/boat_hire/medium_turn_left_2_7.png | Bin 0 -> 871 bytes .../track/boat_hire/medium_turn_left_2_8.png | Bin 0 -> 966 bytes .../track/boat_hire/medium_turn_left_2_9.png | Bin 0 -> 975 bytes .../track/boat_hire/medium_turn_left_3_1.png | Bin 0 -> 970 bytes .../track/boat_hire/medium_turn_left_3_10.png | Bin 0 -> 984 bytes .../track/boat_hire/medium_turn_left_3_2.png | Bin 0 -> 978 bytes .../track/boat_hire/medium_turn_left_3_3.png | Bin 0 -> 923 bytes .../track/boat_hire/medium_turn_left_3_4.png | Bin 0 -> 911 bytes .../track/boat_hire/medium_turn_left_3_5.png | Bin 0 -> 918 bytes .../track/boat_hire/medium_turn_left_3_6.png | Bin 0 -> 928 bytes .../track/boat_hire/medium_turn_left_3_7.png | Bin 0 -> 865 bytes .../track/boat_hire/medium_turn_left_3_8.png | Bin 0 -> 940 bytes .../track/boat_hire/medium_turn_left_3_9.png | Bin 0 -> 971 bytes .../track/boat_hire/medium_turn_left_4_1.png | Bin 0 -> 986 bytes .../track/boat_hire/medium_turn_left_4_10.png | Bin 0 -> 975 bytes .../track/boat_hire/medium_turn_left_4_2.png | Bin 0 -> 976 bytes .../track/boat_hire/medium_turn_left_4_3.png | Bin 0 -> 959 bytes .../track/boat_hire/medium_turn_left_4_4.png | Bin 0 -> 894 bytes .../track/boat_hire/medium_turn_left_4_5.png | Bin 0 -> 901 bytes .../track/boat_hire/medium_turn_left_4_6.png | Bin 0 -> 972 bytes .../track/boat_hire/medium_turn_left_4_7.png | Bin 0 -> 962 bytes .../track/boat_hire/medium_turn_left_4_8.png | Bin 0 -> 900 bytes .../track/boat_hire/medium_turn_left_4_9.png | Bin 0 -> 977 bytes .../g2/track/boat_hire/s_bend_left_1_1.png | Bin 0 -> 972 bytes .../g2/track/boat_hire/s_bend_left_1_2.png | Bin 0 -> 959 bytes .../g2/track/boat_hire/s_bend_left_1_3.png | Bin 0 -> 879 bytes .../g2/track/boat_hire/s_bend_left_1_4.png | Bin 0 -> 942 bytes .../g2/track/boat_hire/s_bend_left_1_5.png | Bin 0 -> 940 bytes .../g2/track/boat_hire/s_bend_left_1_6.png | Bin 0 -> 888 bytes .../g2/track/boat_hire/s_bend_left_1_7.png | Bin 0 -> 963 bytes .../g2/track/boat_hire/s_bend_left_1_8.png | Bin 0 -> 975 bytes .../g2/track/boat_hire/s_bend_left_2_1.png | Bin 0 -> 982 bytes .../g2/track/boat_hire/s_bend_left_2_2.png | Bin 0 -> 988 bytes .../g2/track/boat_hire/s_bend_left_2_3.png | Bin 0 -> 871 bytes .../g2/track/boat_hire/s_bend_left_2_4.png | Bin 0 -> 957 bytes .../g2/track/boat_hire/s_bend_left_2_5.png | Bin 0 -> 977 bytes .../g2/track/boat_hire/s_bend_left_2_6.png | Bin 0 -> 903 bytes .../g2/track/boat_hire/s_bend_left_2_7.png | Bin 0 -> 990 bytes .../g2/track/boat_hire/s_bend_left_2_8.png | Bin 0 -> 1000 bytes .../g2/track/boat_hire/s_bend_right_1_1.png | Bin 0 -> 964 bytes .../g2/track/boat_hire/s_bend_right_1_2.png | Bin 0 -> 969 bytes .../g2/track/boat_hire/s_bend_right_1_3.png | Bin 0 -> 991 bytes .../g2/track/boat_hire/s_bend_right_1_4.png | Bin 0 -> 901 bytes .../g2/track/boat_hire/s_bend_right_1_5.png | Bin 0 -> 871 bytes .../g2/track/boat_hire/s_bend_right_1_6.png | Bin 0 -> 976 bytes .../g2/track/boat_hire/s_bend_right_1_7.png | Bin 0 -> 976 bytes .../g2/track/boat_hire/s_bend_right_1_8.png | Bin 0 -> 965 bytes .../g2/track/boat_hire/s_bend_right_2_1.png | Bin 0 -> 979 bytes .../g2/track/boat_hire/s_bend_right_2_2.png | Bin 0 -> 983 bytes .../g2/track/boat_hire/s_bend_right_2_3.png | Bin 0 -> 943 bytes .../g2/track/boat_hire/s_bend_right_2_4.png | Bin 0 -> 889 bytes .../g2/track/boat_hire/s_bend_right_2_5.png | Bin 0 -> 872 bytes .../g2/track/boat_hire/s_bend_right_2_6.png | Bin 0 -> 936 bytes .../g2/track/boat_hire/s_bend_right_2_7.png | Bin 0 -> 983 bytes .../g2/track/boat_hire/s_bend_right_2_8.png | Bin 0 -> 976 bytes .../track/boat_hire/small_turn_left_1_1.png | Bin 0 -> 960 bytes .../track/boat_hire/small_turn_left_1_2.png | Bin 0 -> 963 bytes .../track/boat_hire/small_turn_left_1_3.png | Bin 0 -> 864 bytes .../track/boat_hire/small_turn_left_1_4.png | Bin 0 -> 901 bytes .../track/boat_hire/small_turn_left_1_5.png | Bin 0 -> 985 bytes .../track/boat_hire/small_turn_left_1_6.png | Bin 0 -> 974 bytes .../track/boat_hire/small_turn_left_2_1.png | Bin 0 -> 959 bytes .../track/boat_hire/small_turn_left_2_2.png | Bin 0 -> 990 bytes .../track/boat_hire/small_turn_left_2_3.png | Bin 0 -> 906 bytes .../track/boat_hire/small_turn_left_2_4.png | Bin 0 -> 925 bytes .../track/boat_hire/small_turn_left_2_5.png | Bin 0 -> 959 bytes .../track/boat_hire/small_turn_left_2_6.png | Bin 0 -> 982 bytes .../track/boat_hire/small_turn_left_3_1.png | Bin 0 -> 970 bytes .../track/boat_hire/small_turn_left_3_2.png | Bin 0 -> 965 bytes .../track/boat_hire/small_turn_left_3_3.png | Bin 0 -> 864 bytes .../track/boat_hire/small_turn_left_3_4.png | Bin 0 -> 897 bytes .../track/boat_hire/small_turn_left_3_5.png | Bin 0 -> 968 bytes .../track/boat_hire/small_turn_left_3_6.png | Bin 0 -> 979 bytes .../track/boat_hire/small_turn_left_4_1.png | Bin 0 -> 985 bytes .../track/boat_hire/small_turn_left_4_2.png | Bin 0 -> 958 bytes .../track/boat_hire/small_turn_left_4_3.png | Bin 0 -> 941 bytes .../track/boat_hire/small_turn_left_4_4.png | Bin 0 -> 918 bytes .../track/boat_hire/small_turn_left_4_5.png | Bin 0 -> 986 bytes .../track/boat_hire/small_turn_left_4_6.png | Bin 0 -> 955 bytes src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/paint/track/water/BoatHire.cpp | 1125 +++++++++++++++++ src/openrct2/park/Legacy.cpp | 20 + src/openrct2/park/ParkFile.h | 3 +- src/openrct2/ride/rtd/water/BoatHire.h | 2 +- src/openrct2/sprites.h | 10 +- 174 files changed, 2160 insertions(+), 4 deletions(-) create mode 100644 resources/g2/track/boat_hire/flat_diag_1_1.png create mode 100644 resources/g2/track/boat_hire/flat_diag_1_2.png create mode 100644 resources/g2/track/boat_hire/flat_diag_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_1_8.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_10.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_8.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_2_9.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_3_8.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_left_to_diag_4_8.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_1_8.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_2_8.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_10.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_8.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_3_9.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_1.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_2.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_3.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_4.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_5.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_6.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_7.png create mode 100644 resources/g2/track/boat_hire/large_turn_right_to_diag_4_8.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_1.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_10.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_2.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_3.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_4.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_5.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_6.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_7.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_8.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_1_9.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_1.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_10.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_2.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_3.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_4.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_5.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_6.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_7.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_8.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_2_9.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_1.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_10.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_2.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_3.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_4.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_5.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_6.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_7.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_8.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_3_9.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_1.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_10.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_2.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_3.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_4.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_5.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_6.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_7.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_8.png create mode 100644 resources/g2/track/boat_hire/medium_turn_left_4_9.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_1.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_2.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_3.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_4.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_5.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_6.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_7.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_1_8.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_1.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_2.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_3.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_4.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_5.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_6.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_7.png create mode 100644 resources/g2/track/boat_hire/s_bend_left_2_8.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_1.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_2.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_3.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_4.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_5.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_6.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_7.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_1_8.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_1.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_2.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_3.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_4.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_5.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_6.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_7.png create mode 100644 resources/g2/track/boat_hire/s_bend_right_2_8.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_1_1.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_1_2.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_1_3.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_1_4.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_1_5.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_1_6.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_2_1.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_2_2.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_2_3.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_2_4.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_2_5.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_2_6.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_3_1.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_3_2.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_3_3.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_3_4.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_3_5.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_3_6.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_4_1.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_4_2.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_4_3.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_4_4.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_4_5.png create mode 100644 resources/g2/track/boat_hire/small_turn_left_4_6.png diff --git a/resources/g2/sprites.json b/resources/g2/sprites.json index 9490124b8b..b622f3effb 100644 --- a/resources/g2/sprites.json +++ b/resources/g2/sprites.json @@ -17003,6 +17003,1008 @@ "y": -22, "palette": "keep" }, + { + "path": "track/boat_hire/small_turn_left_1_1.png", + "x": -25, + "y": -4, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_1_2.png", + "x": -9, + "y": -5, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_1_3.png", + "x": -19, + "y": 8, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_1_4.png", + "x": -20, + "y": 7, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_1_5.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_1_6.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_2_1.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_2_2.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_2_3.png", + "x": -8, + "y": 23, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_2_4.png", + "x": -16, + "y": 2, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_2_5.png", + "x": -24, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_2_6.png", + "x": -21, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_3_1.png", + "x": -14, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_3_2.png", + "x": -15, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_3_3.png", + "x": 18, + "y": 8, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_3_4.png", + "x": 15, + "y": 7, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_3_5.png", + "x": 6, + "y": -4, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_3_6.png", + "x": -15, + "y": -5, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_4_1.png", + "x": -20, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_4_2.png", + "x": -22, + "y": 15, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_4_3.png", + "x": -18, + "y": 19, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_4_4.png", + "x": -10, + "y": -2, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_4_5.png", + "x": -25, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/small_turn_left_4_6.png", + "x": -9, + "y": 15, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_1.png", + "x": -25, + "y": -1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_2.png", + "x": -9, + "y": 4, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_3.png", + "x": -32, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_4.png", + "x": -14, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_5.png", + "x": -1, + "y": 11, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_6.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_7.png", + "x": -15, + "y": 6, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_8.png", + "x": -32, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_9.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_1_10.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_1.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_2.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_3.png", + "x": -2, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_4.png", + "x": -20, + "y": 6, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_5.png", + "x": -32, + "y": 11, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_6.png", + "x": -11, + "y": 25, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_7.png", + "x": -4, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_8.png", + "x": -30, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_9.png", + "x": -32, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_2_10.png", + "x": -17, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_1.png", + "x": -20, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_2.png", + "x": -2, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_3.png", + "x": 5, + "y": 6, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_4.png", + "x": 2, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_5.png", + "x": -7, + "y": 6, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_6.png", + "x": -30, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_7.png", + "x": 29, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_8.png", + "x": 2, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_9.png", + "x": -2, + "y": -1, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_3_10.png", + "x": -19, + "y": 4, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_1.png", + "x": -16, + "y": 4, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_2.png", + "x": -32, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_3.png", + "x": -24, + "y": 13, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_4.png", + "x": -12, + "y": 25, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_5.png", + "x": -8, + "y": -4, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_6.png", + "x": -32, + "y": 8, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_7.png", + "x": -21, + "y": 13, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_8.png", + "x": -4, + "y": 25, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_9.png", + "x": -25, + "y": 4, + "palette": "keep" + }, + { + "path": "track/boat_hire/medium_turn_left_4_10.png", + "x": -9, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_1.png", + "x": -25, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_2.png", + "x": -9, + "y": 4, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_3.png", + "x": -31, + "y": 10, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_4.png", + "x": -12, + "y": -12, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_5.png", + "x": 2, + "y": 8, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_6.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_7.png", + "x": -14, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_1_8.png", + "x": -13, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_1.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_2.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_3.png", + "x": -4, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_4.png", + "x": -20, + "y": 7, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_5.png", + "x": -32, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_6.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_7.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_8.png", + "x": -8, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_9.png", + "x": -20, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_2_10.png", + "x": -28, + "y": 15, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_1.png", + "x": -22, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_2.png", + "x": -6, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_3.png", + "x": -8, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_4.png", + "x": 18, + "y": 13, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_5.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_6.png", + "x": -21, + "y": 2, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_7.png", + "x": -10, + "y": -4, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_3_8.png", + "x": -13, + "y": -2, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_1.png", + "x": -14, + "y": 3, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_2.png", + "x": -30, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_3.png", + "x": -32, + "y": 7, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_4.png", + "x": -20, + "y": 21, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_5.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_6.png", + "x": -14, + "y": 2, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_7.png", + "x": 0, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_left_to_diag_4_8.png", + "x": 0, + "y": 17, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_1.png", + "x": -25, + "y": 3, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_2.png", + "x": -9, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_3.png", + "x": -22, + "y": 7, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_4.png", + "x": -6, + "y": 21, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_5.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_6.png", + "x": -28, + "y": 2, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_7.png", + "x": -32, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_1_8.png", + "x": -26, + "y": 17, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_1.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_2.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_3.png", + "x": -13, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_4.png", + "x": -30, + "y": 13, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_5.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_6.png", + "x": 5, + "y": 2, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_7.png", + "x": 5, + "y": -4, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_2_8.png", + "x": -14, + "y": -2, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_1.png", + "x": -32, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_2.png", + "x": -16, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_3.png", + "x": -12, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_4.png", + "x": -30, + "y": 7, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_5.png", + "x": -18, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_6.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_7.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_8.png", + "x": -12, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_9.png", + "x": 0, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_3_10.png", + "x": 0, + "y": 15, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_1.png", + "x": -4, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_2.png", + "x": -20, + "y": 4, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_3.png", + "x": 21, + "y": 10, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_4.png", + "x": -12, + "y": -12, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_5.png", + "x": -20, + "y": 8, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_6.png", + "x": 0, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_7.png", + "x": 10, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/large_turn_right_to_diag_4_8.png", + "x": -13, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/flat_diag_1_1.png", + "x": -32, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/flat_diag_1_2.png", + "x": -32, + "y": 16, + "palette": "keep" + }, + { + "path": "track/boat_hire/flat_diag_2.png", + "x": -13, + "y": -2, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_1.png", + "x": -25, + "y": -1, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_2.png", + "x": -9, + "y": 7, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_3.png", + "x": -32, + "y": 3, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_4.png", + "x": -16, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_5.png", + "x": -1, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_6.png", + "x": 4, + "y": 10, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_7.png", + "x": -22, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_1_8.png", + "x": -4, + "y": 8, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_1.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_2.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_3.png", + "x": -2, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_4.png", + "x": -20, + "y": 6, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_5.png", + "x": -32, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_6.png", + "x": -12, + "y": 25, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_7.png", + "x": -14, + "y": 3, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_left_2_8.png", + "x": -32, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_1.png", + "x": -25, + "y": 3, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_2.png", + "x": -9, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_3.png", + "x": -25, + "y": 12, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_4.png", + "x": -7, + "y": 25, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_5.png", + "x": -4, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_6.png", + "x": -32, + "y": 6, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_7.png", + "x": -32, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_1_8.png", + "x": -19, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_1.png", + "x": -9, + "y": 1, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_2.png", + "x": -25, + "y": 9, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_3.png", + "x": -14, + "y": 5, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_4.png", + "x": -32, + "y": 10, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_5.png", + "x": 28, + "y": 14, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_6.png", + "x": 1, + "y": 0, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_7.png", + "x": -2, + "y": -1, + "palette": "keep" + }, + { + "path": "track/boat_hire/s_bend_right_2_8.png", + "x": -20, + "y": 7, + "palette": "keep" + }, { "path": "support/flat_to_steep_1_1.png", "x": -32, diff --git a/resources/g2/track/boat_hire/flat_diag_1_1.png b/resources/g2/track/boat_hire/flat_diag_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..93c86a41c9aa547b8c969070177ca8e1efab3a4c GIT binary patch literal 939 zcmXAoL5SmY6vp37XC|GkyAdi>3>c+{fKhS?m_rU(H(lxwoy=}_EmD>U0V{MdNERaW z5HVnp9C9d9v`7y@Dn#sIRwHCENYsiwv~~#c6N4mcT1(x-rnB+{{F$i z0fu4aa{2J^uvV|vS(Xt+K~W@4Ya51c+xBoco=$@}UZm+J&shcp9%QM~Zdbcq((EyP zhaZmQ$y5y^W1cvxwI|Y8i?8TX&1#XZMvV>j)E1**Yd+P}SwBm??Ivy#pweIp;40We z$07$`POABwKpBH_6%DN~@cFc2VULMj7N0O>X4u*j29 z&_(k;N@0ij bZ<)XG%atGB9i){40!P=68(&^~O-g7nZs4u!26)+$Ad4p^2R$})%FEDP`Z9`EwK!+YQ7 zR}ZE0=PsNBfb$2h>>cHNDIcs@$hY@zbP=EcS6{uhpUaJnjm^!?LZPs=wY9yyy|c4} zVOX(P+}+*9tJNyYGNLG`s%)CNZClM|v)kDtoVI6kU!*aOFIh6~YNTgUeVaXLig8yP53Ov}T4erunMec}G&BV8RBT{j zal1SnR90gGEf};i(3yu&QUy=|3=Ff%WtSj4it>5>L{Uby+SGMV`+XG01Y4;JIHQof zK}i;^xvc5&c28^uawk&#u@Po9k|P+Y%B!?&a=Im2Ev3~r`k@u3ZjyD<#bCCM%K}tX zz-vG{KzSI~$E6{q$AXn=?V0T_y#$>obj9R|hD5hDeqf4`t)@+L+O_9Fa~XHnX@KTQ zxx!Jj#&R`5Y^ZA6G<%K4u-%UP{WJ_`lgVCNX{ulo@8cr5C=TCbaqW3fz=W4Zzxh-@q~6NO%ARb-IJrBIJWp@333FF*H8>E44M z_~7VJg-d_`@=h*{gT2ew9{c*+FD^fF>&ar_K5D%1+V%Z!zH9yV(&W9}Umtz^<2Qe* ze{=!A`Ok|-&YdfNJu&?LUAy!A@%1-ezx&5$Z;yUIeeTcqKh-+-et!CguWm|XA;h1( lwRijYDeHFO%KhWQ-5)Q0c;n0e{M-r-_7C@Ny!_TD{{s@#mKXp4 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/flat_diag_2.png b/resources/g2/track/boat_hire/flat_diag_2.png new file mode 100644 index 0000000000000000000000000000000000000000..5e3478d8d33ea8c87f6ea5cddecd5cb2aebbc070 GIT binary patch literal 907 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 Q-Oj+}>#K|3U){X_AD`xT*8l(j literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_1_4.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..63b27ff1023954fe271b840c888e71fd61c98c72 GIT binary patch literal 990 zcmX9-e~8<36n}TUyW9`XqLoD!C1RZsqGk|A#0XJyqaM-AxC{yg%t6E|on#Q9Xc>W3 zuDU4ksH}tj(Mb-f1T1n$24xE)V*e-_v9da%6fIa~f0U!>=??swG5Eaq`26!eANaiY z!Ksbh>hjTL09ajracwi14-t=&Q6r6hL^vQ(I%*@Qr&ZbhSxw*Od`T2!~ z1q{O$7Z;b7mhfyg%d(6p3W_4>x@ww6rBbQao9(tAhW$96Os6aZ0uQpZqN7eZ!BeFs?=8*6<)m z3y@I&F92Bv%E7oMo@-NTAQ(~J9-8jN3DKTRXLODz%Dp5rr)XkAsnFRHN z$U~zro#7}t&vFGpEGdeu>y1*WZQDV!8TtOO-=9n-2nYkHI>xrrVuw(AbYUn~N2)t6 zbtX=K+8!Sc4$umnPIEY(BeM$4=sa&qa#c%~mD_f$+iJ&QG#v_{NtmgmEsb=FbfYYI zRi)D?bUkYjG{%E)I=zJifINT+-~f04U4Rh=D1j`ZvWYww#RHiFgN2#^ehy+8kOIiS zkG?-8s;7BaTq*Z||Dr~tRIablFSskwyh2A(0(R9d367m7XfKZY} zHIcguqEc>*MqHzQ7iO;~s;W{f>gBS*G8K-g3#=!yfyDG>dYsQ9jYJlO8Z7b!6iLbP zb5E}9-}!;JH#Zb`?)RTwPsoSsYtNs4eCOQGmor}bno#!#>S!fA`TDV8YbHpS<(WS?1Dv|7~6P`~3d18w)$$^7Za*`_t>MHMcK6MTO|% luZ_3V@8Z>P_MD)m`-cZ;3BhKe@5?#S2^K{|8|xsmcHV literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_1_5.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_1_5.png new file mode 100644 index 0000000000000000000000000000000000000000..43f85a938ca789e0f81ee118d78255ca5d9e7d23 GIT binary patch literal 942 zcmX9-L5SmI6n-DJcP_V#w6P}teo+1=gU z+uOr1tXM4W@9$S@wHm|Fg22nNsA)~Z&~4iu3`UcQA4Rh?U9Hy)4Lk>uSZX#a?KWX{ z=x&c245jfz4MHPMdW)qiP?*A%bg^nFgrkuogE_T@aG=B!J)L&5)ZMJ2Iu0rYCJ&B` zjdd*SmFMHiI>u2(qqU089fYD9fCQjom|iYhIPQ?7%WK*2e19>UtyU`pxDMn1W5#76z~z`~Erjl}>1JlI za%SsEc0S*r5>+m<)oPun$rP<|oFPhGHDA`5^!n5BB#n~wf(KQ^47qHngwv*m9p3B8 z!LT*;ta&)h=Fxh6hIjx4AP;~8-~mhlmKdNMl7Kn}@?4b8B@%Q7`aJk`NF_irAiauu z400vpw^7_hsSD4HXF(J|k+8N_wM?q-)W@zC1a^{mS(cz&3vU6_De+EKatYNZ^^|i~ zO>b=mn?Zc;FVK8NR)8h2I$dt^L|bM$Ezz;sZr=*LeiC_E8lm-q6-DF&N&%tVi*7FW z9Jt*XE|=_Z@Ek@Q3(cn7Zfl*6&d@eX4|v8Cm{6o=5|t@6q!P#?(U3ttj}kEtKYO+G zyQ3A$;rK=!#9p!{QlGLu3dtci-o7iJSZMx_y2zTdVJ-ZlN%quiv9WX z=dXNt@R4$G`-dNI-+%w#_pbi_+xVAXuf5Q}^4Zy=2K7fH+=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_1_7.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_1_7.png new file mode 100644 index 0000000000000000000000000000000000000000..12b3bd8e47516ee98365da820a8f7a482d87d963 GIT binary patch literal 892 zcmX9-F^HsQ6n?w2yUyOQ3}Ff(5-cVloCHIJSXj7;dzi&!JCc#PUr0G?EL)v;^G3s zux__|d3lKsheMWSL{U&x*)(`;vdQU|Xib&r+?c0UT6#q_E9=GXnD+%3sDO`v zbb$&mZjMV!O3wwW)clMy{Q*bO z8q19Y(NR_3G$Y4Z`hGs2mub4&Y?`J)Kv+P97`y0;8KJJ}(N3K1^|*GjCfFR7_2c%4 zdUU_f;kZN&Rhlt*-jqR}exws}-< zi^Jgo2>=>^4G;h%04sn!2B?K1BG*PqjH<0dfyKg1fK-A?0i*)5aOATnR!}-d>nW;Y zco#eevIv@jjZNHh=vg2wVl&GoWtr4yG5W8^<#*OJ-$})K!5FJ5H8S3aA2v+AOB6-FpxdH`?#HD0~ll zy%u#{9gj`dwOD4tF`>XFBAd(1MxkqMhzt^W6pC1s3aFIZ5t*t=Hu%>rC&am^f%FG@m1#m!K3rhzu*0F S@8 zhV}dX%gak*G#YUnD@mfJDVAk8j_vz?7_K&(B+qwM)wC_gf+&Eh3=Cs9nNU-goy~=C zsjfF>nmI)|KO7^8!E|9@D}<+0fkm$z?#`F8P%k!iwVl;fbl>DM2_^$m5dsZc+gLWo z_v>L>kf>%+Yodn$p?n0O0+<+Pml)DQc6 zG+=O?CkUAuX$)%#f}^N2vs>nF=8NrmQ{`oQ5W!S1N5egn3MS0b72}zfF2~#0+h@yq zpSSIMBm(FF4nP1918f0~7@!WSgj@&35vuko4K@c05fT|H6_5tVCeWNik&2QDDrTsP z;A8MSC=%!@Hn9kA$}9qT9a(AWmt|bnCF;D$F>vlc3C;@sJ$Q zzM+S}Q<%)+hDc2`&K)a(H;EQr8ZXK`uB#li2VPN70;mFnx-4d$-6xQ~yF4EGW%vnB zQAmcNO(vG>+8pciY$$TE#AOP*Q<+*HA(KKLjg}lrL{uu>@$+8}K79OvpKot8`1h>%6{?_#V`w`&j+s~c`?(ao63fIqXu6}#= H!`uG>9ba?W literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_1.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..7d43e53a1f6adf95089d4be207ea11667c3c99d9 GIT binary patch literal 993 zcmX9-Z;0D;7=G_>?p9_Q6{`zaq=QU?1dJ?59P!NEx+8kIEe9P0j2N-gg82|Z~lneds|x6f9U}gQ6At;dDPU2G9GxJYU}Df#-d< zH#Z804;?)O0EgF4ubxfj(@7m!noD}cxiAkf2b(W%ttE73W@dJFc5ZHNetv#oVPSD` z5yP;hrKRQN~vSu-7t3*?$cP&0}ioLcLcdMh=osPo-4hjhs4r~c) zX;@H8_gk4s4@V;kO%!xsBNXNVL;wZDv~=3Uaho7qmfaP_ZmHBa&AZJe3Id$Ybw zgNy{(666dZY>a7U3vEIUI4vsH2D&@8L$oWB8I{2+1+rFTTPoktrN~nIjz09Pao|iN z4-La~h9Srz&6GI4B1tt>ZB#1lS}kZcBi|qF?TyD{1h@u-gVC)t-@&CGSsL)wq3n(- zow2<)X^#&2QW_&GFgdJ1rDZNxmT03S*k;+Sn;ownh2AI*(PY2~0`dXHfKZY} zHIaJ=+%g)&A=7XkLhto>S(eIW)i5-gvKY$YXpg4@f!Y(vQ8AB{95M;ippnm^NJx&K zc_#JegCBVJ?1ls{{jgjl>$PuWhVef9bUk{|AR~tyBO2 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_10.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_10.png new file mode 100644 index 0000000000000000000000000000000000000000..998e05c38f2ad9dad8dbb149d7fdd63b9c6aee4f GIT binary patch literal 928 zcmX9-L5SmI82x5CGwEzugA@!HA%`Av2uoH1<`6NinI#Tcnq{*XFo%didng(tYK4ly zEn1~&4qXV^Ly&+yM7H3F0egs$!+;SY^iUy44+VSJLzJ=kB^UuR;$HvtR#t=rdXEYIQC#L@cm#mi_>&b6yv-80VYmYM0<5G&LYP zK=pz4Fg_sU8Eqt@o$I5O6P8|z&Qzvp@nlbCM!GPyq`9Nz18eC!>u69W{w|NuI>nnj z&FCE85v87{jVx=@>&-@^Bna|2UM&`7St1~9pnZ&+;?kVdGN!YVhHE3-^ya0v*v>W= z%N=SkIL;GgKpbDyl`VNXhR4i2*Y!1dE#4;2rAPtaBpb>{c6~$eY z4N(!oBw!RORQdH2!=11MlBz zYw+?vf4yCi_UXyB+x2fh@QSD4`Gb>3sC@I!>08D-Kl!b%Pq9zG`0A6VKl=H@7jM7| zSF@`>3a@|v(r4VY@P~h2%ijIt!M)#!hrbZtz4uJ>$~XSU!EfWn-8;6^e)RdTl`@=O MZ=c+I<&8W40~UUY%>V!Z literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_2.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3dbdc144923c6ca1d7b9680721b5007e9c7cab GIT binary patch literal 994 zcmX9-VTjvw6n}TUyY%ij%Pg*NK_V6xHI6s}=0k+sEq8Qx8JD?Cs@9o~Lxr9M=`do!LnBrR7+H~i$cOt-AxecFRv4p5VMR~;n=$yk_xOEzzaRYG zd;i={Ze?k82>@2M&TO2I=VNglOD5u8w%?osNWi(X7dB%$Gcz+gJDW%(=H}++=jRs| z7BCD;CX#@6EkL>uvD_CGy4_6xAVQW7Imwm$eE6V91aQvWgaXU zYiXEYOZ8jnNe@RO8ch^*WFZt}0VDtg!?aY&#Bqxx9gf?Vq;9d;H_cnkCh~opNoV;C zEfJhT<}@mAGOESt4WZ(S^^WZH6fY_gEKcXLoJ@%-ThIipDpi|G)6=}r45E5CY7M4- ziiflenIaGdkQT-^Gr2Zd@OdrF*9N*XwgR*-QE8RM%Q>o+=US@J(dDqB_HBLWR>r

    fKg53c|^N2SvnmIb|w@RiYXO z?^fkbqu6!LzTX)2gURF;;sNpiI)DY>0(1d}7@!!EfD9eE4vP8`2^s@+9=sex5+E6n zmO(WJITG?ps8>ai19yXGK@=b_VI?(VmZ`dxYdLDCQwc+NGzw9yg%^P_mU$~9IfUYo zTEto7f;%a9rgrbh8=(G}Oan_`IXYF~iIU71MbR=#PTlOd^)PTpQGg}`Ruqv3C<27y zEUK~GJ>V6iF&wfD`yTXOPbd`RQb{!ojiDa9=&$;+WLJzJ(S%1VZHc*fta1o&s^F3`{ven zvuOJ|_V(%RkB4WePq#nuslCtc{99OaR~~uh>FMs}Q`i5wxb(^gH(%O4_M33!=cjJp z_{QoT-+SVA&;mkNTxA*jMj--}>rg q;?l$a9isK$Z#(qWcN=d!_-o?CvwKS)@%(n|4YoFSHoiQ)``-WHyr`%E literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_3.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..75a5bfcec5f4aa83585305a2b9509407613c7c12 GIT binary patch literal 892 zcmX9-L5SmI6n-z?gG33ELk>|hOB^DTWin79LWH0_^pHaqatIQz zhax#dsSu=xqB-;sv4=V25Fto}3OxiYONAUN6zpNaAUTv}7=E)XeD8gHhxfk2_ue;8 zuH{D;uU`PbqpOcEZyJ8Bsk3&g=?_2s`wXB3Pd>SQ+{mM&qvPY_R;zV#a&mfldUke( zVOYD}K0iMvdc7XUv63Wenqr!|ZCj(!C=6$dMUv<1vaITwV?h)^RXV!f9S$kSWyih{ zPSyFsNHcp?_}g71F<4*dSPJ3wslcRXHg`9Yvar8eSmkoOFQY@1%On^KI3ffZHn*_M z$2aqCy&}<`MYVzM1BCJ(fC^w>n1$mWNd`0>3BsMKE(e2+=RKdzP?nKgwK31$&-%E_kjbck_tTuMo8#SFI6c&A5uC#`~Yz1ZJx z4yeQ6I8P8V)zcW(6a-sQ$40ZvUHFsbd{O2_y%oVwFk8btg9?Vs)D`2gmQDxD*xO{& z{U)#L=ST$T1K0ooKn$=1*kOPgs1kB*6i2Ass5Dp{OhiazC{;ijAd5gghawdvL$n&B zGJ==E^Pou3SFxc8L2;{k}kr7dZgV?T7)PMwF4zRw)FP9@kEK2v_&X z7HulJ3p|C%EUt^xP~+Tz5_rRC;-&GV$m4yPqk79L3Q7Q#fKZdgxUqW$a^y~TJAN9z zg1uTvx~>g}rt4Z9JL1_;5X4ke}DC7GX+-_;jG|?k)oQibYodSBu45xlC1T zwpJIKEv3`d!^j%M_0iaq7)%pZO_^{s$~EY=#qCw4sHqLQX40=s67Oi*E0CZwP!YjZ zv5tvFb$r;#%?2czuxO^EV;7-b9zX%mG0enqha_E^_5@*1QTnCQ&~YBN+bD`iE|(Vx zR-pu)E|`qwaE2>bEvf3ujZpOldXSVTo@5JoL1kovFPf5BQ)+F!9hgDv^pZwA>5Psd zT!fqoLuxX9`>NIK| z#XcJM@ElJw8poGJsiLZN!)R41-FiK0x8oof9UM%jQv{?5bQ9w`xD=A=fGLfn+PLUV zD&f>Um~|(|!y~lH;5bhZ1uCyHtRV=Ntkm>$ncb~7`kijli)SMdbQ!Z$+|enw%(QIL zuc=|H)c2iX)S3)?v)Mx=0%!mhfD7OQ^Z~{gpcIOPYzz4wN`?vzCI<}>f&wH8AQg~F zpgM;<1qEd^sG-Dzli+!fCD0VCY!FU`X}E=sXM|xjj{V6bMyVEA0?u9)T|)6FJ)q4* zaHmCoRtb-qgX3U?hEqBRJcSilyeLv-m9tB->y*8Q6Z(y~=TDLznvHl_MggD%5K6PC zrE-r!R_)e!%(t44VGRaSv8a~IhHaZ1TjklN$oUc%$?So`Otd`GDdf+@S{PuzJnyYL^XtX=ryi;W-NedFuv__b`~ z?#o}j`1AMY&QqV>tNk^<`}{wr%lB4pZ0%gTOK!aR^yybVyZY@fKRx;W+t1zqn>gIz zot>LZa+rDbksaQ@`lD7Zz4qNlAKXZGU#h>*cyCD@J(X`A62HMVcjnH&*zL93e=cu* Xv;W}w(wApaFR*!Wdwuuyw?6qF`2eA6 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_5.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_5.png new file mode 100644 index 0000000000000000000000000000000000000000..228156794900168437b50717efd5b5e6ab278856 GIT binary patch literal 971 zcmX9-QHa}g82|2ice&eb7O7l@kwqwyL6C@f2pA-8xlxbk<+u#;P`1bdD^gjI2xask z^ZHP-1_S?RfLtRe%iaymk3fN*5Lu78e&YnatAC((>~1 z%E}6cVXLdFYinzGKA&e_UECT`$vb0_-=E`NV zQf2B5zTJ^~ea#QdC~k}=j!0uFzivplrINNzbxn3q6N9!I^^N49K24nCSy&)IqoE>z ztzbO^3mVx`FE@_}G-c3SLnk&uVIDvR&@jx%W-WrSDazsbfh-@CN+Zj9-0h+uAlO`9 zz!{n3HL76Hs>SLyZ+66*E46&Zi8L=MksQGk^1MPzI#)DAqb}FGTGunY*b0+YJnfB- zgRB5K1@ID(RiJE)>*9qzRSX0pRvTl}nb{#4$aGHUh)RKOsC-WseN%~R`lxMA+}bQ? zAIC15gxMTN(JIT81hJwh4PEb4D*Z+y=yqez8xM!G*$e?;0M*9WURLx8C8A4Xu|6p} z(~3W{hx7jQWOR(y>1>w6@dBAwXh!FGQ!4&LQ(&;r62L1!A_GzY z88~XN$dQp(Mo}Fl4m=5-14#r`#>zTwRp^#o=sCLY*W%cnPGgj65hY-&>w=BT4yk#R zk?{7c=*}ztaXUKk#%MI7a=?*TfyovHvaGPxl4M(Dr)BwWD-PXh5~BH-lO*H;N&ulW zi+U>e6hy7snM}A&`zg#Q5{pHpT-K{qgJo(Q(-v4)WCMvA%JfvtBaK8Bg*q(q1Qbi@ z@pCV)|M}zxKG@w>;EmsYxt@}nTbmaypKpG8xb@7f7f&zm{9#>rZE*PWwdcg!H_m<^ zF*{$srw-2UAMFpJdE@TItG}M#_-FWS^GEfwN4|9bL6h1j(RcrQm-+bZ{eSQO_4!cVW=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_7.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_7.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_8.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_8.png new file mode 100644 index 0000000000000000000000000000000000000000..a1bb81aa422c463d3cc288794df2aa145da5baf6 GIT binary patch literal 900 zcmX9-F^HsQ6n?X_yUyOQSj>S*Bv?$qLW1EeEQFYxyG$0tdYlIaEIbfmUqzu)ILR+255bhLZWm#L#dpVz@EF-yIUnE$C5)67^ zGn&Vlf#A#}KbEIUHCh{KX;D1M4*G)1$R@Abl08<&b7P*`Y2oGNw5S%lV}^^+Q-QF6 za)AyoeohP$TF*qg&?Y-4s)HQeDNN7g$FeU)KNL2zVcY&6TSb5z_js9?yzE`^}hvWp~|_I9C*WM>Mi4Gk;he;qr;AuWt0Lc0ih;~abx!er0>r5dwv$a zfwNvqx~>j~rt8`q>+@_Va8n@YUB7kuq4(cO_{#_H ezW3^%E_~T~^xMPFzOb5UxVgT)`tkAeZ~h0aj(Z&d literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_2_9.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_2_9.png new file mode 100644 index 0000000000000000000000000000000000000000..4a0184ae6d5cebcf2655de2cbbe1f8ff55505208 GIT binary patch literal 904 zcmX9-L5SmI82x5CGwEy@1KWkd28mc9hoCtG%pr%kW|mm8OqR_`4nZOW&7nw;$QCRT zutJpx0V@QlP&9`g0`@S69CC;dq+r1udZ-Yvhk`-&P$dgJ%))P$h4+0Q@ABT^z3-cc zSJK6;ySD(~qW9kAqx#;d=d9VN_p{#B0-ym8A3VNa)1#xKu}7m(5X=^fILp>Wv9BtY0f7faZs~fv-zNt{X6*67 zRGBY~Bz0D~x7~#zjcI(#mOHLS`X)7V*z1v)2HI+27t3*3gok}55n#|T5WrWlxs9bB zzL~eH6@f|yRR+585z4v%3V?xOHjcXl;Zsz|^Vf>9w5*NmKAp`_ni6cgD|8rzD3T|M8m^4Eut<(zq%N=0vdQVTXpfcg%$UV?oV!^u$;zIG#DS`Mra2u97M_>RW_cWM*X#X$kASd&3NUt#iwU8wXlpBucY0V3lD)sK7Uj+6 zfLb(;bDfSvc2$}&dESwgu~CZ+7v5w!UldthZ3Qr7%u#XIApJf)9SYG{O{Uf|ayRL; z++G9R{d|BBG&#q7W4ug#w#}i2$(#g#t(gWOtCqqEJC`AFaly z2;oKW9LOSQ3f4C}?tq^7(mXViWR&MoS>~wrA}nBsEy3?7A!)>vUGV;1kE%g(2v#@o z7H#%a8#oe^7+e>~zRC_Q*?0Tl#7&|}o<(Jmp=!&?GKv8efKZ*qxVC!*tdGB%ahxdQ)y#lW_PwpY~!B3~k&!2{Gef7up-+ldsV!is?^EZAqUw`n| llh5yb`{NV;ql??m?*8NT{v|)jZ`TUYyMJ~0%exJyZ>DcIj%6 zz!oh_(XjT=U858YSRt}Kj1t(gM2XTv4?%jU5TruEC?f>PLXkm#W?A^Y_xN7k=kR^+ z=DDNV*)va_0f4gyuk4*KCQ;NATWdwXdGga+0BdmW@WOs!S5{V5S6A28*4Ee8H#Rml zH#ad1+uGXN-rlZMt5t@f1%a1kQP)+|G+M1zuh$uxTC7&MuTWt zbi2d#Txl@WMxi;0JM)DnP?*B)7-Gd%2uCOTCUe{p!k#i28p*hwCf+iOYB*>VG*O^(zsrq+4f1lkHQdV%2mEX zO9ZEpHG@)YMt3;V6OfdPIvCrp)P|%Q@(=5vn;0BOAj2V=K5iU=t`dnx)R4;9g zGH03()6>}!?NFr>TdCBDs!Y*3$C;wk){14;u+tq6hDj9Xa~?DiGv$)45l(}0E#7a- zBey>G?OEuivnbC`5D%aLm;erd4=@H;V1Noq0`hLCIhti;8CU|V(Iu598Zu+mMaOP Ck)me+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_3_2.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..89f7db7bd543fe97f7807d77d3f19b63422af088 GIT binary patch literal 971 zcmX9-Pl)4m6n-w}>^j+?W&FVdLCZ&`B5)kx2vx;A@Q7l&cjHs%$7Q5&S* zBr;wra`tA45Zv1iW(mCnEl_wv${=gZ@ zG%vq+`sAx0fB$FnQS#DT(ZOH3z500f(nEImrt{e?^YzKUA71_Tzh2hf zet+lO=CvQbzIyXP{Jw)5@7#K#c=53?bq=43U-;#}Z-k$IyE$LJxc$Y``=5XRT5bY% MclNfwJNxRv{{kGNcmMzZ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_3_3.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f54a0ef08ee71b93ec968eb39e43ec0b635c7ee3 GIT binary patch literal 950 zcmXAoL5SmY6vp37XC|F3OTju@F<^A6W+5y&)ZD`yIab z?p!|+FJ5@|0sve*e)FiF&x5?4DHig6sJ`(DKmo2_yKyzQTU%S(+uMagVP|J&cXxMh zZx6$;VzIctzhAA@Y79dQ0@^W0s<~T}dlxgVPK`5*N$N(CK8RfE#;|@u>9Cs$mvu1N?+Yd)06a+X^sqs}> zCOC~04NA2c-Qmok(D9`HRB`8;A2$gWr^OnlP?F9z48iEi-H|r(4L`EOxF03s)g~zO zP*I@T1i}K+!Prq%oRE!xHzKvSGTqb((V0wDbQW)mR8Qr`x-d1BsG~0j=GyC|!C(`4 zXdRX-EJ>*h+vJ6|qV#lq*ltgHyq%(yH}ab-?5S3-B)aFg~l zbr#tqIbUv2i7J=bYE>j^3PtN2XG(Hc%a>V`UVk>8#9@@Jc+e!wRLZtSI4x>u@m^P% z4x2O2UIxQt8D`l-!~>`RCV&Ir0n7l_7@%CTfGiVvE{c~j2?hgw9()mE8IS_VsG=T& zTp9T-H1DF=g~!3OAPJz#SWBC29?61hPpqWRTCJNXn0&y;Az; z@eh1lKT+V-KOel8o14c+uidzO`sFEi30^1`?x9=X7%%;O`^C?{&VJn)9h!fbhs=N9 z-@y;=pVXcdzZ$*;8 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_3_4.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..76a1fe096b3a522369735579a923982f9eae4657 GIT binary patch literal 902 zcmX9-L5SmI6n-WZ5j_kVAyP_K-sk5el0_ zz#NK12-riEf<5F=A!5Zj1k53ah&}X>Ly?L(R45o>g(5`;9ogS33*UPm@9^Gt_}=&F zgUkM{v)g9?aO>jz^M?(;)YNIa)%3R>zw;QN1rI)Wbgvl?4h{|v4_mF)(b3WI@$t#Y z35H?qcKh`7l<4((9LGwMsH(DQ>W*Xkz8^)?`8+L(RaNcwdyWNB07dTTde^e3q05c} zA(|+&xsm10vJ5ucSYj|u=-4vhX;f&^Q-{0qr99G>bGurM>MFk86@3y628JSpDmJsR zJiynp?tV$4nnim9-Gm4gJpcv3z%U!fJ(3J*Iu?X0MOh36YtMT+ouWJ^xo%G+ScMV{ zx^FX@$C;tvOe8;%$C(;0jkFq2JjwQZg38DyuiKJ6Qbto_n%ZgU71g+`XPfIB7on>H zF#yU1I>h)X(Vx?LF50CQY@B!(7U)W0x+YH!`%It-GgHbOwe-z(mp^ToI8+1&x*%hmW<0HsjC9*H@qyP6i@{SHC~JwxfdXPce35` zljsGU-3*+}FPiOXenr7*SDLk5LB8cjHqil~&E=jY$({PjEoA3wZQ z;oaYVX@UW7U!324)c*3r&+eYVo9*I1=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_3_6.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_3_6.png new file mode 100644 index 0000000000000000000000000000000000000000..f6f3f02c92d94566ae7c9400ef3e81802515af26 GIT binary patch literal 937 zcmXAoL5SmY6vp37XC|GkOVut!3``CMg9bMYL4xKG-OO5t=w#Wf+}Z7jo#KU>EifB|;A){LQlPz4!4h?|1m# zyL;`daq+^d7XaYm=?5p*3xBbwOXX70rw>263Q&S;AKoY&c6N4lcXvyr(%#nzKNqM#^}VQ7|RI*v0Kj3$#Hju&Z~U?6Rv+gGKwprXDK&PQCfU96* z6N`G)<+zs53AABQuA_4op|}np1LzoLR;xBaxD@5_{8W}_&F0d!pN>W-iU_t=7jQ-< zd7WyQv}&`4%UeUy@uhyKcym2Snn30F(kkMHbxx_gsY2 z8LrpdaPVB#d@gF5(rOu$3(#|#A47uiT+7Ban2>qsY&O`#!+0s$pbas1qym4BZ7 zz@6)73cUN*<4=o0Jw18v#w+)3es}yb9G7=#O2>D9B72UkA%`hV8Yjg0^R literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_3_7.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_3_7.png new file mode 100644 index 0000000000000000000000000000000000000000..a6eea09be8bfcfcbe37a16c56dcad574de201601 GIT binary patch literal 897 zcmX9-F=*pv6n=@5$cdYJ@E|x9R4_#xqNr2_4H}eIIh3Fh9Z{$Uaj2l9rg+exf(H$P z(_jt_8Vps72M-!NsMOF5f|??z22(r;n!yJe3^i1=8N{K2hYWue4nE%dzTv%Z_}+W{ z{7O1Kd2#{(r?5!&%L2orT^W~_>!(Ew51n4vj1@KjDW@3rg zUe7w!ia-T}Djhxe2&G*B1wh9zv)y(G!l$T^=Wi8d+3&9%=YBdxNkXulu7EQN$?KG4 z(mjVYeBPRfZX}NvYPizlyialjBXxO|mJLobMRTN#rusBC+v%~Tv%%68tcH?MsAq|yDUQ6wB6w- zy2o;TK^&^8XBd;=aPE1@behHS=I*X6O9X@oRDiLwwzweF72V&6qpcPe!$s-eRrBIu zy+bX!-R5vyBD*Th7(8#u%1E!5*>i8aoXztzt2P4YGG?i5M<@LOJ+Xyoq%J1?W#p`r zNwH3=>K+LIJpc>92Z#Wc09y=D4Mjw@g`yDUYlQ-ng|Ps!1i1o81!UsLV^OG}cz{+T zl!x#bJO{D}Jp~&WxHF{3zBCJs#lp?9s3HtS#64TZMa-gzyU-q3rICd7%I7_1iOk$7bkXY~okR|WCM=2tl*#q+b04?fKK{UW*H z{r%>fS}>RApWifp{OFI%_u-TGem_I#w-*;zr~iHW3w(d_=HJ$}f_{4WwDIk|`Ps{} cw?AMno__G*KTj_HtViMU+12^aUwr-Qe;1p1cK`qY literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_3_8.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_3_8.png new file mode 100644 index 0000000000000000000000000000000000000000..7c6eb15054816bbbe5bf1f9840b5ef21c00e24f7 GIT binary patch literal 933 zcmX9-L5SmI82x5Coph!wl_^*;LXhGH2@)iSAUR~5%ut8OWZCQzp@)bO3s%e_E=7t2 zj7wRvkVBCOW#}P7k%&b{%pqVFa_FH*7<#A>*d8jI!@^c6OAn*`W>|RN_wg>@JG}QE z+&XLA*nf2&0B)SVcYHg)cs>WELcY(7cgFw)xb^;>lbmjCZEbIF7Yc=)otR1cCiY_K2^6MqWnHY93gKwv&|oesA##=JSWhRtEcG_4xPgO8L5BxN#zs08 z*_HXIx}M@FqtRMLR}MmP9Y6w5F-)&iOdNMe(&M-bNt(1;bJKh}9HJ<~nQEP{(GtO_ zWJ9MElhGW`7zmax_Cwj5szKT!Se$OuIhhhQwy6txPwEZTVW0vP zwH6RvARUYy)*5578S#3e*bBp3IWfABsH(=|od#tq+(;8bLryGh?ix$qT1Dk-V$7%_gt$DVS_`4KY0*06xG3V2J_BAql8!Am2mjTp~edpwC0lfK&n`1JY~AW{@YL zppB+IlzMP&JPV=#iiEYbn%SZHPGjV0VQ3|ZpJfTkweS`&-7@dgB#%%7QcpQ&)%4e$ zaN|y|f(4qd$SSY|)}Sj*o@mQVwV0uzb!OrkQSj#L7fBpNU%;87yx;b-3}|8w1e zFK(a7aQNiUPjVuk9>06%m2bbgeER@iFBKmBi^79P&;I)KV1K{!&BN`(BL!#fJ-qzx z!BO?(ga7LHpP%3S@%!g*eDv(|Hy{5T+`HL2|MfNhk6+&T?RS!UOn>~@%U}Mzb$R#j Ue({HwuKNb3Cuhe$9ew!q|3Ha~oB#j- literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_4_1.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..4c491bc67671fbc87c8628d4277f35f4187b72ce GIT binary patch literal 986 zcmX9-QHa}g82_%lyWFjw)%Bscctj`?F}R3%2%3lJ(j%Uc%XS&-W@HfpRw*Mw1_dib z)`xDZXPAAc+J~Z<^dVr;lf}_N9)eU>G!GRzmWPUkRlJ9y1&cez-;BZU`#ydz-|q*% z@4IqxN8C7a><9pCY`>o0jVBq`lWWPizkhzq14zQjH&1WHbZKcRkw_$y$>rtcm6es% z)m03`*4Eb6*VnVTT#jLALEsfd(sk7|jcT>pY__{yF9?QFG@H*E8h8$5DW$5JQi&*6 z=vtj?w&YG%>-pv&tdA#-Kw$+gWk^}8K-fCjHktjZ;5Q3{t`YTX)5uxO0ucv|f-(=b zf^`hcuct?y%zS{ODUIeDI!Dp$QFU90BK`vJ1cfc)#r_{P#>Gl%ns1LOl5QyFN;*Yz;$$?XDVS;A2rR1Tb=pM zMd+eQkj}6qRbbd6FO(IfuIsIGxm&OM?RMyStW!t z@79!FtJrs~k>8q*g8BRa@c;z?6Tk*=0r~(F3{VVNKot|Y4vI!H2?hfV9y}2u8IS_V z$f7!f92t2fG^nA-frr7fAPG>Av67y(%2dM^JC5G#Rm0GoPD2!H;YDC7Dc;V?4xxFZ z5pniRb?4>YqB%J9#%MGnGr$s;EU*}phkS^xcyo2l|EZunocUMr`IxRKV1IeS%3`eUD@AG>C)2D^73*flUZ3=$!4>w ztE(7>t*x!Cudf%1#Ujfxq9~}UY#5qlne}?zbvwOY5Jkfzna$@c0|F0uh|Scoj3@_!{KZ;LqM27xft8U#Xg}9=<-->Of+v= z?a!Ryyf-}^El`feajsC1$f8O!2G3iv($LdowO+Gz-0dY%JRb|7%b2C&woW<~x?L0e zhT3nJk9~U-wx^?LK7W7&fD(WO-~jjl#{d%yPzpsvH4FJ3N=6C=CJQYA0tpfYkP65w zpeBnv1qBr}XrRP{$H8+Ti%?Rqiczqubjy*tp3(2uLjAe3g& zNadb@sMp$)3D!3txSBLf?DmjrWhPWP|g6Endfd`}IBi7vjes zZtMo7eQodLrd0p${&&KSJD**%>_;EncZJ+@7qxfMpV(^$hhzHAi|wI)|AU_{Y{&n= d_0Rua`R4YQ`Mc*XoTRQ`XM1<+?#pl9{2w1&rEvfN literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_4_3.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..603d0805cda0c7befb76a0e38ff0b2fb19a3e12b GIT binary patch literal 984 zcmXAoZ;0D;7{{Oco4Xyi4Ev&Tc@d#%HnJmVU{NxNE;r(ld6~r>pfss~(+ooZX`UQG;}#eUaJ_Umcl%_fmVfJQ?_ z09VC2CKfvQu#=ni36wHus-Ytnp{M|$0B9Iy;!d5w}xx@fby%Udn6=F5$q>h-lCDU%$*NCjS{Wt}UTqFGn!ZLJ-cL2O4!BThS` zS%?deQz2glvI>-oaqYa+rAnb-#zkjjc@sB6dkUS?Iie!bPLc2EV$V|Jnm%k=W4|^D zo3q$Q;|R}j6kTMwvLIGe)zS4U^Ey^CKCjN2~-nfJGj^*)IMDviS=>G zODnyJJD7IUqu~s#(KycK^AcH5X-4OHOIGSywyfH98vC7Y62;Sz0Gf?X^3%~{N0rmmL7@$mwh^iLyJ(LU;3QQIn0t6By3Lq7b znMV$bJOu>?>eo@?!6Wb-$RZRK%+T|8g>JY~$J2YgS{(an8lxHcqTW#--Ot(PyK{NUsG)hBK~wX$^W@R$FT+yB0|`TS|Z*f@3O z%YSa*0JjA3P2mLV+zX#ePwM1g_rc-LxjU~XKVNick-QkG1P-gG^k*T1`*VvK?N1mMt4;Xl~ag9J%~mvDpkM~4QepO zgJ?XMph1Hv8cbt|1`mRm_67~2RZ~GdxS)Vr+*VLS3>77V2?`wHhQA7d_kAC4d2e{{ zyLbImJUqC3004(4*N$$K_i{N0)k?X)yZVy>P=V_o-8?So*4Ebc_I9OG+1c6I-QC^W z+ru!dTCMKy?>Aem7Q@hjz$=QR>#Aj${eIu`#?xt-B#SKD6a_;A&w(t}RJGCR5ZxX< za5!%yPo`QFTl3Uet$l&Q+FZ?)ns%FTb#iPmXMG{|+ViQI%?5eqpKlTo2aSR*53Yhu zOe}Wl%Soe{<0z+5p`i;Gp`-;M185j#*6TKoyCmsz+?g!T3}b2APsd{v$2iky@l9GL zIE@rds%dVvAEKNoQ44FbDErtc^o6Ozk8aruk%b9@lwj zD9|*3=mF_s?6@gTNj2upwC$`cf8!?TOr{z-i+4rJX>$`@h%6=T>r2mC2mMX#ou>g> zC-nwPQf-Dcc%iE(j;@co-Kpcm<8c~>tHolo*&x78AU%wk)P)FF=9IA#25Z&NyV1s7 z6w~}-d5&sSz0Nk9BGFPPTIV=Rk_TET)|)!R*<_j}X|du#lQ2uE+Zy3^s8Np(21+zC zW`VtoNBJ@-il>MNXaiUPEdKwHK-deiPwLsy*mdKC53G|2N5m0q|3Os~efP1z^3kTf&S-Kas) zjn2LKMYuxC4cP#ez(l&P@+jlcNuAzVYoH_xsm>ezPjPK&!(KA66s{Y!8CcZYq!y!YGV2l!_ve?0p2-Dgj(@PB=N_wQRDo8R1jr}oeDYtm~Mx9^p* OaB_Tl^ziDZcmD^$VT%j^ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_4_5.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_4_5.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_left_to_diag_4_6.png b/resources/g2/track/boat_hire/large_turn_left_to_diag_4_6.png new file mode 100644 index 0000000000000000000000000000000000000000..a125a67085fe370790952475f157cf94f195e125 GIT binary patch literal 945 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 Bg}nd( literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_1_1.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..2cdfb9acc81581e41f44ef6ae7e2c1b97e554d55 GIT binary patch literal 967 zcmX9-L5SmI6n-0w~z@SA1fd++gG-uJ=x z-tEH!ackqb4FK5Mzp{HRpJZN7uNU(E!Ml3_KmiWlyuO#yrKP3i<>f-5u(GnUy1Kfy zwuWKY`ucjYSgcg5RfeGjfmamCFf_|D9mnZ*`@>-n$Ky2377K<3o&#Ch)Uc1RmZVgMt?@!bQQC&lYcz)KcGT}DK`6ABTp3ZdsnD8f-nCRHl2m5NAI6^b@E&XVMoo-b<-+ntlaFpZPNlm}hHETv@Ygj=V2P2O)Q zVXt=L+mom_pTvvBDdGWC01Lnc@BvN$W*DFxvVfWv@;#JJWD-mUIy?j-q%t4{kXb=( z26-|H>S)wLsRxgPXF(D`m9e@}u^Uv!6$hRXhE9_B^Lc`DExZOybCY)~vPb9vX{MZ; zY5t-So^?kT!4yq0vJ5PNiF8ThiMqlxYm#f%y^bCFoh0_>X^a+AR+3NvCH=D7&?h{y}k)UZxy>2v{CPO6iL@r(=-~5MyJyo47@NL$8oY)unY)1$Wl&K3)L!F zt250O-|5Qzf#wJ1C~8e-j!0u=K4(a{RVHnn>Y40eLkv3Q(ZGm@&3WuBldwd9Mng>i zTfzDU7PRt{eqk{p(40XF4ISGEg+%}vK*KO2pSK9YrYMK!4`q2+sZ1>Eey@jufM5$n z0cT{A*Qk;~mn~Med9y1vT&e9V&Pem(3ds>nsmLp|q;skv8cn&`(|VraMOGNMqj`V2 z4DtdL6u>J$)`7Ayu7{Tflo|*|RBla8C$U3xDANU9_NFtPFtg7Qyjc(hezN7noBZ}PlJVGgpr~q5f2{tY}q~=jZ z%-f0TE^7X=GdlLBXp&F`;7F{*eYJP%rEMQ$4vwz9 z@!E~s=MsEl>zxmaH&4I()6;nI#WSBCZ-4ju*{xf5emr~qsR!8WSMGgGJ@E^DvpK%} zz<=S{Uq64+_}~^tYl|9;kvZ0+v1Z%St7t-rp!^6J(Oozh`{?_l?v ISKj{Ue@jf6!~g&Q literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_1_3.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..876823a5323e8a695d58a7ed8d7072a7d4d2eb25 GIT binary patch literal 993 zcmX9-Pl)4m6n--6=~L>QbSHq7myFvBDgJ7Kuw%dZ?O1St>@U(#4_!#v$Oa4D8P=3*UQ>@AAG6 zzV~iyZwY6YpIiojvzwRJcar%+Qt8E1(m(v?hkbw)Y`?s_k|tu~wOZrAnwVHienOjE$IAc-r*Vy0Zi zD+X1ov(1*&=_)->9|ZOB#O6t?z^-Uw)-2$bO0;$Qu*!SQ!l0{#{n|9NPaBT=25$iJTFIQ z@?4gZa8@A%jVze7YO#8YuR3C*C))$X4NEwaql7#wlcLHLHD0SpwYJiBH8(K*un|l< z;}b8(8da9WhEO| zTtW+3D=Ip1rFYUCoVsH)iiiv_I3`f(B8Qh{+9-*ZS+*Ny&uIj{GYx$dj~P)!E}#$) zO0uXWa*vU#8m-BMX*C~19}M_nQ7)HN!_a7|%1}*?c6izosi8zp3wfmA$RtpUMlOc} zF*$zbxs~HbKk(MhmJApE{Q0$nSexrF?XDf%3jSEWyLu+|`?u(5ukqjba^;ox;!m&N zId?z*+tsIqpKf5EW10Pj&#zt~&tXfKf8;)S_RTxju5UkF%Maha{q;u++!qJycXuBs z;@UmqGy1~bgWH`Qdi8_SFXrE8Zk@j`nNJdn~$F;fB(k4i`VvV n-aL4pJlbpjdgb+_ug>F}SEG&Zim4Y9Yp}Vowf^PBSKs{~yy~pi literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_1_4.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..0acd5980b0254629a971d7397f282101318c60ce GIT binary patch literal 924 zcmX9-L5SmI82x5CGwDnjdng#$AUPDtAxa!`$RR@9$*kQm%Vgaw28<9PvOVOGLtJ_Y z7_eZGz(y>RLzNyPR0x>Epg9zbki#4b1}Rt}hl<6`VGczq_AuaYmWB6yAMf(s;l1zk z`xl+#qgzJ+aD0CE>_K&JRdZCYRr{OMpSl1wxPR~Aor>=4?CkFD)@rrAy}kYY{ey!8 z48!X6`r+Xr-fp*9mJvlkQ6$6AY}@Mh`#~^{<0Q-GMX}y&SOx?hWT~NPEz=}>4m0rh zU?fjseVW>{+*__fk;YWMVM(~FlDS7>7U6cCbqLUD=n3E}*u=t8 zueq4CHZua14BF`E#z!b?1IPe6hFQ&~OAtOqg*<;L%U9j*!ga65W0a-@+iD9qBa^&N zbu3zSS;Ob;k=T!<;ZzA{dQx;rj$k@%UZEv}(=5>%$b+#yPOKz%vtpQ+ljSyT3eZvj z?*i!n6|mcbFd4(+M@#1N;plJ|{8V6US7It{jYgjQLz z#Zk1%a$P~}DT-$pqh2reymUOylVmxcuh(k?gauT9v6H4aC6pQ6U5bO17M8u~+MjRY z@@BC`4Z7LnaJ)md6`C=4-j?KnUWqxeH@up}MV4=t0_YNED@|7?eUlzJLNrjOqwZDY zF49rC$Tpj6Bmk%YHh>Qh0bBvBFhCV#5ji%BLR2hd3M>|e0wf(MWIzfa3r8M{LK!6{ znhj79!n5ExkVH^r%rtPfM-TnZBs8Yeex65VnWM^!=mP6B1Rs|}QcozW;Qh50ZF!#oX=(y#Dy-9$eAf(z?lc{$N)i%;eANcse zg#vFq{ryoz-Z?+J{qUu)9zS{ag`Z!qpE~IJ{oDV&efjO|(e{&j@axGhAN}Rm{(beg z`adtecX&d+@fee*k<`SI=tk9WT|D^)nZb8+_l I>4%^G5B;WyMgRZ+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_1_5.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_1_5.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_1_6.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_1_6.png new file mode 100644 index 0000000000000000000000000000000000000000..e8ae545fcb55a703986c5f5fa3da2f67076890be GIT binary patch literal 953 zcmXAoL5SmY6vp37XC|HP4qYuvVRFc!hpYz8A!w8wvQB2GLv*rE1}hdetAXvIhky~v z(nG|eRjUT65~M+9>qQmMo+v>@=ZEUIc%*R@uwWm)~<&<%od6vaux(7 zCf)9ER!zRn!A1mCKRhFWyoo=5f~4$3$v6f}4+ zWo)2fekVT}6p|5+<}^wabZR0LlmH|E1;ey_-oSB_ByEm6lBDBWZDJVr`+em5I8!L` zMOq>_g)D1S#b8vE(|bb85xbsjj}$km5iCxZOPoxJDqGbAtu3|tO5fGo&WzAuydpsCML6}T=P()0Z^M*p0b*k6o zown@tYR8T-@q6=0kR{ zim1aNTS9IfjoK)(;Zg7`hyqk3tgaS~2Gupo16%dHRv0?-d5BULUIV6?ttIejy&@Gm>c*YSJU!=zpHLsMALLh@gJqEcv3dQvJ z*=KSO9{s?(`+G86{Oj)3)YNvjUplz(#bYKs0&z)KuFFgC}k#+d>!$1Dnym4>ydVJ@>6?o#OYu{uqKSf>p zU)h}QY7r|>}`Lyb>;p40r&Qu AHUIzs literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_1_7.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_1_7.png new file mode 100644 index 0000000000000000000000000000000000000000..0c35ad321647f66e17ba2fa38788aae35e9d8e12 GIT binary patch literal 931 zcmX9-L5SmI82zT5nRK=c)vegk95T>DSb}6FV1x*9%`A0{OxDRP0fS^AXwe=5M$93H z!1hqIhaAdo#G*X}=^~y~BIo zH+N22``2E-1_1lV?;o8O_pq2srCjWZy8i<}8SZ>|cDtZkTU(`4sa!5^Z*TAH?CkFD zVi;DbRQC4v8qH>tVQ4|%Wm(j9)ijN6x9fSM$s~;9%QVf`Yla4%14*o^YQ57TESv82 zId3S9C)zYJ=ShFL@&yW0xT+yG9EEUoa%3{+T_N(6`NT+Py)5-NdECN5qrl?9m9epb zMg7`hTwl*|l+kFdp(_`mxCtNuXc%VHY7UOOBF;Y_{BH)x6A zG_qw-io@tGXAXsKAP%OoKi9&vO|UrKYH~6q>a1!AMo;REv{7h;i4&)TBpWX`QH_VX z42?DrHjpmHjvB2AsYbk!DE+1B=WdM7C91BoxYeTi3OCk;sVOI2ec_p_pqoeDCJE3g zuGLwRQW&<)3zjVRb$w`AlYT!Mjgl~2US8&TjsQ1+^e|>z6Q;O4r`k)Qw^IGgn&$51 zdXil&HmFL~YHXv?BAPNq>l|l_Qco+y>`8wx8&A?WSuc6eM9h?Hjz+j0YH0I8Po56j zv%pzI!)y_+*G~}-pa7TvE+# zDD0ql52Zdl51s{407b$&dc(1(f!iAU`gGb&k|4_xRCwWSVC*XIHYA_WLefY%H&=tT zHQjjgt8j@HIavpmz*=-o<%y2W*lp2uI{v_!27@FHvNT5PB`b<31e5|oMHaon?gj9! zJzTBWq4xsjd@iV}-0A4HZ7_6~r9GYr1SS&cONq*qCejGxkZ8!DkVlDFl%IX0`t11+ ze06#v!@K`H`m7)y9Ut8~J9zMk`{s2xti=Bz>%psU{aKbSUitXorOzM#c0vCB?~_k| zJ$>!(?{7T5`m*$sefZ?zje8HTQ*SHp99Vz6oQa*gcYpk#ee-_)^P?{=lG3g3zWw^_ SufQwB;rRB+(J$}ayZ=97%8L>J literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_1_8.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_1_8.png new file mode 100644 index 0000000000000000000000000000000000000000..57b2070a2e5221ddbd976d2e9be9250f7186c358 GIT binary patch literal 918 zcmX9-L5SmI82x5CGwDoO%Tn3GL%r4yu)M-+%wTCjcsN^Of7DCEeNC+1=f(R4RLWd;9zQ2L}fj zhE=Q8!^6X7tJPu{S`c_ekqkq#EVJ9~4hEyiBubJ+mTiiHp@HW>mTH>T=yV9%p?e-T z7|P>`K8>w;>aEs+Kw&CZGo_}h623u>Easvs!~=CcF|%1O&w}kH5pmEduzBzmY;0n& zS6_}B#T-XDjS3xI`UoX002x5XFtc8Faoi`#fa5M?dDd<(UH8FggyI-y8ZEv_%LJ#B zqDiSPWB8mk6uP0*pDMvzkFqww;Arc{z0V#mYCh`~*$SCTd zc@Jd)JPe)%NdQ&GI!4pAslG3c17kYvrfHbxDJs42HZV?&_nUG+=n-jVoWIe+!k%si z^UG+3mK(AGEP;u1UE_(4!Z>ZocRNAfore813G*yL#fp_A6amTrp)!kJY4-?t*BP$Y z>~Qc1)_g8#n$qbQj$<-(m!$_h6ADZ$(F>W%)fUnT44$l3{zLX>cYnL~^HV>4aPQtn&mVvL!{gd>==(cw zzVOTSyV%v&?i~I8#iys&zy9h=^!HnpZV+Goj>2!uf6-DnU{KSc6xsD%}cL; F_&<1!hP?m) literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_2_1.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..dbf45ba6452192a57dab675e02f7f0b450939916 GIT binary patch literal 981 zcmX9-QHa}g82|2ice$>NI_sz`xHvk(ZemOJZ_<8myMjujUnxI9#eki!ba zMGabyqEY)$p$~n?L)C~CZ~1 z%E}6cVXLdF>2x|@C=?im76e|FMO7^uhHhC_tJUfCydW4w(QH0vXy7@J#7w!It5k?; zjjlJiR$J=!l)i5a!^ULl2ozT0GP;;ION6bG9fR4o1iw`p_Vj2_k0a-B78G$%D5&ya z%UD;({6==%&CQ26ifJ@g(23F&qnnBbI0p z&+?FyA+G^Z1JcIWPQKV9%RaA%rN+c?W_Ez~B`T+~c(q71N?cbJ`i2}@>bPZ0U2EpI z4nr4BgKUl^sS?9#yik?phN`x!)n23FcRHcxO-7^HY=!{Wfox$+H!JjUc}Qs!p*}4; zakW3QNAq5MG(JQbDw}2V`65w}DO%+?LzL=DvaHr?GzZ;Y6om5$4~mExa@JG`yF#^V zyjz$1ZEfJ1W4|4bgZcab@c<^f?{Z-t>7$016za1EGRhPU&QLnt1p zN1Qz?yYp)Qur)mLCTKh(bHEZdP1zt^$VBJee}kM7aqO!o8<4$oH}{?%(s8vN!?37e|LNE z>U--yJay*fcQ)3pzw}nPh}=&<`Sq8<#V_8xb@l3%)6YJ3?}^h_UdZg-IQ!>kYybRv c^JBPn?)!J|4$f}vCw5?SV|)F}i!Z+YKT*J>3IG5A literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_2_2.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..654c4a03990114ed2eedf80d7106f45b8859d2dd GIT binary patch literal 977 zcmX9-QHa}g82@g)yWCxO1}qv~VL>WJmK|{h$wR>0Eq8WD#^qQ}`w%cnoP8)5M}#0n z!`6o?L827wphyoh=tIDYr{tjzMZzdpB*F<5GAORFKHMOTB2`ZOn=$x(-^cIe`~Bee zeV^~|71!6!tpULL?v?Fp=_J#7b|sT`+zvv34D4S$*h%Ta!ory|XEK@0;^N}c($ezs zGKOI*D=Vw3t3;ttU|B{K1x1l`T{TUkR;x9e?QS;+!{azkW;2!nfd^U2s%oxMA+0J? zclc&Y?sThUiG9b2^u|inLSWJG$62m8hnVn&!l>CH>|+ z^3f#3a~wsNSgtIHmZCVi-m#m&s+BJTTg?hCA$z12P)5wV ziR#a+-n=&7z*l zJwd)!ZA~UztN8@xa44#(QmN?Gs=+cfj%f<4FS31!IhN^Zsem*R*%WHAC=gI2rN_^0 zWFI~Lfsd~3DX{tAkM~nz?{04$y!_QCUtW4Tb7>{>@#U8uA@X_b=K9^A@4Rv0-r>81 zbMU(KVDrYvI&Zx?_~)&qi^u~cio!Yx$%XXeY>%<^>DMW z^}=Cr-=_aM`@`YJzx!9%4{Pkjr>_6D^y~L0_xIL5ICu5i7r*&$`c$< literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_2_3.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..244af324852435ba8aa31e47842f4626984f5eba GIT binary patch literal 952 zcmXAoPl)4m6vyBE&CCugp+9>4YPHHRv>@=ZENWWaFm&6tyWM^egmHY5rul5f(7W^pZ!kx;FzhO$Ku?d`S?bO6xQ2sDL5l}h z#s)ezbV}nvc{ajPMx&XE&Rm4zDu4u_VwhekSvc;Jq{nebl62f?j4kVazmJAPoGDlN z3M~OzZM3prbZ`CMA;Rc!z8FFH4|5huFB`|R*?q(VC;$e43*ZAB157bMg(Lx)2J$_WjwKRw20A>1HAp2uG9bNz z90qw33Y%!uMyUr6f@eV#K#{PfRDG_i z^TWT`P35as;yXVdzLS5x`N^HvKSR%dY(@XPdH1zjU))&!`tR(y7k;|v+`jrl{N;rw u|NVU{Ft^Ih+n0l9Zf<|`e&gG_2gK%kZ=KpV4}U9&uzO{1=ljbyKKdWu`2OcyC z>cJEZ8a$ZRg9{oA71Z=HXfQ=k4IVsbFvV8{6~#~$GKiodEus9?aqzwO@rL)l;d|e= zFE6?$k3M(=04L|4oxZC1ab3sFM%|xXe|!zlfR~?Np4H>t-roNHexuPiI5;>wJUlu& z!Z57aY#tvU6P-?n<5)=&RaG`k-L|daa5$OF7Kr2r46+ylzR>NEywHS!6}2n`Gm(nCJH~E<#%c zq6d@%w2$#KqPw8=ShP~j%k7}_6Lh06ZIdSlUB=UdxhXAeH65DUiMQ2yfT$LE*lzkGQG&ptfE%r}4k{`Su|zun#b f@bA}O{qg;C?fS{~zbAKjy$k1O7pFgcdiBl!piF*2 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_2_5.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_2_5.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_2_6.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_2_6.png new file mode 100644 index 0000000000000000000000000000000000000000..8aa6999a515cb9d2b81e0b12ad6362eadcd574b4 GIT binary patch literal 928 zcmX9-L8#kw9R9u6_g?x|X2l8-bI74$4q-+Ol0%Se%Nwy|YvwX2STI7^3g(bQgdTbb z*hAGEvQZ^q4`t*~B+McY3>qO|kRlZ#yg`K=iWJOYhaf#vsPZ>s@cn)t-{tomzVG+> z?Y4CJ(yNyM;BxD|vpXffSkBAUO1aN}x^)Af0=IA8Eg23D4h|0wE0xO8(b4ho@yW>v zhGEre_4M=57P~=*-+b|5WKVU`< z?@g51T#I6BnL6u@FVa|tubDD#cSu*KrWSiX6l1TmoSWHVlxO~~NF)L@8u|jbDmF8* z*r~5(jqQ>^IfJ$u+PerPO#lTz!!Wa6w+X_fD4*xg6=l)ut!(@0bc*7bU>i*VXB3jx zD9NNdHmke5H4%q_JdRX{UF;SIKt!6bS$w01Lnc2mlrU8w^khMMMJ&1wP7F3I!$$V*x@5G6j$d$i$JuB40tF zftDkb`S2`w4rCEJ3TEiI-KWQ{H1qW+8m4KG=P4?^h#s(mn&9G!Pii4$X1rT;gKaq)eDKfj+Uv&kE5AN`{PV*H-{aq5Up#KT{eHABy9>~| M(LVe3`bVGs52>??8UO$Q literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_2_7.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_2_7.png new file mode 100644 index 0000000000000000000000000000000000000000..12113da0f59c2a4d1ac80d1ae0f3b358c4b9a7ca GIT binary patch literal 898 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 HlPCWJr(ubl literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_2.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..d7a9fc1415013d0b640628a43816a0b23efb4e2f GIT binary patch literal 968 zcmX9-QHa}g9RA()?sB*D$g~f^1?-^CIKl`RC1@U^=8kwoFUK-0u8ue(*0W-SI4g7z zw2UfI!stUEs#eHD!N@8cl7|X83DSoSGcBw_zzP+6G9*ZZQ|{q!#^C$?KE9XV_waqc zk9T*ZjT5I%0KmrfbDQTgKAX+`tGR5~+Ei%? z6%4~xS6A28)`()U$g+$m3aTpWdf7CMMx)Vgcl&)m499Vtq$$gQz=I;Mm&^HTwNR@w zO`C6blwMyO1m-BRr!!Ziu@b*-$b?lYI6Boe+5LtXv`eGD5f7X5*gZ-@i3E*?ngEW9 z^$aYq@kuYAjz~0TP^zJ02cfVCpa5tXX5hF*k`6_=Jio6f!%AghS$Dc!6a*xjFA4;s z6nKr247y~oy2G0tvEj+Bf$EMlKduxwl97tMO3OM|HbkSTG`m{YH~h#7<5o29O^*Ux zfV>Js1qyYb9E|G{QlBaZf)SPMsp%$8i1rmauXAKgqU{pj)5U?QMh$(^HfLTV3ED@I zhh`z3=P0_wauq?Wsj98(om#DL+d;P*`Tle~PLc!xX#my6*d8tpNOeS4rebqecIUN0 z;*8V&{CIMN)@dB)2tq0pRhrRx-jtQ5mL042?bfi@kHaXP3ZTiDsp6JaaH@2tE_h9K z(5VbPYZ7$klQ2#1AOWBRU;;P*9>5S_h5^c;h^THN&qeV>p}=6FC4etMtN>C083eLf zm|Gs?jY+>bd%0(1;>$K95l5MOJ{VuL};LxCPCpjF@+l zvX|BdNA1zEKSh&-$^%!xBnB@Fg{sQdE3#u%-Ig`*T2biD;}E4&PL`1mCQhML^hC_u|m&FMWhvwMWGIhd;vvrR(|f> z`rmhd;N9~(Dm?wiFRy3fz3t6sE({Ej#k;H>D z;pWC`FJ0X`_0CgY|9SD(bHT0qKDvD4i^o5?_VevM>aYJEzH<93pM3S(i)TpY&BKH5 zUR*mo_~%LV0rMk%RT#ei{bxVC{AJGm{N(R@FKF@ghtfmETbADb>4|Sn{`S~7D>%UR M*3RaQXJ7g7f9>_1x&QzG literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_3.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..93dcbfad149540e172dd42a36b0bb71a9559039c GIT binary patch literal 891 zcmX9-F^Jn{6n=NUJNaUQ3mzOQiYP9KB8mnLDritr-Ju*Rrw|1+Xiz}39z3X^f(OGX zRD)?WXz(D42SYV@5LCkr8Z>AS)PoCxn&N^64~A+8L~S*=;FiA%f$zPKZ+Pz;zW2U= zb}K%7@ZkdhczE;l>UqN-GzPq#yofmwluNS z?QWO7dX1x!MzxNP9zxjwKnBn;%%{aHSVwRW7-68Gr&{Lp4 z1Y!cDhp~&k7?E1ao4M-ltf2BTbT3mqgT==p<*MA$5E4tt9b@ZT`_QRU|B#1hpLKgI zNvRAwFJk^_JlgOQ|mQj)A^^ON!!Yrk0>x4I=<`X`gD#?7f3hiw= zFSl7;zd<~J3Sa?v03pB%V2=T6APZ<>p)f$jRwlt@V8%l%LLmcE0GWN{GANKyJVNU! zDgt;HJPVQls*H_{zCEU9p12H*BysXQEXy1bSeZp5cIS5IEFe=uIYaw`7r-^YJGx_k9c`{QW&U-!wyTbA5aD(-$wl`yYHFdsqMf literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_4.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..b695108b4e11b8fb610265886fc92a54d7d3e091 GIT binary patch literal 982 zcmX9-QHa}g82_%lTkh6vQ3@7UF-n;k28k{YK_W!Wje5jgZkK~T^dW=53Kq#QN(X(2 zT&6|(kh!9H2v{T!1p~{&p+Sn|A;Kwj=JdqMA{4Bw98<%{!@&;rx5wbe_kF*Y@Are> z_kFUlUOj#C>`4GPz4q4X=Dc4xo|p6U`sbZHM*w-)czf&OoGvUZ&%WRgm!J@YsqeBmbiy$R4s!-L5l}V z#s(S|cJc9`n2pM4Mx#tYM;1a+1waB&FigX7qg=K~(&e}vN!o2R#)fgf-$!9sW{MTQ zL`wvxkX4PU8H{Rix+9pL*c;03NC}b#!ItT2g_9{!W$T)tb)-&T=?7X68&T4WXM@RM zi1SdCq0|7P4Wxy!{ZiE@>mjejweCcBQ!7F{5>-^$a;r*pYurE;hPoV^>e$w&o|%UB zVeFx4gcn(osxfSX7h1C1RaK|e^1I!z-;aY}vcI3EDT1;Fq>V8HTo{(+5!ILoooU^j zwT7v+pZT++@gXWuIL?+zRiYwOw90Y1D0P(ivbNvt?GF4Tin9q1iiqhlZYYG+q?|VI zb>yMb*!7HY=*-4Zmfc4@Kn*|#umC)OU4SVDXbwq0Z5??oO2!fi8UsBZf+{2uAQ_NW zLR|*A5(=7V)Io_0$HB883Q&`w(H-Kpuc&jA2gc6Wi z!dYqE%UZ)jdvp{`&^RTFz!F%M#_K%Ml$mxzw2Y?PGlpI-j=WhCp=`p6A_@Q{fY3aP z&Rp&>%4XY{PFcr(41F{b>UFu zz{w~^K~J2@b26XtX*7Rz5V8u?f(JBuc+Dp literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_5.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_5.png new file mode 100644 index 0000000000000000000000000000000000000000..35b024433356dc30abb893879f308ff172aa7cbb GIT binary patch literal 970 zcmX9-L5SRB6n?w2+w69_9bqT|BSsk{l~974LWF>E&DL~D*|eL&h=ZmO*eQ;ZLxhMy zqUJEjC}A1v9Of{TfP=<%locZ85FyY#%prw6jF7`@9dLvmhB}2kEcQ30@V)o=F7Nx` zd+)2O+tS+U=T8H`+ScXGoqVq6b!MfIcYN=~_W=rU^~&{2IbB#-SX^8z6begAOUuj4 zr%s*1Fl=RIWp#BGuT&~5%ZQ?&s8*R&F#% z%VwG_zSC9u11*ZpVcHr`e38bge9@3`r%HM{)ic?BSByK=;lRian$yfbo+T0i8V!~J zo{IGiEN+!X{qlTBpecjq8anY1N-6*ffQDg4spJrZM^Qe{?<>kdy*_fBhrJ$(V}dPL z1e{SwUZW&~t~#vl@n%`}?RN+-x*14J?8cn6y(|Vy1rcRQz(`kQv z9G3(rtAN*mw1M(4u7^tlsul}IT5XL@f954@ADb)nBp|W;e_MC>_cA}u2Cc!jI(0t6vG714@fKZ-A zGnab?!nM1T3D@mBgE<_EwVK*!=(cUJjLR_{fel19mYG9^o>nVJBauU)E{j3|rE-4! z+=b$!r$6xV&bA6~{{81}PCnV%+_-*z@0Pc5_K%lVmi|N5t@nOA7hKbSy=|}W?tby@ zlehmmfB($AwI5%*Sh#aBdhiSX`tP4w8|NPT@7{PP`Uby!Grn?}k-ppg=Z%HJPx8^7 zyN~{T`MK<~57swy=jUYSY;o`Vn@3-x7aqKN;fD{OeBNB5UXkuU255xbwWE*R+yiV~ M+TOhT){QU!2kBCrga7~l literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_6.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_6.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_7.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_7.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_8.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_8.png new file mode 100644 index 0000000000000000000000000000000000000000..8a01daf4f029884de8dc5de0d46a75e2c25818e6 GIT binary patch literal 902 zcmX9-L5SmI82x5C({#41JyZy6z^qgV7$mR}g60s%%o2ylWSQ*JLy(98d*~rxgdTDT zm_v~YL3#*Mr9uuB0-M7ea>yZvAO&;Cp@#|)D-^9ThawSr81Og4!u!6DclqAoz4!IA zE9v2bM-Kqt;pImc*Y$n9o@T32?|(0^B7g=w`}q0OnjRe;9UmVz8jX{alhf1FX0wT5 zSgX}KJ3GUBy&lUlq9~}UY#5qlnXc>l{yd7}EL)Z3zN%OT1RfN*t!drikQ~{}c*6TL zWfAE~YURabvkgQV>+@|>#+^Rt8PwcjZ(K3;`*~!R%ki!Z4*N_ZK&N3OfTv;$6H6zZ z^`cwl1llpE($SrVP}T!b0CWs9I~|80Jc+{%*3nwe5#cr`Vq#XgeD&PYk zZJ<1io8wYMX{lfq{mI4(_Fjf=6uN70#7LqieSTqxiKP~?4`2a!03pB~Zz5`!gU#alH zU%!4{lXovK&Y!owd-2QpYw)<$IR6iQ^5f65x8DBa`@fstp1+y?`Pt+5u3xs^_~FrS i`tcV({m$IHpEqBOpWNMk^W?rzaQXD=;^l{*e)T_r%X~us literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_3_9.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_3_9.png new file mode 100644 index 0000000000000000000000000000000000000000..f00c854db0946821f16db453611dde24c92e108d GIT binary patch literal 907 zcmX9-F{tBo9R9u6_g?z0oDnJ%%wdEM8N!hvLzE0T%{yX=z8sea9Wq3TUWW=9A{5CG zG-x@3WT;Z4NQVqn0!Dm8zzjh$R4JIDLxsR~sF>k~dPJ!3hQB!uzTfZ1w|w95eZR*K zE~VSIUcChXw|nngJgo04^_(>u_5Qba838ol!Mj)YYkG8abbNf=Xf#evPEJox&(6*; z3~M%<=jZ30Znw*_j3^4KDjSAoS*Gi{)9E~l;w)Pi#lEUo1_T}yxut3C;gB5J%-G|n zGi4F!NouWfZ@UXb8td~dQ|>r@(l@BN#a_E&I_<9_vsjMHA~@_bi2$93kpRAmEle!+ z@XexKtq4>ysM67mk5JYHPylocGjZG@2%n+?p1)R<hSucZCk4ki1Sw zCf#>f!{@D;=!WtnQG=Bp7Xy+b7^%yvv}|yiDVk$tJlE&38Rt$`O!9KEJ*2n*Z528L zAZ?(0jGK3)h|*HQ%=_Nf3if`6t`)j%aKuQWy*|G%#Kcl_*Vs(0UFh!9=^+o%F2ma# zMfX{5Ac!MX^$cS+8bzL$&gXd?Z`bSnevg1Kftq6M0v8iPUD1QBINoVNIZF2ax{Au1 z%>lJ&9OpV6iR`L0WAMBsD`UMDvmqqHJw*aQAHV|e0YZQ!zzzdcLlKc}p)f$jMxnrDVIn{*L7@Or0ht}-u_#bbJVdK8 zDgt;OJO{D}eFYmD9cM&Od}$FFN#f>tSe7}ey@&y@c1!R(N1ckiFc8^mw)%U}QZ{dgc=wX(9Zy1Kfy zwuWKY`uh6D#zrom&oc}y2)v?5npQFly;iHWTAg0c3xZJ;&EuG%f#*P$(xp{jmgvzD6Gh(btz{R30osO2D4ui{8n+;)1yIs7C8s=K*T|%pvr@- zU|k*a8<}x88xL_bqfxA)g^f^<2ao|&4AV0i3&(AebU1EbmIvkX*s|_+I>`5NCY$GT zv`la+De6?wVl>rM{* z3=dfaa%CV)AZ?88qNOE0GmYKaqbI|QYK^RYXP$kSzGL}l%6{>CW zZe8iO%LCUM`|a5{h~vA62Pgs<05*UNFaVfhfD*_8G7aQ9C>qNo=nOP@@I;7YKnfr| zhZ+oWWaL%Qu#O@J?g!6;BtTKdDq7B}QcYXzI$FP93qyA{3sItlmw_?Uyq%LBLiI>J z;_P|JjjR2G)^OoX(0EQ}fh91J&XjnfqA+GzvaO2KwEAu{4BS~1pm@Sc67m2=fKZY} zJ&}6=yk@qiQ?}iD0An~5N+qRI(M(fk=o(A6c*YeNU!q4cH7n+kN+63wZ3cNf3Z>-u z*(cKX?*G6Wr*{M{_VaY=_y@1;op}8Ehj%Xi_=RacKfQkQslP6Ke`W9G-#+{Ht*6sB z&J&NatN#pt|K`+B*S-`#y-j`c->-$M+0><5s`=dBiN#BU>InUPF8(h3`m1Aq-g!Os Z%HZAAhhDw%bK(WIPwo`1zHs)v{{iH2r(*yB literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_4_2.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..93f4da37055453b9ce728f7ace29608b8c5d4ea3 GIT binary patch literal 984 zcmX9-QHa}g82|2ice%T|RV=P*m>KjT!*JG_hoE_gTW-c9<1&_E#6Cm_*oT67$gr}4 z5vx`yF3dheDN-d51%uazL&At7LdK4flfdqwCsF%QT<3;Yq(~hH{>>QtzVGAr^8J4B z`@YZ4Zwg0NpIHTfBO9-+Ur6Wiw4Pedr2W(fOIH9gaQ@uIvnidMo134X&tx(S3k!>j zi%UyO7=|q`FR!eu6pFLJI!(8%qF3LgGxb- z153twIu^8YgI<0b;b>e!QxzRr2!%xe2|&d#J(n|a+#*SbWw#}1r&1Z1=KXFL1p!Xy zi(H{35v)oII;EJjX0b+xZ@6OHmz_xUk_y4#C85a5l&CRfo!6UEv#WMJ-HXjIX~*N< za2Dh^$jeZu08t0h!kBJB=#%Au(_^JIG@OYQqHT%FYYbi!sFuR^G~PGlxSnCA69de+Gm?7s(m9VN* zr_Q-e+3!?#Tyqd~#)EJ=y^lBm1;7BX09=3_fDr~Lg~X$}fm{bA1BnEkhBgPD0Eq-h z2Ba5Ii$;!wyef*CC~@Fn@C=ANC=yoH3TBOJTSCv#e7_OL?sy!dR12>FUC(k>L2?My zBlU!}CS`Y8^JjK+=nc_eLgs-XFrkzyb3|39>lM*5t4`bW-F6(h<0M4WAtQ>&1C#(l zX%@{??h)`ty)zmy9s3cCDB{ayxmwlgb)7CXn3B!WE>8zyX-}fYN)f39GD*~-k;kD} zOpl*g%l`fF2QFRMl;M>-`){Y@la2M$7f)XO`U~-B_`>q~wbS3dd>uXQd^C6N*r|J$ z-?)+V9>6jC;J3A(@7~?La{1j`pFU3D->zm3ZrxZt@x)_lmV7dLP&oYN;GKIce*M?0 zm-OiPO;?$H_1ud`?>xJ;zj1B*RpG}q<|@rl3eFMmoM!N%Fm^{q2+efU3lld66I literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_4_3.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..98149e701b3f338edc289ee9bb838609ee97db48 GIT binary patch literal 887 zcmX9-F^HsQ6n?w2yUyNlnPMP9EF=txg$WiG78WLP53?B7%Xwg7VL-?fQwZ^32oekt zG6V~YDI`o_3IkIJ8ORnELWCHYVnQsYm;{R{24ZoA1dF+_WdFDve7yI4#d}}zz4zVI z8|m?*w;ln&<>e(l91dBQ5k)~&Wz*Dc+wwdw3>T|alIPp9teb{qK;S`tNfgs=M70 z_2_<|!*Pimsx)Krye%tJqh02#{MmZBD)XY*3t-5Yt@d4m494`_5#p(u&PVIm-DUG? zmp9EzBmigtHb4Ln1FQiK7@!u4h#VWm5h`~I1r`f40TKyH1&|8J!jaFSNI}UMZKkM< z;30SpWDzt48=JU0p=W`#jLbCkiXyJ60<~Vm2w0~l1h^8BMnYL7AJlr>Owwbxxl8tF zS5pJvNK9h-x70;mLp+AOB6-D?n@Gd~=-dH5Rk zW+UplIv$&jW3i0KF`>Z5BAdy~R-r3xhzt_B6q>Ur5l|tw$Irdr`{&^YUOc-|;e)^b z{Ja(KTwi_oy!*ZR>i4g~_~q?e_t(FS?5n$Pf4l#e_~ZWm4*TK1*$Mo7eDmEme*E%P QI{?>DZmxd%=(BJB2gEaaR{#J2 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_4_4.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..2c0c4397148490eba811d1baef45e1432b5f3d12 GIT binary patch literal 985 zcmX9-Z;0D;7=G_>?sgmnt40i3wR2Iz$YGEO5#r1p^~ku4%gqWAGRQO^`XL`86e*Hn zr$PH6Y8e%(b`W-z1+Kz@Q7UE-lKa?5tkT5D7ddSa=!SlW^&zJXk;CbKo z&TW-ePdt1A09H3&THns*Ls^|#n#=khzj!#n9GpA5vysu6nVH$y*}1v7`T6;Ug@wh% zMGV81mX?;6m+@k;$S|}Z@Ukpwnqrzpy>j0Ii2#*?Di4l~ zbqy?NhlMpG3XI|zkE00}_FFe8_<2*M#rm*e&&=|I;qdA<}7V4hZ?91*z^<%xj5_GA^$&{$EiXj-bWOvk#Z}^cF#?2_{j*o&I z4|y4I9SSud9gOYZr5>pSyb+ZfW7AEY5baA;USo-BiE5O&t|s(NIjU=;mO1h2Y0x@~ zJTwV&d6uNg46E}(RhAo?)~;52jYiPvM7}>B4%0M6Ko~%_Fs7Rm`h+~7^s!)16gR2% zQ)f8sCC8&9v_j=_ERL57MVX>Cjx$BcRffI=U%R}q|I;gf zZ;<$_%P)WT&iS98SYQ6^ujfxbuy*o`_t}eBvi}HP+$HhSS2GtM*?TO<#c%H)}wF!d39m!_J3QMCD`29THkx|!rT7?%H*bE literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_4_5.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_4_5.png new file mode 100644 index 0000000000000000000000000000000000000000..6efdadf23527761050307419efe61604821ad2ec GIT binary patch literal 940 zcmX9-L5SmI82x5CGwEzus}{Cm4moroLXfxw%^?nPC$rQcGTGUz6wDz)Rx1=YNQ548 zh-(j30%oDC6?&)=utLDH&Oi=9;u54n4?zl6$e~DOy0BuL0N~=`>jyV-em0*=#X`RSz4NL8P=M=i+`N{{jg5`X&CNogu(h?dy}iA& zvx8w+u~^*Q-L2MYHHM)DftO`b(-gzdJDpCyKOB$!D4Hcnnq>?PJO`3kQj|)oMYK)2 zYjgd9G#aZxXiQ^!v2+CrYj7o9tXd7i(a52}oOFb+-Why#%5Q=I55`caI$DK&hq}iNX)}!GNg(1#VYJ8QJ z2u>yII@Pck&EbrJ(DB4xAiGo5Pnraa)AbrBQ=-Nyx}bNZ?ob{2x*uCn(u-H4#X2nW zP?4e91i}Q;!PsH7J|>lr*W-r0Fx=FM(1}DEfELg+3PchwG3 zXO@ju=kqlxQROmQt=5T}Owk(08KTrx^JC`N?oCGHB#N^I52}b6a@kS|r$r4+-s{T2 zpgHlZc{o_jqbz%bcz^~#UH}Kc1DF6TF+e#a0htE!T$Icu5_AT7Jot4;BtSACy^3rG zxf1eQXxc@I3y*_mK@^}NVJ)p{wW*#{AGul(bmG`stzwjW;Z0!767N(cmr#9DPdF!4 zysRCp`_prOf#xY$0hYk(bXnnvmduz<(Xm=?&kDR=9C@oGLfL{9MdSlY0HHjKZf^Gk zc*h(pm+YYb1jckKD2m)_X{M<&bcdz;JmU#WDAF^DS~Y4&C6Gm;0fT%V#bRE5_Qld) zkAL998%Hv{cJ}MLxp?dF;Ofoi?!E6^eG0A=H~&Lz<@k?x27CK^N0(oE=E2?R*`-ta z>C+#+yR7{D=PO@)`T6bB^o6g#-xFUB;In(bd=qIu{r$Vn?`Ow%l&`XnuH1ikeBb<0 eyZymg;kUbQ{`26I_ip7baCq(L;M@JTKmH%1^OLdw literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_4_6.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_4_6.png new file mode 100644 index 0000000000000000000000000000000000000000..251476d3532a8d2dc3c050cb22b09314a37e9ff8 GIT binary patch literal 860 zcmX9-F^HpR6n-=wvfYv6jS`?u<*V2zW0jv72kWG-#yB& z?!LPNfL9Mc-@otc#Y+qaeSTg3kO2(f-7g>Bz6>ueE-x_aJ z33*E!xoB5bH}k9w_uaO6KAh2r!Ev4- zWNM-@tR)DJqAtvSnY#^^yUn&Ps_rO)sbG$VdnOgmn3XFg3oTnscZqk%SIwd5y01tC z&;cBP5Fi2A0h};EJyZ#~4oYHFA5X_^Z4TI3WscO-^{8dGLU+qDq3M$*l*b5uU3M|5cEG4K>7 zv$!ErGmUenO6bkvrI#hksz{o;K;4m76qEw00ioWDMKAXar0=dyCw>)ugHx80VQ90N z<+?V<`aBznTq1F~!tPb3(I?2HkVm5xhf)z$N`L(P_oIJbe&CPyj~e{=<)7dB=I-JC e&4=Ni*2kV-!o`2T|N2+Y;Nk7#{og-*{PaJsac8Ok literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/large_turn_right_to_diag_4_7.png b/resources/g2/track/boat_hire/large_turn_right_to_diag_4_7.png new file mode 100644 index 0000000000000000000000000000000000000000..86861600b56ccdde6a447e24fd94cffc9f5bb12b GIT binary patch literal 894 zcmX9-F^HsQ6n?w2yUyNZnPQFzF~PtT7ABZrVPWAV?qU{`^*9fvurMHGAX8Wv7=ndx z7DHko$pqvwBvV*SA>0&ONU*T5m~c~AOfdlyrWg{7g-EcNVh{d!9DMJ6e8qcT@xAxm z;~VMX!8;EC;NtqT%O?$=G}URhnr?pk=W~D-JpTOYRU?m%j*gFyTdmf~$;s*I>Dk#C zhGFe?`~3VI@AvyG%ZQ?&sTbNkt zb+?ONy(Un}pjt=wK0;X^KmpJ(%a1aOG--xGaq<6E3Ets-70j?;E1tAdjo!9h>4}O1 zq6aKD6vVNrdWJC@kC&d8&gXd??>3vNst^z+Pyxm+x?)18YkIg7Cwna{$4TXH>ScMq zJ)jQV?Q%FSk$shB44$`SWuiCB?4>tdEtW-=*E<1p8MD-`qm%xKp4mb)QIpwl6*=2< zR&KMpzC!}Q0Kfw90V04Ez#aqCKoOB`p(sSfR-wRTVJbi@L7@Or0hu`RSQIKK9-;LF z6(PJ1o&#Bgfr5<;+!@nTUs{AllDK&um1T|^FJcI+-4T3T2}wPs%!2nTEvm=KAz0tX zJG8B+9&jWkF#6WIXOK&?Q}Y4XJ_Z<=NA_j z7>0Gb-OI~MVlWtR94kqprYV+XIF9XkUKmEpWm*)QsyZ|c$ATz;s`Lz_KN?Zv2|M+L zaIP+vW|lka(%#dYd{Qv zngAVOd_>4g+Q>z_)cu_kAA$nisZ8JE$+67%y0EaM%+X5E+J??P@eX--EEBXZ@IFs7 zI>!%1X{>3!WzEOqrSIoaRHo@}vpF0N2uK^~5aSlOl#$w+8SbR%-iYgQb_h1jvcBIQ zQIElKo*-mupfRi^2#%so&34&j>CaY+WmS~TP6SiI91V9(Di|^IiI_~aY(88i?lzy- z+oEY+A`w6bZ~y{;1YiZQ#{jiZB{XqR5~FIX(qMBi6CstMQUPgzYy$ZlidB@3(0Yoh z7+wd@gCc>hVk3)i$IL8{7qOLPURfq}U82^D90E7#i2jPv`$fePoL#c>Lr9FQB{obFif8fRKjRqh7 z_Ujj|c=!71qvzcptiS)+3!TqiegDlbw+|mi?teeM_w%cNSNtDu!Iyu%{p17biPa9n O_0yZHA3y&5+y4PW>vlu{ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_1_1.png b/resources/g2/track/boat_hire/medium_turn_left_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d5ee3f12e6eb148148e8d1295ab4156a477d1985 GIT binary patch literal 960 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 Z8R~WW;>KrhTB#A(IJ>p}^_f?%{SUHDr5OMK literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_1_3.png b/resources/g2/track/boat_hire/medium_turn_left_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..034d380fb2e19feaa1be636b12a74a659b863424 GIT binary patch literal 866 zcmX9-F^HsQ6n;CiyUyNl7??tcg~b#mNU*T5u<#OhF^ge6&I1bz7lcePg@u7BEQDAL z!NOu75~i5KV&H^Kv4sH(3yUcRVll-8ET$NUkb{_DF@Y`qxEy@%eSAE4U-7;7)7uC6 z^{dZc0l@3~Z*Sjq-0!M4ce*4|~yG~wQT=aUqe!qWtd3kkpb$xw}Vc1|W zxVgC@#^W)^v63Wenqpao`?y-6JSVx)SR`1L5=>gQ8QtTo zP;i!#pD2q=i+5&PO(>pZ<*}eKip3kYWY5+4%3P&(T6#sbDC_m{oZ}*lG$1BGxj=^) zzar!fZRDa|>cP>8o3KDnDl@Wpawao@F03snbF|X84v}+8{3egiWr9uxKH_Oc=lF>z z%``2rtmSOB34(mJD%141-#1NzfV6>*Fm8=Y8L91<$x)i0jJTdqw1j2U~{k#A(f$00cn720tFn3Rg_NAZjP!LUV`UA zkw90msYQ4*W)aHk*vc}$ER(t}QRhWYfOCgpNT@MornFrNVPhoiEIUWL=k$mU4Lt&$ z!ekaVL~5#W?nDW_X}s{VWKkALT@|Q3@`{2|Koua=WijvUK7sVz<>|yPqfc;lJIOG# z>C|#vn`3>RjYKYyxLjfPDpTuYWKzhZ(UL={h)Sh9e*UZBzb`-V!@CC!-u(H;_nr9c o{`TwlgI}!2$Nzr+r=|OF^IPw)FaN%K>}GI(_i+2`H;+I54t#$9wL@u4p}T3Az+mrB39_KL3^ldksSz^;8+09TIQIJlYL{d}$#3;BL>aq%`l0Z!gLJVF6W}#5n+S=OQ-rm{S z!7!{?Ebi{^R;tx1%QB)UsH$ujnq`^ocH4Caqfrn=vm{BgjAcOJL6J+ER&F%NW{c@` zdAF|&NBTIlrg3+%^h6q~@g-BP*fr8IsDZ_vx5dz{O-E)j>8uiOokkJ?It@($92Fay zSlGqq!*Vty(27BsjxHU9qAGv_pktVc<2FG!6y@>!xuQ(!^|@_79t=HGXJ_V@r+O#@w}*emf1_b?l>M zgqJyruCZKQ5SyynHH?0l(8IF=D&K3gbGG?i`t&>iJ?zaTLqmKLa ziEq!t{%Rg&*<&OC)Br312fzoI04y;;ITR7KEaZDAnJW~SEc65jBuErMDj>6hx-9Y( z6g1GZgAxy(2G4;kLQTOMM#XN@Jx3aP#(3P0V}G@ZQSL?5fo+upr=obI9#Ce&JE`Vp z&GFiuUIq&^PpL9+BqlMqCXfx4ZPjJRZg@R=?DyixUnLRB7Mv`j08j!5?2bBrsnzQ~3$GgIhQt%`IK*%a!tC=gIA=jG>KD*gNP z2X5UwR^hcr58lto>CwTB)2m;7Rw0XYLoD-n&RoUj6lz-~PJ(i}uak!w){Z|M$baCtrvd0*8CQK Y!n{Sj^WyD4a(y^DJU;mD_4jW74_hk(I}vzehgL?+8-*&;ba4A?`3AX(`l zN?>~^5+!1hpgk1Kp(|PJVT6D=Lbtw_46i)k?Yhzkcx^Kn3o+d+)TQJ3BkOyStT2Wp8h9e}Dhr z-~hw0YPEWJct|uF4US_aNmNzYFf_|Dd%d3Tk0z5SP3L*ODGH7SQ2<4*X1f7Ad2%d_K zO)PQo#kgL~NVH~Ap`%L=p|k;@0O%NI;=aG@yEc6;GCPe&t^BqUdFhy<%p zf=)M0rsZ&kCs;$N7s`WJ4Q6_jw<(@vn+-u_WP{gC$?Plrkv@vdD09+$kgdndZGwwX zSAl2)WdrSD{D^2yXe|-VtmQ7PVB@9eLSgC#Pj;J(+Y-ix6kBT6GZwzJ3VWNx-)13N zrFfmEnHI;lMX9T*u3-$j-HGcaqfr(`%lUk>*&rZIpnZ%R<5EnjGp43bSrCkWL|oMneuoBFf~l{QR4>f1m%r zgS+P{yz|$eAC~0w?Bw`f_1jOrym{@H8`a7))FnUo=Z_~JfBnPtqu*XVd3^le@oSI1 zDIPK(Jv#d8$>aOi9^`NQedDwHzjN1};ZL{T{_geY`%ib$m)}BzpO0>rf^c?ve)8k3 H_aFWbv0sKd literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_1_6.png b/resources/g2/track/boat_hire/medium_turn_left_1_6.png new file mode 100644 index 0000000000000000000000000000000000000000..dc81f8861a4d1a7687eacf70ad1c7befc535b7cc GIT binary patch literal 924 zcmX9-L5SmI82x5CGwEy@iuMpNGC5SpO4J|$g9glMX336`$*@_7P?jtN?4d%?2t5P| zn3W=33`-9|iuRC04*{zV5|)5LBJ|KhlpklhnknOsMtTM{ve*k(OnhxNG4pA!$b;=Vl?c#j=nCMe*x1C9 zetj`+Y-R*17_`yRm4{H;1W*8U3^VI>hafzP3V8lPQKs$o!f`G~Ba|cr+h__nqmaB# zNhYm1tl{z2P;^6i5UasVkMcIj5scL2Ra!Q2U?X0EaDtySo*6Mvh9XqDC* z97Ss^*A~RCs`d?I*zHdG{bV%CqG&mvuh(k?gb9?7vE#ZJ6Y7j^FU8)f6%^fg?aeon z;%c!)HM(Bsa9kprD$N)?Z^=qeFU9Ohe=r?S@-*8l1<+;8QtOURdL4Rb3t>-H&1ttpv0U`-<1&|8J#8IC`fr6qA zn)Of~z?0xPkVViGtYhF#mmYZ1I56Va&9bm4GE{mIZD8%1;NeO@>Jeq;yti(Jn{K@I zXIIe@E!I>6I1-bXdP^WXDr>i8&*=mMCk_W$8WwqqHcL*HQ3NOlgvu;>rQK5yu033> zxS{_P)@&xWT56|b*tW?sF30!+8;WcqGjoM5v?kI?v+-tt}NATGj_e)hcy?J)> J&D-}r{U0-rhTi}H literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_1_7.png b/resources/g2/track/boat_hire/medium_turn_left_1_7.png new file mode 100644 index 0000000000000000000000000000000000000000..1f7afe8b0b337b2a48040bc33c8de2b3f390762f GIT binary patch literal 924 zcmX9-L5SmI82x5C({#41ITQ&PFha$EQF92ALzFmXhBzCUteb@%a)@kjd#I2@7JCS6 zz#NK3$)SfT1#`$s4*`qJE;;lNB!?cl5M+=F5qhW?*gX^}+QSIH85SPj_r1$|hxfj( zZlB9HZ@h8?0B)XrbaJQK*LSN?tL6{ye*OnQ4Q_vY_q3vWdwcu)`?Xr_;Nal!@UUL5 zV;I(GG>(prh<3ZpajYbXnx>ehZrhgUd81J{ohDg!SrnV?mSaH_KvkN$-s<(JzQYcD zVKi1JQ)8Cei`-wWBZ&Vuqq`O zv}`dQmoo#w9!p-V3};%jFp{E6@gys^1&vWmUbiG`pbkPKOsph#vtpQ+lhrQ8MQCY2 zbb)e!4lq6>^!d|LO*=Zw#LN1NQ97;r#D^>aVx0`=o|G6^yu!Q%be`p+k|M~{d9 ze)HO^FF$?g)Fb+z@ZJ}X-e~>$?SH@AKm2Sd>9^kc`SFhrwZ?l-%DQ<`slwUm`N>Zo He){GA33P~m literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_1_8.png b/resources/g2/track/boat_hire/medium_turn_left_1_8.png new file mode 100644 index 0000000000000000000000000000000000000000..9c4503b375b719769321162863f83660066a5b30 GIT binary patch literal 913 zcmX9-L5SmI82x5CGwDp(sZb$ezz7v`2xC?P=8!{HGfQ@eOqR(&4mm^!Sg?m2qVy0X zU=Bfgh*G3r4?P6wA!-k!WT8UDh;s;-Ly-zORH)d)9)d)vGKb$R3-9|r-sQc+d*3II zFQt1YFP{Lwy^BZZSM`0Ro)?;pdcXOH@H;>Q9=~(_u%>%^d;9zQjYi|(;NbA^@aX6W z!?0$vd3=0~ce`DdWkgX>RoOIk+qOK<8;_^+d7P%pqA071WkBFTkz2an>G#Qj!}vpf zJW*zIW0BZdK3s1?k;XK>Wy!d!k%37~ZT7|!ld+b~t>V_-7U8Z;B?1f@1_A^sHnXr~ z*j~*#RYssKgDL~v1qh{G00qFnFst2m2_m4Vkmqj{<+j&bx$e{H6eS74cDe%2C?s!C zl0|DSYX-bM5xqzrEz~eG;-W`#1S55Mm6lCTw?xZV{HZaGtvGknVw7)Z>s`_oprZob z1JVI1z_=+c%_%(*tXvze?XV0|bfeH6lOqNaJ=FM_DK2a^_srGU-b7xRjCXm2Hfg)V zQMAT#JwY6(>d-VNgTZ__Os3O3j@Qd&S(XS03#c*1&f4OFP&2x>7X6JLZU>7pSXT4x z-D-zgbi2*rxI}hUnlX9amKEQq#hm$YbUT|DXuk*_W$z1zrL zC6nzct*WO;0MGzzfB+x@xCPi?fNCfra%>cZs8}f!SS*YLh$Sc#Kq?>$M?)5c3X1zE z^HCAPv*0<9MbH$iZ{qHN9tF}YG#3jm&!g=&N3|Ex1J-E?0j`9k5mQ#d2c;fWgT-!~ z-NkFPDya@|BqlL!T_F1^>-6Nn?S~_G5smUR+7>CQ)|@P(7*GKS)miwp-E$D0Gudpo z$@n?!EE9EI?e|T`u~^3An6bb{BAdv}QlYn67a1gSDKueGETCMj%g>#){(ANUA6#9k z@Ziti-m8glasJlzOP_!F*&C;Dzq$V(a`d0R{^)^y`r+R%KKk_A!_DhIUVZ=X59L3v uWlzw3>2%`%>X#>9;63}v+0XG;jkD`le>us%d%u=~i-(uz-@N_q$NvNFLWGe3 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_1_9.png b/resources/g2/track/boat_hire/medium_turn_left_1_9.png new file mode 100644 index 0000000000000000000000000000000000000000..81e42dbc8c9b6126ea3a11236240dbb33341f743 GIT binary patch literal 981 zcmX9-QHa}g82|2icj;X{3l^*xTsZoWL7YW02qUmKbGz(_UdD3JVWv5VTptSNAwt2Z z0iy)3N|b_qs8}Hng+=Vc=`tvohYE)l%|jnL7FdPKIyj-Ya&~y&-;BZU`#ydz-|q*% z@B8%XjQNOk!_7?Fl%j6jV8I zWvs1ZVJ$ms=VpBzO^RryqEi>4UI9P?P%%u;W-T0dNz!B4LrFR+mxq>h+-jjP#OYjt z%NHerRY^goN*1lTtkL9cU#xd!udfDinPBjuP+(3m8S-TyOdws1Y2}3usf3&!m1-lyo4P%8C{a0$!K(sQE3s{j?;3JsYr}>y_U&od zm`6Su_p&*Lq)IeX=J={C*EFqJt#)d)u+@r!U^Ey^r&9#D4rBwP+gZMg%YCXm;+?VL zO{(3gJD7DQr^7kQP}wY#&kICBrivQN8lvQ=$uhH3s~@#HaW9&UI8a5*kh7LbxD~2t za=s&Xo8=?l8iviuus53>BMzVhU;wxPKEM&c7z30*;*n_}-$U_GB0;C2&OsnRECG@M z>3LM6ktd;`g8B}MJ$M{E10oM439D#%t4h^fq3vnit{p}GWD=o73oiq0W;i!5d4w8} zdd#|0#h+EX^G5$P7@^^m%mG7SLNTjwL`9~}vgleBuWohyderkLaSzQ#j3}Z2Pz(qq zSvZN@6X3Sl9FLi1;|Yv@pH~#QQqfFPr;9dIY;d&C)1g=#NYtcMKq`SO5;bWQa3~U! z<7dug{(k%e?_S%H;g$P$_7h@nZ(iCx`{gHJuurF6PH$egba2*0^j78KnQr>_y^Y*8l`{Pxzz_ipYR(fc2^9$k6r!RN;(Uo*4cxtkxn(?0o;&9vTg zGIypw+#P=>o&53d&p%y%^dh&h=Kb^Fq4n$F%${@Mxo^*BiNjmo?Z58s3FjYfy?Oml Z?3ww2^2_UsFC}(h`|{4__pk1K^gpRKr-}do literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_1.png b/resources/g2/track/boat_hire/medium_turn_left_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b6aec9ee92bcf8629f7aafbfa41a0b22454a3754 GIT binary patch literal 984 zcmX9-QHa}g82|2icj>LnDisR`sZub`AW<@iT!eVb9rYHujAhb?;^mGEJ1CmN2o*Ys z8n8$_GOrH>3sw!o;t zHL7m1&6e2d%3e?F2j*yO^CVVeQ>u{Fi#ban+8TXe@V#cS-&MoIdKB8TiC@4$CZWoK zC1D*E>zV0cCo}EiD5B6*Mn@JxejY#skTFb6r*#~+2*PIB15rFImxsE3yWK{;9!_WS zT$U1ZtV|SCvZ&LF#cD0yaD;{@*?rj!%Q*(83VBu{1%)Z8yjmCQZMp5LZlL>NBZxYq zSuf2&MuKb^ay1|^JU82}GH1^XOh9HYHQ|9=pB$X;NC3b5@0H z)i|dvd9CuHqYrznXy{L;w-E(Kmw}Se06xwhvcm@O>iXv7~vU-(lScQ(Qc%BgiP80MlOc} zAwGWQnbbe`e&DUMn-aYE`_0#4^1;U1>ba*r-n+E=K;nty`n6MoYrDaf`FZo9=U)GD z_tM_}^^2qI_D2_Qoxi-}{f0gM-*-Q~dG%z$`<~jkbKbl4{9h|SfBE&!C#P?mc<~B5&#m&{-3xE82`G?fjBl%Y%_6mCkJNQig^vu6^&HX>+SD)RxyZ^$<-@oW9 hd1LGC(@R_M#`e445RaXFauz#+jrGm7Z%=K%|38(1rgQ)R literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_10.png b/resources/g2/track/boat_hire/medium_turn_left_2_10.png new file mode 100644 index 0000000000000000000000000000000000000000..b619907ae055bb805bdefd69be0a1f74bdee6b6c GIT binary patch literal 970 zcmX9-L5SmI6n-F{^v>xvb0oKJ+O-4i26@+{x(D($ezsaxRx!Sy@?KU0qvS z!!RtL&#$kqm#Wn&MUfoGN|KwPK@DX&Pj! z%{X1LKTw8&K91V6xyuol%xr2x$&@R$iuZKt$l?M=9uKs5)JkIaG!6MOCJ0Tc|=3I(%VwsG8Lm?Kdf)$3E!yxr@eAShGCDqAAO z3Zvk>M#v_m+Kk@iEKleRC3md&alJy9NxsTRgrL$jjni6UtEcpQ&5z75?nFs{b{Z5| zC`wSOL&X5x#^_#&AKTID)W#wKf*M7N^&xE3>Z zTJsjo;i)q|^Ji$9;zgh<7*7^zY^5PlMqRMYhTAcRUMC8@Bo5JHMhgP+0mXn&=0z)$ zyNj}Abmw!r>)eGt9&@#t)M%)Np;4qolMYLH92E%UL?jZqij)d6anz-d&!R}k!cRZ7 zd2;6m-nhIk!Pc!`Ue3syd)v<(KJn29KYe%p+eh-bga1(T-uL|rlNW{i|9r`DZtNbu zyG8sE{>ooG{A>Se{9*oM6n-ZCc3yrieVniUeBtX$uRQ(g=jrjy8*e@T$pinaD%TQe zs+i_YDKC@AzL?$sgCU8(?o| LfBVZzFTDLfTXmx6 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_2.png b/resources/g2/track/boat_hire/medium_turn_left_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..2d1742ebde1ec01eb12e5f616cb0ef285d44c55b GIT binary patch literal 989 zcmX9-VTjvw6n}TUyYzO>O!^_XdWeUNTLiUaz-WonFt6qG6KE=5vk(Q2<3=E0uDU3RSJK z4O?inm2OW9LURz?Zoe*tt>U0(B>l!TagSzEfdq|#stAsX zbqy@E@liK7ACPFuqPd2S9fYDhfC8Xln1SOKNjfy`3c|jk^vmUuWgT`pC=5w1mlp|E zp#+UC7);UPbVo4TQr(lAf$9!4KPgi@$rkd0%E&rjG9;s+G&)+xH~iR&l4d;Zj*miI zgq#XQ8K@f24#szgLXR$mq7fJEvFXm72<Dl|JV6wwyvne;Aege!(9&hKp55$sdr1_}$0BGlW~#WQQBH+v*F>+O z2JLd+vqoWiI*R7=LnHze0Zae~zys(5OfWzx6baQ#OoB%*!(J0VRM?nnfd( zdjPUtYfmP8yY&F(U?7!BYNevrY6i#FdA22Tp2USRJ5-oyF^@C~Su|>M$QMy8r^nAf zwf4{bA9!nbM}_DAy!%EHBZk&Gl>?_aSk$=iZFMYb|T|y5{e!1|-57+x2|9H{6`Pufxm;d|K-IG5* z{O-4F*KY^?YV+>0L418L(pi=G`SxF9eQ&`3e(&|2_VT+2+3(-E@VEcv!JU84yubU$ e6Q|JR)-e!Qyk}mEKiW=h!Pe%^#*G(Vz5G9mUagA& literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_3.png b/resources/g2/track/boat_hire/medium_turn_left_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..920a7d36f23420991bd0cef63ef7298d083966c3 GIT binary patch literal 868 zcmX9-F^HsQ6n?w2JI>y42$@0>3yUc%B(boturL?*FpI}}oCg*X3<#NG0u~0Q5F(t# z5G*XFkTAs*7E=hBVhalc78X-XVKK!VSPaKNEUu75j=8XbKOP6)dmkSU-dB9@{r2)+ ze){CACjjvD?)%$U9rwGs9Q3;W!vEoCfF8Vj@%niuFD@=FFE4w&-qqFB_4ReX-^Va) zFc{q2+z{jOnB!PU5;aY+EW>eZ-}j?vwb`Uav9GG8Z8;W10aRsZ7^CTwnz`&e5Td2J z-k4eL?8@MHiX{fqg`uqwo=$}py>hq*U&U?FcQadfZqFR*o`gqQ95k?vi6QEq6 zLyTV$@`g5Y(JuAi=)_G}pa+#1Sv)zDnLroTmXtYK>05`$IVFCRN9Qs@rve}GG^2C; zM3iQl7FgDDHroV2zFL)Odfe}ura?g3Kt~w2#-)tZcFg1`%}+*L&$1@mx10L$a7IH0 z$9aN~sjJ;gAk<|s@9aK<^xfs@#4n@IaCSS% zFtq8^a$TEaeV&a(E|IugVfQLi>tke6$fMDcL#c>Lr8|E9>*3#@e&Cl^_Zocr*V~^u t@x|Tkv)6;)t&jhFsQCWi<9}bmHy^J5bpHMIT{nfh=l8dNeD~v<{{f}4Z&v^S literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_4.png b/resources/g2/track/boat_hire/medium_turn_left_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..f8357ee1d71413a8cd2cadd2a1969eddeb8d9282 GIT binary patch literal 958 zcmXAoPl)4m6vyBE&CHawLJv`M$ZBD72ur{q0V77u>}H3^WZWzk>}rI_^iUy(tW?M$ zXpy=^H!DRd6zM?JB2jx7F-li565J7b2w0?Iz#a-4bji%UyO%gf6vD=Vw3 zs~Co@t*x!EujA!%nPnMK6jW8#^{Qza&1SRH=?w-!6pfQ)o@Fcp0uPE@s8&n$I@z$8 zmcw_tN`IgYLvs{6)0rpIScNYbGHzE$SEqU=d(afaPGvMOlA~6dc*pZdB0!^|A%Lr5 zeFF=f;-p{7Mg&S3lxgV1MJOr*C;%FU8O5Sa5H3Y|Jb$1lN446-w(s2BZa)i*Y?%8c@|xFye|cHNCkTp#z03=^W9JXs5#Wb#Z8_aZ{gk%$eVuhn?ft zN3*C{;wZYpay3D0sH&su-9}^JIAO0B2f=hap3mn92m`1N#`cTikWfc-Z7Q~ARWEG} z=k7Qgq$iVORG^DR4#y?3tkR6m^QNq{w0xO0aN0-xK@!E;Q~*uJOtolhq+6%Emf*M4 zVYhbV+mo=HPNFQkg9LyIfC=CN_y9)$GYn8JMMRc~d=DiPg#v?xwg7t&Q#6@VCE!R*Vv1FPtgEb5lU=*+we6wbjw3%!B9u)zSw;b%1Q5!zXyv$j zBAQlrHsiXTdoo8Ov07E@b=|TImT7WKM__%C4P|Dm&}pTNG!oeq>ar*hP%P)i&z&p$ zefk4eFYT!C)a{@5a`Wo;*3*|Cc>moS@_mPA*S5YzuVEKH>OOx_xc19GpKpGb?tgsc z@aDg_zItK*75>A!58wFg)>-TDk0)A>Z`}XfOCP9@eEt3I@6Ls{pS-#M*jszQQP-Wl zU$@@5z4^nJuRnPA6ZRnc@7$-?|MIVnUc}$n~;Jt{WN4ylnQNN|fLV1{XC-#d1Wh z5A`S#X3@%(vkyV52G)n6L3$b`!XAPItlD87Dip8C37splhk5+Waq#(mzkFW4pAUS# z-|L$j*>el$7XaYg+UoL^cwUNYer_u6U;Xj>D!>$Mu5YcxbYfy+a&mHNYHE6VdS+&3 zc6JuSu(`Rp`T6;DCX-o8&3=KR7l9DoVVp)UMVJTkXgX$9*0Y5i{hZsSuV% zHA=iwkvomTp=0*E#<1s)$9E79kOMFPEC2`K5MY1-iXjQ8WFW^zQBNX4XQ0M|n}tXM zBm>gZsLCK)Lav5_3W{vF7d#81067WM)U;WoYF4&otDR0c44vUHM6niL0H&1St+Zql zic9JdXN~gCxY#+Z2WM^{^+se0SOUw^$vjVJGE*vumZ{k_v*Xl4-x)?e8uwXIL@uBR z5Q?*?#B%q6mrISofNj+8!w3Q)pO-aFEtPbJF0*ug?M7k?c!(0X_1Tsm~V35nB zP>heCeJt_My&rh<%7zS=ZXfN$9viKj&|J`^rP=%Y(O9{M}S0&`w@} z;`;WlpI_X4__^=j`Dp9U$@f2e>el{Sk34?i)$@towKsxy|CWDy_W6^+U%xDdH;hm2 zwoY!}#jn4&Q@eWXUVUkEdyn?kKD+qkP5tT1{mV!A$3L_QEj9{kD;vxEOD|sgA6%Zb AhyVZp literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_6.png b/resources/g2/track/boat_hire/medium_turn_left_2_6.png new file mode 100644 index 0000000000000000000000000000000000000000..14d8234a10bf1319826cf84cc3dec1ceae70cc93 GIT binary patch literal 913 zcmX9-L5SmI82x5CGwE!1&7p^YL4x!UBuI2~$RUTgW`^z%oh+M$AO*7!+#+SoAps+1c6M-L2JXdwYBP`}+q6 z2N;Ic>-EFKL!#AcaU3g2qN>V<(XlME-|q*(csh-pvM+>(U;Odn@`PRHdq(ow#?cj=nU8*_$oFr zvDCvCljdelqBV;)I=b=^%31&lfR14%j=Lo3({v~Z7m70Lb{DSubUa3BN^;GXNU#be z=ycm;G?z1c!5T^ZNFF9?IM?H%OYtPzZV4(Q8+^x<%z-i(>*Lsrb2lr7`FgV4rnm@A z6^JfS4$wZvkBRn_?xdobYu?fdOFu&w3ez-r(rz=JCQJ+|vDCb8ECOp4^~*Ha<`G(D zc$23YjpMtbWUH!Y7$e)BdR{sn=W)Eeye!KS0cipqVB7?k5>lNr-K8{Gb;7lsl>X&r zy1rU$QG>y8o*>#(OJ!I?5G+|4=#`i=^@g*_w8-+!QUqPbEERWk%I`5FM~nt)GV0DE zcae_Pi)^!bibMbnzyk0AB7hmd3IkL@k&t7dC`83Vp~2)}C_>zZLII=#G702yC{$3~ zL-PSDLU<8853&TBg7pl-wV9#co`gn{^z%GguX9v+kzL@NhUgPYNa-{d-7e8=z z_f&;<{{HhpMZ}Y%TleZ;f8^bI<>$Aq|MDNQwQnCxjz9k6{cn`VpWS|VKK%9i8=u&3 zfAP-`XJ5T`|F;kLv&Y}P{^a7vXE*=<>&Zi0|M2Gar{B-Ntfb)N`1I)f-TR+D2l+IH AZ~y=R literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_7.png b/resources/g2/track/boat_hire/medium_turn_left_2_7.png new file mode 100644 index 0000000000000000000000000000000000000000..5ff4414e3045c5142f43f59b0fafaee1027cb171 GIT binary patch literal 871 zcmX9-F^HsQ6n?w2yUyNlSPVfD3yUc%Bv@EjSeV2;%;K>g=YfR;7lceP0Sg0DSQsK? z2nH;skT8XXgeinfv4w?&g@Gxiuo%JwET$NU#T9Z`Okj&Y9tYohA0Is4SA6gN`sP7? z`QnQg0Pynu+q<_t-}H4k9Q6IQ|J@G&19tE;Q)>+74F8w|sS z!{P1iEisu)IF6MhQPUL5G91VDeLsrg%_b|$eO@+6R|UsYA~BdQjBJJQbSkvy*x{ahsfhI5#;&)ErcTanDU)C_Fc%@zu(gd90e)DI zyB&!d7Ih|i4iPFR04jiqVK$C?BpK3lA_z~ax}8oBp7%bEQBjcGcp?(4N(m+{+l=mU zRwy_t$xoGKt|dD&tEUuCvhqaG7{%fZTe27GA~xg9&ML30msPVqo(o)ru?EBxC>Q7u z<6}bJ&_*HJl^z_Oqzy~-q%vcRC+9K~=)&5Pa!0Ft>kv7o)NhOET&3t#;$xm>bdH~j z(p=L5%UaFnn;SH~igteEjdjspfxS-T(jq literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_8.png b/resources/g2/track/boat_hire/medium_turn_left_2_8.png new file mode 100644 index 0000000000000000000000000000000000000000..7a4a0364e2d1514e853d3eb033e8745d6e37c853 GIT binary patch literal 966 zcmXAoPl)4m6vyBEO=pI&hpH7L#I=VA*)^~ca)=UVGedWXOqR(=(BMW0Zowjv$w&?b z1Jys`|9RyIxnZSnpsHu(Jv1KfCaer>fTmr=jP_-=jRs|78Vy5mzI{6 zmzOaN%VaVuD=Yazp};V-An>v*>bh#0MzvaPG+Lcb(CZE2IGIiv8h8#QaZOco!9bmdpa`)9NCsr& zk;5QQLO~hzYbf^MVel-70w@wz*7LSS)!ky-)4Sbj6#0`$gi;n>0;aOYyLrhYw16~X z&P`N*YISFg{&_G$!-UKMOJGGhtMWuyW-2AowaZ@J?)vqp=TG7unvPgeL;;`}5K6PC zrMO4JtCi+>%r+a3WcK@ls> ze1G%h!IK}o^x`*Pt{(opd#2oFo^QVW#>vI~;d^J-?{nL;$A7>2^<_&{H}`H`xN*9^ z|GoFe$<|kY-pTxy{CaZXDF2W3*Wb>~7q0yG4tn>wjrTwJ>1ZkVH~i%GGY3DWeAwRF L+5GOxTOa-pgV3UU literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_2_9.png b/resources/g2/track/boat_hire/medium_turn_left_2_9.png new file mode 100644 index 0000000000000000000000000000000000000000..d454774feb0e9ddb4c8a0e3dc9f956ff53207100 GIT binary patch literal 975 zcmX9-VTjvw6n}TUyWH)VnG_5x9|HD6lps+e1dY3R=8k%cUXJCkLN}vCSD`|{Y<5s3 zYCi-m8l-5!ekc;KLS%&<60kxB5i9E;$O#pK7U^8jsbTa(!4v;x41VuDeqY}22fz2; z+uJQ3KX&pM036?Wdh1L!AI$2+YA);Fj6VMiAP0NT>~CjuVPRo$aWR+6EiElAFE6jG ztY8?ny1Kfywnh{R1&(7SNmNx?*UP49G#ZU|yW8*kVR#tF>1@WaAPS(!>*aF3TBT}r z)@};zj?(LEgTNd`&B@f27_20$8!};)C`YHeCU?+~f_7=tH{zk4#O^!|izH|a)I@Mp ztY=_B6Cd~Tvk{3B7R@wtR9gOc1#XemQL?bFSC#IV^Av#c)yv~!gBGW7hJzW}@YShrjZFA~1(x5$$ zJTwjQJWn$vj<1MPO;ww^-l^64&1TT;M!r8eJWSIR0cil;#<(6X4M=swR3?%=ExSo= zkUEF6esVOPqjd(yd4ecX1(jiSK`>>-*0N>wezP^~_2V#_O+?US%v5npqns+!sf(Vi z4my>gXN`kSG7e|6TSx>b0hj;|fCn%Hm|}o3C=#lh$a7IVR%kFdXo=t#AyxpXfD8gP zIpiwHucDESVi)cN&x0&MNx`Z*Vbz$HQ|!6=V9g%FIC@!V>v=IwV zTJ~nO!Mr^>@+WAV(s|%1tjOYJk*ca(y&^kS)oob=uN8$}5{GCu;bj^5fMP%>%fim& z?t*O8JJTuOY2Sr88cF4{TCM8!y1}sxo^6YqCvkzy9x6;yDj3=$0~gNhs_^8^pU!9Gt(~pS{Rck!;0O7hZy#RG?fq^2d|&+M%BSZaFZ`ymSAK78 z{`eYog5Ce_-j7c`L7qK*X#=~ksXhD3(&k@hFORR?|EPJDy7BrKZ?D)Fe|d>I`N)R; z+->6h1}3BIb~FGrM(&PS(w04-q4q9V=GIVuUJ1 zvYJEDAlapd94hn>v8(|LJ3^46Wr;FE#T>d)F|s`r>|xX@IaGGgpIH{Z_a5KneII=9 zeRyuSym9=*aRAuZd2aiBHXq7rGq;@e{72RQ0G8q0^B2x!bZKen*s){F%gZY(E32!k zYiny5hUId(_4ReUR4TD7BZ`8eNV=|?reWK*=XH9$Fp5S=GEY;M0f7fu%ByOzRwL^T zrs?orTkiI>{=gi@&SdI~G*;pBhJ;%c($%Ss$?n_Yz^e>Zb%Lmo!*s=~g9W)paY_TNZ zj7;(xRW|5~#p*6^wnaOTT7AVIYGG0(If5ydc!id9PBlcMDK|S>Cp5y?ijr15>rNJf zf&fJY@G6iEpj?dW;N>2r4g@2vI1|&KyAj%#>7vdN^)l^L_^vMYO(nMVv1d*Ldp__M zae$^#p~z8mh2^S(SXUHB*W2}a&v6EwP8^1l(P%!OBOnZ*JdEuY#6F=6>FPvmPE~(a z@6X*)+M6AX7bs5`3LK7?$&x}dI?tPu+|;sVjh@pw==PE*PA39r5@sp|OC#MH-EIg$ zQ|Y&>2Z1#nv}fZeO%IU(PysLjTz~-J0APv%${>rVVWPlC$ylbqV4)>IScXIfqyRE- zQCLI6CQ5v`8$1V+2o)Kt>9|#=TW-1Q>;1kR$H8nCqfCpa0^7(7E-w3|7E(sS zyK^;2>-~i{JPIdhJg17lkyx22r~+A2*hW=yt(xDm`avs>f>{!wbizpz3IQd6P?kkA zle-7PZnURUuI=4}IUI_rs?=(FqhYX&%`u+91|mC2zjWPkYb z`un$v7jGGFy{W&TKKbwKPo-PzjRy{&*Z`SH@_+n?Td=Zf&d?W^49Uw?cy Q^8h<%cDKJc{ptt*1Fa0AGynhq literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_3_10.png b/resources/g2/track/boat_hire/medium_turn_left_3_10.png new file mode 100644 index 0000000000000000000000000000000000000000..d39ab57c0a0d1e0e9a0c6c9dff78e7a65d383dbe GIT binary patch literal 984 zcmX9-VTjvw6n}TUyWH(K1C~)-#0V851c?$MAA-a)chn=}axBMHtQcKjg%yktp-7N` zomS}}%<3u@j1Z(sWL1w5G{by|dPs#hPN*2A9}0^ww2TP-a3B6=41VuDeqY}22fz2; z+uN;doH}y~05*1>+d7xe2lIMhwUGDI4}E_cpa6Sk_qTJpu&}VWxL7C@mX?;5mzP&o zRxk`(U0q#UTPu~zWtL?`QBV{~(`tsHw_2@U&lwK=C^}A(S(dR32t3HrdaYJ$G{~mO zv^#vSFAs)l5E`SnGnu*~jaB(|T`E~s($*-)U=Lej*sG3)dUDiG6L&s~Dg>xBGzG8~ zY@lOd2OkfL*@!?XgEAGJ*a$^s02x5VFdfG&g0Lyd<@rNdKC0KpmUY{4P#6+yu`HAr zndDWfqSIB2)okAAi!D#;28ugU{iIHE1XC&V3N2||O&9gH+;&vQ*ZtUvl5U(1Ci4&% zpr}Bp4x|Z`jd4z?GNfvupvTqD#BgVJgbro8sBuKILU*eCKobK)iCfyZXH31;EbPr= z4^1Py$We5aJVe9}G140?m^@-S?*4(ri z%(+jVW)dE7$#AiO$1OS%usMkCG7^?HwCY) z1pWGvXN|*tI*zjJHWC1;00w{!-~k)~Off(?WD%JL@?4aRWeRi_x&rtWNMt|?Aiab- zEOKS!H_)h!5*O|U&w(UDRmK`x$!gMFyE1UKAZW$0m!>hwwTL>f=DJ{)WS3NZN>6xu zR`arEFz<~{{0SP*s3LGAR$=g(KsFTCtV_1laJyFEb>qlOlL%!KPLhxhC;^1>EZVu; zJrFIkKb>;@-aQzjkyxuKjfQ5LI?J>;rYEqT$c7SgEYoSVj8qa?6za3c7f>wa$Im^! ze&_BFynb$1foE?0ejz9C>}+lBKX&EK_c!nR;fd8kcIhIAEbX&p<>B_mKi3}}UtzCy zpFIB*_3NhoX>uO0kn-nf44+p}L?(0+Qv{O}F$XLkIT{qgzKk$(Hmp{Dqy YGjIPvtv!7?cLY1zyIa?uefh2b0nrYpMgRZ+ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_3_2.png b/resources/g2/track/boat_hire/medium_turn_left_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..f69912c6fbc14d8cf3dbb996d72ce55885896a53 GIT binary patch literal 978 zcmX9-Ux?du9RJ?m^maEQ77ZG;lOh=e2_tC0AerWldgQ#!<)Ca4A_UflqCw(Wp+dG* zsG5iDEZT=YREeWvrbX`|xIRRP*u&n4a)WwC?L)yn3@ln$VK@1iG5CDHUp_D2&j&u= z?+0f#bH|T8dJF)LufMcFv+#*SbqFkQemE~@s(6_8x%_a&0l1*m? zf{`=4M&%4TZ?U?=n+>tzNwtpR_B1~(WH^$^WqE~`bWSxyqbgUMTGKcD$O_|HG-?f| z0WLsV0ipnzGEff2HHloCQUk$=^7g=V$4-cLWjd{MWGP46dA_BK9aD)adcSTCy~;SK zPa_WvLp;q=@%Th|+CuIOSRJbF zsMHxd2b1>bs6R!^G>&rwk;`Nin$daQl;o^Kj6TkuR0J;D}3{V1DL}e3sE{gjy1qKT>0sI`qG9U$z zK_Ht&u8jO5>Qzzf!oA=*kVMGKSWzde5?yn0Em!Y!DpBN(MiEN1$O5qCWx*k2H>3HK z5%bPi^(LjxwB9@N2dF=$(!gb~9D}Purl_#xg5+35w`O&`S`>PtI7E{HCrQW$6azv@ z7S%-VKFCVBF&uJ@`hA$ao~Wuyv8b2J2Fp}9rY^9a$OaN~Ak(9K7HJt|QK-QpUqF$R z96$H;@;~=};H|Tp3Y`Ay*9!@`xW4+r*2$giE2kd*{zOXr4sEZkY&`Y&b2qR2g6_`m zZ{7YR+W&Cl^9yf&wDaRTuiSn8`8|C8v#(PB{{F0U?aTMP2Txqzwrh9DzZv?0(^r4H zuKwJ5`~1z1zvv(S_wt>04=>$*1V8oZjdS5)%su(WwVm?DGk;#by7Nu<;>x+{AHhnv b|HMOk?_YZLr=xEZFR;G0x%%~suU-Bhsi~?} literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_3_3.png b/resources/g2/track/boat_hire/medium_turn_left_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..e36271cd2ce40e78fb12260880e935d16d230774 GIT binary patch literal 923 zcmX9-L5SmI6n-OhzqY;W@f^9SfoRLXh zr&=bhI;`RG)==z)(qO6tGd;@MBu6l4w1(-4^Yt{MZnumXh|2g>S9G-a7U-X^2)y zy}?nm%5rT%>?(?D7{hLN;=1u@lt$5VK3}ib2nZ7>A7jULaY`sNy1f+pD=o;o)3rA* zCi%r;gKBiW&f$2AY$`Nk@Vq6-eZ3U3C+^^MJjs%@SPGy^n5EPmo%A~N&=$hJG99*0 zLuU~W^F>k=kC6bN0$2bZKnQROu)+Y9kVRx$C=5`xkSQ=(7zhxxAd>+pfJ_{@EDB^4 zbtpRs`&5>egEi-cfL8^efhh)YBC>pU;3ie*6HL6KXU))@@Qq0Nju zelk_&3q4M(RpxDXfkX&4INtJvJc z60g0Pcd8YE3I3usH&b}OozjT=OwdQ7De0jx-3fsgbCCHW9Mx#Ce#((--@H178Jv{^w-s* zxY_Jci*C0$9GA$hN;3w}Te33JYcYG_jhFL9o@Uin0A0o`we9GnKcJ_!5RTM%+Fypw zCYctSw5pyX0iXw90r&tRz!G4G0ji;h$hJ@zpnRiHV6re4Ad(9H@(10#;zEDMVwL$w#t2i9&0KCT3$9#Lk_`=u6E!+1Yg z-9%foDX9){BqlL!O&|vJx6;V&EVox@k&{8D)p?5E`Bv+qCAY9Y9|dwKrd2M-_r51&7UVN$9<9vIqp)D=KcQCah?SMN>iL^cli!25u8T$ z3`%hr-RI1S;6~yok;8=+7kz@o>0XzUDN$!tLohta3$!3M;@ruKQC?10yR^kaTZT>_ z2pdQrV}nj_Mye@qPh0}c~q7;s=V+%Fm{voJ5oq!F=-T>zfq&DmF&ig zeY`@;4cP{kznt^481ndgGV>kag<|^Y{8k55N5G@hj&3n;TCbe~-QW>5cju z_ub}8AB;Zy>Fks8*T291cYpJpAH$EI1lDx@?$bZH-_Cws;FTVn-@Z8g;l2Bx{SSd? BhM52W literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_3_6.png b/resources/g2/track/boat_hire/medium_turn_left_3_6.png new file mode 100644 index 0000000000000000000000000000000000000000..2a4d35f021aff05a62f154e2d61b7ee18bda4ab4 GIT binary patch literal 928 zcmX9-L5SmI82vh(nRK?h7N;(e4H%(Fgt$Zr7&M2dnIR5YCd+2oA~{3|SfpUUh!t`O zTCix*AU)&|v|!K*0ecuBhaMv4FhUOzd+1^g1q=2tXw)D*jPjdh;eFr7yS#UJ@B8TX zsdVkijVl0f?c~*?JLP?%oWokR-1akHTmV$z_N}|eC9PB{J3BkoYIS#acW-ZRe}5mt zuv)ElaBzUPS}m4kL{U&x*)TNAGW-3$=Z&Y+C`lGsmKO!ffWU(y*EOx#?UFs484P*P zS0+<^7F+XlxLOAyjkWo@DdSF?bPZ~3v1ffT_S*BQnVk^MsZBA&6a>O3d!q~ zWYTSiHC*2E#eOJ{W@<3kqpU-61S7S0m6i=oGevWt495C6GNaT!+1PSqiD5Q1Rfyu&1fJlN&0i*&laWrI6prELW z<^z-k@E~{&WD(j5)-`aaM~_@-5*V{tKTX5UCPk$e(E--33ofn%q#jXb#=E%|7QNZl zn_osNw9Kg{a3m%%4NV}sDr~d zRE3v*yZ=T>PEU?rzWelNUw!(*;rCBot^SAd55>2ye|%M}$d5+dH?LPFyZ1l;{g(gp zWB2YI`ac}+7f=2BdX+zWMTx=RSFtc@KU4_sJtS(VyReUHRuluJ-=pzr0o| O!^!dK(YLR>{=xrYLx~Rn literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_3_7.png b/resources/g2/track/boat_hire/medium_turn_left_3_7.png new file mode 100644 index 0000000000000000000000000000000000000000..34b5796dc9a14a5796290757f1e1244b46ec406b GIT binary patch literal 865 zcmX9-F^HsQ6n;CiyUyNlSPVpng~bpINU*T5urP^xn8jmV&Lb8U282v8g@u7BEQGTd zf`!G9NSI;@i-8kviY+WGgjh^5g~b$eU@;s6vA9Bl#RRta<8tu5_wn)IeZ}|Q?+^F# z%NJk20DzZwKi$6RxZhQ8@Z8_O|MS~t{qXwjt4>~AT=aUqe!qWtd3kkpb$xw}Vc1|W zxVgC@#^W)^v63Wenqpao`@CAAJSVx)SR`1L5=>gQ8QtTo zP;i!#pD2q=i+5&PO(>pZ<*}eKip3kYWY5+4%3P&(T6#sbDC_m{oZ}*lG$1BGxj=^) zzar!fZRDa|>cP>8o3KESDl@Wpawao@F03snbF|X84v}+8{3egiWr9uxKH_Oc=lF>z z%``2rtmSOB34(mJD%141-#1NzfV6>*Fm8=Y8L91<$x)i0jJTduh76AL z1R+ynjbSZ8a1?cJcFWvNu-L9QRZ+G_5ljVhG~6?(aLO!QF_~-Gaqw1j2U~{k#A(f$00cn720tFn3Rg_NAZjP!Lo`dH> zkw90msYQ4*W)aHk*vc}$ER(t}QRhWYfOCgpNT@MornFrNVPhoiEIUWLr}T&p4Lt&$ z!ekaVL~5#W?nDW_X}s{VWKkALT@|Q3@`{2|Koua=WijvUzJT=I<>|yPqc3oFJIOG# z>C|#vn`3>RjYKYyxLjfPDpTuYWKzhZ(UL={h)Sh9e*U}Rzt2DL+nak0zW?Xrubsf} mZhv??_{;k5Z@4t`KHU7#`}FY5S3h?nxO;Vf`{Bo5-u(}T(rQrv literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_3_8.png b/resources/g2/track/boat_hire/medium_turn_left_3_8.png new file mode 100644 index 0000000000000000000000000000000000000000..b93943525529b539a1a21a3cada552191c9bef2a GIT binary patch literal 940 zcmXAoPl)4m6vyBEO=s&8u!k<2LxdiJ1PMzHIYfxNnb|l*Cd*``V$iGv>_QiEh}uIA zfeliI93m9Wp+aSIs1Vr-J!GLsWP{A1hoEz)m_voa2At8lbYYZ1er8$tzW4ZE-skXr z@A%GvboI*hD*$kH|Lxtwa=ud5waP}>|2;o{4`2iCymPcy+O@T{_4W0Qjg8IC&8@Ai z?d@$0!zz`^&dyG~(P*$NBZ`8m%7&p?mg%}~5DZ46I89IUe7Rb&3U}jBkZiP!fMPr4o8644(Xs^i+4RK<||xggT{LbFsV7!lE-- z`lqW=aXGs{RT{^+dR-zLD$N)?Z^=qmFPGUPuXi#W3!uxGrQ(iG`fa*z3sF~{ z^jjy9GfVo#EM2Y6kO0sGumF632;c-@fdML|h{(236ry~lP++pq6Cjo#R{*Ji%sTQ| z6e=igqiGlAA-o8l16hQog0+ph)1iC5Gz^W&#Lcp(C^A&Ch!(JRRq*RdNa`_V=Dfeu zqE%;d5lk=RIhrl08gL{gF}Nm>ZI!iKvhTFRo->JhSsE32idJ(@mQf5S2ZYKjx+U(V z2-of}7F<7gDQh|vHBD`|4cj(Z#^snmU?Y)DWad<%i)I7qByuR!XHhJmOfHX~d!zd7 z#SeUPc%Z^tPk;TmH1F^4-aNYY<)>fVcy;SW<(7rcZr?oo@BaAvpJLy^t{Q(G58(Kp+l{a0 duRr<|JHPkt6Y;~ZKPoA(zjv_v=+@l_{{xkHlv@A* literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_3_9.png b/resources/g2/track/boat_hire/medium_turn_left_3_9.png new file mode 100644 index 0000000000000000000000000000000000000000..585aaa79f38efb1d1372e01de59270558aba0161 GIT binary patch literal 971 zcmX9-VTjvw6n}TUYkKQuVO4_$j8GxYID!TV7$M$rM?E5!V>v8a!3?77upa_uP-c9U zd%MLG#~wZg04H`{*gBg`BB=*6sidc`;okzJVDH8K?S!tZtgNoCrc$Z3wYBy2^>jLo zVOS=U+1S{?3xxv9GNLFbilk{}!_XUzMyJyo3|!xzMA0ISSq20iWGP!N=c`q+R%eaV_^dABW{I>ks%NkV4bkhA#sfVXHRqANT=+!-R2pgmSPItH zF|U;i`}ufGpgDtL6&+a!`2_$OK*caUmoo{%q9~i^4`g{%sf4C^*y|zBBiMXFz!{n3 zRjR1dC6m=G-sp-AM`{lhd#t)qh2#jPSl|^}(zvoN>P@-XQ+uxN2BsgigL!|t^l}2^ z6~HS%)`7Axu7?)~RM`{spwyZg_QLYfflTK$j;IysR*COx;?Pinh8A{=nbTN!on_#l znV-vZ6kTGuiXhe$rKM@zT5Zs3dA(lXy3@&Iu~;A=bf7vI+s}zZLK)MQso0#A?Rjmu zuqN?feiSZImd@ok950dug=RFKHzc{KCd=xBR(sSRM1BxY1yCi-P;#b9T2;DR7o4Ut z>{dpO8G7A$=*RIP5&%j727m?N0E_@;7@!2Qi0TG%Y!rnu1v(3D0o)=)G9U$zj-wWf zY#F&#G;X5EhP%OYAc;_tv8slfHM(sT`?fY5HiE#J&jXZb5fxzTS;4|(n^av&k9ccQ zcH-J_*%=?XQxqlkH2dTz|Iu-nH(H;}giAU%OBsN{_B5p>FwG5pM|%+4);#p zJoS=9YES$TOt1Xq+`94G{#P$Y4}`D%^!LBt|M2@qKc6{&=l0Xix#wQh-*{~AzV8kb P6R@+ryY=~*3s?UKWT~T> literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_4_1.png b/resources/g2/track/boat_hire/medium_turn_left_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..18d5a4dcb94f3600203b93ee3a3e25c3dea21b63 GIT binary patch literal 986 zcmX9-QHa}g82|2icj@gm%d8k!V0q|6lqhvXi4Y~5xud&9FUK-1EJ#iRt57sZCPj({ z?4&1E!`6qK^r3SB3kKGQd&ow?u$AqQf?*z`O3*%(E#N%_jc|h#{$>n*-}mu*`F=n6 zecxB>Yo#NHjvWGkBde#E&!+SFw2o#oX|LIz%mHLz{mpYLDV>>_nVp@@WHNJebMy1_ z3kwSvhGnza#l=OuP$)1=Q4n}p7Bx*V48754*mk$y_lCpWFpQIgDFV-dBrYjRzFH+~ z^l_pmrX{qIHMypT(LcnossH=6_O>2r2;3@qQ)w^pf{yvSM7Sb7nsAa9Ynp! zzMtbEF9TiyvJRAmv0c2>rxc&pgK}$PII%TE+Y+7ESfW;pQgoSNE4)yX<(8&(YPEi=<#)S*=S_BZ<2Xh@=s?*R)5{41LLSkTiO`%X zPE;Gj)^5^|4#xXviO%I%950atnJ#J^XNXc$O_$aCt@ci@9}a_L!hD&^m3odg7&L;wjiLahT0{ky`Vw#9l0&K< zrH7mqD{fL7?AxOQZ-T}#l?Rr@O2wSQlU13iS47LKI&E{{wu7M?g+r7~SW!eCpb!vB zvuLJrPe3&4o#~YA*iT@LMuMWq)v8vn>rAo17Hyt!1;!VPyAmCh3rHoANudsdJRSvN zdi?B*OMgH9fs1F?WH|Zow+kuRTwOkO?zzj~TsigBrI)fRH*dXqJ~mIEKXdEO#@^Q5 z`A7K0`wRUvF3bq`{&7*5A=J#KCK*n=l#j{4fCx(ufBWj jCUs)_zbh}l_h{zRuR9N(x$qO4dV?drfy2Jn8P5E#yW=_f~0lC zp$3}6SO$qYhaBcGYLGz#9dwZ(L2?Ln4@1dektu{S;($Ra4BNr3u$14F!uQ_eyS(p% z@4efXw}sW?>&F3Lb?f5Bm3*Gb>%>wa?+y3HJU{_1U)tHs>D=7hv17*yg~I&&{KCS* z;^HEPVM|L(%gf8KjRhQ35*i#h zGS)Y+s9hZOOS2)4G78O9bmSluR{CJ+wB^vc43s70KSDDAQ7O`RC+N@Pi6@P@7x@sEhh%-swTXDMu%vHEEbt^S*TQHlG0e#6s4A$FKZ6koxT1bjg#4!169OKxoD{sM<=^Y z&Tq+Kx4!3Fqo|vW;@RvW;s6u?6TkuR0rmhU7@!;ykD4a(J(P|l0t^~D90UTS5+E6n zQATYVc@heAG;E>NgQvkWAo8F{n68zr2HA0hzNdwuog{viB`DXz>p(YGIHxRm6*VA? zly#;xf7S>O-QiI%Mx!ZF0;YlqRI$cYbeV3}MaR;;jurZyB=)m3Mzb*^iYNe-0z!Ef ztz7OIaJ$)^Oqj0w4CZji*J`q^Yt5!XQ#M1n9PRUTBvShlnJHDIR**%YE{y^XC1QU3 z%&RL0Pk-S0m2DZ${dNC?oZQ^nIKT7qm!E%ie(mn5CH@z5gFOAurzfoN%+=pM{Ki;& zZu9Z_y(iT#K3QDfVixp2r~mx`4{jgaT72@#>*umxPhP)y>a$0$y>RyXZ~y)K+R39! z6#o0hg?G;0dsF#X|ERxqQAk&>eZBhjyMMg(;Ob9rJhl(E1^vet)BE4;sxLh%?1*>Z U^z-lkoEw3y&Fzgl7v8(|KN5nTJ^%m! literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_4_2.png b/resources/g2/track/boat_hire/medium_turn_left_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..de7a1148ffeff416932f4f12337b4a202d3c1a5f GIT binary patch literal 976 zcmX9-Pl)4m6n^tJ^T(xXk%)nbSZAXIi4Zktz_^nc>JWFbvl-~2U|i#FmC6LkV#UB_ zu!rJAiEF{i_E0pVMFMtrN68^d#2yM34DJXObLgRB4s$5l!yE?rnPuU7@9|yU_rdqx zhZnZ;XObANpT^0Wbp>UfJ15>D1KJ^z`)1%*^cU?A+Yk z{QNwIVG9cji;IhRE|+6jMid1_kuw81u?$E7 zq~pkDkt-v=jQTYcyKpyn4kQr@GFH}bt3ubEeB0H6pc+M9l0+!gB1*uT%YuW;E~)yI z9`nw)=uIlYNuz)257A&uWq~8HJd-I3WLaU&lH^!rw{8VqJ?eT%+(nZiCrQW$6azwO z7PVCF9*C;h9F4eU;~tEDUn~}ta#=G?on@*V(-2rsWJ8HLlIf(7Ln?_Z3N=~e3n-G( z-O*a*h4#yt=RuEyKnxry>cUYcQyI^ z%4PF;a@#L|_rR;aZd|>2zW2+|m$vsFzy02`&lqo9-?d*{yR(1GxWt^j`S!K%_s`;T Wa8NqGdwDN)0-GCK>))=u_QC(J@SuhO literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_4_3.png b/resources/g2/track/boat_hire/medium_turn_left_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..df2d3794d22f4e6435b812b28b2e1d92d37020ce GIT binary patch literal 959 zcmXAoL5SmY6vp37JCm6yYY#=@8kne+$sw)*bI2iwxMs#WMkm8$v4;v-Hn3eNOT?`7 z5SFl(rD(w%y3#`q1p^igT5y!e280#IRQ#4fW)xJx|<|G^!Aw($EyZ zRqm*C&>B-0!0>B-m0} zz!{n3RjQ)XRg2YZ-f+a0Cv^kG9jSg&Cpm(tlzD}gG_IzLdRuPy)xNL$u@xoVcs`h( zghc^L3gC4hO`vRy>*JLnRSN|@u6Cw|o7xdNlLoqIfYCK$S2J0A-RzWE#kGQ8JM!&{^mT;8!4#0V#lV z9CcXa%E)h^Q5z*LJPw`%NrbA5H8k96(p|eUaJ3+4#j!V^$0%bFbzsecVB@k&sy?MB zyq(s(MKd_*jZXb3nxs?-I1;Nc#hO4i6xOUuw$*UER^WBx$eSk-T1+`fLO!4b5X!P> zXSgRKTBb9baZc}vjL}G})s#j3_Jq2F<{r=_5T;1J1f8m)=Z`$Xd`r)~?{J*IA)6;(++`NDA_VK$fUf#O$ z=FT|(M}Gg?UvEAC{-1ZxzVq_+iw|x;c>T-we%?I(eD8L0Cus%D}L@v$y@#YZpKK EAN>EGApigX literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_4_4.png b/resources/g2/track/boat_hire/medium_turn_left_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..87a6aff354699e813b0ff68c48f500ae72ce3985 GIT binary patch literal 894 zcmX9-F^HsQ6n?w2v(DbI7#PUFSs0jrg$X7Yu&^+Rdzi(r9_N9Dg*k*wF@=SJDGUfP zVK^)-h9F^zArUf#kO^#IA)JN96jK-uX!JQ-+Rv= z-$<7a9zFno%j?gso-`A0>b%oxI*onwD?ke#fBy7QLr+dlPESu;t=8GuS-agnKR?GX ztkdaSTwL@Ag8|Djq9~}UY?``lTb}2I;e5GF@_bX4hq`7N5O`4JuCDh+BXaC86Q2)f z%3^7xnY}Lj-98d&Oyj$j+;=rHFsZrC-g;sdYU`y{t|nC(-5qj?0E33H0D+1vEG+Z! z?V?w&2~;ttHqbFZC?5bQ00xFxIPMZeKv5CT-zv&#INZAK%lRB-8Nv1jLZ4Ac-k>Cl z)?C&MczY&#u{=%HXl*3rkmLwP8t^JDo1AWm)6*1c9c#orK zjpc@dI965PG-u=S()Y9ZyhxJWW^*_k5D*qnA;vCnF(uSBJ=}?ty&hHL^bl<7Wp&)% zp)QT%T)!`o1C?e>p0{OXVl>N~r9WLQmStYlI{^$CvsK(R$Y4az93h^l>1?=)-EB6j zws~E@L;`>YU;_jIF~AC7j{$0+h{&-~9HDZnP++kz6(EtIQ~;@ftUmHt6e%bfq4fln z5xfqb16c%3!A54^9n;f5T0~}=dPNaeRe>5UVhF6$6@tDJkw!vUB_AC0xE`l>;rf{D z(Dp#}fFm)9!F7QgsjM@U19ucn-87ySd0dq_s&||$qXbY12sK$u8o4(hJZHAwbF=Ub z?DbmIb#*i{9mirBk7GiCjYT$-nTh9yYU%o2ylWSQ&|uwaCMJybSAWGmzl zFhbEB0`?HJU=KMI4A{dQBJ>a>haP&!pMeHHcwAaJKb)VWf@TvR8=;No@JS?>juGeK9AFMo#$m$u?z@2C~~XUYYztG&}K#+ zA54_lTwf&CD)Y9xP^2-9Z<%t((MaE*rWSkUib8a2G#_WhY`afz0op2b z`as%1`4~6tNOP)}2xg{vTPrO66kREF+u(?yM0*-PGsK0ZX0EXbtX<@mNwCi%v`g_e zN6{L~^#yULs-9s?hQqn%CDUmZ$J_O~EK3B02~>cwGhAE{>Wc1f#nG-87Q;p9ud8`+ zz1gD{jpJOWBavN|W(=OUWM!n+%j~%~Ue4xunpIl?bQ!Z$+|fyYKu>HT8mWs(e;GNO zWKwL>s(OM101dzb@Bt!#CBO~?R6`MwZJ{Vc`9`6@WMM2oEJ3aSQURGATAi*yn>6q>Lo7EmVF$Irdm`se8ne0q7I z!drj-@=-0=^Ru@fG{1TH)!ke0dh?5a(e~jRkMDl`@{7-1?!Nu(=fC0h^(%kf{^|Wk lFMa*^1L5~-^2eQDzxz@8?X^d@zOTpO{NBac5AS^V`TzFteNO-Y literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_4_6.png b/resources/g2/track/boat_hire/medium_turn_left_4_6.png new file mode 100644 index 0000000000000000000000000000000000000000..ae1b3c350e6ec4b6d9eb60497d283ece5c3d6a1b GIT binary patch literal 972 zcmX9-Ux?du9RJ?m^maRo)=@BGkUm5VX9i(L%^;h(QIF_lTn;;k5HYYm^dU&Z;;IIW zSkFF0>7YmlMI#m$xq^oT%pjA19rPiLDiwnCp|CuR(Mg5}p71kc@cDkfd|tkv4}8Ag z{fj&0jT29u0Dz6{*S2=Ec`mD5ZYk>@-&nf`uml%h-@A~}g@uL1#l@wirRC-2m6es% z)m03`a=F~v+FG$xDlrT#2)rzdnx+_rZdq2R(;E!DFdWD6JWUxIcn&0ST~P|P8c}c1 z%@)_`O8tTA2gWFBO=pfkVHIv&7mH?vur;!0Fo%{9bSk5P9uJ#I>>SO*G7c&QbslUP z>+4w1%1`=*bcCaXMyZO9ZG^%SfCQjon4Zs@IBt`q!*Pd_G^|!9rg^v5LqUKug%V$+ zC4y7QvQAY@MzcAiD_E}B_GM?JdU2Itak^aMWJ=UnMHlp@)av@y0uZ8<$dRQ@I>yYk=0WEu za?vcz7g&<2Fl?0<>ayI@v~ImVXtjb~FY>(Ucs!ra5#TzI9gOMc1s|73RCOveXNr^5 z{kc6(2g&i|2(453JX<{8FN~b)iB4)^WQzh&g)ot)@ zQ}(;np=(ZpZZZke^e*B7DgXw64d4O{0cIGW43dBv267z~Pb3m_2HHG$Wr!s}G9bN( zS`2a|hKt;l8TG6aiZM)oeG~c(P$W4+6Wmso5UeXr>rO<4^RvUWmz;c zxktdQMt3%2yPZccMk7H{ZnCuq9z%dg{~UOKq^+s`-lzWwWo zgPL`}|KJC|ubh15&F?Q=-AJBx&}ZMhwR&#(P+b#ncc(Ur5-@b}>0`G4UQ`(X3&CpYeA PE@1n@&ep-JZ-4SXYNVrh literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_4_7.png b/resources/g2/track/boat_hire/medium_turn_left_4_7.png new file mode 100644 index 0000000000000000000000000000000000000000..dda475790a63a2c464959f91bd5f4a5b8de72ae9 GIT binary patch literal 962 zcmXAoL5SmY6vp37XC|E)#;o>`b)!@*7~HT#$RSFQ?3h{N5Sgr#)gFpO4QyGfMvPLh zNYJ>HrH8N-?V*PvQ47Yk$OsVwo0W)jC~R1Is1T*Ng{ioQphbEZ^lz4h@4d%&dB4N= z-j(xv($>bQ4FK5MeQswzn`g4x$mg<7yh%L{kc0EjUpSZ9rKP3i<>g#1x3aRby1Kfy zwuWI?KA&G-UnfeX63a58D5$Ee>lM>9Y}@X1dV_% znk~N5Rr&)h2+d*KnoM1h#>)JrArn@)=;&0>WDjgH?39NCBROo&5_geC5(yd&bpad| z>l;|u!pHr>d`O}hgXS7Kb`Xk601AMHVFr#{B@3 zho%u;;3&Gxa#caBt7=QvyY>2@)e3vP*!L%+QJSU*NCT)2#`bYBAk`sVoruk8#hulI z)EUhOv*YmsZPGZ-5rkAMsWhYWyeTV9EnC(YwAzRLK@!FDi2$06nJR8+MW;r08-mwV zgKqWEv&La}Hjd`=J4gU11DF5~fCq30FvS36Qbg1+k>{dhtWaRE&=$a#AW;CRfD8h) zSmY|muc2WRB`(|zo&#BgvVzrg!m874N9wzJ5ZH0-&1NymSY#F0#-`v9id)ot%1C%8 zt$6c#u;>hr{RtYUQ~|gmCNX$LDArWAQI#F5=C-ZCYsZl{OCmI%aI%biKnWm}Wzo!V z_e9!_?sUp^JNIM`hhn9o)@pjAVX%zNF&%;RL^hO}kwVYPC8QORMWHT>d;!IBcKqC# z&A;ycz`Of0aPpJO@%95Z9?9p<{)b*Zar@ejU%mI|Q%66&y7kyQ zyARrrzV*^We++(o0sr#)Ge`GdJ$Qfk`qzW~Q=dO^<>}~y(a$fQynN}ki?{yW{hioO zzy0FLPcPNKyY}JLTax?3!@r%T?mK<_8FSEgn=5 ztp@i{si206;=xc2E{N8{4H`6P(BQ#?22PEJlvPfwf8 zCWc|HR_pBStlR7LSe6k*K~W^b&@9VzT{j43i$$De>!PUkdzJx#2U%)sT4y*UM>aF| z_+To}7kZLftK8e}LXpN)zHLffM%K8N8G>ioB6>M%| zsfTaoo&AbHC4=@ly7dvtdH^zjj$tN_I|SiVRLJu;vb-D&HjeXhHbZGju$`XJWn_}q zslG|84r}pP?I>?id^~>eHUe&kZrLl-xBofwha=Dh&>KgmxL; z;V4>Vxq%>#6vZ=)>1ed@ymU6p<9NGXS5<|8Fo6m%c8-e)p{(e^RvhoNupA|ozuqs( z+sy&BX&mRe-9Fhw0V#mYF7j9u$|xS9 z)fg2ayb7KJNd#5KhDO&J(G$Nv4~-;o^E@ic9MxXL09d;%_+2?9^_VgX-mkQ1KS~b4 z>Neh@O+|HpBe6b%YXUh`SbHG(&M=%fNi@l`s4OzH-*S?KVn78TRA(`+?Oua$?dfjE zO@r64Rx44{l;O~@ZIfkOjtK-d64_K@)-qkHJ*1P!q0p2?v4C=^K7Q_<_TR65;FG6U z3cUZvFE48G?&Zb#v(|SXesz8i-fCt4pwao;ocqm}$$KAvd;QtA@>7JW4U literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/medium_turn_left_4_9.png b/resources/g2/track/boat_hire/medium_turn_left_4_9.png new file mode 100644 index 0000000000000000000000000000000000000000..b1f88f53388afc18ed98e9554118cd688919df6d GIT binary patch literal 977 zcmX9-L5SmI6n-=9OlEf2DMOKhIYj9pvm2M7!ObDCaW}JchR9@?tW@Yob_v=;)hJob zAxOX+ik2a+MS3Vw*q~*M*o9GY2ofQOL3@ZWLS=L4p|U+JY|tF$Fz9cVh3~z`cX{6j z-+Q0!?ba?{c>V$aT-@2-+Rx{uyf#(}c{h3=6#)vc_xi1yIbB#-SX^8z6bi*+acOC3 zd3hPbu$7gS)z#HXwOVBuS`c_y7FD&O>zZxbz20Cn@}uZ9NzyE1Xy7@J#I;7F+-ebq zNw+&(uP+TpN)YPfxHFx(0)^GNHBGEob;41}fzBM;LfEU1M_O{yo+s{E8r5)6C@^?% zWNfHmVW%`1ma{RA<}}I_bnYM&RRJUb1;eyb$-;4mBwda>mZXzrb7EPK2Llv_I8(0j z6W#DUmY(+^oo)4#I zVTp&b43#DjCXf!s4l1<~*$8rCXmZ-AI;zo_?)VZN51iBpC>ZGU7JUb10 zXR(K7QK`(5RGnd)ykN+3M^*cVG3s=}!65ei>FH^jrU-Bi$R5TFOG1FlW2!k7+Ovi` zH-gkT%|`R{$r)OsN+q^ZsS#C~qE(L5MX9ai%gj-ydomm)QJhVAP()0ZOO`@7Evj$w zURw_O%@fa>g#Gy>%Cg6Z2dD$+01ki$Z~`#H0OgPbWa`LsQ8JN8&=~0Q;MX9L0Lg%~ z3hFS(m5|>;<2FiMcp5wlq5yRXYpE5>pt??N=&C_r$FVn`$0*mro4}ZByi<`}Lh(s0 z;hePLWkzt;8=w1AG)c)aumo14OAVfA$&A?)9joPbt-$NXkvC5wlucPtL_VMd5X!S? z=W@@0+h%_@WBa{l(8pt;(U4m$)igDRwpqHzGoHYNB7G`R^LiC21hPofXOPdMSj>-~ zy|VWA(;v9IzbnIQkN$ioC)Uo^^;?_w4!^v<{>uw1#eb1O1s`~uSKr(Jnf1087497Y^53t>$q)_^%=+iV@z)XlOf3_6FX(as@CEU^rj zL%=zVI$&5w7-1|Ca+qSEBkUnakQ}0{FqIq@8A}dx7}^217-Yl+SNKgSeD6KJ%lkg~ z-urBKr+W6xQ)d9+?Dnf$d-){uI=@=T`^s0u4*&(&y?X6RP8Svy78e%_g~HO(((>~1 z%E}6cVXLdFYinynrBY#8Mid1_kuh;{=Fo@%$G|lF7mH~kWSt{1+C0#E! zEvDV!dwqE@RKv&|C7sFC6KSl*7Y&K9Yh_2HT$4R$iBYdM8XD2=K$Z_1jj?SXyDo|%k}XvP zf|1L-N>vTIX0w{Zn|-n6OWjcMMrx2Y${fj5E4)HW8do<&qb;{x)eVdwvE#Ix%m$N_ z2p6EF0MUT51(btvE>Rs)^++(1T4!QS}nJ#G@*{sr?8b8p)&{UF^Htv~Izm-M3 zlf*~U7%y=YU1Pb1AT|}HqiOwSbJ*!buA2nGX83j5TwNdK9qu@D^M5xJ_t`T;V?mE?hr-flFN&ML?LAe&$0M;rB4k3GGHK2@? zce1)aZ-ytm(P=P2x!;xmSwO^i(`5M>x*n8F-I~zt5uL%MmB}|ED8jaNcr(| z8^ymK{lG_iI|^(*`2BiLKHlECbZveA=KiJgKV4Y8{3E)l?Y{B)-M@c*=kw=Br<=F$ zefYxKb^e!a@%tB--o2r(Z~w9BJY(Md^6lciuOHrca%1D0_5J(!E4QEh*8A^+!29Cq zkpC{5B-X8iz2C@}-HNg)1m_BOj-Pw@XZOu>Kf6!-Tf6wu`aic`n_w5;|5Sf3yLusa P0ozx0w(eYh>y!ThHL{+d literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_left_1_2.png b/resources/g2/track/boat_hire/s_bend_left_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..804273372c021a203a1cbc8d65ed90f177821751 GIT binary patch literal 959 zcmXAoPl)4m6vyBE&CHgihq6{CxH%LygJB6v4mkwOYG#N-bW%18MWRFvY!4lY5Vb-N z5yRSDi^Qd9g&qnM-MWO`f&-gFgdjnCC>W%NDnW`=Hpn7Diq2sUKeH@+-+O#7?{oOR zce{EhorWVQVe#pIy9A1z3aXE7$jPyRx#fy1Kfywzj^$zOk{f zxw(m9*w)t8_V#wUQmHTuEeO1#NV=|?reWK5uQwQt{3x0xNw!=vH1HhAQbAQqjRw(d z(d`b`>&wHD7KG*`?#vgiKw&kmU`S=FMmRb-Fqsou2z#~3$VkTRG;vR}NW?*-pvi-y zU_%27JH^?sw4C55rO{GDXAVM91waPSFw7_xEgW}9(&e}lSsvHxGs}8B7@#o3nNo!> z(=x$nq-anzi_sm<>KE>zNDB&cfbl z?4d-}bP)aitSLG1hU=`_nS1h@fY4`YT!A;6UhRi6v(h3clw zAakb6QF=BzMFpx@WXolds3;VzbDSy3Z7pBc8g;tk;V6mX<(vmi!c3)TX@t|D`YqmT zD?z_L_N-ahPiN6``55s4H2@R90q_9E01FIIE?Gb=6L~I5W-|`5fT}Y0>~(% z4uf17`3*E_qr`$Io6a z{PW}o-n(|Fz|}{;-pI{62YWAG-@WsG%sm5FwpOoZ)*I;FmtS4J`N73cZhgLMAN={p zx4)%T@r%X%|DJzz>9zHAxAEzZzYEplkM_sMJB1JLYDa3--PwC^ym?et?|k#@TW{YE z)L(`-kCcDK@9zHe(D?q|(O=QuKMa3<^@WG8-+K4b#@F|AFdXb3?mc+v&5!>FK#7|y literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_left_1_3.png b/resources/g2/track/boat_hire/s_bend_left_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..f785b56cf1d190c10c2c0c588e3db577280e73e8 GIT binary patch literal 879 zcmX9-F^HsQ6n?w2yYAj_kuZhfXVF zh9JRWxU-n!rm&bok}0;ZurOdT#S{{zn1ID38Hj`{!>@yTVc%l~~EsQ^8A`u+1K9X&ZYIXyk?^?GM#XXoeV7Z(>8 zhFxA>UR_-g!{LzQSV@*Of zxw>4LS?+AgV1I}u2GfPUtq`70g%-VVxI16UBYm^7tM#<5;$u_DB$y0LLeKgo+_Rx4DU7HjaBF8Paqt2zRQw9*uUM_inL3c}{YJp-8YQC785q zGrGrFq2SCVKT&3x7H`b78c{sS%0oe86pJ@($)2jyg}F%WwDgKz1Xh4jB za)AypenH49+Q>z_)PubfH(`P9RAylDJS@X$c6$JTWQKspByKR~V0cisrVcZgzGE&igXh z^%)%J2|}iZ8pB$G;3(?U?1s6kV76Yas-kT7BA5#1Xt-xm;h34bVlvgT`DmSZyL?{n zine`+L;xMY0SEySfHlAY1Jps4kn5l%M%7NG!RBBlLMlV00@4841PVA5t0*0#%@kEJ zd@!B|MFL&L#unjCm{}+@3X@sf5UH`oxg#a?#_`O{l37_Kbyc8t&npT_0abud=f$*>`v}r^=Z6D7k3PcL zY$U_b#$(HMZI1PMHWIl+;&O%Es!Xj9kx3zsMsp6OA}W>c`1#NK??3#&kI!y3`1;>J zf9S~Lo9l0$fA-3H@%zyZv=wy~SL?+8-F-nyvVeDdYgJh+L zD8a2zrC<(4awyV6aDzm)!l*gqkd+(?7Rg}_bqQ<_g)KUVx)iN2uz#~GeD6KJ%ljR^ z_rAJzEM3~$-vfY4N3S1VFD72p3*}PLA9TNX0#Jf$Z``i&CShHskF7VwY|N) zv$KO?Sh-x@-QBI#>vfi8L{U&x*)STGWp+9p&l`?LQJS9R`Es>l84!3-&@oANMjmbG3A=0k*+}vE%vk{CZ0AKnfbW8$o=&)l?c#jXba$~ zSYTpF51$6r)r3F`2CZ~-;UbjQ0Tcio!%Q4^2*RZ(pXW~%W!!8|9p`*FL`g!h)w)n) z6q45|$)q)hHC)~rh@DXG$ErWkqr6FS1S8dXm6i>zVTxu~=??W_WJZ~j=KX9D%+?7m zKvjiW6G$5<7vqLCX+$*=!OXPY%<`9RicS@}YH&nbqI()27-DRxS;v@q);#Pi6K|b` zXrAI#j-oY|YYJjpReOdpXtzhbUNRhJQ8YU{TP~Lf2oop|V*^}_33Wm@XJU8W@E7fP z>7K1di;L+RRcIXNYBhoUAD#x!fh>ZiU@fEOwCTPp1-=o-oh%C%iwqSkq6w^B5!{;MlX^s%IqxnT z;i?_4y~#y1L(?Ty1&+id25$&tOJ(h*>^d#K@5Et0OT$H;qScI(WfTF*0ihy`Zh?Cy zqGJ!{b8g^0lQo%$jfUE48MbY*OowAUfel4Ak(o1vUTAfslgOdafJKpjGPyW@?xo7( zr$2D}`mqYHKKkQ>!n|{I_}Y!j-<-IwJb(X6`M^TwceieT_{*J7=AUi6OW!^C{`j{S z-+DRPyGNevfA{&H`+xmNo)FH*w`M=wzdU~U)6L)!b8GhH^w;M;{r#i=-v4=?e*Jg+ h5sm_x*%1q+5HN|hc0 z(?ii5A{32Kq+r0x2JE4Su=Wr!U|D+zQrRjw^iZ+ju#_QS(LsMREPU@hzRUX_eDC|X zdR)17<;E2NxOVjF!R>6~S>4FzvaS{XssiMo`r651Mz^-Mwzs!)x!lgq&hGB+-rgRD zVflQ1e}BJJE|*!B5k)~!Bwbfc(`dKbuG=3DgD9FM$vRD01_T~tsi3OGMuTj&n2yc6 zJ$W$H#-TZl?Zwg)X{^Q<45?(*NJppoCOc}2p<9~{jbzeUCEjKoRS3{%XbRvc*ucO- z8=nt~>6Ab#2BjLha1e^h0CILeh8Z|+5rjig9?y?tc~Y;>E$gh`M`1{?#j;RhWRlmY zib2;bR(E)_C$@d5J661@79@3&BbZ8=S7=G+R6{g6a;LBL10#s7DCx$l!D18Q0u&V} z)q!jQU|gUYOq6iO@)mmAI|XU32NT*P*+KeYA}5 zB1h3Rma7Y5Q&DVP?=_o4+YbBvI0zQA*?PT3Ko~%|7(2klF`-Q9`a*j$Br+fckWoT5i#!$sVZ%l#%exTJ_WB zc;iklf(4qdsUmPBR$*{eAR7wXs!NX5@VeI6@5Yh8N+OglI7vbQpac-gyy#?dk3h6r zz2%bYxsPB@r=qGVjfUQ887$N07*}9@kqsqgCey208EGW4DAZ$7AfQ;vo}YWRaDJJA z_irC7aO;m>-^s`uM+YyTT>tFtPx&Xmzm?yD}MX zzj@;K559isr@@Qt{o~Q;yN9RmUH$H%{n%Rve}DDKhxcbUzjP-*UY%V}KL7XTa|`F* e4|jUc|5g;g)}2uFv<2j9N(=IQ@b&y_|1 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_left_1_6.png b/resources/g2/track/boat_hire/s_bend_left_1_6.png new file mode 100644 index 0000000000000000000000000000000000000000..157ec85e76ffd128e4dcb48643cbebb0977f37ff GIT binary patch literal 888 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 Tjxo0~Bd~pbXY0Go_dow177w5( literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_left_2_1.png b/resources/g2/track/boat_hire/s_bend_left_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c5889ead765b7aa413046b93d4b575021bef0352 GIT binary patch literal 982 zcmX9-QHa}g82|2ice&efMkuUmke~&l2I)f>0fWR_Zp0(5xh<0pGB0vLEA$}`8C2*) z&<@IsGmZ*B^o+%5DN1EGJu9*298?<;ZT&zaeK17UoMX<>!8y?K|nCs zJfADbB&SiLL6cQ~^x)IF)$SKNW-$7PZw3Syp9Xh~;PLogb0qoZ|v!;h>mZbsAY z_%OhE$SRO416c#g!Prht>``jK8&Sy~o9@gB(Vk3ab(W}#v|Zx5y3jY3sIHG%=ESSd zg4SW=p-G5mS&A+(Y?&9Tiel?}yISqpcF^fWzCRugXR{ds!T_p;FCxyAt~>;WC{!hnmqU-#4;cS zkdZ?+gIpQ;6*Op|*oEWZS&#%M$yi0tSyj5}h+S9j_v=yQO{Wn`wTLn>wN>89$u6n+ zlo4~zO!bm#|FAVU^2ca2qq4w~m{`D7o~$TLtt>fK#cf)BuNj5jG!9WRW+e&vfMP%> z&7zUYJpxg$wI>s{-FgIbFc4H#sZ{h@&0q?3w$S1kPhbM6FqG+ODUUP~SrlqB$mdZc zrN_^{wEEBS4_rQ9RN&RW9=wy1E1MhZ7oNXgE^o2BU-&vTL_XqsXex@B4Qdb8d3f}kHolj)Ss0mp(UtSCylSR_j2 zT&2p^8)B=ic6_53R)-^pr!bja(S?jD6ShV+4SLVw{kq(1>ruBdj-1&f$m5_=P~yOr zu$GSb)zqMsp7wAw&Y`J_4sC>jEPx20Vwj#vnK*8fq{Fg%qS!4I2Bvwd*+jmN)9Eai z$%zE3l6jqyOAqrqFQQ0quePxYb#!Qi=kmX#<$V-%g&D`KUoHa*=7%^<3Up)!~w{01^{dT7oZC;!T`k(c~mx#>!4^LlAzO2nbmuT-VhBYWEvO(%jZ%GM-(NxTo7!t=+w-PTMGks90h1PWCQ_ufFeLB z_M#HY-2-lw8>11^sNaLp>+y;r6^mNAtkXG*$<;a9XOA?`sTH5=HR}c9{(qazhVKD?D78X-jNU*T5FvLsT!z>=_aUNJmFd$@#30N4I!a_KU zAy`P5VhB@MSWF>giY+WG46&GE3JFt8z+#GlSX?2Agh|-qkH^9H-p2=z_Z8oJKfZpD zpFjKb82~)L|N8Dt$NjD@2fePp^1t~Wpa-vCy?xoqi;IiP%gbJ`cXf4jeSO{U_c06` z3nrJ1iG-cq|DJu-#RRvQ{p%I@?0k9RNy0?W^|69 zh|)~c0?S&>W}6_$qo_>N<9^>X4Fb{zdWmssT*^po$4rjW{A9%SENjAjyQ!ZJXEbDR zoF@pG8fy$|34)`jbF*9KZi2;jy{U?_J&Ir|n4{sINrh8p<%-E%%T|+Z;vMo;eJI-Y zJrV(Q00$rhNC36~Ck#*rRYIk@TdFqKk&nw2Mu2Q`Nwyi w_~icX%eRA{t$+Jhx3{;E=>7NiKMcJ1;^wDcfB*cqZUF9IKHUBC)wl2d2dIT@)Bpeg literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_left_2_4.png b/resources/g2/track/boat_hire/s_bend_left_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..2020cfcfc6420b883a3f340031861aa747f6f168 GIT binary patch literal 957 zcmXAoQHa}g9LIlmy}R69oqecSFb|m&%pgi0B18?CxpZVl#$`4KdFVqXf%TzilnnY% zFk)b3#u25AK9mtKNFM^La&QqVix}k4ia`#oBaDIt`!FF&VTX6%-;BZc_xtgE`F$R~ zzu(O(yW*Mc=e7ah%+94+J)bYdB z?$BL_>ks7NNE=7yBynbQU!X9RD;iS8QVCZlJ(JnDg{ZGiMn-zrU8MeT7K=D&6tsD8 z6>Ml=kyDxu%gYIl7BpIF=+s3ht^&va8ipCAl7-_gN%|bOFUyC`=G3wtdLD`*oGDlN z3M~_yMv4ZdT8!>;=0LCmsW(>qi58|!g2idE$|;njvkgNqx^makywC^}D^7dKVmLdF zN<5Sms5F7-0O?|^R}n{KBjSxjb!MiYxiQ+8sj|-EZIN!9b6PP=r(lqyRE1 z$YGE#qp*c0U6lIpICvH$0aO`l=@qL@^;~i2>*KMVB*9{lpqzy_f$0=^w<7z57LrEF zxmhDvw#Uc)$!R!4(~K+wOJE{hYVbr$VLDC8wOW498V9{34i;&QmNQn8PzWdmgz_x9 zIqr#YyEB;2*+Kt_%*jM(G?Z3L?{o}?wpqH*Gl9TF5`8373$=bEWP_mlv literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_left_2_5.png b/resources/g2/track/boat_hire/s_bend_left_2_5.png new file mode 100644 index 0000000000000000000000000000000000000000..b9111e02733c63c04e5e8215910d36fd2f9455af GIT binary patch literal 977 zcmX9-Ux?du9RJ?m+^x>&iewni2o<6P$wMBpEz{_7qdTIPv5XZA7%{LS74i^gg{m1> zXO%vLQKe!z$}MQcIQwwy;#pi7d8pVyV14KyV;vM%#)KkK?%^JOW(+>x@0ZWZ_w#|z z_xsi9_3Xg|&mI7PgKMW&&m{9mQmLi6q_6B;X94Em^qXf-CUj+6;S(aHYm+SRryX^`Dxl6H=y3*g48E=%&SOm!)n!*KeCquQG|;y=jmoL1&;S zf}>(B6YEy-VJjW?Ni<=Ln#Kwd4kAN8I@rTL9k?{q9@Br?P{&pYDYmBk3`UA%u;b%r!MXUqJl|id=XUJP)!2IRz^igk5B6PPXM5olZFny~!j*i58g$u9OlTLUAeG zr_D%krkWQQJA3v1zCS|4DV+wM!m=!`iBv)5N_p9_3vSKsc(pL_CQ*Rm5iiTg2NVH9 zNfwnv?lH)6sWBe&jrwC){l27WYN241N+!padA2Tcp2T%!cAzkmTn6bBvT4-dkT0T8 zPL7{{CH2pvANcUhx(ct~zkNO-_S)(jXJ5L!d0Bq);tNl#?xG9Y4-~&~?Y%39E}VPo z-tRAOeSPBGXP35wwJ-4J-ro56;`@Joa^(3BRz5#`ciydHAN>i?fCnEwx>wVqqod>F<3^)#a&mHddfIF@ zF$`<9T4!fxM7P`JI98HGRh3Osw{6SwyfB>3=Sh~Wi=wP5js;NwMQ-bQXE30K4mxxd{-5`$?%+mZ=aqXLtj+T4{VrJ=T(Tg7s;FQP-4^++%n7>W?6*v!IG zAK%P6)rv%W7F7ni4iL(^01AMCVHS?NBpJ|jBnVfEvh4RauKR2{MQKWMovui*3MCkH z&tf!}GXue%NM0DkGb`Zb{Zi8BL98VkNno72|wA+a6L}gpLYC zA1DXt0OO}bZ%*r}Xyux}wWBh~(3Qe;Or9L}7+(`+rnIot+%q?!y^Fmv4G(#Yb{XE` zX-4Dtz9FMWr={afDSQkhD!@lT`~QwG}`IWez+)ubv55# zZw{!<;5bhZJ*ulRtSJb#tc;9W%$fV+kajDF%6=tt>kwGDsMiUMtBFg2u{QTSPe_#B-7Y{F0 z_~4(vKCQ`n7w2~#wSIj3-JM%-yOljh<+qLDyRY7AI-mda`2Ejbq4YPN-v2}X`0pRy m`s!)_$vZ#qZV!Gx{pG(me>;A1_sd!UF792P|9bb6um1;o4||FL literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_left_2_7.png b/resources/g2/track/boat_hire/s_bend_left_2_7.png new file mode 100644 index 0000000000000000000000000000000000000000..225a3c05018495dbc13f9f10b1f02fe3e63f94b6 GIT binary patch literal 990 zcmX9-QHa}g82|2ice&ebhF!s`0W;|&YScbtnuj3q%pKjCxg5)&N|j6lR;U<{Oo{{+ zFhV)12JJ%_Rifmf50TYz4*~lSN05`%5%83%L8=zlheLu_@W6Zcn=$x(-^cIe`~Bee zecPMo%O{RKa0~!WY@A)YkWDJ9mBn1v)0^!506Ew^cX2(VGcz-@v$MHeZfv*s%ll&HOsOb$L;lkDB4SsbUI~9z;hsp%hhVWUMCwy zsoCP3j@0cb{ZJpotIaxH5kLY^FigX7lOSx0@;Gisl6Gsgp=s{BE($|}$rt%T zNg_FgDrKIhht!wyFtQQ);@38)!jnMoBxKbVr9F z&O=^?LJdd*C>vwlLb*p(Ltcw3tfc7%2$Iz%8nWC{)lQ?)Yqdhxje}scx0j|V0zw1I!I&;C^a*)D*G58fT=gc6 zeroScdy}K#AzG$!oGlc}WKpI|D#z)f)Ks!%Mz7W0?e>x=o{o4>L`;`)Qz7j--7$E- zDfc_IUEdsroyjnoPWKTHPyx^ZYycl%7hsG5${-2I(2?( zW^#8ySVm_&W;@PZ=!1b!t;+SfY8V<*ve=TtGrqutVrfsJCzT>nNMur|!=Qjiv6vk{ z`^54;cYfgVh4V5zd;90tGxEX4+UmteKK}5B)fMa1@%hbbmu?)n*Vk9hzI^7!pO@87 z9>4FicdzirAHDU*r?WZu{^Y~LJ#PZ~>h{6u{jFbCPvI{$PAH;g?F(d1T;DVe`A;_s!qIOzXkz*FEQsh4T%^3XNd;Gq<-w%H8 zoj+SV zo5L_HnM}^l&*Rx_mZoz&&q9FjkC~g&tJ=5H2Hj(cWbUMr7 zIWfa3WL~3WlU6NOZ}1gYsCOi%t9Vf{!w|WAmX#<$WeOUvRmEykX?mI$nn6?#hpqm^ zPjQfz053wO45WoIO+4Qw3qGfXa;>jBBP&3gB9&Gd!pKuKnQf_jN0-8i+Oze6TN(NG zBy`arNTnH)l4+*M@rESTRJCCk?OM%mHbc+rZ*PxABLsv7q>a(76yG7FE>-OF)j`1- z8l91~J#G(odlR%krBV!z=QCM}%Bd`?3u0A?mzCSK`c|tQ1>v~Qfg)hKlroi!RiYYY z&aFzFMsdqEdwyfs3&!Ie!~w_vI)DY>0&D>cFhDUx9+h?EIwojiGU

    fWU(+VkH$f4XSSCTaMc4RKn054nq`c5k;WO3!H_EPDb%a zEn=-v!5tf&iQV1x`lvS|)4*h~d@fbsG9`&F7X`~KId!w+*2BOZMgbc489_iEpa>9( zv#7>$w?I_NjlqCv*tei}yL_P_l}c*4tkJm&le0P6iX;7+&$U%?f%369=Lq+-W~If`(Al@Y3kFf zr;Z%_^{1aN?0ad0IWr#wABm5@b|6v4AGmPo+_UK$#`A|a?)u@Y=l(41y_&qXcxo^I z`yWTIEq!(m{+POczw%$>`!ApQdvoPz{o{?_X7g8?3GV&xF2)XFb!Bb&(!)=j{U7+< Bt`GnK literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_1_1.png b/resources/g2/track/boat_hire/s_bend_right_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c6cb44874a4099021a5f71dd05d75129fbf42eb9 GIT binary patch literal 964 zcmXAoPl()f6vyBG&1}~i>l^|`h%icoSRzKqA=IeZWn8js)=go+pjk}WsZ2}I2t&ys z(13#sC6zhMVbBpn8EwEpml9zpsid&T93swPiV;Q}>KqmgI)^>1@H3_GeedzTywBnL z-lw}e<+Ep=IRgM^x8B;=%O{=Jxx!N3KX`951XzOI?TeeaU07IHTwGjQT3TLSURhaL zU0ua6tWYSdt*sHIQiod*EOwJt5J2E zZ8U{;N9pzTL1Yb+=49$i3|0}=O_^{ilxNUgi#v3ss9hQM&Ge`-OZ}59E|Z`$P#3{d zv7U)VO?=!d&W9wLv1qQNQxBoI1fT%u7-r(QLy{g%`+{(&C`Z-m*l~`#T@*zmS1gGH zt5AYYmrbVPaE2#X9mx&k)Nbj z3D7jgi#*L#IKC=MbyaN|MyFoyH=9wnn}p$HG|I9J0cir=#<(6X4M=s!R3}nns`<0} zAoE7^{_J#og4P)v=Lw=rl~jf`1i_M(hMq68`_0x-ub;-rd?JD_W0s0LI_1@vjx7ca zbsg-vouEY2`|ei1e5|oc@~Wv z_gJKBccxRm(|#;#IFvL^t{31Vj@43SAZsxo@eEIKp{(JT6^};c+`t#l& zPd|I_{pVXR-6Sqw`|8RQmsT|U{-vj)bpP(xUwregasMIz%9po4|FC$lJ^A6n_oeMS z7tUYtfBNl5@x}w?+}*v+gWKQTTKVMi)oXk13$Nif-+s7yN58fI*YBfWb2@Bo?rePf I=Kl5n0XImSeExAVK;NM;t-I$V0%~%+2nMUXEp~?21N>Sg?aA5%bW8 z;3^hZC2HA^6ptQx@(2JN-9Eo{A)TkvI-bp>{m0R_HvuxR`|`zeDP3AxT3%kxWHKu&E32!k zYiny5hGnza_4W09p-^C1Mid1_ku4Z@0Vsz83`JC`#sYmH~kWS=uO)vl*|p%p}}Fz!tk zJ}y8`fqVtX8c;UIb@RnORrUovEH$Twlh^^;m+73w5oVEYmiV3~4h$u%Ym>GybL)xU zUW6{11$d65=n~6S1kqHKrlxgFv)^p`-EQc4)A2Y-5(I<}R2yS^xHuq`5nY*zjak`= z%|T+1=l%F_vOpU&j&u2Zkt`@Qqw%~U$qhAKR_ixg!(KlM!ueDHRl*Dfw^Y)u(w&;% zHk3i9GIXtp--#!|e13ogfD(WKU<0@SLx33uD1|Jdnt@ygMH86;x9jccN0#2boJxl?gtNy*2y34e|YonUGAHo`q!U*=j`Siw~1>9e?4*H`%mw_ zsM+4JU+&+yab^!c6{>@7dZW|9ToA;hSSibk$wbTCwU%hq9zaD3-Kim_)?^W)k P7GV3_&enG?yngk6f3u;a literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_1_3.png b/resources/g2/track/boat_hire/s_bend_right_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..d035540f6146fc5ef692412c8be5e22a78215a4c GIT binary patch literal 991 zcmX9-afsV=6n=NTyYyCP7)1(3);~JUBxo2xg5-}lb0eNPE@K&#Q7~#`70S#Y(;^iD zt59d1VJi|w9R>48aRCdvgCKQ;kv|SC81$41L8}z5jGIQyaf9^XIj``~-; z(#du4;DJXE0Kmc37gkQC^Vzg=*-YC1yzu=YfDD{mJAERhb8~a^^YfWZW?^AradB~J zX$ixyY&N^Ryj&=iN(@5_0Z#J8@-5U(NAlQzgI7t{9cn)MKSE=M{wPL+N zx7wWDmHPvA=o_Q3J()TJg_XISE)~pj(bCAC!E7`I-!6{^dbHJ=Mb2Ivhy)w-5?S05X7zVLFbR1Ywb+!*Lt3yj87^O>?)`L%vTi`4V5C zPlHGgO?B>P6KeOVDD8Qz%JeE4rY! z^N?4dP=#UxNDE_o1#v)Dd|nUB?TO*UR)98SDzC9bU8LG&uCED0LkXMO*fyqaGxqJh z&_&Y#&$A>|X4on()D@+zY2A8#&~E#^Ug&v~?d>>@5fD0%HpcXEVMr(=syY!`(~2{z z4`XXP8O-*_dniZYI9n))#ganN8pj!u+)~qJjX}G!)gMGbm`r$3CCpH8Q!QFGs@ve* zmNM*Cw_J1VcW2`uNp=wrPzEpnEC3f^3t)-?N+AoVVIbE*(O4!yXQ0D_Cqg6xQUK`% z)Mk()Bd>-=EfhI$KX?`-0m?E~(+Xyt>R4jm(T2lj7`n4rh*B-03QQx%TLsxEsvfCF zoE2Bxq(0oUNBiCcjbkzoY!MS_yuuf23e%`cmRWN;=Fshgfjf%=luTGjLLQ(95K6OX zrE(8IG#lONl0(8|9kzVY?FbK>W(K7REUcjR4T z^Tof(NBCFH{ra)?jJTP*^~>eXji+z#U&_2EvH$)2#ACOs*th?Da`%hInIE%uC3*YF zdxzKV{QmxLnKS2qx_alYV>@2eJ$~i2^O>_ZUsBdSee}u8jZy literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_1_4.png b/resources/g2/track/boat_hire/s_bend_right_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..9914ce83423525d09bd21ea93858feb627879e78 GIT binary patch literal 901 zcmX9-F^J@36n?uiyP3V=7-iss28=L8#3(6Jq(~7pyNpYY&2c$N5hMozrz2bn*QMXPyPgG!J~&yt{QoAa&mfl+G@4h?e^K(+4=c7 zhGCsf=i=f59}EU8%ZQ?&D3W1lmSwuG8w88hD$cTPQB-x!G9d6EOI=OtkH_T1W~Lq= z%;n`uPf}}>d;3Eu(wNG3O$m2Y(l@Au#ooGN8mOCZkmSCp0tX0CdBE3Ets-O6;|;E2hP_Edgph>4}-uCWWOL*!OzaLglg$a;N_ zqE(g~3F1UiJj0kzCM(ZN7mGZO_uFk%RR{ z{QcKwjbN`YKYY^p(RlhB=&$`@3cvpT!yuX{(8gU#eNus7HmSs4O?fZTdE!XR`D0WrVv@OSiD1fRA3}ZN%P*azk1wyn? zS8FrNooyK$jkNOq-C4Y zJ2^ynVykSfBOr0&wWooCTS5)(|UL8(3F2Ya)VhofE zbcpdwLSEBGF50CY9Gtib3-q8eLyIS;G85>+%91iiD}8GpImg6r^5|41=vd%Go@R88 zAB)md(*ny{OsDH0$d}79O%JuJ`6yLMea?oVjI z;5bhZGBwf|))E9qQDm_=l~8t2#^450FD@-4yuG)2PHA8_9_iF2Xhfp87dW!2FNB*z@b=0=>%FLwOZjS>~5zQr9KwyvQ+d?m!F)HKxpzwksiQjHI1rr)c|_9?-s_ zhrm;q%;JVfO*GCOE1@@u=U$e~%Oa_(0<{NTQBVq~0))COW}V#!kiNS(9{EM|0nTP~}af4%*_ y6QA7PeD%8ji*Q1 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_1_6.png b/resources/g2/track/boat_hire/s_bend_right_1_6.png new file mode 100644 index 0000000000000000000000000000000000000000..d766a89112c1fa21be2acff0cf645fe8d8e71f13 GIT binary patch literal 976 zcmX9-QHa}g82|2ix7=Ml%PdF0JVY!mlOO>zj2baJbF&^9m$^*)(1#3zR_sH>=n57L zTBJ&muobD=X&*8z7+8dp1?)qFAcyNP4+mDrpbyoHFd>WxeK?Q58H3;Vef(a&-w%G@ z_vyKv^7`7tYXGpm{nFO?Y@W($Z6%lWTfcv{1dxMsXD^(|=)%In;^Ja1ms?s|T3%j0 zcI+62VJj;utE;PcsZ?TFMid1_kuh%V$>jlAn6eVfOG9d6EOZjTGSg(_f zCe!Zly}mqj)sb(E!_IVOi!@f@^SXqa71GkEfx+&!M88)VyLz)*f#W1~4FbTqQg@`-W7UglBu6mi60gvb##MDuZ_Dk0I`DKaG=r!c#>45{ zF9=Xn0Ivbr1j@p=0bX{gsxRnar870`#0t=^OcyndXq4$rg&%6-$WX$THt88NrHdC_BnSu{s2;`+3*v}S#&m5ewr5p4 zZj2IZKXv27$sFbBLV?5aGFeh+M&o%ylG|#wtm$^TdqX!0!gMNtDq)6FFjdm3)BUF4 zw3Si6w&$1=zaLM6G`)iafC_*CU;#J)djK;GPzG5GAO(<) zqYjH~8F_UyZllPCd%<%ciBOTTx`vw#x@(n(wl*5I!qAE15M^3K4cKO0uyENXRgcmm z-b$)Y+8E7y<3n$XCJ9vpj>O7Lp(>Ddg>BX(%dFd7bL4cxz=@*(rBhClkOwFNgt9E! zncRI4t!95VaklE|b`pGBU4LMc0b z?uq=}dq42*`5gsLAN=t~Mn2fy+PrY`^5@p(L%|~t2JP%@Y3ZI@%PJxC!c-m&5I}A|M{7#uZ(~D`})o&{~o;a=laKQ z_pd%`Yz^Y@}}h literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_1_7.png b/resources/g2/track/boat_hire/s_bend_right_1_7.png new file mode 100644 index 0000000000000000000000000000000000000000..a9b108bc0c5970fc94eef68fd9b7eccfd328b827 GIT binary patch literal 976 zcmX9-QHa}g82|2icj@&w!z@}@gbG#S5hX|-@{otz%#C_PF7tA;Xc-a0*@r#^%w~i# z16Eg#qCq+cqe6vnR0&wz-4UVF2oXByL%=?C5@sI?D`R4mf;YK`zZrwy_kH|czTXdi z-*<3nr?{Rup8`Ihi^Fg_XE9P0X34yrq&IojIxtzFivjv}n+nMb2p)6bVo$FnF+J ztgB&u6CZc8^C5v|G@2{u%t9zA07w7|hG{r%5`;yP4#yoy(x6fqo93fV2l+n1WD9(b zmhzlJ7B#A5GOEStZK3Xpt-kCG6)&pfS%NMWIGGYvwyX(SLuz!Cj;DE{8APpc)}5UC zI1gDFauvwefV42SlPmVfvd?Q_sX5V|*b2~*L}gW$Fp5;O#C27nughUw9ozcUt;fE7 z8oFp2;8~WWN(@`!1w)pbs@gV;UbE?UI-%!HMx!{65fB=XHpX;up-;#|sxlE8)3P%& z`mr^d_hx6~Q?y3mIGf8A^97lrRgTj|si7pxYQ1J_(CtM*IG^yKh?p+prjoa+RJ+Ez z4Y}X03|w>Uw`b#EK7WLGfD(WXU;(%Q1Ar+8D1juPnvPrtMPrEsje!;qUJ)V*kPJx6 zp(cYI33*jCY@o=2C&9BI3Q&@;s+uzms$~_sj@s|n!_b}0LX>C`6<}&>yp@xjyyB5s z#949Kog4jAdwAwe&^RWuz~-?cjhFd+Rc2}x(K4$}%j~dQ3|(hwn`c~s@kM$hQL|D3DS2d)sLddcN1>P; zKl|F+KTm$(>h6vVn-A`NkdRNdw=V3x^3@l=U3m7F7t^Utgs!}N;AIX+;^BvX+_>?> zN&O*tcW{@v_xkl`UV2Qg2L^VW`SRqQ-G_hOPVYUq_V?%KFE{poeeB=A{_4-+ZBe!N zZ~nQ#{de;G$KS;3|K4A`b$I9Cqy2O5X1=}hUiF0^5Ae6Y-nwl)VEtpF95P UyQ>?Ui4)kqxU=>B8}EPmKcR-CegFUf literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_1_8.png b/resources/g2/track/boat_hire/s_bend_right_1_8.png new file mode 100644 index 0000000000000000000000000000000000000000..9253d28729b169ffc7f3d1e6602a8173ffd41f9f GIT binary patch literal 965 zcmXAoQHa}g9LIlm?OpD6j5vz~3=**qQL-aSz<@#0nH#+`aygbkmEbZ6TA^SbGVDW< zpna$kBpU_$P)5-xeF)k~IRX|IA;^KnWl*s@!stWMf_n&3juQ_3n=$zQem}l1zt6+> z_xt={zkL4Ov*!Td{NC=)m26(j>cU1Y>$mRSEdk`<;H|5dGrO{~vbwsO%jNR<{My>u z`uaMCVH+D8o12?Nu~_6dR+2O56tAKwMe|vG%AyzGf)@7 zRk6N_g$_RL7nWlZEm*YF(V2@-R0L1}bPO|b+$KqvraeIzD#}r{I<@Uby&eifk}DKN zf>kI%r^_Z&u{pyPtgh7b<@QMR#(I!cDV}7@ML}g`gV#*SY$>gt-V4kiwxgsSFZ#37 z5Er4K0#OC30kn(pJ)%6IwNNzUiZipk)Q!+kVG0IM*2|1j5&DKSvedX~Ogq-xZ>C}A zH1^Rv!V5gjR5-pWN_ACr45M4G4;&}#_2M9yO(toYA|OqmI~do;r4gx)nd(ex%{6aP zAEoYOIar)cPtg{G<2*r>siMlTh9Fq7($ceKje*lX>JO4AUd}|&Wz14>Tc_L_(`|@; zOC5EqN4`A`yNhYGTs}e~Kn1`8Z~=UPBY-&uD3cyndW)OCrX}jgVXN*S8IQAEd7-cN73S47LbP2_y^nf-K z!A&)PSs$Ht#%I9{O;fr6JcX56Tob99$~CI8YuCKCJ@VUe2xVEc zGTal9%|>@V=ewOJvc_Xc)6`ncXf#ZYZSrhKWp<)4i%Jpc6tZd5weCZGTw2cJYq~yZ7II{rKdaUvzYn{r#oG z$usZW`H|UnzWwf-e){SwU;cLxb>BT69@<>#AL{nzC&Y8y@Zp`WU;Ze=!`|ino$uec G{^|b?&Ya}{ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_2_1.png b/resources/g2/track/boat_hire/s_bend_right_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..35d455b10ff96e59fe9d185e9fd94ad4a64c32cd GIT binary patch literal 979 zcmX9-Pl()f6n^_RyIr3TQ6q+S4nabRFvzH} z4$DweNM(vahh>l)1_?Nag$5ik)le3kLu#io#T@1^#T=IICuF0GzfI|Bf#TW@XbW|PS3*`>LxUq8D05x^W=eEZU7MrUSbW@l&T=H}+-=NA?h z78e&W3|m@ST3%i*6pKZMp#_1LWl_`0rfJmcb=PfoyFnBUl4LTSGBofUNa9MloY!@t zTB92_=eDFySM7ynKek6>PoOY`TQS6fr4WurwoT@sE`+Yq?;6QrBTc-MNmRl?rJ%}# zBV!!{3+>#nlb`l+l+tLbqEiQT&F+X^b*0yaG&Zg?9>)N2md5 zB%CuT`_pRg#OqTeb*)x27`o2VF3aeqEe-ZR03HfYB4C_Q7mT1 z&%V0y?~@<+cz0WdH~)TkB_r3iHZELx`Rl!#7tTiKm*ziN&;Nn=`|sU(qw&}FgJgI6 zn|B`HIQOmj^PUsEEB$o)^&fuyZ*}qD>eV}yi6^enHkvH+}`+c{ev(62VWVaPXGV_ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_2_2.png b/resources/g2/track/boat_hire/s_bend_right_2_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4a68ef77aeb4e307ba9a2999f9dbfbf993d13d65 GIT binary patch literal 983 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_2_6.png b/resources/g2/track/boat_hire/s_bend_right_2_6.png new file mode 100644 index 0000000000000000000000000000000000000000..3f3fad0d53f0eb2d1bdf07a598b98746e2c0ecd1 GIT binary patch literal 936 zcmXAoL5SmY6vkht(@AIQl9eJ+14b#5LvX{ALl&}-bu&vHB9mn^Y*zwCHfRq8bBItO zhky~H6pc`%Vp)60p-8}@a|l>4BSA)}kV6-{OBi}6*uyTArLaW?{F`Ord++gG-tX|e z_vOvQ`h~q$_Wm5O1YT#hu-J^0TkipyGJ*2TPPH^wzi7J;`a7-sZ`q8 z*}*WZTrThK?h>_HjpJBJ5>-_;49&7k*L8cn!DtjE$u!GW>ov!MD1ahYG_BfdQEi*` zIzq3n3`hDnwkBz3z6c}+YX}unCY%Q48}z{9j$JA4H6|l7JN1@XuvsN_5_AUIBKRsc zG_kmY&xY0YghWdgt#x$nBb3wt6aXE=OdNMe(x>S_5RMh)wAq|F&ZEHq#WBfMYa+oa zl%UgflW91d;R{w@aznX0R)dKiWlf4F*?LV-8QI`9Q!+ip8|Z_`j8Z4by6JK_-^92G zRTYRPP&Uv$#t(@4h}L4!OdFlK6|DRO9V<-L;K_EK=`@6)A&o6Hb&XliT7>Q@?rqW# zEfT!S(@cZoo1)ZK)sA8G+wD=O6AuPy6wRm8)oO)+G=c76+z^+>q&i`mbIDt1!LmJG z`P21ic|O~q3WMW3LDZ?5%CLqYShC{j`7(Rd>7EWpS(2{jBIq(^skoz4ev9ebV(6*k ze)BYRW^sQxOV;a0NCapASO7ji2yhCpzyRe^BxGAC3{W;xXfQeGiV)QyQvj)eOagT{ z6euWap^1mG0G4yhrd*5BYS~!xve=@lL=AWf2cdvc*`pFmE3wQ1Yzn#6u beERp5+kd_P@zs7#fP)){`#)X(;Isb$%pQ)l literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_2_7.png b/resources/g2/track/boat_hire/s_bend_right_2_7.png new file mode 100644 index 0000000000000000000000000000000000000000..7013bdd8d4b7bb988f39901df90e94c4c3a30b37 GIT binary patch literal 983 zcmX9-QHa}g82|2icj>KnR46Q9z$itc28kFnU}V`{Zqy@k8Oxw-9YhUUq+%X&QY1=n z-C2%;VRYI-kv`@8%er4-iJc+nYCKGXAxrW~WNWj@w&!36u!otGh;$k9^SXx?IUS3{V zS-~(YnM|&(uHxBjmSq`H6ck0$w1Q#il}e@2XmvVX5DcPdI-9W!2t3GAs!+(3N@Uq& zsx`jRl-nJ(>l^*BHX1u3jpg~2F5y<5v^A<_u!j}VZ{+(OJ?d2_ku#qLIRaD~$^zI5 z*48n}U=hUw|FMG!VcIXr(T%e`W8Xj%7LE#&(Io5>0| zBa^&J<#al4v6{^rO|jxi^{(RdRWB-%9KqzWyh2MFSI|YhDpy--%hSEk3Zi;AX^-Z9 zT7ZlKco9ewC>!Hic&8a0V#lV z9MxFl$jB?9eicOyJP4ixNrb$Nl{DNc({(%7cC>D{5{B+%5~5g(C<1Gy1RIwfQuQc3 z;_Yd{ot3-uM*r9wq2ZLu07qguCS4H7lERur$+k*P-RipaFmNYPfMz33l8^@|0)*l$ zs-rmOx8A+(n(M^csr~O4UcB(--BUmAZW#Ced;L3Y<) literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/s_bend_right_2_8.png b/resources/g2/track/boat_hire/s_bend_right_2_8.png new file mode 100644 index 0000000000000000000000000000000000000000..951ac2897bc9968e5dbb6b5d6feaedeea2c5cdc5 GIT binary patch literal 976 zcmX9-L1^1%6n=@5C~3$H^)kb>Ri%b$R4amsp@9ZkrW7@(M4{@YftzWdQ6GE|Lj@O1 zCpIy}FhvwYeK4CD>Tp3YLvzrR6r-aG*SYg-pKFJ<%Xtk#!vS-*K|eFq>1I~OmX&*2wd1Ym#SSpnmh86@~Q6yb2o2FsgcB|Ft^@73RAdZtXWoY0zkfqgfxlpYV zwL0xIxK>;4_OyOz4x`3+;t3R{a;t_^v{b^?$&ShF*+SS-hdm?Scc!s7O9mni8U-~T zTm|bISlGyqx`lLzqbZG24IR4(4N3qqfQDg4K5yZ;OOhVP?aA_fr82Ut!%hc?|8v`%0Iku`{$(X>0B zg?Szd3KT0q)PZy{wo?>)WI5!GNNtQwFL4KGPo@ewi`PV|p>kba=$lGp>!X%A@$DpR z%_1L72KfR@QYyn%c%h~!4P9^7YQ07y>~x|a7#|!YNrC`3fNWt*H!t*YWk^-Vf-@<5 z(^@}q57OTBcr-(+R6frZiy~1{C|c(@Q<5DmTUPHin)}^eJc!aU51NFTO5V~4w@S6^ zyzeOec4gnUMqzt88l>qV;sI0u6Tk)V0rmkV7@!QYfa)glJrs{*5)1~KJOm=dG9U$z zQA7;}c`^#BXy~BWgO|axAPJz#SXD1tHLB@~T~F`#?I`l6(+Fi+cm3o?dstQxDNUl}&npWR$MgxBu4^TR0B?$$9Vn8U% z!pY=b0k`Yz$%JjUUcnp=g>qS`R`q(_U}&4ATRh_nOeoO@GBs68NF$I%qBes99z{}i z{Oq~aXD@%?+NEs;K7R7&)r@?zwYhQm-CH+qZJhl5^zy=g8~4^zB%aOPbsl~8`1ZF| zH9CF!r1yRP$(@VPzVg~fOY$4n&lqnVJ<~s5d%yZ%ZTH&qQ`g^nc>n98r|g4!55F7~XsF)$GMjyNUhx)iZZT0WzFVk3QhO`0K+9|Ljfvef0EoOtpY|d}HgT T_V8Th1h&p^Z~pqpm*4#l*vh13 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_1_1.png b/resources/g2/track/boat_hire/small_turn_left_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..188172dec2fe40e31f27e532e2ed5d540b03d7b8 GIT binary patch literal 960 zcmXAoQHa}g9LIlmy}R^Qw!n&H8ZeALWDq2SJOqiD&D_~LqL;B87Oa@f!1bYEz_|4x zLeM@GtuBlr85FFLLBWU>?ja9F0tPIzNFMr7XT*wC>oG963WpryZ^q#J`~CR7{5}ug z-|xdKd*#!oo;d{or+0U@u4c2C)zkT0)_;HMk2?T4xbn*Wc4k*rR#sP6bGh8w+S>a1 z`o_ivhGF@9esgn^D3wYa$4Zi@sO(CeWvB)MWq zBv^$KG`egs6`Ru?!R$&+U+xT5Z>$ALjp9kRToP19*7>R-87-yN(|Ums#CDW);zfUU z9O5DrRUm3WSwK4&-y_Ncx*Cc`TxritFLfexs4zvHCmUs^T@m`aG&I$?sZU*V?l;rW zJ&t`ekMJT-GZl`niBdyV+q&LuGzRT<*z3hXFq=%$G(|ufK)V>%$E6{uj+xp_YR#+O zqA^UJ$#SqbnI5A8gX26wl&O-+u(}|aveMGBW!9kG8TAKA6fb8YXfkH1xUEr6o#|Sl z-%^L&+Q_%3VRtc&mdgi71gHR*01ki;FanrkfHEl(vP|TAD48lW7#ws&2+EKsfK)&R zf!ZAM6cp6axP=lA9tY2ZEI~!V>N;UJn2uBKd-`zLjAMVXh*8EOYrt6r(IFI%(gNB@ z1ShTf%f|579iIdi~>LjAe3d% z%5YCaHm&Y_&Uf7>GRI@7T20o?rJ0`t)~{)=DU{pr2Sw-V;9d%yf}bR&HBwZE)8 zBlc$h?Am{y@0>YGW)I2N-!w~ZbobX9_vi)U;mZB%H;&Hz{QkX+47=NVTVK6&?SuaT Dp&FdJ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_1_2.png b/resources/g2/track/boat_hire/small_turn_left_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..46d0af8371cef4c45e1e9a7c22dc91b47dbf4a7e GIT binary patch literal 963 zcmXAoPl()f6vyBG&Fl{A6z7m)z#wyo7$ri4prNF0wvJ0=(>9AK446X1K?aGM!ccMu zIESguA;=(E$YH2K<`8HOE95XjgaL|NXNU0<6HrxArgOc4=v8d3kwdWo31Bb!}~J zeSICnutK4*v9WL4_%0LTCuh8d-jO%M)6`854HPizHJccA!VElTSoM=;e2uh5dt)eO;S%k7@li;O6-hiNyN_opXu zNr18fcpXR!CXKMNjXNV4Ex~y|Vvr2bVzORb|Q%PF-#5HF@YZ1FA zNq}aWjjpv}XxH zTN!xuQD9GEZ$24j*+V1%r~oE_0}ud=0A?7VT(XEP69qm>Co%;F3ta)CDx@+X1(1QG z4vTylMGZ7=qtu7T!E+#qpvqW7$L%KFb*g<|9}HSa63pib%2`AmSgR;Fxa^Z!L>VdX zENVg49Gtl0(`bq&3#tqpiB*|WO&}WzYt<#kZunh$5OkAaFi(dln{twbB0wo1lxNY- zaZg0FEN?dBJokyr@mQ?Yltx3hEQ4iQ9ODXXAhNN<9Lw}vtssp=HibMEMFL8s{P?+- zihn--foqrd6gdC;Pw(aCqurg?_n-g#w@a@sfBSOb4-|VhM*Fv~92LL6vH6)J;1AyZ zmpbEazx%?yqjBM!^winn$8dA~(U<1YquWnw_wTwte)vQ9?7{sz#Sgyz=Fa=qzcLO^ zU%W!8|7>}`yz<8RYv&Gb-MnWJfBpJJJ37kV`R_Y?yL)|O=jv;hayaZ>*xR|aef5+7 E0j&|AnE(I) literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_1_3.png b/resources/g2/track/boat_hire/small_turn_left_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..50becdad953eadf24775083b4e3da2309621c343 GIT binary patch literal 864 zcmX9-KZvAu6n?w2yUyNlv6w=Lg~b$-NU*SwU||yXFpFV5&I1bz1CmTJg#-grSO~F@ zU|}&F5~i5KVhSM>*uuiX!eWYnSWGbii%A%W#T6!4Okj&&Tn@hXj}P8geDD4I`aypA z;^P+p@bdoayElEk=wmP(^!dBNyWjdAUVroU)iZH%ad~+;7!0niuCA}IZ*Fcd3>yxI zx3{;%WHRA6R+2u!7G9n%sxocr5_LyjQBVe`284Pqf?nF(kNz$k3P!MiZbu}1lT=&I%j?$Fmx;>F#RZ1{u z*3p8Y@%Hw%swxDe1$2OM3tUP_ZOsg}(sdTAJOcF28qq59V<3$dDb2_3=s3B#O%siDR>1I2fT;nYo{X`V%8k)e9aD+-DM6@XBa#kjG11=4e7yB$9Z zUcp|krG8%<4o%0gIM(CYK;$BcOBME3WlFt=3<|k4nsF!=QLZ${&wteU>*Wu8b$zM9 z$G`vfs1e-7*(VR%-#vc*;B|PX-TL)Elsvim;PLLm?E81$gr`5mf2M!GW?ldCNP70( g+tru<{96FVfBXK=(ofI7X~yB={POJCr(ZnzA5eXMhyVZp literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_1_5.png b/resources/g2/track/boat_hire/small_turn_left_1_5.png new file mode 100644 index 0000000000000000000000000000000000000000..83d8837537a765af4d629b3d700b9dec2cbf5233 GIT binary patch literal 985 zcmX9-QHa}g82|2ice&fS3tC3NJX9zcF=}=T7%*s@xtX1j%WXL*l81~1E!u}XWEf_J zfK|!}7>=raDAGY5szz4fgiH!n7O-HIJoKT?C>1)_$-p2L?%_E8W(EwyWPXNHl?ekj~vq@w{uI93S{rNk81LR=$^}TZ$U07IHTwKiMa!X4~%gf6v zD=Qd=t*)-Ft*sHoVv%JTQ4~~FHVnDQZlivmWb;LV zV3Y!{Q<6!S9Mq@c(!t)$OmsqYWh_Uy@U+I1U)PB)3-`9uI+#w-QGFB)sS!f6lN{}dkR6r(y zTo(BX3M*(>M~M#)g6BXMp`>6HgK%uR;Yl6e==ExG9L#1h%CyKbu+??JBNV@&hm@J{ zUaAFiyLZ?e9)%M$PN_U_1x#XaO(;}Uwpx}wr{Xu9UeJi6V3tH^KH+2;g@6)3D9fUr z$vp&FtG1?7uGM@9Yd91&O|4XnYSmHj%D c-aG#Ow@rKb>lbp9%o1#$+u6GD%B2tf2Xv{Vr2qf` literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_1_6.png b/resources/g2/track/boat_hire/small_turn_left_1_6.png new file mode 100644 index 0000000000000000000000000000000000000000..69fdae5b07bc19849b822c8e4888605f3acff304 GIT binary patch literal 974 zcmX9-Ux?du9RJ?+Zn-~h#j9E{U?zRYBpg8k1`QZz?#PbJ%drfLR?Hw{eW;K@hDACF zUXkL;h+BtM`Vb)xg$3;39->AJGq4T{2Dyh0qIO!b4-<%nZUE$9=k(dljLyx?&Ck#0a=C?tg~i3i zBS(&47`C*uw7k4rER{+OLkj}0D3YdC3`1`=o87KG7kG|Pmgk+#9?HHDyC9u4$(*qX)8K@y5Ms1($B zuoSGXV?jGV?ibP#j%GAURdi?}6qW#F02RaZeBQ)yizFS6+mq#CwK_J<2eyrZ0A~s% zzDUair;?&hl}$#oIHM;tU8&cz`m10bl{R07HN&1}K9ppoW252gPHV1f78n51t6I3`hZ_ z7g3u*j*Pq-8nsaDz{B8KkOU~pSWPRMb*f{DeMj^CW)!)zS%fkzyb4TXmA8trL#Q69 z$DEZ^+_df=bVrBY1dS8204#xtbiTq9HHB$ZCCjWi9n*I^QRvR%5Tz4Vl8^@|286OK zTAAD<;LS#FI%Rv^M=(Ysp;A$5HLcOm8M?{RU7m3TCXncTnVOYLNF|U-q8@`h9z{}i z{OtPbUk`ua(wS`qUitmrg^XO@+BkXk#I>s*KYwiD*~fC}F17tN;@2*&-TU>Mczynt zOQ%ZK)z98Q@BeZ6*!_Q3j=%WZlhs=?ffZS{PyPV4N84aymR4u;_>6> W_I|kX()G*-Y;A6DeDUhJ-TwjZrJ!v9 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_2_1.png b/resources/g2/track/boat_hire/small_turn_left_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..81be773d349788815e7d4b39d993756bb1053938 GIT binary patch literal 959 zcmXAoZ;0D;7{{OM{YmfYD6C+I8H>_MkT7x>G(ynK%Z=>FxE#x%FY+RepcTppXM`fb zMXXXZFXB<9FZ!ae2o(aWaA;lx2^g?o!3Y&Q2vSDH$|jUi@RS38W(>a1^YDH1d|rH? z=aYkd@yymUTL5ro@9OULY(AIOQ~A}br}>ND0Ib5nwHsG5yRx#9%jH&ASJ&3o*4NiJ zHa0K}%jff(o15iIrNS_@An=MJ>AGr~Mzh)Mbb5n95Xa**T`ZRj4Lk?3R8ZAYy-qYN zy5(@4uG}AJVPuXHXFBr)3afGjLn_-Le^f>NVmWQ?4#I_&ydMJu;rc~j} zv`lasDH>GOW^|V`yF$~K+M(i&v>>e!EKZ9RPN5{7RSm&t$*rE&3ydJK+3>jDoInHbj+FGTtuCd z#7DEZSYk=4%CI$FXef%K>)l3U;5bpQmjuCdJYFmo2yg?)4#xD0LWnCPsx}o`Gu4|n z!i76t4(6wm6I7szMYdcPiHbteI>(uk+|sgT*1%~G`-3!2mQx-y2{VRPvg{FBKpH9M zE>wTn2v0hr(_o4w3$g?(fr)fc<%zn&ST)JD>t5Rq{dN-j^E5`wDJw}R0F(kkSr)Af z_e6Np>dt0txAR2iXe6krQm^ZlWiWJ;r8_+13rr-@W0{&)D@Y@dO`wm1 zOYdBGK78>t@wcmgzxvNBXTSR~cmJ4$<5 z`=N|Fv!m0173$1~eu!AceTYynupmYIA&vuk8nm#Y5hg1x!y6p#XU5=p-<75dfAqUR&Ev=E&#fnPYHDhFdU|GNW_EUVZf-7> zN?{l_KR>^)u#m~+ax|Uic}|u^RW0heR;$%4tKIFozJCyglQ^dHz_B2SOT}WkTqY{j ze7(V1EveI0dY(QA8l$nzQ&@pr(!`8WAWW5P>-2t&_pHL8tA+h~6xv4FigX7Bbzlz(q`FxN$QtML&Lb$ZX?gj(&-$R z$x8&Qkb*`P3|ci=y~WoYvDuUDf#QZGg30EE94k|z$`mzTt4sB^(sngBF#NC?M4i!* zhjWmYAyWdP3Z#iK?TpYRiyo&1g~mv?C#H|~B`U2l*@{3l3T#K^d%7Id)S;!1o!Z2+ zjsgdbeLT&ORDotn9AA;;hN`wIm2RWqwcCN~jt&kclL>;X2Bd}29h~oF7+p&!H}4ipj7W!z8*vrM(B zoKu&3ty14HhF&Wg`f+>bJ-86bmGw_`#^ie!wL=m}wLO>|V zqMpb-M7CCKjmJ#OdI)_m;EP4MTvn@9jn3DYyv5NDPkUniK%$~T4k-jONYtW{%b`F_ zj-Ppc>7NHbaAA8>hFAYQd@CUzZ>+7JJF$1^viO+))cpDm|M}m>-jBkCt-ZU4k8bbY zocyM*!iVpjzkKra&G^&J;QFaIPMN8{cKKlKyOp1=Ja^;qCsub-&hP)7d2#XS+izo^ zl%9Qm>eolEd=S0x%=!I0Cstm1ML&D#-JKtZdsn^JzZJgc_`BEkFTQi;-hJ$kFRu~! ljnT_r{Id1r{jYw$lX~;2cj(;yx03jRjrGm7Z%*%i^gsIVs?q=e literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_2_3.png b/resources/g2/track/boat_hire/small_turn_left_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..592be11f917af61e1772567c6e18a0c18a261c49 GIT binary patch literal 906 zcmX9-L5SmI6n-pE&S>i*xC|NIKjfXnwD+^y-}-roNHexuPiI5;>wJUlu& z!Z57aY#tvUce>p!%QB)UsH$w5x@}vY=LNxZK993(SrprJ}8cC{c-$)L(WH$FmH7eE0pFwDYnmmqwK3VHrYQLcNvmFqs8PEnc?Y`ZIT7=`2w zO0sCpWlf*AC!!b0<3tS?MqKnrj$ouNuhO!~>6T~>mEqKw##WrWSuxJb*?O1a0<=}= z^ne@y%A|07J%X6?YBN@6(fk5DnF2(z}k_ zRXQnGSyeqn0)Pf!1NZDd$fyKgDfLMY;0i*)5I%veAP(g7Y zErzHF;d$^J$RcP8);Bw@LyvuF7Me-o<#|+=IjXgY9%$m6Pm( z#ZA0Mt1ZIGe*9Ee#vV)%NyZvzNCeb+0qO!*ME6ThE^Vz{C3& zD!lXO?;q9V_W9YJ2hGplfBfAEy!BG{4f_6P)4}*RpB%n^`QsnI5PyC9#c!{D^~RIa pgvEaN__I%|pHAC%{>J{@d;0_N_Ptjh)vf}Z-@Q2d`rQvd`5&Sef13aR literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_2_4.png b/resources/g2/track/boat_hire/small_turn_left_2_4.png new file mode 100644 index 0000000000000000000000000000000000000000..cc002b219e185b35ca700498e2071c5b146c3e28 GIT binary patch literal 925 zcmX9-L5SmI82x5CGwEy@f))*!LzEtZM9E@=h&eQ%fYIZa({3Xod8te{yPuvmUL%lXLonEQmO3i?d|XH9~>ND z7*?%T4-XHCMx()TtR#u5DjP=2vdnI`I~a)mNB>nZqml#YFYNkxM8s!=E*y1j`QZ&>SQ!}0Svee(^agzj{0b2x5#U>^e z_3_oDUMxtIv8d3|jfYU&08jvQ3^Q@uB}tE_eL=WXlzF?oa^36k7)24u)f*zgDwLqp zO_R}F&hP|lBy|IMFjM`79;R)IC)s90P#M|aTc%|8l-^h$hh~_#aXLt{$$A^%BGgqN z+CVu#dl)|^np3(JiDshp*Os4qF}hTky1|onlj&>1#E@o|nsklT(AosuJQ{A30BvHt z&eM#>@oiDERkd#zBio+#`_XuugyDL*%<~)pX#zdOxCt)JNOi%q*HUlO@-usud&^>) z-K@5##^5+l5KXF~GOQs8maO#jQp}n52lL4^jgw+6f-Ym0in}`Hb(oPO20e8)YR?0A z6^*i0Tol(x1keC101qGlm;-DuKqV9jITi|hl&%ySOb!MjgiS~lKq?@UKz$DR3JN=D z(L<>ZPlD$`mOxXmjzPFKGw_-d-}XRA$jD?Vf_{I-|{o z9}Sl{S_A16a%nW;P$;5AF3ZoqTKnh84}A9E zOog}p{QcvS$fw6|KdhdA^tJr#)$QsX3tb<)YkznCjZ*w^`|9GSdv8wO|D^Kk#rN5B z_E#t5y&s-&{(9x{-!J38eS7}+^%{|XdbMYMxcl$tuf6djcJaLV=)d=Vd8w3z)4ONK JKi_%u#s7BdhtvQ7 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_2_5.png b/resources/g2/track/boat_hire/small_turn_left_2_5.png new file mode 100644 index 0000000000000000000000000000000000000000..4ccd46e620308b586036fff0fb04d1c08d7f633c GIT binary patch literal 959 zcmXAoL5SmY6vp37XC^aK)(&(bVi=?J5HM(z9D?K!HM7kX!5 z@tv;RAEfU8(IW&Pes*D#;N{vA`>|q;VBp)LU|^r}jMEi_9=?NAv!48RP`W zD}YylYyf3rTn{e}s7fH{QQ4Xr&cY7SiA?7;j;I%DtIYQ`(KnQ+sZBb@%xx}$&N6b* zEX?IOiY~KURS@fnVrg2pULROi(CbB>Hyw``ivve z$jGaqQ47TmoCnW=BtlunY8r0V>9$?$JDTq|qsX1lBb2g;DzJ^LVB@kwsvf1syuGNn zN!?#|MrYm>O%_xhI1(!|xr#v66t+>7Y_sOHP2X)tp*xR5luS8ELLQ(P5K6OXrML$o znvL#k#&tUnWQ;~)rJ~eoTBD(}Op{|e0_%!wATeW^o|g+qC6P&?E{i+?MN)eF+>_Zq z&wt>ZqXPw=`}N*ysd;mM@A=ZhH{QQ~<)LpL+Z5~Qbo=6eFMj;g?aOB$9uF>l`|j@D zgX>2>zp<13jeF(RC;IO3mrr~?y8q10JFoxo5%q=r-p$`X`0Iy9OLu;}y`uXozuc#f z$KkbScT1lVM^C?u4-c>W`_uPVZ~27vb@I3V_FFeTyZ2A@T?&T%O9y*jz3}R_{{iZ@ Bo*DoE literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_2_6.png b/resources/g2/track/boat_hire/small_turn_left_2_6.png new file mode 100644 index 0000000000000000000000000000000000000000..39d6860e3087495e64fe72baa1cf9c7802ad0501 GIT binary patch literal 982 zcmX9-QHa}g82|2icez`46fLf>K13)OF}geimWSZt%x(3ET+Yj&LI#-&*g+qHWUj-4 z5v!I_W*ikO_Mx~a6(TF_kO&0>3#?$pY%5qXNFNI3;k*kHrOG}0%`y0W-^cIe`~Bee zeK)qZitEQt9s_{&%~v*dl6fkr%xWs>-?rC314zO4s~65CbYWp(ad9z~N-ZrdEiW&x ztgK)dwz|5ywzifl6bdv=@jNF$z7`A{VPMT8ub2mggenK7 zg!MGcZDuCDY&^=NkV3J74o!r-0)PmhV3?N482P+O5EjesisG#6DkE#W)({(ArR!*pZ+Jn=4|~(O zo8cfUL9PsV4G0rsy18PXkX=smOUTl2Tb#7sQ5=EUWdKtzoYpcz!(PKoKxq$`}f6R>)3` zvm4T&Qy$vJ#O;I=FOK&R2T%gg0ZafJUX&xWen_=@7ZDCp?Jy&0&)NafKZY} zBawTIe7)A0&6rO6G4#=hmu0C^QEN4grs@pU=4hLzU4a^lWLPR71xE&fIy7=P;{9*(X1I`gm&l!1(>qR|oIPm;UzOJDom# z=JI)&Jb&Z4f39AVHZje^!2o$4!4^vb z&d4OMQe~a4n5<^;Mqg|>Qg^J_f$Byzk|UUMiC1VzM02Y7)um>>30A-Lx)HIM|qi7;iptH~wz%4^015yC# zIO?#-mXTXWK^sLjJPMuzNrZ}w)ivB~&|RxMw6*cL6^71i7NSgxr~%u|3l=Whr0P<7 z#9K+#NgLy%UU2NjXp&Gx;7F{@6siJQSJ-Avvdp^OHOEdj^qpDcqcr9u3AunGKq$+i zoyk20(Q5XmQ?B283?m4{YE`M%wPsUinHI+{y1xE$0#xzxKpe^G{#B`0g6VAO4)X zDPLN@&fQMWP7dz-zupSIIQ`8tUw?Y>;X4N(ojN%9Da`%o#DDLw>CNDiSK`&%x9&as z?EV`U{`%qB=g(fhbN9i$GavN-x%(w?od5Uq)!K)z!}@#14Rq!0%kbS(SN?l*bM3dx P18i+>Z`^q4t@r;2;1{SA literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_3_2.png b/resources/g2/track/boat_hire/small_turn_left_3_2.png new file mode 100644 index 0000000000000000000000000000000000000000..09c5a72917896dbd46f6e7ca4cf423e4285fdf8b GIT binary patch literal 965 zcmXAoQHa}g9LIlmy}R7)*eVu{E@;N}A;Wk^$V1S$MVA}d5xH#3qz?fj1}xG+9wO$U z4-xy&Y0+?0C{kvTh(!ZdxPv?t%}E}L78c|VDrQ(+VFkyC+J`dk;cv#^`}_U)zWhE9 z-{0?}%RAD^6Q@rAz{%}PTUWDrHmk>1b6J1(r|X{q$uC^}4%bT(rd5O`4JbxkW& zDx_Uy>J7ftR=PdCA6mn>F`jrLjg|OyQ^uVV=^9kWV)trd*eVTsW-_Qx6K|eI5&=35 zwg9e*bxka65QIxn9?$P7%Ai~xInKRK2ZbTQ z7K#GSC?u~_l1Y~w)^K^NE!KRw*;l=x9wcRwBN(a3tF&xznkkxfrQXpyff>Y3lr-aM zcRUaC0u)rh%Rp9vaxt!hOFc>p1v4%+#+H}55!zGeg255CL^n!&*AV-b8rO_b%bNJL zG;GadA5EfsfuraW%asMuR@H`Kv~9cBXoQ_k90cRT!!%715GGJ9jP2&dKA{fj@>r}- zG;eD6Q}=Mzn;wtmXr0dIIUJYBqDnIc&s(xm*Ry5SUZXka_L3-`jRnwU%u@4?PP!Gk zT^0Pg+HaQ!zB3Bj(@`{=-9rLE3BUqy0epY~zyt%7NfA-iLcWKRkwSsVLQ{Z1f;x(PV-;5)FnnY+e=42TKfD%9` z%c7p)9*L+`+mi{`ZatDU9EzHzRw_odYO+j?V_E|1i)<(}hYCF{6_HLNheB-@1p`~1O`>%Uw$Gy3$0t@HbP zVBc;wzkTl3{LWV|?;ih}hWCHZzp!!s&ME5d&wsp+fBfc|1NNWA$*s44{Q79=L57Fz Ni#uE2U3lxm{{a%BpH2V( literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_3_3.png b/resources/g2/track/boat_hire/small_turn_left_3_3.png new file mode 100644 index 0000000000000000000000000000000000000000..03dbb819c248002095017f6afadaf90255e20ec5 GIT binary patch literal 864 zcmX9-KZvV#9RJ?s?##XL>X1RGgU}2PQXGUjIM~*E*u!!@o(~)xEJ&LngM)<(4ni&1 z;@}X9lnfahG6+rK1_uWR3!!9i$dH0VD1l0OgDnmz-0-W%gU|OLANYQT&-eS|>j(Me ziw|D_z{~qD?%wqEqL0CF(C4oQKmFSG@cPTQubzpEi_6Q)!C-K8b#;AxeRFezVc2ju zyuH08CX)%rv63Wenqpaouu1~$+<0M5=;i>B19Utwy`3_59@Ka zBT>Vm&O}cULgfTN1u!wp#&M4%BbrVG;Zaq$)9JzU-mO-sC`fKR5eZhM1e2C+M)x=? z5}c*vr^+JNlAW2=Q;H{9c_L_xV)2G8*?}6Y%vEM*l~>k_s#zb;1unu^17Zr43v`6> zD?;ATMj_gj9v+>fjY{;WGGmJ;=Q0!O!rGE@N2`465Id*TZ;SX`rRY@RW1ePoj-QIs zT+>3!TF&R2Ff3N9D$9=hecQGONE_%F z03E;qhyYT6Ex-u_)I*h!>!372^+Bb<=3pU0CPS?P(g4{63OSUhD4U^Ofa(OEjpsp; zKv%JuMR;>&5y|Vs%5%S}(x$0UuSHIQb4OxCs0n3ev|S5PYoy&gKgYYL?1&C6JqDh_ zWEM9>YNm1SREfM;$)QX{mC_$S|MBSG=O6g?&4UJ?{`JQ<{qVv4 m-DhuyKU@F({?Fo15{AEB{{8(&KYY?NaR2Jz?w8NM`tE-Md29p# literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_3_4.png b/resources/g2/track/boat_hire/small_turn_left_3_4.png new file mode 100644 index 0000000000000000000000000000000000000000..71eddb8b89ca68746222b09d5a277234b605f249 GIT binary patch literal 897 zcmX9-F^J@36n?X_yP3V=h%iOa6e$J_8YDuH6e;3ec8N=5b6gHnq=*o>DW(XRlN2Ka zOc5kSgee9YaKs=Z1{`FI6jP)~G2j#dr>fPEUUWaSP%tJm9Am*hC|97u|X(I zrs{lQE;DCcgu8t#F_OY2oGNxH!yr#|#&trvWhl zY6NtI@iRhR&_*WOg&yvlxQcRgt1>-{CtaBdbzyEvOGhhwYddlFiC<-tW09bJj`w() z(K&t~O0K4bmNj+VMHptYS&^o@&8Dg<1f&i01motov?R4PGuTPN-iQzGvWhnK;&8V; zqAr8uJVD4*Ut?HH5FAAf%x2kW5sp{$MVS}%P6SiI91ZtODjG7=k(dP9aynQg-Zq;a zws~E@LLz_;-~dDb3BU?qj{$0+N@(PuBu3>{rNQQ4EJ7+nsRGgf*#rtX6sss5qIH1E z8194TL6JaLv7tqHE;Ekgd2B70eo-WcLxCDEasb?@D@KGGQ)Wurr4Us{QoGCJWPO+J z(6*v`z*Csa;)X~KHEuLeB5xRvy=5{k^5jtFsNV64f>J;wAk<_LG z;jGt^VQ9mlH5%C*>+|eH3VAe|awrv1p)|+Ozt{cm{s&$>z0u&q zzg|9X1bcn?=vn8R&wu@;1@CuG9vw~n``@mA?1ke$`ky^^|M}PIzWm~Yum235zw_?z bpA1{yz4`XH)eqYJC|qCNT>kv{(=Y!AGR%8( literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_3_5.png b/resources/g2/track/boat_hire/small_turn_left_3_5.png new file mode 100644 index 0000000000000000000000000000000000000000..14c0febc5e633963d3fb4b862710599f78c9587e GIT binary patch literal 968 zcmX9-QHa}g82|3tyYyB@(IWMhhrp@?37Sd7AbE(Io86gl8Oxv#5i*F_hk`*PR>&k^ z=duwcLQksnp$`Fzi>%;11S}dP;2|C4p^OT_6|Jtq@TvqYcn^Ow2EXt7_`Q6;AN;=W z#)ZAw$rGne0Km!Jb2}HaS+88(E}zeDY;0_9 zZekc#C=|A~wkp+Xm0@T>;AL6VG{rFVcDvo}_J_kDiY7_2OjCvio&!lNDoVN8Bw8kI zJ6yLX4TkC{G{&(rn|lI<)w!ZBR;)VVYGmJF4%$N4t&fL#a%e9SZ?%kSIH(k~cyMKG zpktv^nhwh87)J{lr7Ajh5sIn+5`ciOOo)#n^tOHYAmh*WK8gswB47;n? zNAsvuW=X2funk^l$+Dwqy;f`JIAOmZ2f=JISuU3da2?1l#tcfr2$#oHV2Ma^g7na@5GV6NFtQZSW!d)pac-gvamC` zhrrurZ$4*x-G?y7V?j~mW>YgwouS(--Q^iyU_z0eNYtWUMJjG4lL{)Br}c(#yx|HCUs)(^KYUp@28U1NLy^gefe zI#1zw+@@!uLPl;{Utz&%M9)+0X6o-n{+R+H+UleuN@_Jjxuv?%BPa JTQ6V!;D0mgpb!86 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_3_6.png b/resources/g2/track/boat_hire/small_turn_left_3_6.png new file mode 100644 index 0000000000000000000000000000000000000000..9fc72c2f0fece3012d4d5de31716427b53d9db3e GIT binary patch literal 979 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_4_3.png b/resources/g2/track/boat_hire/small_turn_left_4_3.png new file mode 100644 index 0000000000000000000000000000000000000000..38241ff3ae0482ba840fbc6b4ebf301edae876ee GIT binary patch literal 941 zcmX9-L5SmI82x72nRKS^_E4m14iUPTLy#;64MPsuHM7*&$YkBjQZ#6m4O*c}4pDn3 z7_f)91PxN8NL&gAsSvct9Kup1LJmC?$wCiZ2+~7ga~LoyJye;)ZFP z?v3Ndh5Z-y0pP;X8;3V@zLXDED&)KQhvMg$vVi;wsxw0nwHBs%HXNcb#F=WHuhA00 zsboW^nkJ(;oZ$*RU+hn0Z>9!Gi(qlOQRiez)L2CqbW5^^>M+oQ*o=~XoQ{^8u);%C zhFS}VE|3n!4r`4usf4^9H|?e2Wln@nC90~ic&9U$K6GM)B+G1d={9YCgHnERZ zQKia~RFh#_ywH(lThrW5XKdTya2N-{az4+p3<0hKIl!1vMVR37jA|_fYo&N;XOcPd z^*B9WY*3l1RM=XrLDXf6);P`(B}>hZb;ovpIvOWYyk7F4ikKl+OqFojl-uQfOP;u` zsc$YqH(f;Q^%>&x0st5Q4uB6Z1z2H#a!3N|8p!uhvXDs78R+v6G$4@x$$<14vKiz_ zC}^XZg%S^*1kZvfKvTlnTFvZGeWx+q|3jT`-hF)X>-AUf6$@v@XAiD?x_|$} z_bzIGJ%4BPbNrqD;PRIb?^%C-b=$hUC;#@~o<~8@Nzpu~kU-~H3es|wF_>7xo fw{CrY@-OWCc-Q>l;H95(8#ualeE7@jx4-xwXBLj# literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_4_4.png b/resources/g2/track/boat_hire/small_turn_left_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..6f19fdf62a9b32a3d74792fcbb5b041d6d6dccb6 GIT binary patch literal 918 zcmX9-L5SmI6n-_}+VbJovuD_uecX0hx(m<#P%j#A`-8jZH9a^uI6ORTG#W=oN5{vP^8A&eEPB1Q>pq%JQJNBLrz_x$Lh=SB zS+wS|X29DMaTv*?L=BflT=YneV5Bau(z40vmS}m3H#MfQ73XeNjPl)VvrpRsbX355 zKsrDL7&pbGIi;t9m23XS4$B}zR|?%RIbtBuzQ)f?F|pNrXs*ZhHX4@cc%MgTo3%R} zMQbeA6U2e4`ldM<4CcO{PN#VsZ&s_aED;bEP-BdpwZ()`mvnC4Ymh;oo;X6}smY|bh}?BL z*{!pxdV~Z34ZsEn03v_|z!n2kLlKc3>b#I$vR?5nKPlLNOOj@%>~!b zod*+sUYi9qU^8VMqt{%SmR_oL}cnpV>`&8QPMJp6w(qfV#FM>HM>mLted5&4LFCi1|4vyIYgO5 z(17DImN`TnWS}F=A%{5xoWddjhY~R0LI;U<4^ubFR7Q6STMQC#4=enp6u$Q!-{pND zeDB@d+AN(s@%#w@IJtgl^>Q{ZWcAEqF6-Z&S%?90u(fezEu%9tGqba^xm<2;Zf<^l zeqmt&!?4B0#igaCLa|t6Sw<8EMUiy9Y??;BUT?R%{k|WDdvTnkDa(MsgDfqV%lT@R ztXWK>$+tUludfXPa~L(p6IY}$m0vcbf~}H{PIXOor!EFyeY{IEn8;wo2}hmKMtdGEPy6qrh?lV=~U^C zC3p>G(5dWt_9*B~M`4;CA^|`JFaaC@4`3Hyf&t1Pi^wvO=c0HdQ(&;r62LD(ECW&i z83oj2kt-v=iiQmoyYM)84kQs&8LR3AyGFO1QqR=~gL)Ks(`keW+ z$Io3@{^#)ze0X_Nft7>%?`7ok_0@}4&VBjyR~MfS&pb7kqU4=q-{0RleRjV6_jb;G z7c}+7|L$wo*`MB`Fa3CLh2>6t@!Jn?L~q_aIQ8$NYs0(eKiOJYyDHuJga7P(>(1%l z&*CpUpt&2?YtKzTxc$o91MSvd*7nS^?yt8GzggIM`R7|3&Jy|YOXq*t|7hE(P!H{c eM;q7w%-v{x|Msg_ANDg(u)emr`t9r2KK&oVlcvM~ literal 0 HcmV?d00001 diff --git a/resources/g2/track/boat_hire/small_turn_left_4_6.png b/resources/g2/track/boat_hire/small_turn_left_4_6.png new file mode 100644 index 0000000000000000000000000000000000000000..6971d8df5cebfa619aec1686bf5806c7c856c0b2 GIT binary patch literal 955 zcmXAoL1^1{6vkiTBywsxkNMy+9n|837@}2+wyB_jnkbnTRH9I|c$pb02xc}P1k=D9 zrl{20OwmCHGkoxfp*na>FdqUFn;1F>7KYeVmV*l#xL~L^0ujS7m*w!EO5uC&@m=2U z@V)n7Z&y5j?zM9OaDM0At((~-vU(|>%lec5*f#-kuy^Cuc4n8BmX?>7bGh8g%F62M z>e|{GhGF@9etmttT&YwTh86@~Q6x>P8HV0&w|l+8Xyk?AagwC-IYR@_fh-kjwNj%& zG+T7X;(C2~I8yzub4FiiyHeLzoJjSOI>F+!Sm6{((%70V=pDH;PzRpw#b%gvv*Nf1f78{51t5#3`hZ_ zmyyLFM@C))MIDql@H}`HBmt^2*3imklj_>y(9wLq9mno$7Nd-X*MVsjc)Kh+gzAxc z!r5ufoj3hOFFNxkXq=KIUDckS8kP$^ft)?^@TC1fqbepAnJmU&XAkoJ%HLF&TN+6R&eFk|vilyxM z*-M3gp8vq7H+L1d{`B#OnfYjEYvb0dU*CPS@yfjm`PIGD{NPE>zxT}_zdn-=9$t9| z|2ujpezkva;jh!T_ka8Iz5A^F(~aN1J-z(#>DuGy`togcpOSzq$uTi5o@e?L3>{6V~U|7Z9?w4QC=-oBVYVP|`H>-)_+_x}eM0hopW literal 0 HcmV?d00001 diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 48ac7304ca..881a2c5c0f 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -49,7 +49,7 @@ using namespace OpenRCT2; // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -constexpr uint8_t kNetworkStreamVersion = 5; +constexpr uint8_t kNetworkStreamVersion = 6; const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion); diff --git a/src/openrct2/paint/track/water/BoatHire.cpp b/src/openrct2/paint/track/water/BoatHire.cpp index 022b8dedb4..516ebc36a6 100644 --- a/src/openrct2/paint/track/water/BoatHire.cpp +++ b/src/openrct2/paint/track/water/BoatHire.cpp @@ -12,6 +12,7 @@ #include "../../../ride/Ride.h" #include "../../../ride/Track.h" #include "../../../ride/TrackPaint.h" +#include "../../../sprites.h" #include "../../Paint.h" #include "../../tile_element/Segment.h" #include "../../track/Segment.h" @@ -139,6 +140,1095 @@ static void PaintBoatHireTrackRightQuarterTurn1Tile( session, ride, trackSequence, (direction + 3) % 4, height, trackElement, supportType); } +static void PaintBoatHireTrackLeftQuarterTurn3Tiles( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 1)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 6)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 7)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 12)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 13)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 18)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 19)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + } + break; + case 1: + switch (direction) + { + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 8)), + { 0, 0, height }, { { 16, 16, height }, { 1, 1, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 21)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 2)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 3)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 9)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 14)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 15)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 20)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + break; + } + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 4)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 5)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 10)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 11)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 16)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 17)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 22)), + { 0, 0, height }, { { 6, 0, height }, { 26, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 23)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 26, 32, 0 } }); + break; + } + break; + } + + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 16); +} + +static void PaintBoatHireTrackRightQuarterTurn3Tiles( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapLeftQuarterTurn3TilesToRightQuarterTurn3Tiles[trackSequence]; + PaintBoatHireTrackLeftQuarterTurn3Tiles( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} + +static void PaintBoatHireTrackLeftQuarterTurn5Tiles( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 1)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 10)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 11)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 20)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 21)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 30)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 31)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 2)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 3)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 12)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 13)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 22)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 23)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 32)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 33)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); + break; + } + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 4)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 5)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 14)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 15)), + { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 24)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 25)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 34)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 35)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 32, 0 } }); + break; + } + break; + case 5: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 6)), + { 0, 0, height }, { { 16, 0, height }, { 16, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 7)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 32, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 16)), + { 0, 0, height }, { { 0, 0, height }, { 16, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 17)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 32, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 26)), + { 0, 0, height }, { { 0, 0, height }, { 16, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 27)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 32, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 36)), + { 0, 0, height }, { { 16, 0, height }, { 16, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 37)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 32, 0 } }); + break; + } + break; + case 6: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 8)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 9)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 18)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 19)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 28)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 29)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 38)), + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 39)), + { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); + break; + } + break; + } + + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 16); +} + +static void PaintBoatHireTrackRightQuarterTurn5Tiles( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = kMapLeftQuarterTurn5TilesToRightQuarterTurn5Tiles[trackSequence]; + PaintBoatHireTrackLeftQuarterTurn5Tiles( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} + +static void PaintBoatHireTrackLeftEighthToDiag( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 1)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 8)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 9)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 18)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 19)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 26)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 27)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 2)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 3)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 10)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 11)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 20)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 21)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 28)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 29)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 4)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 5)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 12)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 13)), + { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 22)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 23)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 30)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 31)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + } + break; + case 3: + switch (direction) + { + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 14)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 15)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + } + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 6)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsChildRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 7)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 16)), + { 0, 0, height }, { { 0, 16, height }, { 16, 18, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 17)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 24)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 25)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 32)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 33)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); + break; + } + break; + } + + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 16); +} + +static void PaintBoatHireTrackRightEighthToDiag( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 34)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 35)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 42)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 43)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 50)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 51)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 60)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 61)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 36)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 37)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 44)), + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 45)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 52)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 53)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 62)), + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 63)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 38)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 39)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 46)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 47)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 54)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 55)), + { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 64)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 65)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); + break; + } + break; + case 3: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 56)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 57)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + } + break; + case 4: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 40)), + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 41)), + { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 48)), + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 49)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 58)), + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 59)), + { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 66)), + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 67)), + { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); + break; + } + break; + } + + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 16); +} + +static void PaintBoatHireTrackLeftEighthToOrthogonal( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + PaintBoatHireTrackRightEighthToDiag( + session, ride, trackSequence, DirectionReverse(direction), height, trackElement, supportType); +} + +static void PaintBoatHireTrackRightEighthToOrthogonal( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + trackSequence = mapLeftEighthTurnToOrthogonal[trackSequence]; + PaintBoatHireTrackLeftEighthToDiag( + session, ride, trackSequence, DirectionPrev(direction), height, trackElement, supportType); +} + +static void PaintBoatHireTrackDiagFlat( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 2), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 0), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 1), + { -16, -16, height }, { { -16, -16, height + 15 }, { 32, 32, 0 } }); + break; + } + break; + case 2: + switch (direction) + { + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 0), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 1), + { -16, -16, height }, { { -16, -16, height + 15 }, { 32, 32, 0 } }); + break; + } + break; + case 3: + switch (direction) + { + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 2), + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + break; + } + break; + } + + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 16); +} + +static void PaintBoatHireTrackSBendLeft( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 1)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 8)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 9)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 6)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 7)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 14)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 15)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 2)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 3)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 10)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 11)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 4)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 5)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 12)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 13)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 4)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 5)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 12)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 13)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 2)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 3)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 10)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 11)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + } + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 6)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 7)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 14)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 15)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 0)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 1)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 8)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 9)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + } + break; + } + + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 16); +} + +static void PaintBoatHireTrackSBendRight( + PaintSession& session, const Ride& ride, uint8_t trackSequence, Direction direction, int32_t height, + const TrackElement& trackElement, SupportType supportType) +{ + switch (trackSequence) + { + case 0: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 16)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 17)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 24)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 25)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 22)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 23)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 30)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 31)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + } + break; + case 1: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 18)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 19)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 26)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 27)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 20)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 21)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 28)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 29)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + } + break; + case 2: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 20)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 21)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 28)), + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 29)), + { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 18)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 19)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 26)), + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 27)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); + break; + } + break; + case 3: + switch (direction) + { + case 0: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 22)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 23)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 1: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 30)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 31)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 2: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 16)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 17)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + case 3: + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 24)), + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + PaintAddImageAsParentRotated( + session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 25)), + { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); + break; + } + break; + } + + PaintUtilSetSegmentSupportHeight(session, kSegmentsAll, 0xFFFF, 0); + PaintUtilSetGeneralSupportHeight(session, height + 16); +} + /** * rct2: 0x008B0D60 */ @@ -158,6 +1248,41 @@ TRACK_PAINT_FUNCTION GetTrackPaintFunctionBoatHire(OpenRCT2::TrackElemType track return PaintBoatHireTrackLeftQuarterTurn1Tile; case TrackElemType::RightQuarterTurn1Tile: return PaintBoatHireTrackRightQuarterTurn1Tile; + + // Added by OpenRCT2 + + // Small turns + case TrackElemType::LeftQuarterTurn3Tiles: + return PaintBoatHireTrackLeftQuarterTurn3Tiles; + case TrackElemType::RightQuarterTurn3Tiles: + return PaintBoatHireTrackRightQuarterTurn3Tiles; + + // Medium turns + case TrackElemType::LeftQuarterTurn5Tiles: + return PaintBoatHireTrackLeftQuarterTurn5Tiles; + case TrackElemType::RightQuarterTurn5Tiles: + return PaintBoatHireTrackRightQuarterTurn5Tiles; + + // Large turns + case TrackElemType::LeftEighthToDiag: + return PaintBoatHireTrackLeftEighthToDiag; + case TrackElemType::RightEighthToDiag: + return PaintBoatHireTrackRightEighthToDiag; + case TrackElemType::LeftEighthToOrthogonal: + return PaintBoatHireTrackLeftEighthToOrthogonal; + case TrackElemType::RightEighthToOrthogonal: + return PaintBoatHireTrackRightEighthToOrthogonal; + + // Diagonal + case TrackElemType::DiagFlat: + return PaintBoatHireTrackDiagFlat; + + // S bends + case TrackElemType::SBendLeft: + return PaintBoatHireTrackSBendLeft; + case TrackElemType::SBendRight: + return PaintBoatHireTrackSBendRight; + default: return nullptr; } diff --git a/src/openrct2/park/Legacy.cpp b/src/openrct2/park/Legacy.cpp index 4a5c34cb23..0105374d4c 100644 --- a/src/openrct2/park/Legacy.cpp +++ b/src/openrct2/park/Legacy.cpp @@ -2635,6 +2635,26 @@ bool TrackTypeMustBeMadeInvisible(ride_type_t rideType, OpenRCT2::TrackElemType break; } } + else if (rideType == RIDE_TYPE_BOAT_HIRE && parkFileVersion < kExtendedBoatHireVersion) + { + switch (trackType) + { + case TrackElemType::LeftQuarterTurn3Tiles: + case TrackElemType::RightQuarterTurn3Tiles: + case TrackElemType::LeftQuarterTurn5Tiles: + case TrackElemType::RightQuarterTurn5Tiles: + case TrackElemType::LeftEighthToDiag: + case TrackElemType::RightEighthToDiag: + case TrackElemType::LeftEighthToOrthogonal: + case TrackElemType::RightEighthToOrthogonal: + case TrackElemType::DiagFlat: + case TrackElemType::SBendLeft: + case TrackElemType::SBendRight: + return true; + default: + break; + } + } return false; } diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index 5d9a6d3ad5..1eb787d3f5 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -11,7 +11,7 @@ namespace OpenRCT2 struct GameState_t; // Current version that is saved. - constexpr uint32_t PARK_FILE_CURRENT_VERSION = 45; + constexpr uint32_t PARK_FILE_CURRENT_VERSION = 46; // The minimum version that is forwards compatible with the current version. constexpr uint32_t PARK_FILE_MIN_VERSION = 45; @@ -34,6 +34,7 @@ namespace OpenRCT2 constexpr uint16_t kWoodenRollerCoasterMediumLargeHalfLoopsVersion = 41; constexpr uint16_t kExtendedCorkscrewCoasterVersion = 42; constexpr uint16_t kExtendedTwisterCoasterVersion = 43; + constexpr uint16_t kExtendedBoatHireVersion = 46; } // namespace OpenRCT2 class ParkFileExporter diff --git a/src/openrct2/ride/rtd/water/BoatHire.h b/src/openrct2/ride/rtd/water/BoatHire.h index cafff1d78f..8f78ac2d38 100644 --- a/src/openrct2/ride/rtd/water/BoatHire.h +++ b/src/openrct2/ride/rtd/water/BoatHire.h @@ -22,7 +22,7 @@ constexpr RideTypeDescriptor BoatHireRTD = .StartTrackPiece = OpenRCT2::TrackElemType::EndStation, .TrackPaintFunctions = TrackDrawerDescriptor({ .Drawer = GetTrackPaintFunctionBoatHire, - .enabledTrackGroups = {TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::curveVerySmall}, + .enabledTrackGroups = {TrackGroup::straight, TrackGroup::stationEnd, TrackGroup::curveVerySmall, TrackGroup::curveSmall, TrackGroup::curve, TrackGroup::curveLarge, TrackGroup::sBend}, .extraTrackGroups = {}, }), .InvertedTrackPaintFunctions = {}, diff --git a/src/openrct2/sprites.h b/src/openrct2/sprites.h index daa0909219..fe29f564f8 100644 --- a/src/openrct2/sprites.h +++ b/src/openrct2/sprites.h @@ -1494,9 +1494,17 @@ enum : ImageIndex SPR_G2_FLUME_60_25_NW_SE_BACK_WATER, SPR_G2_FLUME_60_25_NW_SE_BACK, + SPR_G2_BOAT_HIRE_BEGIN, + SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE = SPR_G2_BOAT_HIRE_BEGIN, + SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE = SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 24, + SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE = SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 40, + SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL = SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 68, + SPR_G2_BOAT_HIRE_TRACK_S_BEND = SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 3, + SPR_G2_BOAT_HIRE_END = SPR_G2_BOAT_HIRE_TRACK_S_BEND + 32, + // G2 Supports - SPR_G2_SUPPORT_WOODEN_TRUSS, + SPR_G2_SUPPORT_WOODEN_TRUSS = SPR_G2_BOAT_HIRE_END, SPR_G2_SUPPORT_WOODEN_MINE = SPR_G2_SUPPORT_WOODEN_TRUSS + 32, SPR_G2_SUPPORT_END = SPR_G2_SUPPORT_WOODEN_MINE + 32, From 46eb48fb98a743fe3078e604dc175fb78bbe4598 Mon Sep 17 00:00:00 2001 From: mix Date: Mon, 2 Dec 2024 08:40:04 +0000 Subject: [PATCH 138/139] Fix Boat Hire visual glitches whilst building --- src/openrct2/paint/track/water/BoatHire.cpp | 214 ++++++++++---------- 1 file changed, 107 insertions(+), 107 deletions(-) diff --git a/src/openrct2/paint/track/water/BoatHire.cpp b/src/openrct2/paint/track/water/BoatHire.cpp index 516ebc36a6..54e47278bc 100644 --- a/src/openrct2/paint/track/water/BoatHire.cpp +++ b/src/openrct2/paint/track/water/BoatHire.cpp @@ -95,21 +95,21 @@ static void PaintBoatHireTrackLeftQuarterTurn1Tile( { case 0: imageId = session.TrackColours.WithIndex(SPR_BOAT_HIRE_FLAT_QUARTER_TURN_1_TILE_BACK_SW_NW); - PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 0 } }); + PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 1 } }); imageId = session.TrackColours.WithIndex(SPR_BOAT_HIRE_FLAT_QUARTER_TURN_1_TILE_FRONT_SW_NW); PaintAddImageAsParent(session, imageId, offset, { { 28, 28, height + 2 }, { 3, 3, 3 } }); break; case 1: imageId = session.TrackColours.WithIndex(SPR_BOAT_HIRE_FLAT_QUARTER_TURN_1_TILE_BACK_NW_NE); - PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 0 } }); + PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 1 } }); imageId = session.TrackColours.WithIndex(SPR_BOAT_HIRE_FLAT_QUARTER_TURN_1_TILE_FRONT_NW_NE); PaintAddImageAsParent(session, imageId, offset, { { 28, 28, height + 2 }, { 3, 3, 3 } }); break; case 2: imageId = session.TrackColours.WithIndex(SPR_BOAT_HIRE_FLAT_QUARTER_TURN_1_TILE_BACK_NE_SE); - PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 0 } }); + PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 1 } }); imageId = session.TrackColours.WithIndex(SPR_BOAT_HIRE_FLAT_QUARTER_TURN_1_TILE_FRONT_NE_SE); PaintAddImageAsParent(session, imageId, offset, { { 28, 28, height + 2 }, { 3, 3, 3 } }); @@ -119,7 +119,7 @@ static void PaintBoatHireTrackLeftQuarterTurn1Tile( PaintAddImageAsParent(session, imageId, offset, { { 28, 28, height + 2 }, { 3, 3, 3 } }); imageId = session.TrackColours.WithIndex(SPR_BOAT_HIRE_FLAT_QUARTER_TURN_1_TILE_BACK_SE_SW); - PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 0 } }); + PaintAddImageAsParent(session, imageId, offset, { { 0, 0, height }, { 32, 32, 1 } }); break; } @@ -152,7 +152,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 0)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 1)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -160,7 +160,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 6)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 7)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -168,7 +168,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 12)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 13)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -176,7 +176,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 18)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 19)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -189,7 +189,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 8)), - { 0, 0, height }, { { 16, 16, height }, { 1, 1, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 1, 1, 1 } }); break; case 3: PaintAddImageAsParentRotated( @@ -204,7 +204,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 2)), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 3)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); @@ -217,7 +217,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 14)), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 15)), { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); @@ -225,7 +225,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 20)), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 1 } }); break; } break; @@ -235,7 +235,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 4)), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 5)), { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); @@ -243,7 +243,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 10)), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 11)), { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); @@ -251,7 +251,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 16)), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 17)), { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); @@ -259,7 +259,7 @@ static void PaintBoatHireTrackLeftQuarterTurn3Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 22)), - { 0, 0, height }, { { 6, 0, height }, { 26, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 26, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_SMALL_CURVE + 23)), { 0, 0, height }, { { 6, 0, height + 15 }, { 26, 32, 0 } }); @@ -293,7 +293,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 0)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 1)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -301,7 +301,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 10)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 11)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -309,7 +309,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 20)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 21)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -317,7 +317,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 30)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 31)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -330,7 +330,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 2)), - { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 3)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); @@ -338,7 +338,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 12)), - { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 13)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); @@ -346,7 +346,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 22)), - { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 23)), { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); @@ -354,7 +354,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 32)), - { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 33)), { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); @@ -367,7 +367,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 4)), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 5)), { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); @@ -375,7 +375,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 14)), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 15)), { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); @@ -383,7 +383,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 24)), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 25)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); @@ -391,7 +391,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 34)), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 35)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 32, 0 } }); @@ -404,7 +404,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 6)), - { 0, 0, height }, { { 16, 0, height }, { 16, 32, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 7)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 32, 0 } }); @@ -412,7 +412,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 16)), - { 0, 0, height }, { { 0, 0, height }, { 16, 32, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 17)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 32, 0 } }); @@ -420,7 +420,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 26)), - { 0, 0, height }, { { 0, 0, height }, { 16, 32, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 27)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 32, 0 } }); @@ -428,7 +428,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 36)), - { 0, 0, height }, { { 16, 0, height }, { 16, 32, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 37)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 32, 0 } }); @@ -441,7 +441,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 8)), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 9)), { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); @@ -449,7 +449,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 18)), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 19)), { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); @@ -457,7 +457,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 28)), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 29)), { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); @@ -465,7 +465,7 @@ static void PaintBoatHireTrackLeftQuarterTurn5Tiles( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 38)), - { 0, 0, height }, { { 6, 0, height }, { 20, 32, 0 } }); + { 0, 0, height }, { { 6, 0, height }, { 20, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_MEDIUM_CURVE + 39)), { 0, 0, height }, { { 6, 0, height + 15 }, { 20, 32, 0 } }); @@ -499,7 +499,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 0)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 1)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -507,7 +507,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 8)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 9)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -515,7 +515,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 18)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 19)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -523,7 +523,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 26)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 27)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -536,7 +536,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 2)), - { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 3)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); @@ -544,7 +544,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 10)), - { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 11)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); @@ -552,7 +552,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 20)), - { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 21)), { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); @@ -560,7 +560,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 28)), - { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 29)), { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); @@ -573,7 +573,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 4)), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 5)), { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); @@ -581,7 +581,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 12)), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 13)), { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); @@ -589,7 +589,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 22)), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 23)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); @@ -597,7 +597,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 30)), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 31)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); @@ -610,7 +610,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 14)), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 15)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); @@ -623,15 +623,15 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 6)), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 1 } }); PaintAddImageAsChildRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 7)), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 1 } }); break; case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 16)), - { 0, 0, height }, { { 0, 16, height }, { 16, 18, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 16, 18, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 17)), { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); @@ -639,7 +639,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 24)), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 25)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); @@ -647,7 +647,7 @@ static void PaintBoatHireTrackLeftEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 32)), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 33)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); @@ -672,7 +672,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 34)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 35)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -680,7 +680,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 42)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 43)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -688,7 +688,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 50)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 51)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -696,7 +696,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 60)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 61)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -709,7 +709,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 36)), - { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 37)), { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); @@ -717,7 +717,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 44)), - { 0, 0, height }, { { 0, 16, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 45)), { 0, 0, height }, { { 0, 16, height + 15 }, { 32, 16, 0 } }); @@ -725,7 +725,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 52)), - { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 53)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); @@ -733,7 +733,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 62)), - { 0, 0, height }, { { 0, 0, height }, { 32, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 63)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 16, 0 } }); @@ -746,7 +746,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 38)), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 39)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); @@ -754,7 +754,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 46)), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 47)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); @@ -762,7 +762,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 54)), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 55)), { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); @@ -770,7 +770,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 64)), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 65)), { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); @@ -783,7 +783,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 56)), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 57)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); @@ -796,7 +796,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 40)), - { 0, 0, height }, { { 16, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 41)), { 0, 0, height }, { { 16, 0, height + 15 }, { 16, 16, 0 } }); @@ -804,7 +804,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 48)), - { 0, 0, height }, { { 0, 0, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 49)), { 0, 0, height }, { { 0, 0, height + 15 }, { 16, 16, 0 } }); @@ -812,7 +812,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 58)), - { 0, 0, height }, { { 0, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 0, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 59)), { 0, 0, height }, { { 0, 16, height + 15 }, { 16, 16, 0 } }); @@ -820,7 +820,7 @@ static void PaintBoatHireTrackRightEighthToDiag( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 66)), - { 0, 0, height }, { { 16, 16, height }, { 16, 16, 0 } }); + { 0, 0, height }, { { 16, 16, height }, { 16, 16, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_LARGE_CURVE + 67)), { 0, 0, height }, { { 16, 16, height + 15 }, { 16, 16, 0 } }); @@ -863,7 +863,7 @@ static void PaintBoatHireTrackDiagFlat( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 2), - { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 1 } }); break; } break; @@ -873,7 +873,7 @@ static void PaintBoatHireTrackDiagFlat( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 0), - { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 1), { -16, -16, height }, { { -16, -16, height + 15 }, { 32, 32, 0 } }); @@ -886,7 +886,7 @@ static void PaintBoatHireTrackDiagFlat( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 0), - { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 1), { -16, -16, height }, { { -16, -16, height + 15 }, { 32, 32, 0 } }); @@ -899,7 +899,7 @@ static void PaintBoatHireTrackDiagFlat( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex(SPR_G2_BOAT_HIRE_TRACK_FLAT_DIAGONAL + 2), - { -16, -16, height }, { { -16, -16, height }, { 32, 32, 0 } }); + { -16, -16, height }, { { -16, -16, height }, { 32, 32, 1 } }); break; } break; @@ -921,7 +921,7 @@ static void PaintBoatHireTrackSBendLeft( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 0)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 1)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -929,7 +929,7 @@ static void PaintBoatHireTrackSBendLeft( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 8)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 9)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -937,7 +937,7 @@ static void PaintBoatHireTrackSBendLeft( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 6)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 7)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -945,7 +945,7 @@ static void PaintBoatHireTrackSBendLeft( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 14)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 15)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -958,7 +958,7 @@ static void PaintBoatHireTrackSBendLeft( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 2)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 3)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -966,7 +966,7 @@ static void PaintBoatHireTrackSBendLeft( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 10)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 11)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -974,7 +974,7 @@ static void PaintBoatHireTrackSBendLeft( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 4)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 5)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -982,7 +982,7 @@ static void PaintBoatHireTrackSBendLeft( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 12)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 13)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -995,7 +995,7 @@ static void PaintBoatHireTrackSBendLeft( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 4)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 5)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -1003,7 +1003,7 @@ static void PaintBoatHireTrackSBendLeft( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 12)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 13)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -1011,7 +1011,7 @@ static void PaintBoatHireTrackSBendLeft( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 2)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 3)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -1019,7 +1019,7 @@ static void PaintBoatHireTrackSBendLeft( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 10)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 11)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -1032,7 +1032,7 @@ static void PaintBoatHireTrackSBendLeft( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 6)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 7)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1040,7 +1040,7 @@ static void PaintBoatHireTrackSBendLeft( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 14)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 15)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1048,7 +1048,7 @@ static void PaintBoatHireTrackSBendLeft( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 0)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 1)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1056,7 +1056,7 @@ static void PaintBoatHireTrackSBendLeft( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 8)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 9)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1081,7 +1081,7 @@ static void PaintBoatHireTrackSBendRight( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 16)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 17)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1089,7 +1089,7 @@ static void PaintBoatHireTrackSBendRight( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 24)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 25)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1097,7 +1097,7 @@ static void PaintBoatHireTrackSBendRight( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 22)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 01 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 23)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1105,7 +1105,7 @@ static void PaintBoatHireTrackSBendRight( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 30)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 31)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1118,7 +1118,7 @@ static void PaintBoatHireTrackSBendRight( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 18)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 19)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -1126,7 +1126,7 @@ static void PaintBoatHireTrackSBendRight( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 26)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 27)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -1134,7 +1134,7 @@ static void PaintBoatHireTrackSBendRight( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 20)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 21)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -1142,7 +1142,7 @@ static void PaintBoatHireTrackSBendRight( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 28)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 29)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -1155,7 +1155,7 @@ static void PaintBoatHireTrackSBendRight( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 20)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 11 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 21)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -1163,7 +1163,7 @@ static void PaintBoatHireTrackSBendRight( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 28)), - { 0, 0, height }, { { 0, 0, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 0, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 29)), { 0, 0, height }, { { 0, 0, height + 15 }, { 32, 26, 0 } }); @@ -1171,7 +1171,7 @@ static void PaintBoatHireTrackSBendRight( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 18)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 19)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -1179,7 +1179,7 @@ static void PaintBoatHireTrackSBendRight( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 26)), - { 0, 0, height }, { { 0, 6, height }, { 32, 26, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 26, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 27)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 26, 0 } }); @@ -1192,7 +1192,7 @@ static void PaintBoatHireTrackSBendRight( case 0: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 22)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 23)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1200,7 +1200,7 @@ static void PaintBoatHireTrackSBendRight( case 1: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 30)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 31)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1208,7 +1208,7 @@ static void PaintBoatHireTrackSBendRight( case 2: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 16)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 17)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); @@ -1216,7 +1216,7 @@ static void PaintBoatHireTrackSBendRight( case 3: PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 24)), - { 0, 0, height }, { { 0, 6, height }, { 32, 20, 0 } }); + { 0, 0, height }, { { 0, 6, height }, { 32, 20, 1 } }); PaintAddImageAsParentRotated( session, direction, session.TrackColours.WithIndex((SPR_G2_BOAT_HIRE_TRACK_S_BEND + 25)), { 0, 0, height }, { { 0, 6, height + 15 }, { 32, 20, 0 } }); From 7e850f12b8d2834506aedd056691ee671ca3ac20 Mon Sep 17 00:00:00 2001 From: mix Date: Mon, 2 Dec 2024 08:42:10 +0000 Subject: [PATCH 139/139] Add changelog entry for new Boat Hire track pieces --- distribution/changelog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index f28ee9bdd4..24cd452ac3 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -7,6 +7,7 @@ - Improved: [#23211] Add boosters to classic wooden roller coaster (cheats only). - Improved: [#23229] Add debug option for making the sprite sorting algorithm stable. - Improved: [#23233] Add diagonal booster to LSM Launched Coaster. +- Improved: [#23277] Add small, medium and large turns, diagonal track and S-bends to the Boat Hire. - Fix: [#20070, #22972] Missing and mismatched flat and sloped footpaths on several scenarios. - Fix: [#22726] ‘Force park rating’ cheat is not saved with the park. - Fix: [#23064] Stand-Up Roller Coaster unbanked to banked track pieces are misaligned.

  • f|Msg{YO8Z6eYP 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 H%60z%R;O!z literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_3_5.png b/resources/g2/track/bm/medium_half_loop_left_3_5.png new file mode 100644 index 0000000000000000000000000000000000000000..f540fb01340842eedbf729193d6fe2a7b5d501a9 GIT binary patch literal 5246 zcmeHLe{d6Z7T?lB`U8kswP@=krf7hWY?5u8UyY%rHPkeuG=&1yOE;TM8q;ReY-kEO z2@z`3dmL5`z9?==A5}<=KPP$ zH`)DuzwdqCd!P5-ce49>;XKup#K#jM2%3^VH@65}XM*pO@v-2SyyVycE(ezvFLD;4 zE~ecE3`UH_qA?BY5;&e8=ivL%py6JZbRe;zx&8A1#HT znAH}gvM^t%ycG|KV$;iS%jb5_N&8G+s@__hHhaeAwawDSagS8ZUNC#r>JtmgPyX%P z3Ap^k+AUq;#N88Vibva~^1k>)+LgHKENxAPw_$VLyT1gs9Ao{%JFwz_|9Y33R@1a# z+cddg&U}sh{WVD+|GM*mn!E?RL)gO&EM%Y2BuMJJvXoBOhc{>U+&trJ(ekEE9*RFG z*mmLRE0eDLxNS$(H|(h$duJs3lC|GEbN;2;t)3dF;+_8S{6%5zs+Ow%s%sDBw_BRCh#f2rp7g{B&;?}RtO`I_O%lSEvJiU3}&MnjC z_O3YdnWADuckZ3T3u4j_O?au0`PGUc#V=p)n!o7-$2-qf{gpB-W?*y5Qpz)DUmQ8L zcL{rC__3}c*>6jdH;hdG^!Ra>Y7UiUuloA<7Wr8RZQAk^xi9W}ilHI)#2@e-7oC6Q zl~QKccR&C0n?o03*KXato>=KsmL14FeUTTweChI~e&o_`E1<95avXEbqBB9^Ra-!T zEz%T7F`|-(8VLi=tEseu%7dV6MU5TBthkeDz|9t$oE7#5SWJsi&ML{&@HKWNUT&GY z+=1(s&nw23TQP}|rFbSWyG9BCDsd;utf{Q9kJ|4n|-PX4+byP&d zF=8-YfmZ@i5?B@7Wm1)|DZH%_p}=gZv`4i7*>_1gEv7qU-Q`$dwocLT;vrFX4+bQIyY@ zjDyfRETAgUit%1Wpo{>@WXKX{WgV1Y;;;-i8d3H8Ep$Gij9UqqSd%D>L~BJc#awH z2)F_T8s&;PV=PrO@0NF!c7%D4hPcN}Fbcq~{ra$?+yHXHsgKC+_%porg#K1iX->oc-)GKiJ35ALTqeoTwL75i4!MHnna_~;^X5J z5)x9<)6)?IRw@-bof^YRNs{n-y^W2&_V&*1?%q%+JUooRkU|D&)k&qL$yO`F<%VnP zWQ|SQ)^@!=K=uUd`UhH+99oGiiBP9_N*MJR+eacDUS*)Mq^F$-9jYA+wOkK(t5P97 z2XZN(dL6BmpatsaeXYsEJ*m_nObzR)k$Q^iPKO{Z1nFrsf=>6Orq;9BEize$R(r^7 z?(=vq`g~L%kcuRyD^g%BL#Ah|2u_Iy!RlpXlhWI!Zt&|`di0$kGeeXLtI}mUjv5n{ z5=x?0TkF&NI*HDpr#sXT9Bl2s9-u3rWF3@Zh8S*$T~8DFQdI5i(tv^pmelo=E#dlZ zszb|3#zd(u6{oI5)`}_pq%P>i`WnfBHg7o4cs6b*G`SURwK{*3`B0mu zFVHmD*F8LZky1cV33$x|LG=*S20@1)Xn+P$U}%+;o21%Ws8FAl4G{>`pny76P)G|= zI*1}ts5*pd(NdjOs;8C;wLp=?iy*ZUD$&xcSc=ERX{cAVwqSn0HyCUi91K#xR;n37 z+)0Z16m1Jb-^nIIvifjo+px=jy|HJcv!ChYNmn90;4GS_gXVm93cTKeVhn0kF0^Li z6LY~N!9I5}AS)?3@{NJs+cXU<(wzC4Jlgk(DHB;Ui>en9K^}IIn z8g9>N*LM(Ie>w1e+P_bpy>V6Yr@o)6RNJ;+|NH(mN2We>iYkx$VZA1x2q@nhd2r;& pX~$vVPgSuSs=s()A#u?2=XV%sA0_QM4=983^XBF5ezt7Ye*j{d!c71G literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_4_1.png b/resources/g2/track/bm/medium_half_loop_left_4_1.png new file mode 100644 index 0000000000000000000000000000000000000000..c160e3ebf3fb6cc1dafafd19d19826f11b048d9b GIT binary patch literal 1267 zcmXAoZ)_8F7{`D6$8~hGgK8Qmv2&eNEKv1^Cm!a2E0l5Dj&PebX<}z?tYQf#9HG;0 z98j?=XL8JfRr{i{f>o;&sis01MXL-b*k~6E7E`rim0{{AI$*-j5|Z!p@6Gdl@p+!X zH65n<>9eN;0P0&;8P}HUs(PDD=I1~D=Vw2s;aB2Yieqy zO`C=wh)gD{t*upQwOSN4kR-t{6w6w8o^!ceUavnKjwTZ6Y_?b`p$0(UfTrXYi_&h_ zIGhHzhFl>#*`D9AWF!nofL z<8d{r)DkKKt--B26Q?%|C@bN-k9377PmBp9t8nLq~!J+p^reJ`L z#ayXWs8C43vX|NhP^X-bRCGXNjq128E)^}Ik|Q?hO-@B~FjLei0j5Dr28D&t*csGm zqa?u|@CdPxCzS{lvI$tqVH5?U0A>M%WftzT-94#YPG3Hc`MmeUCzGVb!r1Ms)5)O* z7iRDhXoy7Plp#&)3uY~}YM`KlJ`_d?n4-$Zk1dc--2H(qYdaXQ^!E$B<$iywaarf8 z!SiFkY<#V;4tY5TzuSm+_TS&|V)9{oh2v7wd%2ZQc#htwylsB6{h#m0w{Rc65^Fs% z*6;AbmCx^Qx;4G;r{=J^{fBj{X72uU&-P8m%>(nBLE|~QwBhN@=h3G`y^iG!yJqQ%m=xkp}~dD3_Fi*_hu+?FZq(1UdknXb<2OAIY~ zcb-wxbh`b%-r1(N1`o8&IsmtQBIg_4sUxI6(ZvY&)#RJwI}Ud}=NWrr3+OsKvJM@h z_9+jW&)~gi^Qo?(8OJ7$u7;88JAOVDJZqd+sI)#HtQU=ae_gwt|MmFC4fgY&qX*aZ gNSoUHJ@CeDWMO(_+#QVEERzGRD>{samUr*`9~#ClzW@LL literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_4_2.png b/resources/g2/track/bm/medium_half_loop_left_4_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4eb61a6f7724ce562319b45aa60e6fa595350e84 GIT binary patch literal 1375 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 V-X!MK(O5n~@uJeAuM0og`ad);rZE5j literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_left_4_4.png b/resources/g2/track/bm/medium_half_loop_left_4_4.png new file mode 100644 index 0000000000000000000000000000000000000000..9b564d539167c5d3f826c00299403e7b2a47f2f5 GIT binary patch literal 1671 zcmX9-e^gWV9sPzN4@fk#@Fbd2T%jAsa$@YH)Qfh?BTeFE(8o5FcpBU1uy~etxS;idxL+?1n$=Sdebi%)`yJ$zm(JkBTnWNg2vH4=8|89~M&mRZJyxsV zxMh|R&dJh?!i z7Gnlk;+fWIG!5CEA+J9c76O?VQsZ=;j7=!H7Ol`>z}*(bkV6;rSRz4hEcPuaOvC^H zH2?$v4giJ#n1TSA0EUuUHR-UCp&$kW6#`5`;1Yol21p!`Dkf<}NE=4Fl%&rX+naD+1N4{tO^N;sMHbDxZ`Hu zqAN@Wqc8*T*^r1wmkQZR9MLMogidKQ>D&&J-|L8kyksoQ7mG<3AVYv86J8h+azBEl z*IK5g_!jezQ2TtSREjH=a;;W{@brA1S%^4L#3SYfFm6P`A!Te*2a^_rbO}knI1zsS zo3xidbl^x;1r7?HjlG*F#@5oJoz*ohS2~p+>2qFdc}hNdXXhv471IavP07D|JYG?E zvdUw!Os~v;eplUjeKB{guhEd3A=9fK{+C*3CN}(WK=}0j9|W&D+DCTHHb8;fJ?v!9 zbWe8O?VHR9dy)T5`&CL+`|ELHaN$$I=z*J8z4I3alFT2Bww_BYRJ(k)KD_z4f=% zwJ(!>1&?!bnqq76m1BVst*AKayL9*^W&3C*d+FA#Ri8IEjSsIIt&XeWksoQ(HS#-PaCu?0L*L{p-cx%&$Kz zygPa$ry+yZH8~I^Ui%6y@8hnootr)O`QX8V$-*=L$gHo>+b zQnKr+D0G~Ckb2_`?fiqBt%0ISX4^7tau}W8v%8$JHtmhxiX9VDO38ETY>#|DJ>$VV ze^t$$C%v2Q9FEm2G_8i$yvMy*bwXEhFVwt#&)Od4;q%WjcLWNWq`?yC;ks_-!y<0+ z7tmbc@2_4=9+*Ed+kB}rjCLS1m#05_eQSTE{v%QDe=_>$7hArZf7%_)$e&mt$?{a5 zmA|BXcl>{S3at9v@rBMUE${E`+~7Y|`Smoxc-}QRe5I*;qs#U2u}?}i9QoP4EfYEL zpK3S#LhnCR@ON=*%R5Qdw))=6mh98KdUoEx=H0JG&hHJ=x@(P3-`sGx}WTSOz&V(@84;-=FW?@&#t&&-xEupoB6BzP*wgd+P2QS z`1*d4ciYZK)pw1Q`UVSS`fX#@(SdtiD~D}aJMK4@?$gi)UXlO)KMtO}LPy=Z-M zJ6~#Q&gxKRitE4PXAf3%FM2fJV_!73>|RQm+!gFAZo6E+z9TLh7Z*a_8do8it>~+14SmQj|jb#w=&{Mr z@4ZvgQ-R@4TQ&i}@Z_`OGu^qnTaOJox_$E8y%7KhOz)qa=+d5^p5ESGhr`j=*Vo_Q zKQJ(WVc6i{;Ly;J$LI4=l%L~RQRHPgq^e3Hk;r6nhGCY=HQR1?I+Pz+1_a(23b`W@ zJR0*SQ%oi+ZkTn?2= zUdrubJ$?aaBqE@Y!8j#rjGE;V1wLIA^{QmrVVw5*13pG1d6^C=oRSohIVoo2%)-hTe^>ySVT`t<=3E)1F^vevR@X+(CcL zuD-BaJa=Pi0za|X7Ao=*e|qu!uaAGYES!fo&x~xjIrQY!lNXOoN2yy!+=)Zct=E5> z&dnu1`t;RP-)>9py_*?{u6_UFrSRgy@yq$SqyPSC42&9^SFXLgJb&T!&e*ld?ajBn zeKWq3H)7lMGTf#eaPYZbmW9u*n0ty72ku?^`t+^0-0zP)ji=Oyw^f$@-mB03F#OK- zUGvEncl@PeJHI=7_~O!K{h6T;M)zS?*LM88tN-j@4%y*h9{K&7(&~@@-Lya9o}W6D z`}~al+StlZJJ%*&`SQyCBgVnQ#-kg~13N0D6n-LnV(yDOqg@MNa$;)ytFf2o{|Cmr B-}3+f literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_1_1.png b/resources/g2/track/bm/medium_half_loop_right_1_1.png new file mode 100644 index 0000000000000000000000000000000000000000..f1c382ddcf9ed1b63590cba9716d8b0f40a22aeb GIT binary patch literal 1259 zcmXAoeQXnT7{`Bm>veR{kP1Z)D6ED86;C-#gC`#IMmnt7AqN(@;jvXMTY(d9SVMtM z%4|l#OKh-02}K&M<^sjccuK*->bAJ*N~p7tOQ={wRY(dpZpw&1OGv)Y+dt3ukI(b; zt!cGRo$}Ze0KnAMEzN5yb!jCqbxkFI_<83L05xFEOY2ru#;U5S>gwv6nwr|$+PbRc{^ z+k^Q7L?}$h;#?vrq%(nhAxfDMJE7ridavCeI!qA(@Apy3kUbsem0^ETiB6PKRuph% z;3k2{ATb_E2DG`DuAD|;5rbt8PKpqwi~!I8a0tR{wO$kzO{OS8^wadP)0y*nZ$%<7 znM84&kCtK#aMnKsU?Aq0eUAecz{VnED^mmZeo)ppRot>LbN2NU_WivIV`B#Y7W?mn1f0P zOvdNPg@l6SDCBwyBs$9MWNdW8s2mpuxNB|52P(T2zh^C-N zfKn7HIobqx90W-qTY*9Y$N|6zcPY3k6F!^iV=NO|dNFaydL69>;tZ zEJWfGg(q!TmNpmdM#veU*95~jlu4MeRgT}XM05AS4|K0>Wx&dtSKqAkM^`sDt!wE! zGRA&zU|vJrn(^e9ok#o^bPdzLeXmE|UDe2~SbyTuZ>sjK9e0oVyDrHS9V=eb3|;?d z;jC}Y-PdP+Jp0q@bBCTovDJN5^=b#K#-%MEi{j&kU{ z?HzFBtCKf};`E4i#}n^Nx3>SY^0US7KXMLQ=QQ=gTJ@rxoh%Y)-8}ctW$Vu#nE%CT zIuN0po9;;m&l~Sg9?UM+kHbFds!A<rlXjRQeW`&j6=H1dA%6JUD zTz|Wszp^(v-#Ry}G@Na_H(Kf%JD@INKc3s7+Hm@(#o*BC-RIH2WT&QADTbdkJ>Rwd zg66yJg9FamNAC=5JhNcqE?rOd%CT>LIkkLGf6EV>qV1jDJ==t7$gQ652hz_lLnLu= W^wsWn?~hlAfz_*8o6o$kdH??`NGi7g literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_1_2.png b/resources/g2/track/bm/medium_half_loop_right_1_2.png new file mode 100644 index 0000000000000000000000000000000000000000..47039a93ca3a5b451da20a765637d329e5e9f76c GIT binary patch literal 1277 zcmXAoe{2(F7{}jkYj0bb4OXqvY!#bu!4r#|F(;-TC1j7tZuBYG|)<%UwQCC-2UtizQ(4bT* zRVo#NAdQWUO-)TYqtS@tCbOAh7%R)#Jsytd`EWRzNF+0v$wHxAso*9+k$|?U?RKr( zZSeX`fgl-<(D8&bmGcK~Nb2@CxCAdO1AQxiQa>k+u zP7HV{ATUUrL()M_KCZ3g^iVdziWANY5N3=3&;U3QgwtsJdcA<6F_Iji>8#6@_xo=} zqcEM;<60x7GtmapiCQ?!=Eqrq^hC_OXbq*9Sk9R&xD15eWHFKqW@QOGXXXNQAnJ@J zxuoRJ6he|5FILkU3TPRia{+@7paMcfb(REbPg9&^3l=@GvXFrzG^S+P6vZHjL|UZhPePN#K3*y31Bq?8;!VGo!^Uv1WP=| zrc%5liLxxgnwH)LaG#nIbac$%Orl(Y6v}q7;!RbVtRE@!se8MmAD`8eFf z6Q(eQi)K7+HBHi(Y%@Zq0s2uG!C{hulC^gH#0vG?{U6w~bu$CnZ~U^O){EU8>wCHm z4h(c3d+*6b9pAy9?y8&mA6a(w-a9M!)}C!&^&jjUYG2xR;RkxUE$7oD zN1t#gFU<@64ZBpcisxP*&Jr((dl$AZ&g{K@;mnN>Z%zU}jvH!L2uZ)eKBDsk*@tt>*B)6$m zbocE$cWQ9of!=FJhoYgXbIyqB9s2@rO^>do`Y%qjjyd`ct(@UMI@SB~`){9K`+4MU zo5Z%x1e$&0$l_t;Fg@OSEjxYlVp`ldj*TwAa3>g*tI;F9*A2XT{UOE7Eplz@d0xF( j?p?a9ug2lOx)$mOJ^z5mR?Qx(c?h~YH+Kwgc;&$V8dW*N literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_1_3.png b/resources/g2/track/bm/medium_half_loop_right_1_3.png new file mode 100644 index 0000000000000000000000000000000000000000..266a859da7569c6583a132434b9d2bde3cfbdef7 GIT binary patch literal 1353 zcmX9-e{2$W6#vp+*IFIfP>Dr%i#VBLW%jyJdofpcRjg>wc(tsuj3&g=$kyAWmM9u( zF~dq5W?0H5RE*4!m0DEd*u;tPwsw(Ps#Q@>gBzx7s~g!a8FNm*!rBW$|DM*r_X|-OjHJKQj&E|IdLZJxDPH|k8=P?B!a6qZcwOWzU zh?*@5y90N7s6a>;jhW&JM=I?n<%k9^XVhY=26gIXJ`)zUkukR>9%8sLdxrDpvaCu1 zbaG%OfRjc73=(q)lK~MQm%xky@;dm$2_Y*5fC4~=AdFCGl}Ma2nIFf)6g6frB(2sN zpAW`j5=6H?*O776$ z0X-Qt(FvPA={BW6^fKHxdu}j2+~Z`4!z!EHisOJn9rApL{d{z*=!a9 z2?Jzq1PchssDzHo4Jp!|*7`H%Xx2H!hcZu+Ian?i3YB893YF4wg&xOEYRaz5AG3rU zuCYLfV-tLe06H~dqJ>r+>NLtd79wb;qaMRp(3*^SGD()_XCMK91^^QPP5^=ci~*2F z0L+6Tp~VD)e#j*$8DKErB0xk1I0`@-Kt>E581z#xVuW!!0k zcR5u7zdjnZB@)3*CIRzW5(B_2<%CmA`B7a&#&EbZs}1tzXwDsf5=p^iRwe>U6j3RJ zS^_oFn8l!WT8(~}H5zm!*kFcZA)ivJ)i44e2O!LQVb9CGfW&6;q|-`|`vpw#IH}dr zMx)+hVK9YFsc;imki=qY#S|saXrxewLaPjVFc=|VLY)u4vaw`JvmDnaUI z%}m|q;_o_sc=z_;VCCu2E1W6HKV;WyQghpnfK?jt5&eyYxpEM zJ$rZfP>>gN*WfMFNcR$Hzv%(~?<>_u_&uqP`@3yD1KxSmMORDx#E$BFy(J*q-4#Z= z<_oIZp6-tVkh^xNvi+F93|yLOIm|D&a3|kx>qj5|GFhb Q^LYRb>l*7v-f8XmAD6pYCIA2c literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_1_4.png b/resources/g2/track/bm/medium_half_loop_right_1_4.png new file mode 100644 index 0000000000000000000000000000000000000000..933d722bd13e3a92044f820735fd5080a2f8ed80 GIT binary patch literal 1517 zcmXAoad47#7{`Cx*cg&S#YII%iXJUm?0n649oDP9Gn}vaPG1xqD!a(B!ui%-6_qn| zw4+7(I?=-ul^L5XX>#f*DxPS#%|Z`#DJv>WoOouDl5%U>FFfx)&-2{#&-4A``+Zt# z=BY-GcxeOxU}W{|ss*`OnX5&`1-agRptA^o0#GwoJuA27<>lq)=NA+da5$X8!os4W zA}*I(TwKiK@kCOo6hRa?j!_h$*J~Muwpy)Dr`zujgv0&ucsi3o6aZ5KlHhB#LZeY) zGAnF$rPD=v{kmX?iA3#*qz9LCHA+5Bh%6cjtCzVMN18n8osk z+YLh@F(Q;=A_XZ?>SQWfuCX9`R>`<wKPuKNSj;d z4$y(9B^-A|Q{F^2B*1`>0wM#Dn1PJtqHdAOFVluFI;ycJ7*CoF!=t2Js7J*nmE5jT zdi8jap`uoO%*iBu)^y03jrw3RED)kHxduTE7;d5{yI$`ynf!Kp$nA~>0*U_qbUF=z zm_s&Hb64@W|TqMwwfG*YOOK#L5z5E#HnQAeYv8-T*EWydwQt&x{nMHMHW%?0-fBIJ^tjJ#K5n1(=Pb@?Sl{%KWQp!kdEcQ;!~DSaqu>$Z z#{Bl{>y7n${@c>K#5BMC$wTT8@$K%NSEuay=%rZCM!};UH`v=fwUh2tj(oiTNP0_z zy)tJAOaqc>c8g?eBXJq zVc*O2i61xcdUuk=_c|x>u6@``Q&(T;d~lIZO}PKybNh<>ojv-UTdUr#ZY*oF@J?@8 z*gWo{bMvaXk{e%3d9srOm$z-}JlQr;By{$kwQo{i2TW7zB3t*Ru74i9w`TRa?22V& zC#nVyCYO(P^UiNqmtN3*Rhn<^cHF5v@z0u`>95x{T-emSY~zCau<72^VWsp>7`7buzX zTyfW(i9dc)JELsOH*>tNoTqlgCO%j*m^b(E>Q77BnRQ=!-`vou4-edJETrz$ZaX)Y z=*S#K+sC%v)a*HJM=N>)v#-2)+>vK$oBi3+ORA2p8vEIDN!f&w(r!abvhCmoVYsb+ z@AI2IZFiaX_c9F~CtJ&ES5H>&>%zT@J9?UsMHN>+XelV%S1u^3-HoyhS?yZ!h0BdK km;Y=H*P#TZeIg250=oy=hEiLbbD0Izv*uMDnpxNUKg*}FQ2+n{ literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_1_5.png b/resources/g2/track/bm/medium_half_loop_right_1_5.png new file mode 100644 index 0000000000000000000000000000000000000000..55c4e2e21daf825aee95d64a91894322a07c87f3 GIT binary patch literal 5240 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_2_1.png b/resources/g2/track/bm/medium_half_loop_right_2_1.png new file mode 100644 index 0000000000000000000000000000000000000000..870a429c4807bcdbc93b552d95cc08bc1a18d365 GIT binary patch literal 5178 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 literal 0 HcmV?d00001 diff --git a/resources/g2/track/bm/medium_half_loop_right_2_3.png b/resources/g2/track/bm/medium_half_loop_right_2_3.png new file mode 100644 index 0000000000000000000000000000000000000000..41f2df9e3c459f039cc9c46c76f1913b7a1971b5 GIT binary patch literal 1351 zcmX9-e@qj16#pW^@x!Jj%vHU`f<-EH(%~tmGm*{k&HSUhm)}HYD_-wect=$eg61- z-oBP*l^}0!9soeFs-dnm&Bf``b;xuBOmO5GNj9D45YeHToI%G*iT@%Tm z3I#eDFcN^L5I2Jatip)9AQeJkLJm_pILSj8lmI{iphFNwDCAI-mr7j<#Tk+u((5A} zH|BK0Kmf%GB!oy#iWNGkijiqJjOG=rLuvM?ZGOrX()pr#F^=R)Rj0c4UxKyUWa6O?kQk0dZ9Y&+qY7ID@VV^HHJe*7> zAwU@*wIi5YsPv;$NT!b|Epe?YVe}{Y;gmNq8JU3jGNBL`iBw_Mbd!xZ{DnLXQhZBcv2C7_bq*rvgzDKng%c1g#i!k(ld-Rduy(4f~FcyxkovoB>+Kxo?Z>H+e5M-)*kFnJqcn|Io_gUu1RtRMMd@+^enK zk#)h|x3*T+AJBZVZTJY-+WufRGh^4XM@V^FeQ`=~r+>eyZZVf}{@tSa-PgA6It;Y+ zC38uHU0>dM|2E%J79PB|`f%TzYn%5zUYn;zB_}_vS|i@nc<7h;ttaO-lFnjo;hObSjcJ7ZlY!=v>ir?`jxz%Wrh;{Jw}j=)TpGvv^srZ*lQa z?BK}DO=C=7RVm`msA-?k9BsAr3Of=@zQc1@SN|UQt+;xbVBGjk|37=5BtG7T&f;!_L)BAsiu|^WEE@99@liu2;u}; zFV53ms&UKK*fPsBtJHdgMVIlIny^%hl-$HFYlEuP1x2^}F3#QS^ZDH8pU?Y`_xn>{ zS|ZEInw$jy$SGP{up%)fi6S#n5`97?eFA_KQ2J5XlEj*nl$4yDoRX4~nwpxHmX@BL z&SJ4LGBPqVGr0nR071kUCM8K+rBZ0Ml+kFkTJ3JPhhcg{p;$bQh=EiB2s~S%;Ak{_ zonCA*ORP4+=~jAuT7SSCjyNz8OD@T#aIQhlr&U6`7U?izKC9gCrb1n&Xvi@VV`My_ z6ak$S&?L)Av3zEB(8-DWc`z!5aU~q3A!Gyq5CAAyEQ-xG@OZRP=#WS{2%<}^4jK%D zc02U>cnC)z<%$WuL@AU}BDn!k(Gsl5RBC$#$(c*+jnK-6* zn=M^VcZdnZ!&0EcSz3~9Q1WSw$flRNOr+PQ?s6G|K3g=%#N&fd3V<8{EdVqCE&#d! zh_C=mKwwa>g)RpS1qmUb5MYr4j|_we07(ETE;J+1K|qfN`b{w8056P30geGV!P2O> z2A#-4%bX6C*J}&}T+wI%CbW2JfatTOG?#Gjl^!7#lF%`QE3Wg7SpB1(Fbu|o9Dwp! zGBH~rjCxxng4(Pv(fa+E zLP2UYD!raU#70zXl_D+-@!{fLLKKw?ppp*_LTE#vM+yUYBK+u#?1wLYpms$G2|gU? z+W*`28*$xX)_C3CSJN< zKXYO9%EWN|&Xg$!7v$~VJA7ngF@MU8&C@tptagvt`Wp=(wY6f z%pLD<+t}T8y=CpwhX+kT>ghK>+y-aOI~Qb)d~L(})<(CyJEpMR-=ND`IQY!gwz)nS znzm!Ct#68^R(SSdnREKO>Xkjt%G-PF?^I2=KD~X0 z^IwdfuwWZ}Zs5bp(JKlFK=*f4L zKUsKb%co6yXES-_g>74ZZ)5Ui_jB{M#cEP7R-G>^y(%m{T2(MqWm$Pvfu1<9z2~ot z^EV%FKDG7g(9oAnnn4A6q2_M>qPOl9e{i}IfBgB4U#vBEcbl;b!IHj@t;Z%UYwqvK zq&kV7)zyE`DP5B>m_Kvy+G=9y7rv}PrEBl=sk={IZ4Hs*2iA>&W1lRp*mCApYx}0r z$>Z|VSN%GtbIr;9so`}E^|u>0H?MvzS9J@|c@`G!tnB{BpZnizA;@L0vTy6YF$|CcOjS=D;dh;b4b14T