diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..17e60ab4f --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,26 @@ +### Description + +Please describe the issue you are experiencing. + +### Reproduction + +If the issue occurs in multiple routes/ trains, please provide one or two samples. +In order to reproduce the issue and debug it, it's helpful to have the following: + +## Route + +Please provide a link to where the route may be downloaded. + +## Train + +Please provide a link to the train may be downloaded. + +## Logs + +Logs may be accessed through the 'Report Problem' button on the bottom left of the screen. +Please provide a log, and a crash-log if the game actually crashes. + +### Related information + +* Operating system +* Method of control (Keyboard, joystick, RailDriver) diff --git a/assets/Compatibility/PreTrain/train.dat b/assets/Compatibility/PreTrain/train.dat index 4477c20ec..77079db0d 100644 --- a/assets/Compatibility/PreTrain/train.dat +++ b/assets/Compatibility/PreTrain/train.dat @@ -5,4 +5,8 @@ 1 0 1 -1 \ No newline at end of file +1 +#HANDLE +0 +8 +8 \ No newline at end of file diff --git a/assets/In-game/Large/doors_left_back.png b/assets/In-game/Large/doors_left_back.png new file mode 100644 index 000000000..5acfc2493 Binary files /dev/null and b/assets/In-game/Large/doors_left_back.png differ diff --git a/assets/In-game/Large/doors_left_overlay.png b/assets/In-game/Large/doors_left_overlay.png new file mode 100644 index 000000000..9cefbd459 Binary files /dev/null and b/assets/In-game/Large/doors_left_overlay.png differ diff --git a/assets/In-game/Large/doors_right_back.png b/assets/In-game/Large/doors_right_back.png new file mode 100644 index 000000000..bcc3c2929 Binary files /dev/null and b/assets/In-game/Large/doors_right_back.png differ diff --git a/assets/In-game/Large/doors_right_overlay.png b/assets/In-game/Large/doors_right_overlay.png new file mode 100644 index 000000000..fc6bdf602 Binary files /dev/null and b/assets/In-game/Large/doors_right_overlay.png differ diff --git a/assets/In-game/Large/handle_back.png b/assets/In-game/Large/handle_back.png new file mode 100644 index 000000000..2b7efd661 Binary files /dev/null and b/assets/In-game/Large/handle_back.png differ diff --git a/assets/In-game/Large/handle_overlay.png b/assets/In-game/Large/handle_overlay.png new file mode 100644 index 000000000..d6e290ee1 Binary files /dev/null and b/assets/In-game/Large/handle_overlay.png differ diff --git a/assets/In-game/Large/indicator_top_back.png b/assets/In-game/Large/indicator_top_back.png new file mode 100644 index 000000000..e7bad44bd Binary files /dev/null and b/assets/In-game/Large/indicator_top_back.png differ diff --git a/assets/In-game/Large/indicator_top_overlay.png b/assets/In-game/Large/indicator_top_overlay.png new file mode 100644 index 000000000..d3abd37b9 Binary files /dev/null and b/assets/In-game/Large/indicator_top_overlay.png differ diff --git a/assets/In-game/Large/interface.cfg b/assets/In-game/Large/interface.cfg new file mode 100644 index 000000000..cdcbcffd7 --- /dev/null +++ b/assets/In-game/Large/interface.cfg @@ -0,0 +1,303 @@ +; -------- +; messages +; -------- + +[element] +subject = messages +position = 8, 18 +alignment = -1, -1 +textcolor = 0, 0, 0, 255 +textsize = 4 ;0 +textshadow = 1 ;0 +transition = 3 ;2 +transitionvector = 0, -40 +value = 0, 20 + + +; ----- +; score +; ----- + +[element] +subject = scoremessages +position = 0, 80 +alignment = 0, -1 +textcolor = 0, 0, 0, 255 +textposition = 2, -1 +textalignment = -1, 0 +textsize = 4 +textshadow = 1 +transition = 3 +transitionvector = 0, -96 +value = 0, 20 + +[element] +subject = score +position = 0, -1 +alignment = 0, -1 +centermiddle = indicator_top_back.png, indicator_top_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = 0, -1 +textalignment = 0, 0 +textsize = 3 +textshadow = 1 + + +; ------- +; handles +; ------- + +[element] +subject = reverser +position = -8, 1 +alignment = -1, 1 +centermiddle = handle_back.png, handle_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = 24, 2 +textalignment = -1, 0 +textsize = 2 +textshadow = 0 + +[element] +subject = power +position = 74, 1 +alignment = -1, 1 +centermiddle = handle_back.png, handle_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = 23, 2 +textalignment = -1, 0 +textsize = 2 +textshadow = 0 + +[element] +subject = brake +position = 156, 1 +alignment = -1, 1 +centermiddle = handle_back.png, handle_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = 23, 2 +textalignment = -1, 0 +textsize = 2 +textshadow = 0 + +[element] +subject = locobrake +position = 238, 1 +alignment = -1, 1 +centermiddle = handle_back.png, handle_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = 23, 2 +textalignment = -1, 0 +textsize = 2 +textshadow = 0 + +[element] +subject = single +position = 74, 1 +alignment = -1, 1 +centermiddle = handle_back.png, handle_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = 23, 2 +textalignment = -1, 0 +textsize = 2 +textshadow = 0 + + +; --------------- +; door indicators +; --------------- + +[element] +subject = doorsleft +position = -32, 0 +alignment = 0, 1 +centermiddle = doors_left_back.png, doors_left_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = -18, -1 +textalignment = 1, 0 +textsize = 2 +textshadow = 0 +transition = 1 +transitionvector = 0, 31 + +[element] +subject = doorsright +position = 32, 0 +alignment = 0, 1 +centermiddle = doors_right_back.png, doors_right_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = 17, -1 +textalignment = -1, 0 +textsize = 2 +textshadow = 0 +transition = 1 +transitionvector = 0, 31 + +; --------------- +; stop indicators +; --------------- + +[element] +subject = stopleft +position = 4, -64 +alignment = -1, 0 +centermiddle = ..\Default\stop_back.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = -40, 0 + +[element] +subject = stoplefttick +position = 4, -64 +alignment = -1, 0 +centermiddle = ..\Default\stop_tick.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = -40, 0 +value = 128 ; vertical radius + +[element] +subject = stopright +position = -4, -64 +alignment = 1, 0 +centermiddle = ..\Default\stop_back.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = 40, 0 + +[element] +subject = stoprighttick +position = -4, -64 +alignment = 1, 0 +centermiddle = ..\Default\stop_tick.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = 40, 0 +value = 128 ; vertical radius + +[element] +subject = stopnone +position = 4, -64 +alignment = -1, 0 +centermiddle = ..\Default\stop_back_none.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = -40, 0 + +[element] +subject = stopnonetick +position = 4, -64 +alignment = -1, 0 +centermiddle = ..\Default\stop_tick.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = -40, 0 +value = 128 ; vertical radius + +[element] +subject = stopnone +position = -4, -64 +alignment = 1, 0 +centermiddle = ..\Default\stop_back_none.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = 40, 0 + +[element] +subject = stopnonetick +position = -4, -64 +alignment = 1, 0 +centermiddle = ..\Default\stop_tick.png, NULL +backcolor = 255, 255, 255, 255 +transition = 1 +transitionvector = 40, 0 +value = 128 ; vertical radius + + +; ---------------- +; other indicators +; ---------------- + +[element] +subject = ai +position = 8, -26 +alignment = -1, 1 +textcolor = 255, 255, 255, 255 +textsize = 3 +textshadow = 1 +transition = 2 + +[element] +subject = clock +position = 8, -42 +alignment = -1, 1 +textcolor = 255, 255, 255, 255 +textsize = 3 +textshadow = 1 +transition = 2 + +[element] +subject = speed +position = 8, -58 +alignment = -1, 1 +textcolor = 255, 255, 255, 255 +textsize = 3 +textshadow = 1 +transition = 2 + +[element] +subject = gradient +position = 8, -74 +alignment = -1, 1 +textcolor = 255, 255, 255, 255 +textsize = 3 +textshadow = 1 +transition = 2 + +[element] +subject = fps +position = 8, -90 +alignment = -1, 1 +textcolor = 255, 255, 255, 255 +textsize = 3 +textshadow = 1 +transition = 2 + +; ------------- +; ats/atc lamps +; ------------- + +[element] +subject = ats +position = 0, 1 +alignment = 1, 1 +topleft = ..\Default\ats_top_left_back.png, ..\Default\ats_top_left_overlay.png +topmiddle = ..\Default\ats_top_middle_back.png, ..\Default\ats_top_middle_overlay.png +centerleft = ..\Default\ats_center_left_back.png, ..\Default\ats_center_left_overlay.png +centermiddle = ..\Default\ats_center_middle_back.png, ..\Default\ats_center_middle_overlay.png +bottomleft = ..\Default\ats_center_left_back.png, ..\Default\ats_center_left_overlay.png +bottommiddle = ..\Default\ats_center_middle_back.png, ..\Default\ats_center_middle_overlay.png +backcolor = 0, 0, 0, 144 +overlaycolor = 255, 255, 255, 64 +textcolor = 255, 255, 255, 192 +textposition = -8, -1 +textalignment = 1, 0 +textsize = 0 +textshadow = 0 +value = 0, 15 diff --git a/assets/Languages/ca-ES.cfg b/assets/Languages/ca-ES.cfg index 94f034ae4..12d6a78de 100644 --- a/assets/Languages/ca-ES.cfg +++ b/assets/Languages/ca-ES.cfg @@ -1,5 +1,5 @@ ; openBVE interface language configuration file -; last updated: 2018-06-12 +; last updated: 2018-08-20 ; by Marc Riera Irigoyen [program] @@ -291,6 +291,11 @@ assignment_invalid = Sense assignar assignment_separator = ,\x20 [raildriver] +speedunits = Unitat de velocitat de la pantalla LED +milesperhour = Milles per hora (mph) +kilometersperhour = Quilòmetres per hora (km/h) +setcalibration = Estableix el calibratge: +launch = Comença notdetected = No s'ha detectat cap dispositiu RailDriver. config_error = S'ha produït un error en carregar el fitxer de calibratge de RailDriver. calibration_start = Seleccioneu "Següent" per començar el calibratge. @@ -390,6 +395,12 @@ page_next = Pàgina següent... kiosk_mode = Mode quiosc kiosk_mode_enable = Activa el mode quiosc kiosk_mode_timer = Temps d'espera de control (segons) +hud_size = Mida de la interfície +hud_size_small = Petita +hud_size_normal = Normal +hud_size_large = Gran +transparencyfix = Intenta corregir els errors de transparència en continguts antics. +hacks_enable = Activa les modificacions per a continguts antics amb errors. [dialog] csvfiles = Fitxers CSV diff --git a/assets/Languages/cs-CZ.cfg b/assets/Languages/cs-CZ.cfg index 247d87ddb..6f6df4fe7 100644 --- a/assets/Languages/cs-CZ.cfg +++ b/assets/Languages/cs-CZ.cfg @@ -287,6 +287,11 @@ assignment_invalid = Nepřiřazeno assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV soubory diff --git a/assets/Languages/de-CH.cfg b/assets/Languages/de-CH.cfg index 25d35fcdf..56d892a59 100644 --- a/assets/Languages/de-CH.cfg +++ b/assets/Languages/de-CH.cfg @@ -287,6 +287,11 @@ assignment_invalid = Nicht zugeordnet assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV-Dateien (*.csv) diff --git a/assets/Languages/de-DE.cfg b/assets/Languages/de-DE.cfg index ad24888db..da1f08870 100644 --- a/assets/Languages/de-DE.cfg +++ b/assets/Languages/de-DE.cfg @@ -287,6 +287,11 @@ assignment_invalid = Nicht zugeordnet assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = Kein RailDriver erkannt. config_error = Fehler beim Laden der RailDriver-Konfigurationsdatei. calibration_start = Bitte "weiter" drücken zum Start der Kalibrierung. @@ -386,6 +391,12 @@ page_next = Nächste Seite... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV-Dateien (*.csv) diff --git a/assets/Languages/en-GB.cfg b/assets/Languages/en-GB.cfg index 0e6f6228c..f4493a37f 100644 --- a/assets/Languages/en-GB.cfg +++ b/assets/Languages/en-GB.cfg @@ -291,6 +291,11 @@ assignment_invalid = Not assigned assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -390,6 +395,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV files diff --git a/assets/Languages/en-US.cfg b/assets/Languages/en-US.cfg index d118a7e18..4c392bef3 100644 --- a/assets/Languages/en-US.cfg +++ b/assets/Languages/en-US.cfg @@ -287,6 +287,11 @@ assignment_invalid = Not assigned assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV files diff --git a/assets/Languages/es-ES.cfg b/assets/Languages/es-ES.cfg index f6ab69be0..2af76a32d 100644 --- a/assets/Languages/es-ES.cfg +++ b/assets/Languages/es-ES.cfg @@ -287,6 +287,11 @@ assignment_invalid = Sin asignar assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Página siguiente... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Archivos CSV diff --git a/assets/Languages/fi-FI.cfg b/assets/Languages/fi-FI.cfg index e7b136f9e..23bca3bf5 100644 --- a/assets/Languages/fi-FI.cfg +++ b/assets/Languages/fi-FI.cfg @@ -287,6 +287,11 @@ assignment_invalid = Ei määritetty assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV-tiedostot diff --git a/assets/Languages/fr-FR.cfg b/assets/Languages/fr-FR.cfg index 2e2e5c991..c8b294788 100644 --- a/assets/Languages/fr-FR.cfg +++ b/assets/Languages/fr-FR.cfg @@ -287,6 +287,11 @@ assignment_invalid = Non attribué assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Fichiers CSV diff --git a/assets/Languages/hu-HU.cfg b/assets/Languages/hu-HU.cfg index 8ad005322..b97a18df4 100644 --- a/assets/Languages/hu-HU.cfg +++ b/assets/Languages/hu-HU.cfg @@ -1,5 +1,5 @@ ; openBVE interface language configuration file -; last updated: 2016-10-07 +; last updated: 2018-08-20 ; by Phonteus Nevolius [program] @@ -287,24 +287,29 @@ assignment_invalid = Nincs hozzárendelve assignment_separator = ,\x20 [raildriver] -notdetected = No RailDriver conrollers detected. -config_error = Error loading RailDriver calibration file. -calibration_start = Please press 'Next' to start calibration. -calibration_a = Move the reverser lever to the full reverse position and press 'Next'. -calibration_b = Move the reverser lever to the full forward position and press 'Next'. -calibration_c = Move the combined brake / throttle lever to the full power position and press 'Next'. -calibration_d = Move the combined brake / throttle lever to the full brake position and press 'Next'. -calibration_e = Move the dynamic brake lever to the release position and press 'Next'. -calibration_f = Move the dynamic brake lever to the emergency position and press 'Next'. -calibration_g = Move the independant brake lever to the release position and press 'Next'. -calibration_h = Move the independant brake lever to the full position and press 'Next'. -calibration_i = Move the bail-off lever to the release position and press 'Next'. -calibration_j = Move and hold the bail-off lever into the full position and press 'Next'. -calibration_k = Move the wiper switch to OFF and press 'Next'. -calibration_l = Move the wiper switch to FULL and press 'Next'. -calibration_m = Move the lights switch to OFF and press 'Next'. -calibration_n = Move the lights switch to FULL and press 'Next'. -calibration_o = Calibration complete. +speedunits = Kijelzőn sebesség egysége +milesperhour = Mérföld per óra (MPH) +kilometersperhour = Kilométer per óra (km/h) +setcalibration = Kalibrálás: +launch = Indítás +notdetected = Nem érzékelhető RailDriver. +config_error = Hiba a RailDriver kalibrációs fájl betöltésekor. +calibration_start = Kattintson a 'Next' gombra a kalibrálás megkezdéséhez. +calibration_a = Állítsa az irányváltót teljesen hátra állásba és nyomja meg a 'Next' gombot. +calibration_b = Állítsa az irányváltót teljesen előre állásba és nyomja meg a 'Next' gombot. +calibration_c = Állítsa a kombinált menet / fékkart teljesen menet állásba és nyomja meg a 'Next' gombot. +calibration_d = Állítsa a kombinált menet / fékkart teljesen fék állásba és nyomja meg a 'Next' gombot. +calibration_e = Állítsa a dinamikus fékkart nyitott állásba és nyomja meg a 'Next' gombot. +calibration_f = Állítsa a dinamikus fékkart vészfék állásba és nyomja meg a 'Next' gombot. +calibration_g = Állítsa a független fékkart nyitott állásba és nyomja meg a 'Next' gombot. +calibration_h = Állítsa a független fékkart teljes fék állásba és nyomja meg a 'Next' gombot. +calibration_i = Állítsa a mozdonyfékkioldót alaphelyzetbe és nyomja meg a 'Next' gombot. +calibration_j = Állítsa a mozdonyfékkioldót fékoldás állásba, tartsa ott, majd nyomja meg a 'Next' gombot. +calibration_k = Állítsa az ablaktörlő kapcsolóját OFF állásba és nyomja meg a 'Next' gombot. +calibration_l = Állítsa az ablaktörlő kapcsolóját FULL állásba és nyomja meg a 'Next' gombot. +calibration_m = Állítsa a fényszóró kapcsolóját OFF állásba és nyomja meg a 'Next' gombot. +calibration_n = Állítsa a fényszóró kapcsolóját FULL állásba és nyomja meg a 'Next' gombot. +calibration_o = A kalibrálás elkészült. [options] title = Beállítások @@ -351,7 +356,7 @@ misc_simulation_toppling = Felborulás misc_simulation_collisions = Ütközés misc_simulation_derailments = Kisiklás misc_simulation_blackbox = Fekete doboz -misc_simulation_loadingsway = Enable loading sway +misc_simulation_loadingsway = Kocsik lengése (utascs.) misc_controls = Irányítás misc_controls_joysticks = Joystick engedélyezése misc_controls_threshold = Joystick küszöb: @@ -383,9 +388,15 @@ package_other_directory = Egyebek telepítési könyvtára: package_compression = Csomag tömörítésének formátuma: page_previous = Előző... page_next = Következő... -kiosk_mode = Kiosk Mode -kiosk_mode_enable = Enable Kiosk Mode -kiosk_mode_timer = Control Timeout (s) +kiosk_mode = Bemutató mód +kiosk_mode_enable = Bemutató mód bekapcsolása +kiosk_mode_timer = Időzítés (mp) +hud_size = HUD méret +hud_size_small = Kicsi +hud_size_normal = Normál +hud_size_large = Nagy +transparencyfix = Átlátszósági hibák javítása régi pályákban/vonatokban +hacks_enable = Régi hibás pályák/vonatok helyes megjelenítése [dialog] csvfiles = CSV fájl @@ -639,7 +650,7 @@ MENU_ENTER = A játék közbeni menüben kiválasztott parancs végrehajtása MENU_BACK = Visszalép a játék közbeni menüben MISC_CLOCK = Óra megjelenítése/elrejtése MISC_SPEED = Váltogatés a sebességkijelző különböző működési módjai között -MISC_GRADIENT = Toggles through different gradient display modes +MISC_GRADIENT = Váltás különböző lejtviszony kijelzési módok között MISC_TIMEFACTOR = Váltogatás különböző időgyorsító módok közt MISC_FPS = A képfrissítés értékének (fps) megjelenítése/elrejtése MISC_AI = Robotpilóta be/ki kapcsolása @@ -653,9 +664,9 @@ MISC_CPUMODE = Csökkentett processzor mód be/ki kapcsolása DEBUG_WIREFRAME = Wireframe mód be/ki kapcsolása DEBUG_NORMALS = Normálvektorok megjelenítése/elrejtése DEBUG_BRAKE = A fékrendszer hibakereső adatainak megjelenítése/elrejtése -DEBUG_ATS = Shows or hides plugin debug output +DEBUG_ATS = Megjeleníti vagy elrejti a plugin hibakeresési adatokat ROUTE_INFORMATION = Megjeleníti vagy elrejti a pályainformációs ablakot -SHOW_EVENTS = Shows or hides event markers (For developers) +SHOW_EVENTS = Megjeleníti vagy elrejti az eseményjelölőket (fejlesztőknek) ;------ New controls ---- @@ -700,7 +711,7 @@ BACKQUOTE = 0 BACKSLASH = Ű BACKSPACE = Backspace BREAK = Break -CAPSLOCK = Capslock +CAPSLOCK = CapsLock CARET = [^] CLEAR = [Clear] COLON = [;] @@ -763,7 +774,7 @@ LSUPER = Bal rendszergomb MENU = Menü MINUS = Ü MODE = Alt Gr -NUMLOCK = Numlock +NUMLOCK = NumLock PAGEDOWN = Page down PAGEUP = Page up PAUSE = Pause @@ -783,7 +794,7 @@ RIGHTPAREN = [ ) ] RMETA = Jobb Meta RSHIFT = Jobb Shift RSUPER = Jobb rendszergomb -SCROLLLOCK = Scrolllock +SCROLLLOCK = ScrollLock SEMICOLON = É SLASH = Kötőjel SPACE = Szóköz diff --git a/assets/Languages/it-IT.cfg b/assets/Languages/it-IT.cfg index d70d34400..ebefd3fcf 100644 --- a/assets/Languages/it-IT.cfg +++ b/assets/Languages/it-IT.cfg @@ -287,6 +287,11 @@ assignment_invalid = Non assegnato assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = File CSV diff --git a/assets/Languages/ja-JP.cfg b/assets/Languages/ja-JP.cfg index 6bd808be5..3dc093112 100644 --- a/assets/Languages/ja-JP.cfg +++ b/assets/Languages/ja-JP.cfg @@ -288,7 +288,11 @@ assignment_invalid = 未割当 assignment_separator = ,\x20 [raildriver] - +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = RailDriverのコントローラーを検出できませんでした。 config_error = RailDriverのキャリブレーションファイルの読み込み中にエラーが発生しました。 calibration_start = 「次へ」をクリックするとキャリブレーションを開始します。. @@ -388,6 +392,12 @@ page_next = 次のページへ... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSVファイル diff --git a/assets/Languages/ko-KR.cfg b/assets/Languages/ko-KR.cfg index a71a56d45..3fb095637 100644 --- a/assets/Languages/ko-KR.cfg +++ b/assets/Languages/ko-KR.cfg @@ -287,6 +287,11 @@ assignment_invalid = 할당되지 않음 assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV 노선 파일 diff --git a/assets/Languages/nl-NL.cfg b/assets/Languages/nl-NL.cfg index 264e287da..d10ed690b 100644 --- a/assets/Languages/nl-NL.cfg +++ b/assets/Languages/nl-NL.cfg @@ -287,6 +287,11 @@ assignment_invalid = Niet toegewezen assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV-bestanden diff --git a/assets/Languages/pl-PL.cfg b/assets/Languages/pl-PL.cfg index 409468f78..fa9032673 100644 --- a/assets/Languages/pl-PL.cfg +++ b/assets/Languages/pl-PL.cfg @@ -287,6 +287,11 @@ assignment_invalid = Nie przypisano assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = Nie wykryto kontrolera RailDriver. config_error = Błąd wczytywania pliku kalibracji RailDriver. calibration_start = Wciśnij 'Dalej' aby rozpocząć kalibrację. @@ -386,6 +391,12 @@ page_next = Następna strona... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Pliki CSV diff --git a/assets/Languages/pt-BR.cfg b/assets/Languages/pt-BR.cfg index 383e4e130..fe0144606 100644 --- a/assets/Languages/pt-BR.cfg +++ b/assets/Languages/pt-BR.cfg @@ -287,6 +287,11 @@ assignment_invalid = Não atribuído assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Arquivos CSV diff --git a/assets/Languages/pt-PT.cfg b/assets/Languages/pt-PT.cfg index d53c0ceee..e0e0c249f 100644 --- a/assets/Languages/pt-PT.cfg +++ b/assets/Languages/pt-PT.cfg @@ -288,6 +288,11 @@ assignment_invalid = Não atribuído assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -387,6 +392,12 @@ page_next = Próxima página... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Ficheiros CSV diff --git a/assets/Languages/ro-RO.cfg b/assets/Languages/ro-RO.cfg index e0376cc21..cee63f472 100644 --- a/assets/Languages/ro-RO.cfg +++ b/assets/Languages/ro-RO.cfg @@ -287,6 +287,11 @@ assignment_invalid = Nerepartizat assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Fişiere CSV diff --git a/assets/Languages/ru-RU.cfg b/assets/Languages/ru-RU.cfg index b79dba86b..f46b18c26 100644 --- a/assets/Languages/ru-RU.cfg +++ b/assets/Languages/ru-RU.cfg @@ -287,6 +287,11 @@ assignment_invalid = Не назначено assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Файлы CSV diff --git a/assets/Languages/uk-UA.cfg b/assets/Languages/uk-UA.cfg index ae64d5abc..a01c0df84 100644 --- a/assets/Languages/uk-UA.cfg +++ b/assets/Languages/uk-UA.cfg @@ -287,6 +287,11 @@ assignment_invalid = Не налаштовано assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = Файли CSV diff --git a/assets/Languages/zh-CN.cfg b/assets/Languages/zh-CN.cfg index 87bec3509..b508e8ba5 100644 --- a/assets/Languages/zh-CN.cfg +++ b/assets/Languages/zh-CN.cfg @@ -292,6 +292,11 @@ assignment_invalid = 未定义 assignment_separator = 、 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = 未检测到RailDriver控制器。 config_error = 在加载RailDriver校准配置时出现错误。 calibration_start = 按‘继续’开始校准。 @@ -391,6 +396,12 @@ page_next = 下一页 > kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = 逗号分隔文件 diff --git a/assets/Languages/zh-HK.cfg b/assets/Languages/zh-HK.cfg index a8f402ca9..f54393207 100644 --- a/assets/Languages/zh-HK.cfg +++ b/assets/Languages/zh-HK.cfg @@ -287,6 +287,11 @@ assignment_invalid = 未指定 assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV 檔案 diff --git a/assets/Languages/zh-TW.cfg b/assets/Languages/zh-TW.cfg index b7e6c0f90..1bc932683 100644 --- a/assets/Languages/zh-TW.cfg +++ b/assets/Languages/zh-TW.cfg @@ -287,6 +287,11 @@ assignment_invalid = 未指定 assignment_separator = ,\x20 [raildriver] +speedunits = LED Display speed units +milesperhour = Miles per Hour (MPH) +kilometersperhour = Kilometers per Hour (KPH) +setcalibration = Set Calibration: +launch = Launch notdetected = No RailDriver conrollers detected. config_error = Error loading RailDriver calibration file. calibration_start = Please press 'Next' to start calibration. @@ -386,6 +391,12 @@ page_next = Next Page... kiosk_mode = Kiosk Mode kiosk_mode_enable = Enable Kiosk Mode kiosk_mode_timer = Control Timeout (s) +hud_size = HUD Size +hud_size_small = Small +hud_size_normal = Normal +hud_size_large = Large +transparencyfix = Attempt to fix transparency issues in older content. +hacks_enable = Enable hacks for buggy older content. [dialog] csvfiles = CSV 檔案 diff --git a/documentation/HTML/object_animated.html b/documentation/HTML/object_animated.html index 26181e1b5..4c2ce1683 100644 --- a/documentation/HTML/object_animated.html +++ b/documentation/HTML/object_animated.html @@ -426,6 +426,7 @@ distance[carIndex]The non-negative cartesian distance measured from the object to the car carIndex in meters, or 0 if the car does not exist. Only meaningful for scenery objects. trackDistanceThe signed track distance measured from the object to the closest end of the nearest train in meters. Is positive when the train is in front of the object, negative when behind, and zero when the object lies between the ends of the train. trackDistance[carIndex]The signed track distance measured from the object to the car carIndex of the nearest train in meters. Is positive when the center of the car is in front of the object, and negative if behind. Returns 0 if the car does not exist. Only meaningful for scenery objects. +destinationThe currently set destination for this train. (Set via Track.Destination or the plugin interface)
● Trains (brake) @@ -535,6 +536,7 @@ FrontAxleCurveRadius[carIndex]Returns the curve radius at the front axle position of car carIndex. RearAxleCurveRadius[carIndex]Returns the curve radius at the rear axle position of car carIndex. CurveCant[carIndex]Returns the cant value for car carIndex. +Pitch[carIndex]Returns the pitch value for car carIndex. OdometerReturns a signed number representing the distance in meters travelled by the current car. Odometer[carIndex]Returns a signed number representing the distance in meters travelled by car carIndex. KlaxonReturns the currently playing horn (if any) as follows: (0) No horns are playing (1) The primary horn is playing (2) The secondary horn is playing (3) The music horn is playing. Note If multiple horns are playing, the lowest value will be returned. diff --git a/installers/mac/MacBundle.tgz b/installers/mac/MacBundle.tgz index a39da7efa..2cba7a7e7 100644 Binary files a/installers/mac/MacBundle.tgz and b/installers/mac/MacBundle.tgz differ diff --git a/makefile b/makefile index ccd4bbb63..e1f450539 100644 --- a/makefile +++ b/makefile @@ -319,8 +319,7 @@ create_resource_tmp = $(eval $(call resource_rule_impl, $(firstword $(subst ^, , # OpenBve # ########### -OPEN_BVE_FOLDERS := . Audio Game Game/AI Game/Events Game/Events/EventTypes Game/ObjectManager Game/ObjectManager/AnimatedObjects Game/Score Game/TrackManager Graphics Graphics/Renderer Interface OldCode Parsers Parsers/Object/BVE Parsers/Object/Generic Parsers/Object/Loksim3D Parsers/Object/MSTS Parsers/Panel Parsers/Routes Parsers/Route/BVE Parsers/Script Parsers/SoundConfiguration Parsers/Train Properties OldParsers OldParsers/BveRouteParser Simulation/TrainManager Simulation/TrainManager/Car Simulation/TrainManager/Motor Simulation/TrainManager/Train Simulation/TrainManager/Train/Handles Simulation/World System System/Functions System/Input System/Logging System/Plugins System/Program System/Translations UserInterface -OPEN_BVE_FOLDERS := $(addprefix $(OPEN_BVE_ROOT)/, $(OPEN_BVE_FOLDERS)) +OPEN_BVE_FOLDERS := $(shell find $(OPEN_BVE_ROOT) -type d) OPEN_BVE_SRC := $(filter-out "$(OPEN_BVE_ROOT)/Properties/AssemblyInfo.cs",$(patsubst %, "%", $(foreach sdir, $(OPEN_BVE_FOLDERS), $(wildcard $(sdir)/*.cs)))) OPEN_BVE_DOC := $(addprefix /doc:, $(foreach sdir, $(OPEN_BVE_FOLDERS), $(wildcard $(sdir)/*.xml))) OPEN_BVE_RESX := $(foreach sdir, $(OPEN_BVE_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -371,8 +370,7 @@ $(DEBUG_DIR)/$(OPEN_BVE_FILE) $(RELEASE_DIR)/$(OPEN_BVE_FILE): $(OPEN_BVE_ROOT)/ # OpenBveApi # ############## -OPEN_BVE_API_FOLDERS := . Properties -OPEN_BVE_API_FOLDERS := $(addprefix $(OPEN_BVE_API_ROOT)/, $(OPEN_BVE_API_FOLDERS)) +OPEN_BVE_API_FOLDERS := $(shell find $(OPEN_BVE_API_ROOT) -type d) OPEN_BVE_API_SRC := $(foreach sdir, $(OPEN_BVE_API_FOLDERS), $(wildcard $(sdir)/*.cs)) OPEN_BVE_API_DOC := $(addprefix /doc:, $(foreach sdir, $(OPEN_BVE_API_FOLDERS), $(wildcard $(sdir)/*.xml))) OPEN_BVE_API_RESX := $(foreach sdir, $(OPEN_BVE_API_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -396,8 +394,7 @@ $(DEBUG_DIR)/$(OPEN_BVE_API_FILE) $(RELEASE_DIR)/$(OPEN_BVE_API_FILE): $(OPEN_BV # OpenBveAts # ############## -OPEN_BVE_ATS_FOLDERS := . Properties -OPEN_BVE_ATS_FOLDERS := $(addprefix $(OPEN_BVE_ATS_ROOT)/, $(OPEN_BVE_ATS_FOLDERS)) +OPEN_BVE_ATS_FOLDERS := $(shell find $(OPEN_BVE_ATS_ROOT) -type d) OPEN_BVE_ATS_SRC := $(foreach sdir, $(OPEN_BVE_ATS_FOLDERS), $(wildcard $(sdir)/*.cs)) OPEN_BVE_ATS_DOC := $(addprefix /doc:, $(foreach sdir, $(OPEN_BVE_ATS_FOLDERS), $(wildcard $(sdir)/*.xml))) OPEN_BVE_ATS_RESX := $(foreach sdir, $(OPEN_BVE_ATS_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -418,8 +415,7 @@ $(DEBUG_DIR)/$(OPEN_BVE_ATS_FILE) $(RELEASE_DIR)/$(OPEN_BVE_ATS_FILE): $(OPEN_BV # Formats.MSTS # ################ -FORMATS_MSTS_FOLDERS := . Properties -FORMATS_MSTS_FOLDERS := $(addprefix $(FORMATS_MSTS_ROOT)/, $(FORMATS_MSTS_FOLDERS)) +FORMATS_MSTS_FOLDERS := $(shell find $(FORMATS_MSTS_ROOT) -type d) FORMATS_MSTS_SRC := $(foreach sdir, $(FORMATS_MSTS_FOLDERS), $(wildcard $(sdir)/*.cs)) FORMATS_MSTS_DOC := $(addprefix /doc:, $(foreach sdir, $(FORMATS_MSTS_FOLDERS), $(wildcard $(sdir)/*.xml))) FORMATS_MSTS_RESX := $(foreach sdir, $(FORMATS_MSTS_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -441,8 +437,7 @@ $(DEBUG_DIR)/$(FORMATS_MSTS_FILE) $(RELEASE_DIR)/$(FORMATS_MSTS_FILE): $(FORMATS # Sound.Flac # ############## -SOUND_FLAC_FOLDERS := . Properties -SOUND_FLAC_FOLDERS := $(addprefix $(SOUND_FLAC_ROOT)/, $(SOUND_FLAC_FOLDERS)) +SOUND_FLAC_FOLDERS := $(shell find $(SOUND_FLAC_ROOT) -type d) SOUND_FLAC_SRC := $(foreach sdir, $(SOUND_FLAC_FOLDERS), $(wildcard $(sdir)/*.cs)) SOUND_FLAC_DOC := $(addprefix /doc:, $(foreach sdir, $(SOUND_FLAC_FOLDERS), $(wildcard $(sdir)/*.xml))) SOUND_FLAC_RESX := $(foreach sdir, $(SOUND_FLAC_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -463,8 +458,7 @@ $(DEBUG_DIR)/$(SOUND_FLAC_FILE) $(RELEASE_DIR)/$(SOUND_FLAC_FILE): $(SOUND_FLAC_ # Sound.RiffWave # ################## -SOUND_RIFFWAVE_FOLDERS := . Properties -SOUND_RIFFWAVE_FOLDERS := $(addprefix $(SOUND_RIFFWAVE_ROOT)/, $(SOUND_RIFFWAVE_FOLDERS)) +SOUND_RIFFWAVE_FOLDERS := $(shell find $(SOUND_RIFFWAVE_ROOT) -type d) SOUND_RIFFWAVE_SRC := $(foreach sdir, $(SOUND_RIFFWAVE_FOLDERS), $(wildcard $(sdir)/*.cs)) SOUND_RIFFWAVE_DOC := $(addprefix /doc:, $(foreach sdir, $(SOUND_RIFFWAVE_FOLDERS), $(wildcard $(sdir)/*.xml))) SOUND_RIFFWAVE_RESX := $(foreach sdir, $(SOUND_RIFFWAVE_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -485,8 +479,7 @@ $(DEBUG_DIR)/$(SOUND_RIFFWAVE_FILE) $(RELEASE_DIR)/$(SOUND_RIFFWAVE_FILE): $(SOU # Sound.MP3 # ############# -SOUND_MP3_FOLDERS := . Properties -SOUND_MP3_FOLDERS := $(addprefix $(SOUND_MP3_ROOT)/, $(SOUND_MP3_FOLDERS)) +SOUND_MP3_FOLDERS := $(shell find $(SOUND_MP3_ROOT) -type d) SOUND_MP3_SRC := $(foreach sdir, $(SOUND_MP3_FOLDERS), $(wildcard $(sdir)/*.cs)) SOUND_MP3_DOC := $(addprefix /doc:, $(foreach sdir, $(SOUND_MP3_FOLDERS), $(wildcard $(sdir)/*.xml))) SOUND_MP3_RESX := $(foreach sdir, $(SOUND_MP3_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -507,8 +500,7 @@ $(DEBUG_DIR)/$(SOUND_MP3_FILE) $(RELEASE_DIR)/$(SOUND_MP3_FILE): $(SOUND_MP3_SRC # Texture.Ace # ############### -TEXTURE_ACE_FOLDERS := . Properties -TEXTURE_ACE_FOLDERS := $(addprefix $(TEXTURE_ACE_ROOT)/, $(TEXTURE_ACE_FOLDERS)) +TEXTURE_ACE_FOLDERS := $(shell find $(TEXTURE_ACE_ROOT) -type d) TEXTURE_ACE_SRC := $(foreach sdir, $(TEXTURE_ACE_FOLDERS), $(wildcard $(sdir)/*.cs)) TEXTURE_ACE_DOC := $(addprefix /doc:, $(foreach sdir, $(TEXTURE_ACE_FOLDERS), $(wildcard $(sdir)/*.xml))) TEXTURE_ACE_RESX := $(foreach sdir, $(TEXTURE_ACE_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -529,8 +521,7 @@ $(DEBUG_DIR)/$(TEXTURE_ACE_FILE) $(RELEASE_DIR)/$(TEXTURE_ACE_FILE): $(TEXTURE_A # Texture.BmpGifJpegPngTiff # ############################# -TEXTURE_BGJPT_FOLDERS := . Properties -TEXTURE_BGJPT_FOLDERS := $(addprefix $(TEXTURE_BGJPT_ROOT)/, $(TEXTURE_BGJPT_FOLDERS)) +TEXTURE_BGJPT_FOLDERS := $(shell find $(TEXTURE_BGJPT_ROOT) -type d) TEXTURE_BGJPT_SRC := $(foreach sdir, $(TEXTURE_BGJPT_FOLDERS), $(wildcard $(sdir)/*.cs)) TEXTURE_BGJPT_DOC := $(addprefix /doc:, $(foreach sdir, $(TEXTURE_BGJPT_FOLDERS), $(wildcard $(sdir)/*.xml))) TEXTURE_BGJPT_RESX := $(foreach sdir, $(TEXTURE_BGJPT_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -551,8 +542,7 @@ $(DEBUG_DIR)/$(TEXTURE_BGJPT_FILE) $(RELEASE_DIR)/$(TEXTURE_BGJPT_FILE): $(TEXTU # Texture.Dds # ############### -TEXTURE_DDS_FOLDERS := . Properties -TEXTURE_DDS_FOLDERS := $(addprefix $(TEXTURE_DDS_ROOT)/, $(TEXTURE_DDS_FOLDERS)) +TEXTURE_DDS_FOLDERS := $(shell find $(TEXTURE_DDS_ROOT) -type d) TEXTURE_DDS_SRC := $(foreach sdir, $(TEXTURE_DDS_FOLDERS), $(wildcard $(sdir)/*.cs)) TEXTURE_DDS_DOC := $(addprefix /doc:, $(foreach sdir, $(TEXTURE_DDS_FOLDERS), $(wildcard $(sdir)/*.xml))) TEXTURE_DDS_RESX := $(foreach sdir, $(TEXTURE_DDS_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -573,8 +563,7 @@ $(DEBUG_DIR)/$(TEXTURE_DDS_FILE) $(RELEASE_DIR)/$(TEXTURE_DDS_FILE): $(TEXTURE_D # RouteViewer # ############### -ROUTE_VIEWER_FOLDERS := . Audio Parsers Properties System System/Functions -ROUTE_VIEWER_FOLDERS := $(addprefix $(ROUTE_VIEWER_ROOT)/, $(ROUTE_VIEWER_FOLDERS)) +ROUTE_VIEWER_FOLDERS := $(shell find $(ROUTE_VIEWER_ROOT) -type d) ROUTE_VIEWER_SRC := $(foreach sdir, $(ROUTE_VIEWER_FOLDERS), $(wildcard $(sdir)/*.cs)) ROUTE_VIEWER_DOC := $(addprefix /doc:, $(foreach sdir, $(ROUTE_VIEWER_FOLDERS), $(wildcard $(sdir)/*.xml))) ROUTE_VIEWER_RESX := $(foreach sdir, $(ROUTE_VIEWER_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -597,8 +586,7 @@ $(DEBUG_DIR)/$(ROUTE_VIEWER_FILE) $(RELEASE_DIR)/$(ROUTE_VIEWER_FILE): $(ROUTE_V # ObjectBender # ################ -OBJECT_BENDER_FOLDERS := . Properties -OBJECT_BENDER_FOLDERS := $(addprefix $(OBJECT_BENDER_ROOT)/, $(OBJECT_BENDER_FOLDERS)) +OBJECT_BENDER_FOLDERS := $(shell find $(OBJECT_BENDER_ROOT) -type d) OBJECT_BENDER_SRC := $(foreach sdir, $(OBJECT_BENDER_FOLDERS), $(wildcard $(sdir)/*.cs)) OBJECT_BENDER_DOC := $(addprefix /doc:, $(foreach sdir, $(OBJECT_BENDER_FOLDERS), $(wildcard $(sdir)/*.xml))) OBJECT_BENDER_RESX := $(foreach sdir, $(OBJECT_BENDER_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -616,8 +604,7 @@ $(DEBUG_DIR)/$(OBJECT_BENDER_FILE) $(RELEASE_DIR)/$(OBJECT_BENDER_FILE): $(OBJEC # CarXMLConvertor # ################### -CAR_XML_FOLDERS := . Properties -CAR_XML_FOLDERS := $(addprefix $(CAR_XML_ROOT)/, $(CAR_XML_FOLDERS)) +CAR_XML_FOLDERS := $(shell find $(CAR_XML_ROOT) -type d) CAR_XML_SRC := $(foreach sdir, $(CAR_XML_FOLDERS), $(wildcard $(sdir)/*.cs)) CAR_XML_DOC := $(addprefix /doc:, $(foreach sdir, $(CAR_XML_FOLDERS), $(wildcard $(sdir)/*.xml))) CAR_XML_RESX := $(foreach sdir, $(CAR_XML_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -635,8 +622,7 @@ $(DEBUG_DIR)/$(CAR_XML_FILE) $(RELEASE_DIR)/$(CAR_XML_FILE): $(CAR_XML_SRC) $(CA # ObjectViewer # ################ -OBJECT_VIEWER_FOLDERS := . Parsers Parsers/MSTS Properties System -OBJECT_VIEWER_FOLDERS := $(addprefix $(OBJECT_VIEWER_ROOT)/, $(OBJECT_VIEWER_FOLDERS)) +OBJECT_VIEWER_FOLDERS := $(shell find $(OBJECT_VIEWER_ROOT) -type d) OBJECT_VIEWER_SRC := $(foreach sdir, $(OBJECT_VIEWER_FOLDERS), $(wildcard $(sdir)/*.cs)) OBJECT_VIEWER_DOC := $(addprefix /doc:, $(foreach sdir, $(OBJECT_VIEWER_FOLDERS), $(wildcard $(sdir)/*.xml))) OBJECT_VIEWER_RESX := $(foreach sdir, $(OBJECT_VIEWER_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -658,8 +644,7 @@ $(DEBUG_DIR)/$(OBJECT_VIEWER_FILE) $(RELEASE_DIR)/$(OBJECT_VIEWER_FILE): $(OBJEC # TrainEditor # ############### -TRAIN_EDITOR_FOLDERS := . CsvB3dDecoder Properties TrainsimApi/Codecs TrainsimApi/Geometry TrainsimApi/Platform TrainsimApi/Vectors -TRAIN_EDITOR_FOLDERS := $(addprefix $(TRAIN_EDITOR_ROOT)/, $(TRAIN_EDITOR_FOLDERS)) +TRAIN_EDITOR_FOLDERS := $(shell find $(TRAIN_EDITOR_ROOT) -type d) TRAIN_EDITOR_SRC := $(foreach sdir, $(TRAIN_EDITOR_FOLDERS), $(wildcard $(sdir)/*.cs)) TRAIN_EDITOR_DOC := $(addprefix /doc:, $(foreach sdir, $(TRAIN_EDITOR_FOLDERS), $(wildcard $(sdir)/*.xml))) TRAIN_EDITOR_RESX := $(foreach sdir, $(TRAIN_EDITOR_FOLDERS), $(wildcard $(sdir)/*.resx)) @@ -678,8 +663,7 @@ $(DEBUG_DIR)/$(TRAIN_EDITOR_FILE) $(RELEASE_DIR)/$(TRAIN_EDITOR_FILE): $(TRAIN_E # LBAHeader # ############# -LBAHEADER_FOLDERS := . -LBAHEADER_FOLDERS := $(addprefix $(LBAHEADER_ROOT)/, $(LBAHEADER_FOLDERS)) +LBAHEADER_FOLDERS := $(shell find $(LBAHEADER_ROOT) -type d) LBAHEADER_SRC := $(foreach sdir, $(LBAHEADER_FOLDERS), $(wildcard $(sdir)/*.cs)) LBAHEADER_OUT =$(OUTPUT_DIR)/$(LBAHEADER_FILE) diff --git a/source/CarXMLConvertor/Convert.ExtensionsCfg.cs b/source/CarXMLConvertor/Convert.ExtensionsCfg.cs index bf85f8619..444cc9658 100644 --- a/source/CarXMLConvertor/Convert.ExtensionsCfg.cs +++ b/source/CarXMLConvertor/Convert.ExtensionsCfg.cs @@ -477,6 +477,45 @@ internal static void GenerateCarXML(ref TabbedList newLines, int i) newLines.Add("" + ConvertSoundCfg.DriverPosition.X + "," + ConvertSoundCfg.DriverPosition.Y + "," + ConvertSoundCfg.DriverPosition.Z + ""); } } + newLines.Add(""); + if (ConvertTrainDat.MotorCars[i] == true) + { + + newLines.Add(""); + newLines.Add("5000.0"); + newLines.Add(""); + } + + newLines.Add(""); + newLines.Add("" + ConvertTrainDat.MainReservoirMinimumPressure + ""); + newLines.Add("" + ConvertTrainDat.MainReservoirMaximumPressure + ""); + newLines.Add(""); + newLines.Add(""); + newLines.Add("200000.0"); + newLines.Add(""); + newLines.Add(""); + newLines.Add("50000.0"); + newLines.Add("250000.0"); + newLines.Add("200000.0"); + newLines.Add(""); + newLines.Add(""); + newLines.Add("" + ConvertTrainDat.BrakePipePressure + ""); + newLines.Add("1500000.0"); + newLines.Add("5000000.0"); + newLines.Add("10000000.0"); + newLines.Add(""); + newLines.Add(""); + newLines.Add("300000.0"); + newLines.Add("400000.0"); + newLines.Add("200000.0"); + newLines.Add(""); + newLines.Add(""); + newLines.Add("" + ConvertTrainDat.BrakeCylinderServiceMaximumPressure + ""); + newLines.Add("" + ConvertTrainDat.BrakeCylinderEmergencyMaximumPressure + ""); + newLines.Add("" + ConvertTrainDat.BrakeCylinderEmergencyRate + ""); + newLines.Add("" + ConvertTrainDat.BrakeCylinderReleaseRate + ""); + newLines.Add(""); + newLines.Add(""); newLines.Add(""); } diff --git a/source/CarXMLConvertor/Convert.TrainDat.cs b/source/CarXMLConvertor/Convert.TrainDat.cs index 7621beac2..7cb11dd98 100644 --- a/source/CarXMLConvertor/Convert.TrainDat.cs +++ b/source/CarXMLConvertor/Convert.TrainDat.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using System.Windows.Forms; using OpenBveApi.Math; @@ -13,15 +14,24 @@ class ConvertTrainDat internal static double CarHeight = 3.6; internal static double MotorCarMass = 1.0; internal static double TrailerCarMass = 1.0; + internal static double BrakeCylinderServiceMaximumPressure = 440000.0; + internal static double BrakeCylinderEmergencyMaximumPressure = 440000.0; + internal static double BrakeCylinderEmergencyRate = 300000.0; + internal static double BrakeCylinderReleaseRate = 200000.0; + internal static double MainReservoirMinimumPressure = 690000.0; + internal static double MainReservoirMaximumPressure = 780000.0; + internal static double BrakePipePressure = 0.0; private static int NumberOfMotorCars; private static int NumberOfTrailerCars; private static bool FrontCarIsMotorCar; internal static bool[] MotorCars; internal static int DriverCar = 0; - private static System.Windows.Forms.Form mainForm; - internal static void Process(Form form) + internal static int BrakeType = 0; + private static MainForm mainForm; + internal static void Process(MainForm form) { mainForm = form; + if (!System.IO.File.Exists(FileName)) { MessageBox.Show("The selected folder does not contain a valid train.dat \r\n Please retry.", "CarXML Convertor", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -107,7 +117,71 @@ internal static void Process(Form form) i++; n++; } i--; break; - + case "#brake": + i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) + { + int a; if (NumberFormats.TryParseIntVb6(Lines[i], out a)) + { + switch (n) + { + case 0: BrakeType = a; break; + } + } + i++; n++; + } + i--; break; + case "#move": + i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) + { + double a; if (NumberFormats.TryParseDoubleVb6(Lines[i], out a)) + { + switch (n) + { + case 4: BrakeCylinderEmergencyRate = a * 1000.0; break; + case 5: BrakeCylinderReleaseRate = a * 1000.0; break; + } + } + i++; n++; + } + i--; break; + case "#pressure": + i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) { + double a; if (NumberFormats.TryParseDoubleVb6(Lines[i], out a)) { + switch (n) { + case 0: + if (a <= 0.0) + { + mainForm.updateLogBoxText += "BrakeCylinderServiceMaximumPressure is expected to be positive at line " + (i + 1).ToString(CultureInfo.InvariantCulture) + " in " + FileName; + } else { + BrakeCylinderServiceMaximumPressure = a * 1000.0; + } break; + case 1: + if (a <= 0.0) { + mainForm.updateLogBoxText += "BrakeCylinderEmergencyMaximumPressure is expected to be positive at line " + (i + 1).ToString(CultureInfo.InvariantCulture) + " in " + FileName; + } else { + BrakeCylinderEmergencyMaximumPressure = a * 1000.0; + } break; + case 2: + if (a <= 0.0) { + mainForm.updateLogBoxText += "MainReservoirMinimumPressure is expected to be positive at line " + (i + 1).ToString(CultureInfo.InvariantCulture) + " in " + FileName; + } else { + MainReservoirMinimumPressure = a * 1000.0; + } break; + case 3: + if (a <= 0.0) { + mainForm.updateLogBoxText += "MainReservoirMaximumPressure is expected to be positive at line " + (i + 1).ToString(CultureInfo.InvariantCulture) + " in " + FileName; + } else { + MainReservoirMaximumPressure = a * 1000.0; + } break; + case 4: + if (a <= 0.0) { + mainForm.updateLogBoxText += "BrakePipePressue is expected to be positive at line " + (i + 1).ToString(CultureInfo.InvariantCulture) + " in " + FileName; + } else { + BrakePipePressure = a * 1000.0; + } break; + } + } i++; n++; + } i--; break; default: { i++; @@ -120,6 +194,31 @@ internal static void Process(Form form) break; } } + + if (BrakePipePressure <= 0.0) + { + + if (BrakeType == 2) //Automatic air brake + { + BrakePipePressure = BrakeCylinderEmergencyMaximumPressure + 0.75 * (MainReservoirMinimumPressure - BrakeCylinderEmergencyMaximumPressure); + if (BrakePipePressure > MainReservoirMinimumPressure) + { + BrakePipePressure = MainReservoirMinimumPressure; + } + } + else + { + if (BrakeCylinderEmergencyMaximumPressure < 480000.0 & MainReservoirMinimumPressure > 500000.0) + { + BrakePipePressure = 490000.0; + } + else + { + BrakePipePressure = BrakeCylinderEmergencyMaximumPressure + 0.75 * (MainReservoirMinimumPressure - BrakeCylinderEmergencyMaximumPressure); + } + } + } + NumberOfCars = NumberOfMotorCars + NumberOfTrailerCars; MotorCars = new bool[NumberOfCars]; if (NumberOfMotorCars == 1) diff --git a/source/CarXMLConvertor/mainForm.cs b/source/CarXMLConvertor/mainForm.cs index 94dd419dd..848c119b7 100644 --- a/source/CarXMLConvertor/mainForm.cs +++ b/source/CarXMLConvertor/mainForm.cs @@ -68,6 +68,7 @@ private void process_Click(object sender, EventArgs e) else { updateLogBoxText += "INFO: Using a train.xml file with child car files." + Environment.NewLine; + ConvertExtensionsCfg.SingleFile = false; } ConvertExtensionsCfg.Process(this); updateLogBoxText += "Processing complete."; diff --git a/source/ObjectViewer/FunctionScripts.cs b/source/ObjectViewer/FunctionScripts.cs index 9b49e4cf4..c3cc15458 100644 --- a/source/ObjectViewer/FunctionScripts.cs +++ b/source/ObjectViewer/FunctionScripts.cs @@ -18,7 +18,7 @@ internal enum Instructions { TrainCars, TrainDestination, TrainSpeed, TrainSpeedometer, TrainAcceleration, TrainAccelerationMotor, TrainSpeedOfCar, TrainSpeedometerOfCar, TrainAccelerationOfCar, TrainAccelerationMotorOfCar, - TrainDistance, TrainDistanceToCar, TrainTrackDistance, TrainTrackDistanceToCar, CurveRadius, FrontAxleCurveRadius, RearAxleCurveRadius, CurveCant, Odometer, OdometerOfCar, + TrainDistance, TrainDistanceToCar, TrainTrackDistance, TrainTrackDistanceToCar, CurveRadius, FrontAxleCurveRadius, RearAxleCurveRadius, CurveCant, Pitch, Odometer, OdometerOfCar, Doors, DoorsIndex, LeftDoors, LeftDoorsIndex, RightDoors, RightDoorsIndex, LeftDoorsTarget, LeftDoorsTargetIndex, RightDoorsTarget, RightDoorsTargetIndex, @@ -513,6 +513,25 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. } } break; + case Instructions.Pitch: + if (Train == null) + { + Function.Stack[s - 1] = 0.0; + } + else + { + int j = (int)Math.Round(Function.Stack[s - 1]); + if (j < 0) j += Train.Cars.Length; + if (j >= 0 & j < Train.Cars.Length) + { + Function.Stack[s - 1] = Train.Cars[j].FrontAxle.Follower.Pitch; + } + else + { + Function.Stack[s - 1] = 0.0; + } + } + break; case Instructions.Odometer: Function.Stack[s] = 0.0; s++; @@ -1359,6 +1378,10 @@ private static string GetPostfixNotationFromFunctionNotation(string Expression) if (Expression.EndsWith("]")) { throw new System.IO.InvalidDataException("Unexpected closing bracket encountered in " + Expression); } else { + // ReSharper disable once NotAccessedVariable + /* + * If this is a simple number, we can short-circuit the rest of this function + */ double value; if (double.TryParse(Expression, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out value)) { return Expression; @@ -1607,6 +1630,7 @@ private static string GetPostfixNotationFromFunctionNotation(string Expression) case "frontaxlecurveradius": case "rearaxlecurveradius": case "curvecant": + case "pitch": case "odometer": case "speed": case "speedometer": @@ -2470,6 +2494,11 @@ internal static FunctionScript GetFunctionScriptFromPostfixNotation(string Expre if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); Result.Instructions[n] = Instructions.CurveCant; n++; break; + case "pitchindex": + if (s < 1) throw new System.InvalidOperationException(Arguments[i] + " requires at least 1 argument on the stack in function script " + Expression); + if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); + Result.Instructions[n] = Instructions.Pitch; + n++; break; case "odometer": if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); Result.Instructions[n] = Instructions.Odometer; diff --git a/source/ObjectViewer/InterfaceS.cs b/source/ObjectViewer/InterfaceS.cs index c0a22557f..6334e3566 100644 --- a/source/ObjectViewer/InterfaceS.cs +++ b/source/ObjectViewer/InterfaceS.cs @@ -83,6 +83,7 @@ internal struct TrackFollower { internal Vector3 WorldSide; internal double CurveRadius; internal double CurveCant; + internal double Pitch; internal double CantDueToInaccuracy; } internal static void UpdateTrackFollower(ref TrackFollower Follower, double NewTrackPosition, bool UpdateWorldCoordinates, bool AddTrackInaccurary) { } diff --git a/source/ObjectViewer/ObjectManager.cs b/source/ObjectViewer/ObjectManager.cs index 732849c65..e144d6f3b 100644 --- a/source/ObjectViewer/ObjectManager.cs +++ b/source/ObjectViewer/ObjectManager.cs @@ -1,6 +1,7 @@ using System; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { @@ -1440,7 +1441,7 @@ internal class AnimatedWorldObject } internal static AnimatedWorldObject[] AnimatedWorldObjects = new AnimatedWorldObject[4]; internal static int AnimatedWorldObjectsUsed = 0; - internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) + internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { bool[] free = new bool[Prototypes.Length]; bool anyfree = false; @@ -1467,7 +1468,7 @@ internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vec if (free[i]) { Vector3 p = Position; - World.Transformation t = new OpenBve.World.Transformation(BaseTransformation, AuxTransformation); + Transformation t = new Transformation(BaseTransformation, AuxTransformation); Vector3 s = t.X; Vector3 u = t.Y; Vector3 d = t.Z; @@ -1495,14 +1496,14 @@ internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vec } } } - internal static int CreateAnimatedWorldObject(AnimatedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) + internal static int CreateAnimatedWorldObject(AnimatedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) { Array.Resize(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1); } - World.Transformation FinalTransformation = new World.Transformation(BaseTransformation, AuxTransformation); + Transformation FinalTransformation = new Transformation(BaseTransformation, AuxTransformation); AnimatedWorldObjects[a] = new AnimatedWorldObject(); AnimatedWorldObjects[a].Position = Position; AnimatedWorldObjects[a].Direction = FinalTransformation.Z; @@ -1807,7 +1808,7 @@ internal static void JoinObjects(ref StaticObject Base, StaticObject Add) } // create object - internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) + internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { if (Prototype != null) { @@ -1823,7 +1824,7 @@ internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, Wor ObjectsUsed++; } } - internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) + internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { if (Prototype is StaticObject) { @@ -1838,11 +1839,11 @@ internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, Wor } // create static object - internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) + internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { return CreateStaticObject(Prototype, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0, false); } - internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) + internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { int a = ObjectsUsed; if (a >= Objects.Length) @@ -1874,7 +1875,7 @@ internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, ObjectsUsed++; return a; } - internal static void ApplyStaticObjectData(ref StaticObject Object, StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) + internal static void ApplyStaticObjectData(ref StaticObject Object, StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { Object = new StaticObject(); Object.StartingDistance = float.MaxValue; diff --git a/source/ObjectViewer/Parsers/CsvB3dObjectParser.cs b/source/ObjectViewer/Parsers/CsvB3dObjectParser.cs index 44bb7cd87..48a734bef 100644 --- a/source/ObjectViewer/Parsers/CsvB3dObjectParser.cs +++ b/source/ObjectViewer/Parsers/CsvB3dObjectParser.cs @@ -622,9 +622,9 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te y *= t; z *= t; a *= 0.0174532925199433; - ApplyRotation(Builder, x, y, z, a); + ApplyRotation(Builder,new Vector3(x,y,z), a); if (cmd == "rotateall") { - ApplyRotation(Object, x, y, z, a); + ApplyRotation(Object, new Vector3(x,y,z), a); } } } break; @@ -1414,27 +1414,27 @@ internal static void ApplyScale(ObjectManager.StaticObject Object, double x, dou } // apply rotation - private static void ApplyRotation(MeshBuilder Builder, double x, double y, double z, double a) { - double cosa = Math.Cos(a); - double sina = Math.Sin(a); + private static void ApplyRotation(MeshBuilder Builder, Vector3 Rotation, double Angle) { + double cosa = Math.Cos(Angle); + double sina = Math.Sin(Angle); for (int i = 0; i < Builder.Vertices.Length; i++) { - World.Rotate(ref Builder.Vertices[i].Coordinates, x, y, z, cosa, sina); + Builder.Vertices[i].Coordinates.Rotate(Rotation, cosa, sina); } for (int i = 0; i < Builder.Faces.Length; i++) { for (int j = 0; j < Builder.Faces[i].Vertices.Length; j++) { - World.Rotate(ref Builder.Faces[i].Vertices[j].Normal, x, y, z, cosa, sina); + Builder.Faces[i].Vertices[j].Normal.Rotate(Rotation, cosa, sina); } } } - private static void ApplyRotation(ObjectManager.StaticObject Object, double x, double y, double z, double a) { - double cosa = Math.Cos(a); - double sina = Math.Sin(a); + private static void ApplyRotation(ObjectManager.StaticObject Object, Vector3 Rotation, double Angle) { + double cosa = Math.Cos(Angle); + double sina = Math.Sin(Angle); for (int j = 0; j < Object.Mesh.Vertices.Length; j++) { - World.Rotate(ref Object.Mesh.Vertices[j].Coordinates, x, y, z, cosa, sina); + Object.Mesh.Vertices[j].Coordinates.Rotate(Rotation, cosa, sina); } for (int j = 0; j < Object.Mesh.Faces.Length; j++) { for (int k = 0; k < Object.Mesh.Faces[j].Vertices.Length; k++) { - World.Rotate(ref Object.Mesh.Faces[j].Vertices[k].Normal, x, y, z, cosa, sina); + Object.Mesh.Faces[j].Vertices[k].Normal.Rotate(Rotation, cosa, sina); } } } diff --git a/source/ObjectViewer/Parsers/MSTS/ShapeParser.cs b/source/ObjectViewer/Parsers/MSTS/ShapeParser.cs index d2d56db56..5958c0177 100644 --- a/source/ObjectViewer/Parsers/MSTS/ShapeParser.cs +++ b/source/ObjectViewer/Parsers/MSTS/ShapeParser.cs @@ -16,7 +16,7 @@ // ReSharper disable NotAccessedField.Local // ReSharper disable RedundantAssignment // ReSharper disable UnusedVariable -#pragma warning disable 2019 +#pragma warning disable 0219 namespace OpenBve { class MsTsShapeParser @@ -630,7 +630,7 @@ private static void ParseBlock(Block block, ref MsTsShape shape, ref Vertex vert break; case KujuTokenID.texture: - int imageIDX = (int) block.ReadUInt32(); + int imageIDX = block.ReadInt32(); int filterMode = (int) block.ReadUInt32(); float mipmapLODBias = block.ReadSingle(); uint borderColor = 0xff000000U; @@ -1077,4 +1077,4 @@ private static void ParseBlock(Block block, ref MsTsShape shape, ref Vertex vert } } } -#pragma warning restore 2019 +#pragma warning restore 0219 diff --git a/source/ObjectViewer/Parsers/WavefrontObjParser.cs b/source/ObjectViewer/Parsers/WavefrontObjParser.cs index 2b245fb4d..66d452bb8 100644 --- a/source/ObjectViewer/Parsers/WavefrontObjParser.cs +++ b/source/ObjectViewer/Parsers/WavefrontObjParser.cs @@ -137,8 +137,6 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te { Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid X co-ordinate in Texture Co-Ordinates at Line " + i); } - //Wavefront obj texture co-ords Y axis appear inverted v.s. BVE standard - coords.Y = -coords.Y; tempCoords.Add(coords); break; case "vn": @@ -218,6 +216,10 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te currentCoord++; currentCoord += idx; } + else + { + currentCoord = idx; + } if (currentCoord > tempCoords.Count) { Interface.AddMessage(Interface.MessageType.Warning, false, "Texture Co-ordinate index " + currentCoord + " was greater than the available number of texture co-ordinates in Face " + f + " at Line " + i); @@ -252,6 +254,10 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te currentNormal++; currentNormal += idx; } + else + { + currentNormal = idx; + } if (currentNormal > tempNormals.Count) { Interface.AddMessage(Interface.MessageType.Warning, false, "Vertex Normal index " + currentNormal + " was greater than the available number of normals in Face " + f + " at Line " + i); diff --git a/source/ObjectViewer/Parsers/XObjectParser.cs b/source/ObjectViewer/Parsers/XObjectParser.cs index 3f9794893..394f6b1b5 100644 --- a/source/ObjectViewer/Parsers/XObjectParser.cs +++ b/source/ObjectViewer/Parsers/XObjectParser.cs @@ -39,7 +39,7 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te return LoadTextualX(FileName, System.IO.File.ReadAllText(FileName), Encoding, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); } else if (Data[8] == 98 & Data[9] == 105 & Data[10] == 110 & Data[11] == 32) { // binary flavor - return LoadBinaryX(FileName, Data, 16, Encoding, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); + return LoadBinaryX(FileName, Data, 16, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); } else if (Data[8] == 116 & Data[9] == 122 & Data[10] == 105 & Data[11] == 112) { // compressed textual flavor #if !DEBUG @@ -60,7 +60,7 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te try { #endif byte[] Uncompressed = Decompress(Data); - return LoadBinaryX(FileName, Uncompressed, 0, Encoding, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); + return LoadBinaryX(FileName, Uncompressed, 0, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Error, false, "An unexpected error occured (" + ex.Message + ") while attempting to decompress the binary X object file encountered in " + FileName); @@ -844,7 +844,7 @@ private static bool ReadTextualTemplate(string FileName, string Content, ref int // ================================ // load binary x - private static ObjectManager.StaticObject LoadBinaryX(string FileName, byte[] Data, int StartingPosition, System.Text.Encoding Encoding, int FloatingPointSize, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { + private static ObjectManager.StaticObject LoadBinaryX(string FileName, byte[] Data, int StartingPosition, int FloatingPointSize, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { // parse file AlternateStructure = false; LoadedMaterials = new Structure[] {}; diff --git a/source/ObjectViewer/ProgramS.cs b/source/ObjectViewer/ProgramS.cs index e0a24010b..047bd91f5 100644 --- a/source/ObjectViewer/ProgramS.cs +++ b/source/ObjectViewer/ProgramS.cs @@ -8,6 +8,7 @@ using System; using System.Text; using System.Windows.Forms; +using OpenBveApi.World; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; @@ -27,7 +28,6 @@ internal enum ProgramType { OpenBve, ObjectViewer, RouteViewer, Other } internal const ProgramType CurrentProgramType = ProgramType.ObjectViewer; // members - private const bool Quit = false; internal static string[] Files = new string[] { }; internal static bool[] SkipArgs; @@ -220,7 +220,7 @@ internal static void DragFile(object sender, FileDropEventArgs e) ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), - new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, + new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } @@ -324,7 +324,7 @@ internal static void KeyDown(object sender, KeyboardKeyEventArgs e) ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), - new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, + new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { @@ -369,7 +369,7 @@ internal static void KeyDown(object sender, KeyboardKeyEventArgs e) ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Files[i], System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), - new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, + new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } diff --git a/source/ObjectViewer/System/GameWindow.cs b/source/ObjectViewer/System/GameWindow.cs index a2b03376f..1010060e3 100644 --- a/source/ObjectViewer/System/GameWindow.cs +++ b/source/ObjectViewer/System/GameWindow.cs @@ -318,7 +318,7 @@ protected override void OnLoad(EventArgs e) // ObjectManager.UnifiedObject o = ObjectManager.LoadObject(commandLineArgs[i], // System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false,0,0,0); // ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), - // new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, + // new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, // 0.0, 0.0, 25.0, 0.0); // } // catch (Exception ex) diff --git a/source/ObjectViewer/WorldS.cs b/source/ObjectViewer/WorldS.cs index c448a86fc..3f7f36ab3 100644 --- a/source/ObjectViewer/WorldS.cs +++ b/source/ObjectViewer/WorldS.cs @@ -9,6 +9,7 @@ using OpenBveApi.Colors; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { public static class World { @@ -482,102 +483,7 @@ internal static void Cross(double ax, double ay, double az, double bx, double by cz = ax * by - ay * bx; } - // transformation - internal struct Transformation { - internal Vector3 X; - internal Vector3 Y; - internal Vector3 Z; - internal Transformation(double Yaw, double Pitch, double Roll) { - if (Yaw == 0.0 & Pitch == 0.0 & Roll == 0.0) { - this.X = new Vector3(1.0, 0.0, 0.0); - this.Y = new Vector3(0.0, 1.0, 0.0); - this.Z = new Vector3(0.0, 0.0, 1.0); - } else if (Pitch == 0.0 & Roll == 0.0) { - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - this.X = new Vector3(cosYaw, 0.0, -sinYaw); - this.Y = new Vector3(0.0, 1.0, 0.0); - this.Z = new Vector3(sinYaw, 0.0, cosYaw); - } else { - double sx = 1.0, sy = 0.0, sz = 0.0; - double ux = 0.0, uy = 1.0, uz = 0.0; - double dx = 0.0, dy = 0.0, dz = 1.0; - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - double cosPitch = Math.Cos(-Pitch); - double sinPitch = Math.Sin(-Pitch); - double cosRoll = Math.Cos(-Roll); - double sinRoll = Math.Sin(-Roll); - Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosRoll, sinRoll); - Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosRoll, sinRoll); - this.X = new Vector3(sx, sy, sz); - this.Y = new Vector3(ux, uy, uz); - this.Z = new Vector3(dx, dy, dz); - } - } - internal Transformation(Transformation Transformation, double Yaw, double Pitch, double Roll) { - double sx = Transformation.X.X, sy = Transformation.X.Y, sz = Transformation.X.Z; - double ux = Transformation.Y.X, uy = Transformation.Y.Y, uz = Transformation.Y.Z; - double dx = Transformation.Z.X, dy = Transformation.Z.Y, dz = Transformation.Z.Z; - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - double cosPitch = Math.Cos(-Pitch); - double sinPitch = Math.Sin(-Pitch); - double cosRoll = Math.Cos(Roll); - double sinRoll = Math.Sin(Roll); - Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosRoll, sinRoll); - Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosRoll, sinRoll); - this.X = new Vector3(sx, sy, sz); - this.Y = new Vector3(ux, uy, uz); - this.Z = new Vector3(dx, dy, dz); - } - internal Transformation(Transformation BaseTransformation, Transformation AuxTransformation) { - Vector3 x = BaseTransformation.X; - Vector3 y = BaseTransformation.Y; - Vector3 z = BaseTransformation.Z; - Vector3 s = AuxTransformation.X; - Vector3 u = AuxTransformation.Y; - Vector3 d = AuxTransformation.Z; - Rotate(ref x.X, ref x.Y, ref x.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - Rotate(ref y.X, ref y.Y, ref y.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - Rotate(ref z.X, ref z.Y, ref z.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - this.X = x; - this.Y = y; - this.Z = z; - } - } - - /// Rotates one vector based upon a second vector, input as induvidual co-ordinates - /// The vector to rotate - /// The X co-ordinate of the second vector - /// The Y co-ordinate of the second vector - /// The Z co-ordinate of the second vector - /// The Cosine of the angle to rotate by - /// The Sine of the angle to rotate by - internal static void Rotate(ref Vector3 p, double dx, double dy, double dz, double cosa, double sina) - { - double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz); - dx *= t; dy *= t; dz *= t; - double oc = 1.0 - cosa; - double Opt1 = oc * dx * dy; - double Opt2 = sina * dz; - double Opt3 = oc * dy * dz; - double Opt4 = sina * dx; - double Opt5 = sina * dy; - double Opt6 = oc * dx * dz; - double x = (cosa + oc * dx * dx) * p.X + (Opt1 - Opt2) * p.Y + (Opt6 + Opt5) * p.Z; - double y = (cosa + oc * dy * dy) * p.Y + (Opt1 + Opt2) * p.X + (Opt3 - Opt4) * p.Z; - double z = (cosa + oc * dz * dz) * p.Z + (Opt6 - Opt5) * p.X + (Opt3 + Opt4) * p.Y; - p.X = x; p.Y = y; p.Z = z; - } + internal static void Rotate(ref double px, ref double py, ref double pz, double dx, double dy, double dz, double cosa, double sina) { double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz); dx *= t; dy *= t; dz *= t; @@ -587,28 +493,7 @@ internal static void Rotate(ref double px, ref double py, ref double pz, double double z = (cosa + oc * dz * dz) * pz + (oc * dx * dz - sina * dy) * px + (oc * dy * dz + sina * dx) * py; px = x; py = y; pz = z; } - internal static void Rotate(ref float px, ref float py, ref float pz, double dx, double dy, double dz, double cosa, double sina) { - double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz); - dx *= t; dy *= t; dz *= t; - double oc = 1.0 - cosa; - double x = (cosa + oc * dx * dx) * (double)px + (oc * dx * dy - sina * dz) * (double)py + (oc * dx * dz + sina * dy) * (double)pz; - double y = (cosa + oc * dy * dy) * (double)py + (oc * dx * dy + sina * dz) * (double)px + (oc * dy * dz - sina * dx) * (double)pz; - double z = (cosa + oc * dz * dz) * (double)pz + (oc * dx * dz - sina * dy) * (double)px + (oc * dy * dz + sina * dx) * (double)py; - px = (float)x; py = (float)y; pz = (float)z; - } - internal static void Rotate(ref Vector2 Vector, double cosa, double sina) { - double u = Vector.X * cosa - Vector.Y * sina; - double v = Vector.X * sina + Vector.Y * cosa; - Vector.X = u; - Vector.Y = v; - } - internal static void Rotate(ref float px, ref float py, ref float pz, double dx, double dy, double dz, double ux, double uy, double uz, double sx, double sy, double sz) { - double x, y, z; - x = sx * (double)px + ux * (double)py + dx * (double)pz; - y = sy * (double)px + uy * (double)py + dy * (double)pz; - z = sz * (double)px + uz * (double)py + dz * (double)pz; - px = (float)x; py = (float)y; pz = (float)z; - } + internal static void Rotate(ref double px, ref double py, ref double pz, double dx, double dy, double dz, double ux, double uy, double uz, double sx, double sy, double sz) { double x, y, z; x = sx * px + ux * py + dx * pz; @@ -616,13 +501,6 @@ internal static void Rotate(ref double px, ref double py, ref double pz, double z = sz * px + uz * py + dz * pz; px = x; py = y; pz = z; } - internal static void Rotate(ref float px, ref float py, ref float pz, Transformation t) { - double x, y, z; - x = t.X.X * (double)px + t.Y.X * (double)py + t.Z.X * (double)pz; - y = t.X.Y * (double)px + t.Y.Y * (double)py + t.Z.Y * (double)pz; - z = t.X.Z * (double)px + t.Y.Z * (double)py + t.Z.Z * (double)pz; - px = (float)x; py = (float)y; pz = (float)z; - } internal static void Rotate(ref double px, ref double py, ref double pz, Transformation t) { double x, y, z; x = t.X.X * px + t.Y.X * py + t.Z.X * pz; @@ -636,42 +514,7 @@ internal static void RotatePlane(ref Vector3 Vector, double cosa, double sina) { Vector.X = u; Vector.Z = v; } - - internal static void RotateUpDown(ref Vector3 Vector, Vector2 Direction, double cosa, double sina) { - double dx = Direction.X, dy = Direction.Y; - double x = Vector.X, y = Vector.Y, z = Vector.Z; - double u = dy * x - dx * z; - double v = dx * x + dy * z; - Vector.X = dy * u + dx * v * cosa - dx * y * sina; - Vector.Y = y * cosa + v * sina; - Vector.Z = -dx * u + dy * v * cosa - dy * y * sina; - } - internal static void RotateUpDown(ref Vector3 Vector, double dx, double dy, double cosa, double sina) { - double x = Vector.X, y = Vector.Y, z = Vector.Z; - double u = dy * x - dx * z; - double v = dx * x + dy * z; - Vector.X = dy * u + dx * v * cosa - dx * y * sina; - Vector.Y = y * cosa + v * sina; - Vector.Z = -dx * u + dy * v * cosa - dy * y * sina; - } - - internal static void RotateUpDown(ref double px, ref double py, ref double pz, double dx, double dz, double cosa, double sina) { - double x = px, y = py, z = pz; - double u = dz * x - dx * z; - double v = dx * x + dz * z; - px = dz * u + dx * v * cosa - dx * y * sina; - py = y * cosa + v * sina; - pz = -dx * u + dz * v * cosa - dz * y * sina; - } - - // normalize - internal static void Normalize(ref double x, ref double y) { - double t = x * x + y * y; - if (t != 0.0) { - t = 1.0 / Math.Sqrt(t); - x *= t; y *= t; - } - } + internal static void Normalize(ref double x, ref double y, ref double z) { double t = x * x + y * y + z * z; if (t != 0.0) { diff --git a/source/ObjectViewer/formMessages.cs b/source/ObjectViewer/formMessages.cs index e9d9f0c05..1003abe9a 100644 --- a/source/ObjectViewer/formMessages.cs +++ b/source/ObjectViewer/formMessages.cs @@ -6,7 +6,7 @@ namespace OpenBve { public partial class formMessages : Form { - public formMessages() + private formMessages() { InitializeComponent(); } diff --git a/source/ObjectViewer/formOptions.cs b/source/ObjectViewer/formOptions.cs index b05d46d5f..6d3324ac9 100644 --- a/source/ObjectViewer/formOptions.cs +++ b/source/ObjectViewer/formOptions.cs @@ -1,13 +1,14 @@ using System; using System.Windows.Forms; using OpenBveApi.Math; +using OpenBveApi.World; using OpenTK.Graphics; namespace OpenBve { public partial class formOptions : Form { - public formOptions() + private formOptions() { InitializeComponent(); InterpolationMode.SelectedIndex = (int) Interface.CurrentOptions.Interpolation; @@ -95,7 +96,7 @@ private void button1_Click(object sender, EventArgs e) #endif ObjectManager.UnifiedObject o = ObjectManager.LoadObject(Program.Files[i], System.Text.Encoding.UTF8,ObjectManager.ObjectLoadMode.Normal, false, false, false); ObjectManager.CreateObject(o, new Vector3(0.0, 0.0, 0.0), - new World.Transformation(0.0, 0.0, 0.0), new World.Transformation(0.0, 0.0, 0.0), true, 0.0, + new Transformation(0.0, 0.0, 0.0), new Transformation(0.0, 0.0, 0.0), true, 0.0, 0.0, 25.0, 0.0); #if !DEBUG } catch (Exception ex) { diff --git a/source/OpenBVE/Audio/Sounds.cs b/source/OpenBVE/Audio/Sounds.cs index 00011b14f..b8a9651ef 100644 --- a/source/OpenBVE/Audio/Sounds.cs +++ b/source/OpenBVE/Audio/Sounds.cs @@ -29,7 +29,7 @@ internal static partial class Sounds private static int SourceCount = 0; /// The gain threshold. Sounds with gains below this value are not played. - internal const double GainThreshold = 0.0001; + private const double GainThreshold = 0.0001; /// Whether all sounds are mute. internal static bool GlobalMute = false; @@ -171,15 +171,15 @@ internal static SoundBuffer RegisterBuffer(OpenBveApi.Sounds.Sound data, double /// Loads the specified sound buffer. /// The sound buffer. /// Whether loading the buffer was successful. - internal static bool LoadBuffer(SoundBuffer buffer) + internal static void LoadBuffer(SoundBuffer buffer) { if (buffer.Loaded) { - return true; + return; } if (buffer.Ignore) { - return false; + return; } OpenBveApi.Sounds.Sound sound; if (buffer.Origin.GetSound(out sound)) @@ -192,11 +192,10 @@ internal static bool LoadBuffer(SoundBuffer buffer) AL.BufferData(buffer.OpenAlBufferName, format, bytes, bytes.Length, sound.SampleRate); buffer.Duration = sound.Duration; buffer.Loaded = true; - return true; + return; } } buffer.Ignore = true; - return false; } /// Loads all sound buffers immediately. diff --git a/source/OpenBVE/Game/AI/AI.SimpleHuman.cs b/source/OpenBVE/Game/AI/AI.SimpleHuman.cs index 77f7c0a5f..e203fc0d2 100644 --- a/source/OpenBVE/Game/AI/AI.SimpleHuman.cs +++ b/source/OpenBVE/Game/AI/AI.SimpleHuman.cs @@ -148,12 +148,12 @@ private void PerformDefault() } // do the ai Train.Specs.CurrentConstSpeed = false; - TrainManager.ApplyHoldBrake(Train, false); + Train.ApplyHoldBrake(false); int stopIndex = Train.Station >= 0 ? GetStopIndex(Train.Station, Train.Cars.Length) : -1; if (Train.CurrentSectionLimit == 0.0) { // passing red signal - TrainManager.ApplyEmergencyBrake(Train); + Train.ApplyEmergencyBrake(); Train.ApplyNotch(-1, true, 1, true); CurrentInterval = 0.5; } @@ -166,30 +166,30 @@ private void PerformDefault() // player's terminal station if (Train.Plugin == null || Train.Plugin.LastReverser == -2) { - TrainManager.ApplyReverser(Train, 0, false); + Train.ApplyReverser(0, false); } Train.ApplyNotch(-1, true, 1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); - TrainManager.ApplyEmergencyBrake(Train); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); + Train.ApplyEmergencyBrake(); CurrentInterval = 1.0; } else { CurrentInterval = 1.0; Train.ApplyNotch(-1, true, 0, true); - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { - if (Train.Cars[Train.DriverCar].Specs.AirBrake.BrakeCylinderCurrentPressure < 0.3 * Train.Cars[Train.DriverCar].Specs.AirBrake.BrakeCylinderServiceMaximumPressure) + if (Train.Cars[Train.DriverCar].CarBrake.brakeCylinder.CurrentPressure < 0.3 * Train.Cars[Train.DriverCar].CarBrake.brakeCylinder.ServiceMaximumPressure) { - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); } - else if (Train.Cars[Train.DriverCar].Specs.AirBrake.BrakeCylinderCurrentPressure > 0.9 * Train.Cars[Train.DriverCar].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure) + else if (Train.Cars[Train.DriverCar].CarBrake.brakeCylinder.CurrentPressure > 0.9 * Train.Cars[Train.DriverCar].CarBrake.brakeCylinder.EmergencyMaximumPressure) { - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); } else { - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Lap); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); } } else @@ -213,7 +213,7 @@ private void PerformDefault() Train.ApplyNotch(0, true, -1, true); } } - TrainManager.UnapplyEmergencyBrake(Train); + Train.UnapplyEmergencyBrake(); if (Train.Station >= 0 & Train.StationState == TrainManager.TrainStopState.Completed) { // ready for departure - close doors @@ -249,17 +249,17 @@ private void PerformDefault() // player's terminal station (not boarding any longer) if (Train.Plugin != null || Train.Plugin.LastReverser == -2) { - TrainManager.ApplyReverser(Train, 0, false); + Train.ApplyReverser(0, false); } Train.ApplyNotch(-1, true, 1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); - TrainManager.ApplyEmergencyBrake(Train); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); + Train.ApplyEmergencyBrake(); CurrentInterval = 10.0; } else { // drive - TrainManager.ApplyReverser(Train, 1, false); + Train.ApplyReverser(1, false); if (Train.Cars[Train.DriverCar].FrontAxle.CurrentWheelSlip | Train.Cars[Train.DriverCar].RearAxle.CurrentWheelSlip) { // react to wheel slip @@ -267,7 +267,7 @@ private void PerformDefault() { this.PowerNotchAtWhichWheelSlipIsObserved = Train.Handles.Power.Driver; Train.ApplyNotch(-1, true, -1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); this.CurrentInterval = 2.5; return; } @@ -316,19 +316,19 @@ private void PerformDefault() double decelerationCruise; /* power below this deceleration, cruise above */ double decelerationStart; /* brake above this deceleration, cruise below */ double decelerationStep; /* the deceleration step per brake notch */ - double BrakeDeceleration = Train.Cars[Train.DriverCar].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.Brake.Actual); + double BrakeDeceleration = Train.Cars[Train.DriverCar].CarBrake.DecelerationAtServiceMaximumPressure(Train.Handles.Brake.Actual, Train.Cars[Train.DriverCar].Specs.CurrentSpeed); for (int i = 0; i < Train.Cars.Length; i++) { if (Train.Cars[i].Specs.IsMotorCar) { - if (Train.Cars[Train.DriverCar].Specs.MotorDeceleration < BrakeDeceleration) + if (Train.Cars[Train.DriverCar].Specs.MotorDeceleration != 0 && Train.Cars[Train.DriverCar].Specs.MotorDeceleration < BrakeDeceleration) { BrakeDeceleration = Train.Cars[Train.DriverCar].Specs.MotorDeceleration; } break; } } - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake | Train.Handles.Brake.MaximumNotch <= 0) + if (Train.Handles.Brake is TrainManager.AirBrakeHandle | Train.Handles.Brake.MaximumNotch <= 0) { decelerationCruise = 0.3 * BrakeDeceleration; decelerationStart = 0.5 * BrakeDeceleration; @@ -601,15 +601,15 @@ private void PerformDefault() else if (dist >= 5.0) { Train.ApplyNotch(-1, true, 1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); this.CurrentInterval = 0.1; return; } else { Train.ApplyNotch(-1, true, 1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); - TrainManager.ApplyEmergencyBrake(Train); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); + Train.ApplyEmergencyBrake(); this.CurrentInterval = 10.0; return; } @@ -640,15 +640,15 @@ private void PerformDefault() else if (dist > 0.5 * minDistance) { Train.ApplyNotch(-1, true, 1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); this.CurrentInterval = 0.1; return; } else { Train.ApplyNotch(-1, true, 1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); - TrainManager.ApplyEmergencyBrake(Train); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); + Train.ApplyEmergencyBrake(); this.CurrentInterval = 1.0; return; } @@ -660,7 +660,7 @@ private void PerformDefault() } } } - TrainManager.UnapplyEmergencyBrake(Train); + Train.UnapplyEmergencyBrake(); // current station if (Train.Station >= 0 & Train.StationState == TrainManager.TrainStopState.Pending) { @@ -708,7 +708,7 @@ private void PerformDefault() if (Train.Handles.Power.Driver == 0) { Train.ApplyNotch(0, true, 1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Service); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); } else { @@ -721,7 +721,7 @@ private void PerformDefault() { // brake stop Train.ApplyNotch(-1, true, -1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); CurrentInterval *= 0.4; if (CurrentInterval < 0.3) CurrentInterval = 0.3; } @@ -729,15 +729,15 @@ private void PerformDefault() { // keep brake Train.ApplyNotch(-1, true, 0, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Lap); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); CurrentInterval *= 1.2; if (CurrentInterval > 1.0) CurrentInterval = 1.0; } if (Train.Handles.Power.Driver == 0 & Train.Handles.Brake.Driver == 0) { - TrainManager.ApplyHoldBrake(Train, Train.Handles.HasHoldBrake); + Train.ApplyHoldBrake(Train.Handles.HasHoldBrake); } - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { CurrentInterval = 0.1; } @@ -747,10 +747,10 @@ private void PerformDefault() // cut power/brake BrakeMode = false; Train.ApplyNotch(-1, true, -1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); if (Train.Handles.Power.Driver == 0 & Train.Handles.Brake.Driver == 0) { - TrainManager.ApplyHoldBrake(Train, Train.Handles.HasHoldBrake); + Train.ApplyHoldBrake(Train.Handles.HasHoldBrake); } CurrentInterval *= 0.4; if (CurrentInterval < 0.3) CurrentInterval = 0.3; @@ -790,7 +790,7 @@ private void PerformDefault() { Train.ApplyNotch(0, true, -1, true); } - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); if (double.IsPositiveInfinity(powerstart)) { CurrentInterval = 0.3 + 0.1 * Train.Handles.Power.Driver; @@ -806,7 +806,7 @@ private void PerformDefault() { // power end (over-speed) Train.ApplyNotch(-1, true, -1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); CurrentInterval *= 0.3; if (CurrentInterval < 0.2) CurrentInterval = 0.2; } @@ -827,21 +827,21 @@ private void PerformDefault() { Train.ApplyNotch(0, true, -1, true); } - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); CurrentInterval = 1.3; } else { // keep power Train.ApplyNotch(0, true, -1, true); - TrainManager.ApplyAirBrakeHandle(Train, TrainManager.AirBrakeHandleState.Release); + Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); if (Train.Handles.Power.Driver != 0) { Train.Specs.CurrentConstSpeed = Train.Specs.HasConstSpeed; } if (Train.Handles.Power.Driver == 0 & Train.Handles.Brake.Driver == 0) { - TrainManager.ApplyHoldBrake(Train, Train.Handles.HasHoldBrake); + Train.ApplyHoldBrake(Train.Handles.HasHoldBrake); } CurrentInterval *= 1.1; if (CurrentInterval > 1.5) CurrentInterval = 1.5; diff --git a/source/OpenBVE/Game/Events/EventTypes/FogChange.cs b/source/OpenBVE/Game/Events/EventTypes/FogChange.cs index ea711312c..fdb604946 100644 --- a/source/OpenBVE/Game/Events/EventTypes/FogChange.cs +++ b/source/OpenBVE/Game/Events/EventTypes/FogChange.cs @@ -6,9 +6,9 @@ internal static partial class TrackManager internal class FogChangeEvent : GeneralEvent { /// The fog which applies previously to this point - internal Game.Fog PreviousFog; + private readonly Game.Fog PreviousFog; /// The fog which applies after this point - internal Game.Fog CurrentFog; + private readonly Game.Fog CurrentFog; /// The next upcoming fog (Used for distance based interpolation) internal Game.Fog NextFog; diff --git a/source/OpenBVE/Game/Events/EventTypes/SpeedLimit.cs b/source/OpenBVE/Game/Events/EventTypes/SpeedLimit.cs index fc98d062d..32c7b8364 100644 --- a/source/OpenBVE/Game/Events/EventTypes/SpeedLimit.cs +++ b/source/OpenBVE/Game/Events/EventTypes/SpeedLimit.cs @@ -19,6 +19,14 @@ internal LimitChangeEvent(double TrackPositionDelta, double PreviousSpeedLimit, } internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex) { + if (Train == null) + { + return; + } + if (Train.RouteLimits == null) + { + Train.RouteLimits = new double[] {}; + } if (Direction < 0) { if (TriggerType == EventTriggerType.FrontCarFrontAxle) diff --git a/source/OpenBVE/Game/Events/EventTypes/TrackEnd.cs b/source/OpenBVE/Game/Events/EventTypes/TrackEnd.cs index 783505f3c..ad7d0576e 100644 --- a/source/OpenBVE/Game/Events/EventTypes/TrackEnd.cs +++ b/source/OpenBVE/Game/Events/EventTypes/TrackEnd.cs @@ -20,6 +20,11 @@ internal override void Trigger(int Direction, EventTriggerType TriggerType, Trai { Train.Derail(CarIndex, 0.0); } + + if (TriggerType == EventTriggerType.Camera) + { + World.CameraAtWorldEnd = !World.CameraAtWorldEnd; + } } } } diff --git a/source/OpenBVE/Game/Game.cs b/source/OpenBVE/Game/Game.cs index 110b91be7..fb48b4871 100644 --- a/source/OpenBVE/Game/Game.cs +++ b/source/OpenBVE/Game/Game.cs @@ -167,7 +167,6 @@ internal static void AddBlackBoxEntry(BlackBoxEventToken EventToken) { if (BlackBoxEntryCount >= BlackBoxEntries.Length) { Array.Resize(ref BlackBoxEntries, BlackBoxEntries.Length << 1); } - int d = TrainManager.PlayerTrain.DriverCar; BlackBoxEntries[BlackBoxEntryCount].Time = SecondsSinceMidnight; BlackBoxEntries[BlackBoxEntryCount].Position = TrainManager.PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition; BlackBoxEntries[BlackBoxEntryCount].Speed = (float)TrainManager.PlayerTrain.Specs.CurrentAverageSpeed; @@ -180,8 +179,8 @@ internal static void AddBlackBoxEntry(BlackBoxEventToken EventToken) { BlackBoxEntries[BlackBoxEntryCount].BrakeDriver = BlackBoxBrake.Emergency; } else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { BlackBoxEntries[BlackBoxEntryCount].BrakeDriver = BlackBoxBrake.HoldBrake; - } else if (TrainManager.PlayerTrain.Cars[d].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { - switch (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver) { + } else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { + switch ((TrainManager.AirBrakeHandleState)TrainManager.PlayerTrain.Handles.Brake.Driver) { case TrainManager.AirBrakeHandleState.Release: BlackBoxEntries[BlackBoxEntryCount].BrakeDriver = BlackBoxBrake.Release; break; case TrainManager.AirBrakeHandleState.Lap: BlackBoxEntries[BlackBoxEntryCount].BrakeDriver = BlackBoxBrake.Lap; break; case TrainManager.AirBrakeHandleState.Service: BlackBoxEntries[BlackBoxEntryCount].BrakeDriver = BlackBoxBrake.Service; break; @@ -194,8 +193,8 @@ internal static void AddBlackBoxEntry(BlackBoxEventToken EventToken) { BlackBoxEntries[BlackBoxEntryCount].BrakeSafety = BlackBoxBrake.Emergency; } else if (TrainManager.PlayerTrain.Handles.HoldBrake.Actual) { BlackBoxEntries[BlackBoxEntryCount].BrakeSafety = BlackBoxBrake.HoldBrake; - } else if (TrainManager.PlayerTrain.Cars[d].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { - switch (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Safety) { + } else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { + switch ((TrainManager.AirBrakeHandleState)TrainManager.PlayerTrain.Handles.Brake.Safety) { case TrainManager.AirBrakeHandleState.Release: BlackBoxEntries[BlackBoxEntryCount].BrakeSafety = BlackBoxBrake.Release; break; case TrainManager.AirBrakeHandleState.Lap: BlackBoxEntries[BlackBoxEntryCount].BrakeSafety = BlackBoxBrake.Lap; break; case TrainManager.AirBrakeHandleState.Service: BlackBoxEntries[BlackBoxEntryCount].BrakeSafety = BlackBoxBrake.Service; break; diff --git a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObject.cs b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObject.cs index 424ddf001..164cc6de4 100644 --- a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObject.cs +++ b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObject.cs @@ -2,6 +2,7 @@ using CSScriptLibrary; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { @@ -743,18 +744,18 @@ internal void Update(bool IsPartOfTrain, TrainManager.Train Train, int CarIndex, // rotate if (rotateX) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates, RotateXDirection, cosX, sinX); + ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(RotateXDirection, cosX, sinX); } if (rotateY) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates, RotateYDirection, cosY, sinY); + ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(RotateYDirection, cosY, sinY); } if (rotateZ) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates, RotateZDirection, cosZ, sinZ); + ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(RotateZDirection, cosZ, sinZ); } // translate - if (Overlay & World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) + if (Overlay & World.CameraRestriction != Camera.RestrictionMode.NotAvailable) { ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X += States[s].Position.X - Position.X; ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y += States[s].Position.Y - Position.Y; @@ -791,15 +792,15 @@ internal void Update(bool IsPartOfTrain, TrainManager.Train Train, int CarIndex, { if (rotateX) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal, RotateXDirection, cosX, sinX); + ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(RotateXDirection, cosX, sinX); } if (rotateY) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal, RotateYDirection, cosY, sinY); + ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(RotateYDirection, cosY, sinY); } if (rotateZ) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal, RotateZDirection, cosZ, sinZ); + ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(RotateZDirection, cosZ, sinZ); } World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z); } @@ -823,14 +824,14 @@ internal void Update(bool IsPartOfTrain, TrainManager.Train Train, int CarIndex, } } - internal void CreateObject(Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) + internal void CreateObject(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) { Array.Resize(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1); } - World.Transformation FinalTransformation = new World.Transformation(AuxTransformation, BaseTransformation); + Transformation FinalTransformation = new Transformation(AuxTransformation, BaseTransformation); //Place track followers if required if (TrackFollowerFunction != null) diff --git a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObjectCollection.cs b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObjectCollection.cs index f7455d981..7b3c61359 100644 --- a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObjectCollection.cs +++ b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedObjectCollection.cs @@ -1,4 +1,5 @@ using OpenBveApi.Math; +using OpenBveApi.World; namespace OpenBve { @@ -12,7 +13,7 @@ internal class AnimatedObjectCollection : UnifiedObject internal AnimatedObject[] Objects; internal WorldObject[] Sounds; - internal override void CreateObject(Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, + internal override void CreateObject(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { @@ -54,7 +55,7 @@ internal override void CreateObject(Vector3 Position, World.Transformation BaseT if (free[i]) { Vector3 p = Position; - World.Transformation t = new OpenBve.World.Transformation(BaseTransformation, AuxTransformation); + Transformation t = new Transformation(BaseTransformation, AuxTransformation); Vector3 s = t.X; Vector3 u = t.Y; Vector3 d = t.Z; diff --git a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedWorldObject.StateSound.cs b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedWorldObject.StateSound.cs index 4c99bed48..d510a0f5f 100644 --- a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedWorldObject.StateSound.cs +++ b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/AnimatedWorldObject.StateSound.cs @@ -1,6 +1,7 @@ using System; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { @@ -147,14 +148,14 @@ internal override void Update(double TimeElapsed, bool ForceUpdate) this.lastState = this.Object.CurrentState; } - internal void Create(Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) + internal void Create(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) { Array.Resize(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1); } - World.Transformation FinalTransformation = new World.Transformation(AuxTransformation, BaseTransformation); + Transformation FinalTransformation = new Transformation(AuxTransformation, BaseTransformation); var o = this.Object.Clone(); o.ObjectIndex = CreateDynamicObject(); diff --git a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/FunctionScripts.cs b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/FunctionScripts.cs index ae3a0d8d1..21bf34906 100644 --- a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/FunctionScripts.cs +++ b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/FunctionScripts.cs @@ -24,7 +24,7 @@ internal enum Instructions { TrainCars, TrainDestination, TrainSpeed, TrainSpeedometer, TrainAcceleration, TrainAccelerationMotor, TrainSpeedOfCar, TrainSpeedometerOfCar, TrainAccelerationOfCar, TrainAccelerationMotorOfCar, - TrainDistance, TrainDistanceToCar, TrainTrackDistance, TrainTrackDistanceToCar, CurveRadius, FrontAxleCurveRadius, RearAxleCurveRadius, CurveCant, Odometer, OdometerOfCar, + TrainDistance, TrainDistanceToCar, TrainTrackDistance, TrainTrackDistanceToCar, CurveRadius, FrontAxleCurveRadius, RearAxleCurveRadius, CurveCant, Pitch, Odometer, OdometerOfCar, Doors, DoorsIndex, LeftDoors, LeftDoorsIndex, RightDoors, RightDoorsIndex, LeftDoorsTarget, LeftDoorsTargetIndex, RightDoorsTarget, RightDoorsTargetIndex, @@ -555,6 +555,25 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. } } break; + case Instructions.Pitch: + if (Train == null) + { + Function.Stack[s - 1] = 0.0; + } + else + { + int j = (int)Math.Round(Function.Stack[s - 1]); + if (j < 0) j += Train.Cars.Length; + if (j >= 0 & j < Train.Cars.Length) + { + Function.Stack[s - 1] = Train.Cars[j].FrontAxle.Follower.Pitch; + } + else + { + Function.Stack[s - 1] = 0.0; + } + } + break; case Instructions.Odometer: if (Train == null) { @@ -818,18 +837,14 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. s++; break; case Instructions.BrakeNotch: if (Train != null) { - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { - Function.Stack[s] = (double)Train.Handles.AirBrake.Handle.Driver; - } else { - Function.Stack[s] = (double)Train.Handles.Brake.Driver; - } + Function.Stack[s] = (double)Train.Handles.Brake.Driver; } else { Function.Stack[s] = 0.0; } s++; break; case Instructions.BrakeNotches: if (Train != null) { - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { Function.Stack[s] = 2.0; } else { Function.Stack[s] = (double)Train.Handles.Brake.MaximumNotch; @@ -840,11 +855,11 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. s++; break; case Instructions.BrakeNotchLinear: if (Train != null) { - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { if (Train.Handles.EmergencyBrake.Driver) { Function.Stack[s] = 3.0; } else { - Function.Stack[s] = (double)Train.Handles.AirBrake.Handle.Driver; + Function.Stack[s] = (double)Train.Handles.Brake.Driver; } } else if (Train.Handles.HasHoldBrake) { if (Train.Handles.EmergencyBrake.Driver) { @@ -867,7 +882,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. s++; break; case Instructions.BrakeNotchesLinear: if (Train != null) { - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { Function.Stack[s] = 3.0; } else if (Train.Handles.HasHoldBrake) { Function.Stack[s] = Train.Handles.Brake.MaximumNotch + 2.0; @@ -944,7 +959,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. s++; break; case Instructions.HasAirBrake: if (Train != null) { - Function.Stack[s] = Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake ? 1.0 : 0.0; + Function.Stack[s] = Train.Handles.Brake is TrainManager.AirBrakeHandle ? 1.0 : 0.0; } else { Function.Stack[s] = 0.0; } @@ -980,7 +995,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. // brake case Instructions.BrakeMainReservoir: if (Train != null) { - Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure; + Function.Stack[s] = Train.Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure; } else { Function.Stack[s] = 0.0; } @@ -992,7 +1007,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. int j = (int)Math.Round(Function.Stack[s - 1]); if (j < 0) j += Train.Cars.Length; if (j >= 0 & j < Train.Cars.Length) { - Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.MainReservoirCurrentPressure; + Function.Stack[s - 1] = Train.Cars[j].CarBrake.mainReservoir.CurrentPressure; } else { Function.Stack[s - 1] = 0.0; } @@ -1000,7 +1015,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. break; case Instructions.BrakeEqualizingReservoir: if (Train != null) { - Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; + Function.Stack[s] = Train.Cars[CarIndex].CarBrake.equalizingReservoir.CurrentPressure; } else { Function.Stack[s] = 0.0; } @@ -1012,7 +1027,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. int j = (int)Math.Round(Function.Stack[s - 1]); if (j < 0) j += Train.Cars.Length; if (j >= 0 & j < Train.Cars.Length) { - Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.EqualizingReservoirCurrentPressure; + Function.Stack[s - 1] = Train.Cars[j].CarBrake.equalizingReservoir.CurrentPressure; } else { Function.Stack[s - 1] = 0.0; } @@ -1020,7 +1035,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. break; case Instructions.BrakeBrakePipe: if (Train != null) { - Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; + Function.Stack[s] = Train.Cars[CarIndex].CarBrake.brakePipe.CurrentPressure; } else { Function.Stack[s] = 0.0; } @@ -1032,7 +1047,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. int j = (int)Math.Round(Function.Stack[s - 1]); if (j < 0) j += Train.Cars.Length; if (j >= 0 & j < Train.Cars.Length) { - Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.BrakePipeCurrentPressure; + Function.Stack[s - 1] = Train.Cars[j].CarBrake.brakePipe.CurrentPressure; } else { Function.Stack[s - 1] = 0.0; } @@ -1040,7 +1055,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. break; case Instructions.BrakeBrakeCylinder: if (Train != null) { - Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; + Function.Stack[s] = Train.Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure; } else { Function.Stack[s] = 0.0; } @@ -1052,7 +1067,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. int j = (int)Math.Round(Function.Stack[s - 1]); if (j < 0) j += Train.Cars.Length; if (j >= 0 & j < Train.Cars.Length) { - Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.BrakeCylinderCurrentPressure; + Function.Stack[s - 1] = Train.Cars[j].CarBrake.brakeCylinder.CurrentPressure; } else { Function.Stack[s - 1] = 0.0; } @@ -1060,7 +1075,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. break; case Instructions.BrakeStraightAirPipe: if (Train != null) { - Function.Stack[s] = Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure; + Function.Stack[s] = Train.Cars[CarIndex].CarBrake.straightAirPipe.CurrentPressure; } else { Function.Stack[s] = 0.0; } @@ -1072,7 +1087,7 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. int j = (int)Math.Round(Function.Stack[s - 1]); if (j < 0) j += Train.Cars.Length; if (j >= 0 & j < Train.Cars.Length) { - Function.Stack[s - 1] = Train.Cars[j].Specs.AirBrake.StraightAirPipeCurrentPressure; + Function.Stack[s - 1] = Train.Cars[j].CarBrake.straightAirPipe.CurrentPressure; } else { Function.Stack[s - 1] = 0.0; } @@ -1374,7 +1389,11 @@ private static string GetPostfixNotationFromFunctionNotation(string Expression) if (Expression.EndsWith("]")) { throw new System.IO.InvalidDataException("Unexpected closing bracket encountered in " + Expression); } - double value; + // ReSharper disable once NotAccessedVariable + /* + * If this is a simple number, we can short-circuit the rest of this function + */ + double value; if (double.TryParse(Expression, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out value)) { return Expression; } @@ -1632,6 +1651,7 @@ private static string GetPostfixNotationFromFunctionNotation(string Expression) case "frontaxlecurveradius": case "rearaxlecurveradius": case "curvecant": + case "pitch": case "odometer": case "speed": case "speedometer": @@ -2513,6 +2533,11 @@ internal static FunctionScript GetFunctionScriptFromPostfixNotation(string Expre if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); Result.Instructions[n] = Instructions.CurveCant; n++; break; + case "pitchindex": + if (s < 1) throw new System.InvalidOperationException(Arguments[i] + " requires at least 1 argument on the stack in function script " + Expression); + if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); + Result.Instructions[n] = Instructions.Pitch; + n++; break; case "odometer": if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); Result.Instructions[n] = Instructions.Odometer; diff --git a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/TrackFollowingObject.cs b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/TrackFollowingObject.cs index 21e1056e4..2a1aacb71 100644 --- a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/TrackFollowingObject.cs +++ b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/TrackFollowingObject.cs @@ -160,14 +160,14 @@ private void UpdateObjectPosition() Side.Z = sz; } - private double UpdateTrackFollowerScript(bool IsPartOfTrain, TrainManager.Train Train, int CarIndex, int SectionIndex, double TrackPosition, Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, bool Overlay, bool UpdateFunctions, bool Show, double TimeElapsed) + private double UpdateTrackFollowerScript(bool IsPartOfTrain, TrainManager.Train Train, int CarIndex, int SectionIndex, double TrackPosition, Vector3 WorldPosition, Vector3 Direction, Vector3 Up, Vector3 Side, bool Overlay, bool UpdateFunctions, bool Show, double TimeElapsed) { double x = 0.0; if (Object.TrackFollowerFunction != null) { if (UpdateFunctions) { - x = Object.TrackFollowerFunction.Perform(Train, CarIndex, Position, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, Object.CurrentState); + x = Object.TrackFollowerFunction.Perform(Train, CarIndex, WorldPosition, TrackPosition, SectionIndex, IsPartOfTrain, TimeElapsed, Object.CurrentState); } else { diff --git a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/WorldSound.cs b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/WorldSound.cs index 89e3add21..4007b48de 100644 --- a/source/OpenBVE/Game/ObjectManager/AnimatedObjects/WorldSound.cs +++ b/source/OpenBVE/Game/ObjectManager/AnimatedObjects/WorldSound.cs @@ -1,5 +1,6 @@ using System; using OpenBveApi.Math; +using OpenBveApi.World; namespace OpenBve { @@ -28,7 +29,7 @@ internal class WorldSound : WorldObject /// The function script controlling the sound's pitch, or a null reference internal FunctionScripts.FunctionScript PitchFunction; - internal void CreateSound(Vector3 position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double trackPosition) + internal void CreateSound(Vector3 position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, double trackPosition) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) @@ -39,7 +40,8 @@ internal void CreateSound(Vector3 position, World.Transformation BaseTransformat { Buffer = this.Buffer, //Must clone the vector, not pass the reference - Position = new Vector3(position.X, position.Y, position.Z) + Position = new Vector3(position.X, position.Y, position.Z), + Follower = new TrackManager.TrackFollower() }; snd.currentTrackPosition = trackPosition; snd.Follower.Update(trackPosition, true, true); diff --git a/source/OpenBVE/Game/ObjectManager/ObjectManager.StaticObject.cs b/source/OpenBVE/Game/ObjectManager/ObjectManager.StaticObject.cs index 2e7979761..b8ff96eb8 100644 --- a/source/OpenBVE/Game/ObjectManager/ObjectManager.StaticObject.cs +++ b/source/OpenBVE/Game/ObjectManager/ObjectManager.StaticObject.cs @@ -1,6 +1,7 @@ using System; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { @@ -206,19 +207,20 @@ internal void ApplyScale(double x, double y, double z) } } - internal void ApplyRotation(double x, double y, double z, double a) + internal void ApplyRotation(Vector3 Rotation, double Angle) { - double cosa = Math.Cos(a); - double sina = Math.Sin(a); + double cosa = Math.Cos(Angle); + double sina = Math.Sin(Angle); for (int j = 0; j < Mesh.Vertices.Length; j++) { - World.Rotate(ref Mesh.Vertices[j].Coordinates, x, y, z, cosa, sina); + Mesh.Vertices[j].Coordinates.Rotate(Rotation, cosa, sina); + } for (int j = 0; j < Mesh.Faces.Length; j++) { for (int k = 0; k < Mesh.Faces[j].Vertices.Length; k++) { - World.Rotate(ref Mesh.Faces[j].Vertices[k].Normal, x, y, z, cosa, sina); + Mesh.Faces[j].Vertices[k].Normal.Rotate(Rotation, cosa, sina); } } } @@ -335,7 +337,7 @@ internal void ApplyShear(double dx, double dy, double dz, double sx, double sy, } } - internal void ApplyData(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double startingDistance, double endingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) + internal void ApplyData(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double startingDistance, double endingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { StartingDistance = float.MaxValue; EndingDistance = float.MinValue; @@ -433,7 +435,7 @@ internal void ApplyData(StaticObject Prototype, Vector3 Position, World.Transfor } } - internal override void CreateObject(Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, + internal override void CreateObject(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { diff --git a/source/OpenBVE/Game/ObjectManager/ObjectManager.UnifiedObject.cs b/source/OpenBVE/Game/ObjectManager/ObjectManager.UnifiedObject.cs index 276c39ffc..f8b04cdc8 100644 --- a/source/OpenBVE/Game/ObjectManager/ObjectManager.UnifiedObject.cs +++ b/source/OpenBVE/Game/ObjectManager/ObjectManager.UnifiedObject.cs @@ -1,4 +1,5 @@ using OpenBveApi.Math; +using OpenBveApi.World; namespace OpenBve { @@ -17,7 +18,7 @@ internal abstract class UnifiedObject /// The track distance at which this hidden by the renderer /// The current block length (Used when Options.ObjectVisibility is set to legacy mode) /// The absolute track position at which this object is placed - internal void CreateObject(Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) + internal void CreateObject(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { CreateObject(Position, BaseTransformation, AuxTransformation, -1, AccurateObjectDisposal, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0, false); } @@ -34,7 +35,7 @@ internal void CreateObject(Vector3 Position, World.Transformation BaseTransforma /// The absolute track position at which this object is placed /// The brightness value of this object /// Whether the materials are to be duplicated (Not set when creating BVE4 signals) - internal abstract void CreateObject(Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials); + internal abstract void CreateObject(Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials); /// Call this method to optimize the object /// Whether duplicate verticies are to be preserved (Takes less time) diff --git a/source/OpenBVE/Game/ObjectManager/ObjectManager.cs b/source/OpenBVE/Game/ObjectManager/ObjectManager.cs index ee87b3fb1..72943f096 100644 --- a/source/OpenBVE/Game/ObjectManager/ObjectManager.cs +++ b/source/OpenBVE/Game/ObjectManager/ObjectManager.cs @@ -1,6 +1,7 @@ using System; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { @@ -34,11 +35,11 @@ internal static void UpdateAnimatedWorldObjects(double TimeElapsed, bool ForceUp } } - internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) + internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { return CreateStaticObject(Prototype, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0, false); } - internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) + internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { if (Prototype == null) { diff --git a/source/OpenBVE/Game/RouteInformation.cs b/source/OpenBVE/Game/RouteInformation.cs index 22484dc48..df2de0aaa 100644 --- a/source/OpenBVE/Game/RouteInformation.cs +++ b/source/OpenBVE/Game/RouteInformation.cs @@ -6,7 +6,7 @@ internal static partial class Game { internal static class RouteInformation { - internal const int DefaultRouteInfoSize = 500; + private const int DefaultRouteInfoSize = 500; /// A bitmap storing the current route-map image internal static Bitmap RouteMap; /// A bitmap storing the current route gradient profile diff --git a/source/OpenBVE/Game/Timetable.cs b/source/OpenBVE/Game/Timetable.cs index a90a0d011..f0a20b240 100644 --- a/source/OpenBVE/Game/Timetable.cs +++ b/source/OpenBVE/Game/Timetable.cs @@ -14,7 +14,6 @@ internal static class Timetable { // members (custom timetable) internal static ObjectManager.AnimatedObject[] CustomObjects = new ObjectManager.AnimatedObject[16]; internal static int CustomObjectsUsed; - internal static Textures.Texture[] CustomTextures = new Textures.Texture[] { }; internal static bool CustomTimetableAvailable; internal static Textures.Texture CurrentCustomTimetableDaytimeTexture; internal static Textures.Texture CurrentCustomTimetableNighttimeTexture; diff --git a/source/OpenBVE/Game/TrackManager/TrackManager.TrackFollower.cs b/source/OpenBVE/Game/TrackManager/TrackManager.TrackFollower.cs index 2898f3770..cf50cb7e4 100644 --- a/source/OpenBVE/Game/TrackManager/TrackManager.TrackFollower.cs +++ b/source/OpenBVE/Game/TrackManager/TrackManager.TrackFollower.cs @@ -94,7 +94,7 @@ internal void Update(double NewTrackPosition, bool UpdateWorldCoordinates, bool double sin2a = Math.Sin(2.0 * a); WorldSide = CurrentTrack.Elements[i].WorldSide; World.Rotate(ref WorldSide, 0.0, 1.0, 0.0, cos2a, sin2a); - World.Cross(WorldDirection, WorldSide, out WorldUp); + WorldUp = Vector3.Cross(WorldDirection, WorldSide); } else diff --git a/source/OpenBVE/Graphics/Camera.CameraRestriction.cs b/source/OpenBVE/Graphics/Camera.CameraRestriction.cs new file mode 100644 index 000000000..0a369024e --- /dev/null +++ b/source/OpenBVE/Graphics/Camera.CameraRestriction.cs @@ -0,0 +1,18 @@ +namespace OpenBve +{ + internal partial class Camera + { + internal enum RestrictionMode + { + /// Represents a 3D cab. + NotAvailable = -1, + /// Represents a 2D cab with camera restriction disabled. + Off = 0, + /// Represents a 2D cab with camera restriction enabled. + On = 1, + /// The camera restriction mode is not specified (Used by parsers) + NotSpecified = 3 + + } + } +} diff --git a/source/OpenBVE/Graphics/Camera.cs b/source/OpenBVE/Graphics/Camera.cs index 395467c6e..23a5e49a2 100644 --- a/source/OpenBVE/Graphics/Camera.cs +++ b/source/OpenBVE/Graphics/Camera.cs @@ -1,10 +1,9 @@ using System; using OpenTK; -using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; namespace OpenBve { - internal class Camera { + internal partial class Camera { // --- members --- @@ -62,4 +61,4 @@ internal void SetViewingAngle(double verticalViewingAngle) { } } -} \ No newline at end of file +} diff --git a/source/OpenBVE/Graphics/HUD/HUD.Element.cs b/source/OpenBVE/Graphics/HUD/HUD.Element.cs new file mode 100644 index 000000000..d314210e9 --- /dev/null +++ b/source/OpenBVE/Graphics/HUD/HUD.Element.cs @@ -0,0 +1,55 @@ +using OpenBveApi.Colors; +using OpenBveApi.Math; + +namespace OpenBve +{ + internal static partial class HUD + { + internal class Element + { + internal string Subject; + internal Vector2 Position; + internal Vector2 Alignment; + internal Image TopLeft; + internal Image TopMiddle; + internal Image TopRight; + internal Image CenterLeft; + internal Image CenterMiddle; + internal Image CenterRight; + internal Image BottomLeft; + internal Image BottomMiddle; + internal Image BottomRight; + internal Color32 BackgroundColor; + internal Color32 OverlayColor; + internal Color32 TextColor; + internal Vector2 TextPosition; + internal Vector2 TextAlignment; + internal Fonts.OpenGlFont Font; + internal bool TextShadow; + internal string Text; + internal float Value1; + internal float Value2; + internal Transition Transition; + internal Vector2 TransitionVector; + internal double TransitionState; + internal Element() + { + this.Subject = null; + this.Position = new Vector2(); + this.Alignment = new Vector2(-1, -1); + this.BackgroundColor = new Color32(255, 255, 255, 255); + this.OverlayColor = new Color32(255, 255, 255, 255); + this.TextColor = new Color32(255, 255, 255, 255); + this.TextPosition = new Vector2(); + this.TextAlignment = new Vector2(-1, 0); + this.Font = Fonts.VerySmallFont; + this.TextShadow = true; + this.Text = null; + this.Value1 = 0.0f; + this.Value2 = 0.0f; + this.Transition = Transition.None; + this.TransitionState = 1.0; + } + } + } +} diff --git a/source/OpenBVE/Graphics/HUD/HUD.Image.cs b/source/OpenBVE/Graphics/HUD/HUD.Image.cs new file mode 100644 index 000000000..a590ddd5f --- /dev/null +++ b/source/OpenBVE/Graphics/HUD/HUD.Image.cs @@ -0,0 +1,11 @@ +namespace OpenBve +{ + internal static partial class HUD + { + internal struct Image + { + internal Textures.Texture BackgroundTexture; + internal Textures.Texture OverlayTexture; + } + } +} diff --git a/source/OpenBVE/Graphics/HUD/HUD.Transitions.cs b/source/OpenBVE/Graphics/HUD/HUD.Transitions.cs new file mode 100644 index 000000000..1f4e5a296 --- /dev/null +++ b/source/OpenBVE/Graphics/HUD/HUD.Transitions.cs @@ -0,0 +1,16 @@ +using System; + +namespace OpenBve +{ + internal static partial class HUD + { + [Flags] + internal enum Transition + { + None = 0, + Move = 1, + Fade = 2, + MoveAndFade = 3 + } + } +} diff --git a/source/OpenBVE/Graphics/HUD/HUD.cs b/source/OpenBVE/Graphics/HUD/HUD.cs new file mode 100644 index 000000000..b997306b4 --- /dev/null +++ b/source/OpenBVE/Graphics/HUD/HUD.cs @@ -0,0 +1,590 @@ +using System; +using System.Globalization; +using System.Windows.Forms; +using OpenBveApi.Colors; + +namespace OpenBve +{ + internal static partial class HUD + { + /// The current HUD elements to render + internal static Element[] CurrentHudElements = { }; + + /// Loads the current HUD + internal static void LoadHUD() + { + CultureInfo Culture = CultureInfo.InvariantCulture; + string Folder = Program.FileSystem.GetDataFolder("In-game", Interface.CurrentOptions.UserInterfaceFolder); + string File = OpenBveApi.Path.CombineFile(Folder, "interface.cfg"); + CurrentHudElements = new Element[16]; + int Length = 0; + if (System.IO.File.Exists(File)) + { + string[] Lines = System.IO.File.ReadAllLines(File, new System.Text.UTF8Encoding()); + for (int i = 0; i < Lines.Length; i++) + { + int j = Lines[i].IndexOf(';'); + if (j >= 0) + { + Lines[i] = Lines[i].Substring(0, j).Trim(); + } + else + { + Lines[i] = Lines[i].Trim(); + } + if (Lines[i].Length != 0) + { + if (!Lines[i].StartsWith(";", StringComparison.Ordinal)) + { + if (Lines[i].Equals("[element]", StringComparison.OrdinalIgnoreCase)) + { + Length++; + if (Length > CurrentHudElements.Length) + { + Array.Resize(ref CurrentHudElements, CurrentHudElements.Length << 1); + } + + CurrentHudElements[Length - 1] = new Element(); + } + else if (Length == 0) + { + MessageBox.Show("Line outside of [element] structure encountered at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + j = Lines[i].IndexOf("=", StringComparison.Ordinal); + if (j >= 0) + { + string Command = Lines[i].Substring(0, j).TrimEnd(); + string[] Arguments = Lines[i].Substring(j + 1).TrimStart().Split(new char[] {','}, StringSplitOptions.None); + for (j = 0; j < Arguments.Length; j++) + { + Arguments[j] = Arguments[j].Trim(); + } + switch (Command.ToLowerInvariant()) + { + case "subject": + if (Arguments.Length == 1) + { + CurrentHudElements[Length - 1].Subject = Arguments[0]; + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "position": + if (Arguments.Length == 2) + { + float x, y; + if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x)) + { + MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y)) + { + MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].Position.X = x; + CurrentHudElements[Length - 1].Position.Y = y; + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "alignment": + if (Arguments.Length == 2) + { + int x, y; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out x)) + { + MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out y)) + { + MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].Alignment.X = Math.Sign(x); + CurrentHudElements[Length - 1].Alignment.Y = Math.Sign(y); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "topleft": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopLeft.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopLeft.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "topmiddle": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopMiddle.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopMiddle.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "topright": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopRight.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopRight.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "centerleft": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterLeft.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterLeft.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "centermiddle": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterMiddle.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterMiddle.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "centerright": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterRight.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterRight.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "bottomleft": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomLeft.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomLeft.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "bottommiddle": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomMiddle.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomMiddle.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "bottomright": + if (Arguments.Length == 2) + { + if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomRight.BackgroundTexture); + } + + if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) + { + Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomRight.OverlayTexture); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "backcolor": + if (Arguments.Length == 4) + { + int r, g, b, a; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r)) + { + MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g)) + { + MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b)) + { + MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a)) + { + MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + r = r < 0 ? 0 : r > 255 ? 255 : r; + g = g < 0 ? 0 : g > 255 ? 255 : g; + b = b < 0 ? 0 : b > 255 ? 255 : b; + a = a < 0 ? 0 : a > 255 ? 255 : a; + CurrentHudElements[Length - 1].BackgroundColor = new Color32((byte) r, (byte) g, (byte) b, (byte) a); + } + + break; + } + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + break; + case "overlaycolor": + if (Arguments.Length == 4) + { + int r, g, b, a; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r)) + { + MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g)) + { + MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b)) + { + MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a)) + { + MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + r = r < 0 ? 0 : r > 255 ? 255 : r; + g = g < 0 ? 0 : g > 255 ? 255 : g; + b = b < 0 ? 0 : b > 255 ? 255 : b; + a = a < 0 ? 0 : a > 255 ? 255 : a; + CurrentHudElements[Length - 1].OverlayColor = new Color32((byte) r, (byte) g, (byte) b, (byte) a); + } + + break; + } + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + break; + case "textcolor": + if (Arguments.Length == 4) + { + int r, g, b, a; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r)) + { + MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g)) + { + MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b)) + { + MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a)) + { + MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + r = r < 0 ? 0 : r > 255 ? 255 : r; + g = g < 0 ? 0 : g > 255 ? 255 : g; + b = b < 0 ? 0 : b > 255 ? 255 : b; + a = a < 0 ? 0 : a > 255 ? 255 : a; + CurrentHudElements[Length - 1].TextColor = new Color32((byte) r, (byte) g, (byte) b, (byte) a); + } + + break; + } + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + break; + case "textposition": + if (Arguments.Length == 2) + { + float x, y; + if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x)) + { + MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y)) + { + MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].TextPosition.X = x; + CurrentHudElements[Length - 1].TextPosition.Y = y; + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "textalignment": + if (Arguments.Length == 2) + { + int x, y; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out x)) + { + MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out y)) + { + MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].TextAlignment.X = Math.Sign(x); + CurrentHudElements[Length - 1].TextAlignment.Y = Math.Sign(y); + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "textsize": + if (Arguments.Length == 1) + { + int s; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out s)) + { + MessageBox.Show("SIZE is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + switch (s) + { + case 0: + CurrentHudElements[Length - 1].Font = Fonts.VerySmallFont; + break; + case 1: + CurrentHudElements[Length - 1].Font = Fonts.SmallFont; + break; + case 2: + CurrentHudElements[Length - 1].Font = Fonts.NormalFont; + break; + case 3: + CurrentHudElements[Length - 1].Font = Fonts.LargeFont; + break; + case 4: + CurrentHudElements[Length - 1].Font = Fonts.VeryLargeFont; + break; + default: + CurrentHudElements[Length - 1].Font = Fonts.NormalFont; + break; + } + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "textshadow": + if (Arguments.Length == 1) + { + int s; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out s)) + { + MessageBox.Show("SHADOW is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].TextShadow = s != 0; + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "text": + if (Arguments.Length == 1) + { + CurrentHudElements[Length - 1].Text = Arguments[0]; + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "value": + if (Arguments.Length == 1) + { + int n; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out n)) + { + MessageBox.Show("VALUE1 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].Value1 = n; + } + } + else if (Arguments.Length == 2) + { + float a, b; + if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out a)) + { + MessageBox.Show("VALUE1 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out b)) + { + MessageBox.Show("VALUE2 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].Value1 = a; + CurrentHudElements[Length - 1].Value2 = b; + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "transition": + if (Arguments.Length == 1) + { + int n; + if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out n)) + { + MessageBox.Show("TRANSITION is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].Transition = (HUD.Transition) n; + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + break; + case "transitionvector": + if (Arguments.Length == 2) + { + float x, y; + if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x)) + { + MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y)) + { + MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + else + { + CurrentHudElements[Length - 1].TransitionVector.X = x; + CurrentHudElements[Length - 1].TransitionVector.Y = y; + } + } + else + { + MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); + } + + break; + default: + MessageBox.Show("Invalid command encountered at line " + (i + 1).ToString(Culture) + " in " + File); + break; + } + } + else + { + MessageBox.Show("Invalid statement encountered at line " + (i + 1).ToString(Culture) + " in " + File); + } + } + } + } + } + } + + Array.Resize(ref CurrentHudElements, Length); + } + } +} diff --git a/source/OpenBVE/Graphics/Renderer.cs b/source/OpenBVE/Graphics/Renderer.cs index be3b718c0..167811438 100644 --- a/source/OpenBVE/Graphics/Renderer.cs +++ b/source/OpenBVE/Graphics/Renderer.cs @@ -56,7 +56,7 @@ internal static partial class Renderer internal enum GradientDisplayMode { - Percentage, UnitOfChange, None + Percentage, UnitOfChange, Permil, None } /// Whether the gradient overlay is currently displayed internal static GradientDisplayMode OptionGradient = GradientDisplayMode.None; @@ -182,7 +182,7 @@ internal static void RenderScene(double TimeElapsed) { GL.Enable(EnableCap.Lighting); LightingEnabled = true; } - if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) + if (World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { GL.Light(LightName.Light0, LightParameter.Ambient, new float[] { inv255 * (float)OptionAmbientColor.R, inv255 * (float)OptionAmbientColor.G, inv255 * (float)OptionAmbientColor.B, 1.0f }); GL.Light(LightName.Light0, LightParameter.Diffuse, new float[] { inv255 * (float)OptionDiffuseColor.R, inv255 * (float)OptionDiffuseColor.G, inv255 * (float)OptionDiffuseColor.B, 1.0f }); @@ -354,7 +354,7 @@ internal static void RenderScene(double TimeElapsed) lookat = Matrix4d.LookAt(0.0, 0.0, 0.0, dx, dy, dz, ux, uy, uz); GL.MatrixMode(MatrixMode.Modelview); GL.LoadMatrix(ref lookat); - if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) + if (World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { // 3d cab ResetOpenGlState(); // TODO: inserted diff --git a/source/OpenBVE/Graphics/Renderer/Functions.cs b/source/OpenBVE/Graphics/Renderer/Functions.cs index 67e9542e5..e05ed20ea 100644 --- a/source/OpenBVE/Graphics/Renderer/Functions.cs +++ b/source/OpenBVE/Graphics/Renderer/Functions.cs @@ -129,7 +129,7 @@ internal static void Initialize() GL.Enable(EnableCap.CullFace); CullEnabled = true; GL.Disable(EnableCap.Lighting); LightingEnabled = false; GL.Disable(EnableCap.Texture2D); TexturingEnabled = false; - Interface.LoadHUD(); + HUD.LoadHUD(); InitLoading(); Matrix4d lookat = Matrix4d.LookAt(0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0); GL.MatrixMode(MatrixMode.Modelview); diff --git a/source/OpenBVE/Graphics/Renderer/Lamp.cs b/source/OpenBVE/Graphics/Renderer/Lamp.cs index 852af1890..b445f9214 100644 --- a/source/OpenBVE/Graphics/Renderer/Lamp.cs +++ b/source/OpenBVE/Graphics/Renderer/Lamp.cs @@ -78,11 +78,11 @@ internal Lamp(LampType Type) break; } Fonts.OpenGlFont font = Fonts.NormalFont; - for (int i = 0; i < Interface.CurrentHudElements.Length; i++) + for (int i = 0; i < HUD.CurrentHudElements.Length; i++) { - if (Interface.CurrentHudElements[i].Subject.Equals("ats", StringComparison.OrdinalIgnoreCase)) + if (HUD.CurrentHudElements[i].Subject.Equals("ats", StringComparison.OrdinalIgnoreCase)) { - font = Interface.CurrentHudElements[i].Font; + font = HUD.CurrentHudElements[i].Font; break; } } diff --git a/source/OpenBVE/Graphics/Renderer/Objects.cs b/source/OpenBVE/Graphics/Renderer/Objects.cs index 92d1e856b..ccc731c5c 100644 --- a/source/OpenBVE/Graphics/Renderer/Objects.cs +++ b/source/OpenBVE/Graphics/Renderer/Objects.cs @@ -106,7 +106,7 @@ internal static void ShowObject(int ObjectIndex, ObjectType Type) } } } - if (Type == ObjectType.Overlay & World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) + if (Type == ObjectType.Overlay & World.CameraRestriction != Camera.RestrictionMode.NotAvailable) { alpha = true; } diff --git a/source/OpenBVE/Graphics/Renderer/Overlays.ATS.cs b/source/OpenBVE/Graphics/Renderer/Overlays.ATS.cs index a846c05fc..a62e7b8e8 100644 --- a/source/OpenBVE/Graphics/Renderer/Overlays.ATS.cs +++ b/source/OpenBVE/Graphics/Renderer/Overlays.ATS.cs @@ -9,7 +9,7 @@ internal static partial class Renderer /// Renders the ATS lamp overlay /// The HUD element these are to be rendererd onto /// The time elapsed - private static void RenderATSLamps(Interface.HudElement Element, double TimeElapsed) + private static void RenderATSLamps(HUD.Element Element, double TimeElapsed) { // ats lamps if (CurrentLampCollection.Lamps == null) @@ -53,9 +53,9 @@ private static void RenderATSLamps(Interface.HudElement Element, double TimeElap { o = 0; } - Interface.HudImage Left = o < 0 ? Element.TopLeft : o == 0 ? Element.CenterLeft : Element.BottomLeft; - Interface.HudImage Middle = o < 0 ? Element.TopMiddle : o == 0 ? Element.CenterMiddle : Element.BottomMiddle; - Interface.HudImage Right = o < 0 ? Element.TopRight : o == 0 ? Element.CenterRight : Element.BottomRight; + HUD.Image Left = o < 0 ? Element.TopLeft : o == 0 ? Element.CenterLeft : Element.BottomLeft; + HUD.Image Middle = o < 0 ? Element.TopMiddle : o == 0 ? Element.CenterMiddle : Element.BottomMiddle; + HUD.Image Right = o < 0 ? Element.TopRight : o == 0 ? Element.CenterRight : Element.BottomRight; MessageColor sc = MessageColor.Gray; if (TrainManager.PlayerTrain.Plugin.Panel.Length >= 272) { diff --git a/source/OpenBVE/Graphics/Renderer/Overlays.Debug.cs b/source/OpenBVE/Graphics/Renderer/Overlays.Debug.cs index 359a0aa88..7c373aaea 100644 --- a/source/OpenBVE/Graphics/Renderer/Overlays.Debug.cs +++ b/source/OpenBVE/Graphics/Renderer/Overlays.Debug.cs @@ -1,4 +1,5 @@ using System; +using OpenBve.BrakeSystems; using OpenBveApi.Colors; using OpenTK.Graphics.OpenGL; @@ -20,10 +21,10 @@ private static void RenderDebugOverlays() { t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Actual ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Actual != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Actual.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Actual ? "HLD" : TrainManager.PlayerTrain.Handles.Power.Actual != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Actual.ToString(Culture) : "N"); } - else if (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Actual != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Actual.ToString(Culture) : "N"); - t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Actual ? "EMG" : TrainManager.PlayerTrain.Handles.AirBrake.Handle.Actual == TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.AirBrake.Handle.Actual == TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); + t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Actual ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Actual == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.Brake.Actual == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { @@ -32,9 +33,15 @@ private static void RenderDebugOverlays() } if (TrainManager.PlayerTrain.Handles.HasLocoBrake) { - t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Actual.ToString(Culture) : "N"); + if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) + { + t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); + } + else + { + t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Actual.ToString(Culture) : "N"); + } } - DrawString(Fonts.SmallFont, t, new System.Drawing.Point(2, Screen.Height - 46), TextAlignment.TopLeft, Color128.White, true); } // safety handles @@ -44,21 +51,28 @@ private static void RenderDebugOverlays() { t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Safety ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Safety != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Safety.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Actual ? "HLD" : TrainManager.PlayerTrain.Handles.Power.Safety != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Safety.ToString(Culture) : "N"); } - else if (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Safety != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Safety.ToString(Culture) : "N"); - t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Safety ? "EMG" : TrainManager.PlayerTrain.Handles.AirBrake.Handle.Safety == TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.AirBrake.Handle.Safety == TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); + t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Safety ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Safety == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.Brake.Safety == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Safety != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Safety.ToString(Culture) : "N"); t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Safety ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Safety != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Safety.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Actual ? "HLD" : "N"); } + if (TrainManager.PlayerTrain.Handles.HasLocoBrake) { - t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Safety != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Safety.ToString(Culture) : "N"); + if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) + { + t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int) TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int) TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); + } + else + { + t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Actual.ToString(Culture) : "N"); + } } - DrawString(Fonts.SmallFont, t, new System.Drawing.Point(2, Screen.Height - 32), TextAlignment.TopLeft, Color128.White, true); } // driver handles @@ -68,10 +82,10 @@ private static void RenderDebugOverlays() { t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Driver != 0 ? "B" + TrainManager.PlayerTrain.Handles.Brake.Driver.ToString(Culture) : TrainManager.PlayerTrain.Handles.HoldBrake.Driver ? "HLD" : TrainManager.PlayerTrain.Handles.Power.Driver != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture) : "N"); } - else if (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + else if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { t += " - " + (TrainManager.PlayerTrain.Handles.Power.Driver != 0 ? "P" + TrainManager.PlayerTrain.Handles.Power.Driver.ToString(Culture) : "N"); - t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver ? "EMG" : TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); + t += " - " + (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver ? "EMG" : TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); } else { @@ -80,9 +94,15 @@ private static void RenderDebugOverlays() } if (TrainManager.PlayerTrain.Handles.HasLocoBrake) { - t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Driver != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Driver.ToString(Culture) : "N"); + if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) + { + t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int) TrainManager.AirBrakeHandleState.Service ? "SRV" : TrainManager.PlayerTrain.Handles.LocoBrake.Actual == (int) TrainManager.AirBrakeHandleState.Lap ? "LAP" : "REL"); + } + else + { + t += " - " + (TrainManager.PlayerTrain.Handles.LocoBrake.Actual != 0 ? "L" + TrainManager.PlayerTrain.Handles.LocoBrake.Actual.ToString(Culture) : "N"); + } } - DrawString(Fonts.SmallFont, t, new System.Drawing.Point(2, Screen.Height - 18), TextAlignment.TopLeft, Color128.White, true); } // debug information @@ -152,6 +172,7 @@ private static void RenderDebugOverlays() "position: " + World.CameraTrackFollower.TrackPosition.ToString("0.00", Culture) + " m", "curve radius: " + World.CameraTrackFollower.CurveRadius.ToString("0.00", Culture) + " m", "curve cant: " + (1000.0 * Math.Abs(World.CameraTrackFollower.CurveCant)).ToString("0.00", Culture) + " mm" + (World.CameraTrackFollower.CurveCant < 0.0 ? " (left)" : World.CameraTrackFollower.CurveCant > 0.0 ? " (right)" : ""), + "pitch: " + World.CameraTrackFollower.Pitch.ToString("0.00", Culture), "", "=sound", "sound buffers: " + soundBuffersLoaded.ToString(Culture) + " / " + soundBuffersRegistered.ToString(Culture), @@ -260,7 +281,7 @@ private static void RenderBrakeSystemDebug() { double x = 96.0, w = 128.0; // brake pipe - if (TrainManager.PlayerTrain.Cars[i].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake | TrainManager.PlayerTrain.Cars[i].Specs.BrakeType == TrainManager.CarBrakeType.ElectromagneticStraightAirBrake) + if (TrainManager.PlayerTrain.Cars[i].CarBrake is AutomaticAirBrake | TrainManager.PlayerTrain.Cars[i].CarBrake is ElectromagneticStraightAirBrake) { if (!heading[0]) { @@ -269,24 +290,23 @@ private static void RenderBrakeSystemDebug() } GL.Color3(0.0f, 0.0f, 0.0f); RenderOverlaySolid(x, y, x + w, y + h); - double p = TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure; - double r = p / TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.BrakePipeNormalPressure; + double p = TrainManager.PlayerTrain.Cars[i].CarBrake.brakePipe.CurrentPressure; + double r = p / TrainManager.PlayerTrain.Cars[i].CarBrake.brakePipe.NormalPressure; GL.Color3(1.0f, 1.0f, 0.0f); RenderOverlaySolid(x, y, x + r * w, y + h); } x += w + 8.0; // auxillary reservoir - if (TrainManager.PlayerTrain.Cars[i].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake | TrainManager.PlayerTrain.Cars[i].Specs.BrakeType == TrainManager.CarBrakeType.ElectromagneticStraightAirBrake) + if (TrainManager.PlayerTrain.Cars[i].CarBrake is AutomaticAirBrake | TrainManager.PlayerTrain.Cars[i].CarBrake is ElectromagneticStraightAirBrake) { if (!heading[1]) { - //RenderString(x, oy - 16.0, Fonts.FontType.Small, "Auxillary reservoir", -1, 0.75f, 0.75f, 0.75f, true); DrawString(Fonts.SmallFont, "Auxillary reservoir", new System.Drawing.Point((int)x, (int)(oy - 16)), TextAlignment.TopLeft, Color128.White, true); heading[1] = true; } GL.Color3(0.0f, 0.0f, 0.0f); RenderOverlaySolid(x, y, x + w, y + h); - double p = TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - double r = p / TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.AuxillaryReservoirMaximumPressure; + double p = TrainManager.PlayerTrain.Cars[i].CarBrake.auxiliaryReservoir.CurrentPressure; + double r = p / TrainManager.PlayerTrain.Cars[i].CarBrake.auxiliaryReservoir.MaximumPressure; GL.Color3(0.5f, 0.5f, 0.5f); RenderOverlaySolid(x, y, x + r * w, y + h); } x += w + 8.0; @@ -294,62 +314,58 @@ private static void RenderBrakeSystemDebug() { if (!heading[2]) { - //RenderString(x, oy - 16.0, Fonts.FontType.Small, "Brake cylinder", -1, 0.75f, 0.5f, 0.25f, true); DrawString(Fonts.SmallFont, "Brake cylinder", new System.Drawing.Point((int)x, (int)(oy - 16)), TextAlignment.TopLeft, Color128.White, true); heading[2] = true; } GL.Color3(0.0f, 0.0f, 0.0f); RenderOverlaySolid(x, y, x + w, y + h); - double p = TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.BrakeCylinderCurrentPressure; - double r = p / TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; + double p = TrainManager.PlayerTrain.Cars[i].CarBrake.brakeCylinder.CurrentPressure; + double r = p / TrainManager.PlayerTrain.Cars[i].CarBrake.brakeCylinder.EmergencyMaximumPressure; GL.Color3(0.75f, 0.5f, 0.25f); RenderOverlaySolid(x, y, x + r * w, y + h); } x += w + 8.0; // main reservoir - if (TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.Type == TrainManager.AirBrakeType.Main) + if (TrainManager.PlayerTrain.Cars[i].CarBrake.brakeType == BrakeType.Main) { if (!heading[3]) { - //RenderString(x, oy - 16.0, Fonts.FontType.Small, "Main reservoir", -1, 1.0f, 0.0f, 0.0f, true); DrawString(Fonts.SmallFont, "Main reservoir", new System.Drawing.Point((int)x, (int)(oy - 16)), TextAlignment.TopLeft, Color128.White, true); heading[3] = true; } GL.Color3(0.0f, 0.0f, 0.0f); RenderOverlaySolid(x, y, x + w, y + h); - double p = TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.MainReservoirCurrentPressure; - double r = p / TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.AirCompressorMaximumPressure; + double p = TrainManager.PlayerTrain.Cars[i].CarBrake.mainReservoir.CurrentPressure; + double r = p / TrainManager.PlayerTrain.Cars[i].CarBrake.mainReservoir.MaximumPressure; GL.Color3(1.0f, 0.0f, 0.0f); RenderOverlaySolid(x, y, x + r * w, y + h); } x += w + 8.0; // equalizing reservoir - if (TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.Type == TrainManager.AirBrakeType.Main) + if (TrainManager.PlayerTrain.Cars[i].CarBrake.brakeType == BrakeType.Main) { if (!heading[4]) { - //RenderString(x, oy - 16.0, Fonts.FontType.Small, "Equalizing reservoir", -1, 0.0f, 0.75f, 0.0f, true); DrawString(Fonts.SmallFont, "Equalizing reservoir", new System.Drawing.Point((int)x, (int)(oy - 16)), TextAlignment.TopLeft, Color128.White, true); heading[4] = true; } GL.Color3(0.0f, 0.0f, 0.0f); RenderOverlaySolid(x, y, x + w, y + h); - double p = TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.EqualizingReservoirCurrentPressure; - double r = p / TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.EqualizingReservoirNormalPressure; + double p = TrainManager.PlayerTrain.Cars[i].CarBrake.equalizingReservoir.CurrentPressure; + double r = p / TrainManager.PlayerTrain.Cars[i].CarBrake.equalizingReservoir.NormalPressure; GL.Color3(0.0f, 0.75f, 0.0f); RenderOverlaySolid(x, y, x + r * w, y + h); } x += w + 8.0; // straight air pipe - if (TrainManager.PlayerTrain.Cars[i].Specs.BrakeType == TrainManager.CarBrakeType.ElectromagneticStraightAirBrake & TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.Type == TrainManager.AirBrakeType.Main) + if (TrainManager.PlayerTrain.Cars[i].CarBrake is ElectromagneticStraightAirBrake & TrainManager.PlayerTrain.Cars[i].CarBrake.brakeType == BrakeType.Main) { if (!heading[5]) { - //RenderString(x, oy - 16.0, Fonts.FontType.Small, "Straight air pipe", -1, 0.0f, 0.75f, 1.0f, true); DrawString(Fonts.SmallFont, "Straight air pipe", new System.Drawing.Point((int)x, (int)(oy - 16)), TextAlignment.TopLeft, Color128.White, true); heading[5] = true; } GL.Color3(0.0f, 0.0f, 0.0f); RenderOverlaySolid(x, y, x + w, y + h); - double p = TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.StraightAirPipeCurrentPressure; - double r = p / TrainManager.PlayerTrain.Cars[i].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; + double p = TrainManager.PlayerTrain.Cars[i].CarBrake.straightAirPipe.CurrentPressure; + double r = p / TrainManager.PlayerTrain.Cars[i].CarBrake.brakeCylinder.EmergencyMaximumPressure; GL.Color3(0.0f, 0.75f, 1.0f); RenderOverlaySolid(x, y, x + r * w, y + h); } //x += w + 8.0; diff --git a/source/OpenBVE/Graphics/Renderer/Overlays.Functions.cs b/source/OpenBVE/Graphics/Renderer/Overlays.Functions.cs index 2054da8b5..5cb4881d5 100644 --- a/source/OpenBVE/Graphics/Renderer/Overlays.Functions.cs +++ b/source/OpenBVE/Graphics/Renderer/Overlays.Functions.cs @@ -32,7 +32,7 @@ internal static void RenderOverlaySolid(double left, double top, double right, d /// The left width of the viewing plane /// The right width of the viewing plane /// The center point of the viewing plane - private static void CalculateViewingPlaneSize(Interface.HudElement Element, out double LeftWidth, out double RightWidth, out double LCrH) + private static void CalculateViewingPlaneSize(HUD.Element Element, out double LeftWidth, out double RightWidth, out double LCrH) { LCrH = 0.0; // left width/height diff --git a/source/OpenBVE/Graphics/Renderer/Overlays.GameMessages.cs b/source/OpenBVE/Graphics/Renderer/Overlays.GameMessages.cs index 5f87a9725..aa68d208d 100644 --- a/source/OpenBVE/Graphics/Renderer/Overlays.GameMessages.cs +++ b/source/OpenBVE/Graphics/Renderer/Overlays.GameMessages.cs @@ -9,7 +9,7 @@ internal static partial class Renderer /// Renders the list of game (textual) messages /// The HUD element these are to be rendered onto /// The time elapsed - private static void RenderGameMessages(Interface.HudElement Element, double TimeElapsed) + private static void RenderGameMessages(HUD.Element Element, double TimeElapsed) { //Calculate the size of the viewing plane int n = MessageManager.TextualMessages.Count; @@ -52,7 +52,7 @@ private static void RenderGameMessages(Interface.HudElement Element, double Time CreateBackColor(Element.OverlayColor, mm.Color, out or, out og, out ob, out oa); double tx, ty; bool preserve = false; - if ((Element.Transition & Interface.HudTransition.Move) != 0) + if ((Element.Transition & HUD.Transition.Move) != 0) { if (Game.SecondsSinceMidnight < mm.Timeout) { @@ -66,7 +66,7 @@ private static void RenderGameMessages(Interface.HudElement Element, double Time ty = y + m * Element.Value2; preserve = true; } - else if (Element.Transition == Interface.HudTransition.MoveAndFade) + else if (Element.Transition == HUD.Transition.MoveAndFade) { tx = x; ty = y + m * Element.Value2; @@ -113,7 +113,7 @@ private static void RenderGameMessages(Interface.HudElement Element, double Time mm.RendererPosition.Y += Math.Sign(ty - mm.RendererPosition.Y) * dy; } } - if ((Element.Transition & Interface.HudTransition.Fade) != 0) + if ((Element.Transition & HUD.Transition.Fade) != 0) { if (Game.SecondsSinceMidnight >= mm.Timeout) { @@ -139,17 +139,17 @@ private static void RenderGameMessages(Interface.HudElement Element, double Time double py = mm.RendererPosition.Y; float alpha = (float)(mm.RendererAlpha * mm.RendererAlpha); // graphics - Interface.HudImage Left = j == 0 + HUD.Image Left = j == 0 ? Element.TopLeft : j < n - 1 ? Element.CenterLeft : Element.BottomLeft; - Interface.HudImage Middle = j == 0 + HUD.Image Middle = j == 0 ? Element.TopMiddle : j < n - 1 ? Element.CenterMiddle : Element.BottomMiddle; - Interface.HudImage Right = j == 0 + HUD.Image Right = j == 0 ? Element.TopRight : j < n - 1 ? Element.CenterRight diff --git a/source/OpenBVE/Graphics/Renderer/Overlays.HUD.cs b/source/OpenBVE/Graphics/Renderer/Overlays.HUD.cs index 56b9457f1..191e88f82 100644 --- a/source/OpenBVE/Graphics/Renderer/Overlays.HUD.cs +++ b/source/OpenBVE/Graphics/Renderer/Overlays.HUD.cs @@ -9,7 +9,7 @@ internal static partial class Renderer /// Renders all default HUD elements /// The HUD element these are to be rendererd onto /// The time elapsed - private static void RenderHUDElement(Interface.HudElement Element, double TimeElapsed) + private static void RenderHUDElement(HUD.Element Element, double TimeElapsed) { TrainManager.TrainDoorState LeftDoors = TrainManager.GetDoorsState(TrainManager.PlayerTrain, true, false); TrainManager.TrainDoorState RightDoors = TrainManager.GetDoorsState(TrainManager.PlayerTrain, false, true); @@ -119,7 +119,7 @@ private static void RenderHUDElement(Interface.HudElement Element, double TimeEl { return; } - if (TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver) { @@ -133,7 +133,7 @@ private static void RenderHUDElement(Interface.HudElement Element, double TimeEl t = Interface.QuickReferences.HandleEmergency; } } - else if (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Release) + else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Release) { sc = MessageColor.Gray; if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1) @@ -145,7 +145,7 @@ private static void RenderHUDElement(Interface.HudElement Element, double TimeEl t = Interface.QuickReferences.HandleRelease; } } - else if (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Lap) + else if (TrainManager.PlayerTrain.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap) { sc = MessageColor.Blue; if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2) @@ -230,30 +230,74 @@ private static void RenderHUDElement(Interface.HudElement Element, double TimeEl { return; } - if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == 0) + + if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) { - sc = MessageColor.Gray; - if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length > 1) + if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Release) { - t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[1]; + sc = MessageColor.Gray; + if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 1) + { + t = TrainManager.PlayerTrain.BrakeNotchDescriptions[1]; + } + else + { + t = Interface.QuickReferences.HandleRelease; + } + } + else if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Lap) + { + sc = MessageColor.Blue; + if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 2) + { + t = TrainManager.PlayerTrain.BrakeNotchDescriptions[2]; + } + else + { + t = Interface.QuickReferences.HandleLap; + } } else { - t = Interface.QuickReferences.HandleBrakeNull; + sc = MessageColor.Orange; + if (TrainManager.PlayerTrain.BrakeNotchDescriptions != null && TrainManager.PlayerTrain.BrakeNotchDescriptions.Length > 3) + { + t = TrainManager.PlayerTrain.BrakeNotchDescriptions[3]; + } + else + { + t = Interface.QuickReferences.HandleService; + } + } } else { - sc = MessageColor.Orange; - if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.LocoBrake.Driver < TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length) + if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == 0) { - t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.LocoBrake.Driver]; + sc = MessageColor.Gray; + if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length > 1) + { + t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[1]; + } + else + { + t = Interface.QuickReferences.HandleBrakeNull; + } } else { - t = Interface.QuickReferences.HandleLocoBrake + TrainManager.PlayerTrain.Handles.LocoBrake.Driver.ToString(Culture); - } + sc = MessageColor.Orange; + if (TrainManager.PlayerTrain.LocoBrakeNotchDescriptions != null && TrainManager.PlayerTrain.Handles.LocoBrake.Driver < TrainManager.PlayerTrain.LocoBrakeNotchDescriptions.Length) + { + t = TrainManager.PlayerTrain.LocoBrakeNotchDescriptions[TrainManager.PlayerTrain.Handles.LocoBrake.Driver]; + } + else + { + t = Interface.QuickReferences.HandleLocoBrake + TrainManager.PlayerTrain.Handles.LocoBrake.Driver.ToString(Culture); + } + } } Element.TransitionState = 0.0; break; @@ -501,6 +545,20 @@ private static void RenderHUDElement(Interface.HudElement Element, double TimeEl Element.TransitionState -= speed * TimeElapsed; if (Element.TransitionState < 0.0) Element.TransitionState = 0.0; } + else if (OptionGradient == GradientDisplayMode.Permil) + { + if (World.CameraTrackFollower.Pitch != 0) + { + double pm = World.CameraTrackFollower.Pitch; + t = Math.Abs(pm).ToString("0.00", Culture) + "‰" + (Math.Abs(pm) == pm ? " ↗" : " ↘"); + } + else + { + t = "Level"; + } + Element.TransitionState -= speed * TimeElapsed; + if (Element.TransitionState < 0.0) Element.TransitionState = 0.0; + } else { if (World.CameraTrackFollower.Pitch != 0) @@ -591,17 +649,17 @@ private static void RenderHUDElement(Interface.HudElement Element, double TimeEl } // transitions float alpha = 1.0f; - if ((Element.Transition & Interface.HudTransition.Move) != 0) + if ((Element.Transition & HUD.Transition.Move) != 0) { double s = Element.TransitionState; x += Element.TransitionVector.X * s * s; y += Element.TransitionVector.Y * s * s; } - if ((Element.Transition & Interface.HudTransition.Fade) != 0) + if ((Element.Transition & HUD.Transition.Fade) != 0) { alpha = (float)(1.0 - Element.TransitionState); } - else if (Element.Transition == Interface.HudTransition.None) + else if (Element.Transition == HUD.Transition.None) { alpha = (float)(1.0 - Element.TransitionState); } diff --git a/source/OpenBVE/Graphics/Renderer/Overlays.ScoreMessages.cs b/source/OpenBVE/Graphics/Renderer/Overlays.ScoreMessages.cs index 3455603b0..58d25c5e0 100644 --- a/source/OpenBVE/Graphics/Renderer/Overlays.ScoreMessages.cs +++ b/source/OpenBVE/Graphics/Renderer/Overlays.ScoreMessages.cs @@ -9,7 +9,7 @@ internal static partial class Renderer /// Renders the list of score messages /// The HUD element these are to be rendererd onto /// The time elapsed - private static void RenderScoreMessages(Interface.HudElement Element, double TimeElapsed) + private static void RenderScoreMessages(HUD.Element Element, double TimeElapsed) { // score messages int n = Game.ScoreMessages.Length; @@ -46,7 +46,7 @@ private static void RenderScoreMessages(Interface.HudElement Element, double Tim CreateBackColor(Element.OverlayColor, Game.ScoreMessages[j].Color, out or, out og, out ob, out oa); double tx, ty; bool preserve = false; - if ((Element.Transition & Interface.HudTransition.Move) != 0) + if ((Element.Transition & HUD.Transition.Move) != 0) { if (Game.SecondsSinceMidnight < Game.ScoreMessages[j].Timeout) { @@ -60,7 +60,7 @@ private static void RenderScoreMessages(Interface.HudElement Element, double Tim ty = y + m * Element.Value2; preserve = true; } - else if (Element.Transition == Interface.HudTransition.MoveAndFade) + else if (Element.Transition == HUD.Transition.MoveAndFade) { tx = x; ty = y + m * Element.Value2; @@ -107,7 +107,7 @@ private static void RenderScoreMessages(Interface.HudElement Element, double Tim Game.ScoreMessages[j].RendererPosition.Y += Math.Sign(ty - Game.ScoreMessages[j].RendererPosition.Y) * dy; } } - if ((Element.Transition & Interface.HudTransition.Fade) != 0) + if ((Element.Transition & HUD.Transition.Fade) != 0) { if (Game.SecondsSinceMidnight >= Game.ScoreMessages[j].Timeout) { @@ -133,9 +133,9 @@ private static void RenderScoreMessages(Interface.HudElement Element, double Tim double py = Game.ScoreMessages[j].RendererPosition.Y; float alpha = (float)(Game.ScoreMessages[j].RendererAlpha * Game.ScoreMessages[j].RendererAlpha); // graphics - Interface.HudImage Left = j == 0 ? Element.TopLeft : j < n - 1 ? Element.CenterLeft : Element.BottomLeft; - Interface.HudImage Middle = j == 0 ? Element.TopMiddle : j < n - 1 ? Element.CenterMiddle : Element.BottomMiddle; - Interface.HudImage Right = j == 0 ? Element.TopRight : j < n - 1 ? Element.CenterRight : Element.BottomRight; + HUD.Image Left = j == 0 ? Element.TopLeft : j < n - 1 ? Element.CenterLeft : Element.BottomLeft; + HUD.Image Middle = j == 0 ? Element.TopMiddle : j < n - 1 ? Element.CenterMiddle : Element.BottomMiddle; + HUD.Image Right = j == 0 ? Element.TopRight : j < n - 1 ? Element.CenterRight : Element.BottomRight; // left background if (Left.BackgroundTexture != null) { diff --git a/source/OpenBVE/Graphics/Renderer/Overlays.cs b/source/OpenBVE/Graphics/Renderer/Overlays.cs index 00a903363..cbfff9118 100644 --- a/source/OpenBVE/Graphics/Renderer/Overlays.cs +++ b/source/OpenBVE/Graphics/Renderer/Overlays.cs @@ -33,29 +33,29 @@ private static void RenderOverlays(double TimeElapsed) //Route info overlay (if selected) Game.routeInfoOverlay.Show(); //HUD - for (int i = 0; i < Interface.CurrentHudElements.Length; i++) + for (int i = 0; i < HUD.CurrentHudElements.Length; i++) { - string Command = Interface.CurrentHudElements[i].Subject.ToLowerInvariant(); + string Command = HUD.CurrentHudElements[i].Subject.ToLowerInvariant(); switch (Command) { case "messages": { - RenderGameMessages(Interface.CurrentHudElements[i], TimeElapsed); + RenderGameMessages(HUD.CurrentHudElements[i], TimeElapsed); } break; case "scoremessages": { - RenderScoreMessages(Interface.CurrentHudElements[i], TimeElapsed); + RenderScoreMessages(HUD.CurrentHudElements[i], TimeElapsed); } break; case "ats": { - RenderATSLamps(Interface.CurrentHudElements[i], TimeElapsed); + RenderATSLamps(HUD.CurrentHudElements[i], TimeElapsed); } break; default: { - RenderHUDElement(Interface.CurrentHudElements[i], TimeElapsed); + RenderHUDElement(HUD.CurrentHudElements[i], TimeElapsed); } break; } diff --git a/source/OpenBVE/OldCode/Interface.cs b/source/OpenBVE/OldCode/Interface.cs index 9e83b68b6..a9c0f6919 100644 --- a/source/OpenBVE/OldCode/Interface.cs +++ b/source/OpenBVE/OldCode/Interface.cs @@ -1,10 +1,6 @@ using System; using System.Globalization; -using System.Linq; -using System.Windows.Forms; using OpenBveApi; -using OpenBveApi.Colors; -using OpenTK.Input; namespace OpenBve { internal static partial class Interface { @@ -43,438 +39,6 @@ internal static void ClearMessages() { MessageCount = 0; } - - // ================================ - - // hud elements - internal struct HudVector { - internal int X; - internal int Y; - } - internal struct HudVectorF { - internal float X; - internal float Y; - } - internal struct HudImage { - internal Textures.Texture BackgroundTexture; - internal Textures.Texture OverlayTexture; - } - - [Flags] - internal enum HudTransition { - None = 0, - Move = 1, - Fade = 2, - MoveAndFade = 3 - } - internal class HudElement { - internal string Subject; - internal HudVectorF Position; - internal HudVector Alignment; - internal HudImage TopLeft; - internal HudImage TopMiddle; - internal HudImage TopRight; - internal HudImage CenterLeft; - internal HudImage CenterMiddle; - internal HudImage CenterRight; - internal HudImage BottomLeft; - internal HudImage BottomMiddle; - internal HudImage BottomRight; - internal Color32 BackgroundColor; - internal Color32 OverlayColor; - internal Color32 TextColor; - internal HudVectorF TextPosition; - internal HudVector TextAlignment; - internal Fonts.OpenGlFont Font; - internal bool TextShadow; - internal string Text; - internal float Value1; - internal float Value2; - internal HudTransition Transition; - internal HudVectorF TransitionVector; - internal double TransitionState; - internal HudElement() { - this.Subject = null; - this.Position.X = 0.0f; - this.Position.Y = 0.0f; - this.Alignment.X = -1; - this.Alignment.Y = -1; - this.BackgroundColor = new Color32(255, 255, 255, 255); - this.OverlayColor = new Color32(255, 255, 255, 255); - this.TextColor = new Color32(255, 255, 255, 255); - this.TextPosition.X = 0.0f; - this.TextPosition.Y = 0.0f; - this.TextAlignment.X = -1; - this.TextAlignment.Y = 0; - this.Font = Fonts.VerySmallFont; - this.TextShadow = true; - this.Text = null; - this.Value1 = 0.0f; - this.Value2 = 0.0f; - this.Transition = HudTransition.None; - this.TransitionState = 1.0; - } - } - internal static HudElement[] CurrentHudElements = new HudElement[] { }; - - // load hud - internal static void LoadHUD() { - CultureInfo Culture = CultureInfo.InvariantCulture; - string Folder = Program.FileSystem.GetDataFolder("In-game", CurrentOptions.UserInterfaceFolder); - string File = OpenBveApi.Path.CombineFile(Folder, "interface.cfg"); - CurrentHudElements = new HudElement[16]; - int Length = 0; - if (System.IO.File.Exists(File)) { - string[] Lines = System.IO.File.ReadAllLines(File, new System.Text.UTF8Encoding()); - for (int i = 0; i < Lines.Length; i++) { - int j = Lines[i].IndexOf(';'); - if (j >= 0) { - Lines[i] = Lines[i].Substring(0, j).Trim(); - } else { - Lines[i] = Lines[i].Trim(); - } - if (Lines[i].Length != 0) { - if (!Lines[i].StartsWith(";", StringComparison.Ordinal)) { - if (Lines[i].Equals("[element]", StringComparison.OrdinalIgnoreCase)) { - Length++; - if (Length > CurrentHudElements.Length) { - Array.Resize(ref CurrentHudElements, CurrentHudElements.Length << 1); - } - CurrentHudElements[Length - 1] = new HudElement(); - } else if (Length == 0) { - System.Windows.Forms.MessageBox.Show("Line outside of [element] structure encountered at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - j = Lines[i].IndexOf("=", StringComparison.Ordinal); - if (j >= 0) { - string Command = Lines[i].Substring(0, j).TrimEnd(); - string[] Arguments = Lines[i].Substring(j + 1).TrimStart().Split(new char[] { ',' }, StringSplitOptions.None); - for (j = 0; j < Arguments.Length; j++) { - Arguments[j] = Arguments[j].Trim(); - } - switch (Command.ToLowerInvariant()) { - case "subject": - if (Arguments.Length == 1) { - CurrentHudElements[Length - 1].Subject = Arguments[0]; - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "position": - if (Arguments.Length == 2) { - float x, y; - if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x)) { - System.Windows.Forms.MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y)) { - System.Windows.Forms.MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].Position.X = x; - CurrentHudElements[Length - 1].Position.Y = y; - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "alignment": - if (Arguments.Length == 2) { - int x, y; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out x)) { - System.Windows.Forms.MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out y)) { - System.Windows.Forms.MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].Alignment.X = Math.Sign(x); - CurrentHudElements[Length - 1].Alignment.Y = Math.Sign(y); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "topleft": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopLeft.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopLeft.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "topmiddle": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopMiddle.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopMiddle.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "topright": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].TopRight.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].TopRight.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "centerleft": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterLeft.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterLeft.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "centermiddle": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterMiddle.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterMiddle.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "centerright": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].CenterRight.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].CenterRight.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "bottomleft": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomLeft.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomLeft.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "bottommiddle": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomMiddle.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomMiddle.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "bottomright": - if (Arguments.Length == 2) { - if (Arguments[0].Length != 0 & !Arguments[0].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[0]), out CurrentHudElements[Length - 1].BottomRight.BackgroundTexture); - } - if (Arguments[1].Length != 0 & !Arguments[1].Equals("null", StringComparison.OrdinalIgnoreCase)) { - Textures.RegisterTexture(OpenBveApi.Path.CombineFile(Folder, Arguments[1]), out CurrentHudElements[Length - 1].BottomRight.OverlayTexture); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "backcolor": - if (Arguments.Length == 4) { - int r, g, b, a; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r)) { - System.Windows.Forms.MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g)) { - System.Windows.Forms.MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b)) { - System.Windows.Forms.MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a)) { - System.Windows.Forms.MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - r = r < 0 ? 0 : r > 255 ? 255 : r; - g = g < 0 ? 0 : g > 255 ? 255 : g; - b = b < 0 ? 0 : b > 255 ? 255 : b; - a = a < 0 ? 0 : a > 255 ? 255 : a; - CurrentHudElements[Length - 1].BackgroundColor = new Color32((byte)r, (byte)g, (byte)b, (byte)a); - } break; - } - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - break; - case "overlaycolor": - if (Arguments.Length == 4) { - int r, g, b, a; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r)) { - System.Windows.Forms.MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g)) { - System.Windows.Forms.MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b)) { - System.Windows.Forms.MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a)) { - System.Windows.Forms.MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - r = r < 0 ? 0 : r > 255 ? 255 : r; - g = g < 0 ? 0 : g > 255 ? 255 : g; - b = b < 0 ? 0 : b > 255 ? 255 : b; - a = a < 0 ? 0 : a > 255 ? 255 : a; - CurrentHudElements[Length - 1].OverlayColor = new Color32((byte)r, (byte)g, (byte)b, (byte)a); - } break; - } - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - break; - case "textcolor": - if (Arguments.Length == 4) { - int r, g, b, a; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out r)) { - System.Windows.Forms.MessageBox.Show("R is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out g)) { - System.Windows.Forms.MessageBox.Show("G is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[2], NumberStyles.Integer, Culture, out b)) { - System.Windows.Forms.MessageBox.Show("B is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[3], NumberStyles.Integer, Culture, out a)) { - System.Windows.Forms.MessageBox.Show("A is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - r = r < 0 ? 0 : r > 255 ? 255 : r; - g = g < 0 ? 0 : g > 255 ? 255 : g; - b = b < 0 ? 0 : b > 255 ? 255 : b; - a = a < 0 ? 0 : a > 255 ? 255 : a; - CurrentHudElements[Length - 1].TextColor = new Color32((byte)r, (byte)g, (byte)b, (byte)a); - } break; - } - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - break; - case "textposition": - if (Arguments.Length == 2) { - float x, y; - if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x)) { - System.Windows.Forms.MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y)) { - System.Windows.Forms.MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].TextPosition.X = x; - CurrentHudElements[Length - 1].TextPosition.Y = y; - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "textalignment": - if (Arguments.Length == 2) { - int x, y; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out x)) { - System.Windows.Forms.MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!int.TryParse(Arguments[1], NumberStyles.Integer, Culture, out y)) { - System.Windows.Forms.MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].TextAlignment.X = Math.Sign(x); - CurrentHudElements[Length - 1].TextAlignment.Y = Math.Sign(y); - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "textsize": - if (Arguments.Length == 1) { - int s; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out s)) { - System.Windows.Forms.MessageBox.Show("SIZE is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - switch (s) { - case 0: CurrentHudElements[Length - 1].Font = Fonts.VerySmallFont; break; - case 1: CurrentHudElements[Length - 1].Font = Fonts.SmallFont; break; - case 2: CurrentHudElements[Length - 1].Font = Fonts.NormalFont; break; - case 3: CurrentHudElements[Length - 1].Font = Fonts.LargeFont; break; - case 4: CurrentHudElements[Length - 1].Font = Fonts.VeryLargeFont; break; - default: CurrentHudElements[Length - 1].Font = Fonts.NormalFont; break; - } - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "textshadow": - if (Arguments.Length == 1) { - int s; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out s)) { - System.Windows.Forms.MessageBox.Show("SHADOW is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].TextShadow = s != 0; - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "text": - if (Arguments.Length == 1) { - CurrentHudElements[Length - 1].Text = Arguments[0]; - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "value": - if (Arguments.Length == 1) { - int n; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out n)) { - System.Windows.Forms.MessageBox.Show("VALUE1 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].Value1 = n; - } - } else if (Arguments.Length == 2) { - float a, b; - if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out a)) { - System.Windows.Forms.MessageBox.Show("VALUE1 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out b)) { - System.Windows.Forms.MessageBox.Show("VALUE2 is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].Value1 = a; - CurrentHudElements[Length - 1].Value2 = b; - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "transition": - if (Arguments.Length == 1) { - int n; - if (!int.TryParse(Arguments[0], NumberStyles.Integer, Culture, out n)) { - System.Windows.Forms.MessageBox.Show("TRANSITION is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].Transition = (HudTransition)n; - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - case "transitionvector": - if (Arguments.Length == 2) { - float x, y; - if (!float.TryParse(Arguments[0], NumberStyles.Float, Culture, out x)) { - System.Windows.Forms.MessageBox.Show("X is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else if (!float.TryParse(Arguments[1], NumberStyles.Float, Culture, out y)) { - System.Windows.Forms.MessageBox.Show("Y is invalid in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } else { - CurrentHudElements[Length - 1].TransitionVector.X = x; - CurrentHudElements[Length - 1].TransitionVector.Y = y; - } - } else { - System.Windows.Forms.MessageBox.Show("Incorrect number of arguments supplied in " + Command + " at line " + (i + 1).ToString(Culture) + " in " + File); - } break; - default: - System.Windows.Forms.MessageBox.Show("Invalid command encountered at line " + (i + 1).ToString(Culture) + " in " + File); - break; - } - } else { - System.Windows.Forms.MessageBox.Show("Invalid statement encountered at line " + (i + 1).ToString(Culture) + " in " + File); - } - } - } - } - } - } - Array.Resize(ref CurrentHudElements, Length); - } - - // ================================ - - /// Parses a string into OpenBVE's internal time representation (Seconds since midnight on the first day) /// The time in string format /// The number of seconds since midnight on the first day this represents, updated via 'out' diff --git a/source/OpenBVE/OldCode/TrainManager.cs b/source/OpenBVE/OldCode/TrainManager.cs index 653800c79..5dd665661 100644 --- a/source/OpenBVE/OldCode/TrainManager.cs +++ b/source/OpenBVE/OldCode/TrainManager.cs @@ -6,73 +6,6 @@ namespace OpenBve /// The TrainManager is the root class containing functions to load and manage trains within the simulation world. public static partial class TrainManager { - internal enum CarBrakeType - { - ElectromagneticStraightAirBrake = 0, - ElectricCommandBrake = 1, - AutomaticAirBrake = 2 - } - internal enum EletropneumaticBrakeType - { - None = 0, - ClosingElectromagneticValve = 1, - DelayFillingControl = 2 - } - - internal enum AirBrakeType { Main, Auxillary } - internal struct CarAirBrake - { - internal AirBrakeType Type; - internal bool AirCompressorEnabled; - internal double AirCompressorMinimumPressure; - internal double AirCompressorMaximumPressure; - internal double AirCompressorRate; - internal double MainReservoirCurrentPressure; - internal double MainReservoirEqualizingReservoirCoefficient; - internal double MainReservoirBrakePipeCoefficient; - internal double EqualizingReservoirCurrentPressure; - internal double EqualizingReservoirNormalPressure; - internal double EqualizingReservoirServiceRate; - - internal double EqualizingReservoirEmergencyRate; - internal double EqualizingReservoirChargeRate; - internal double BrakePipeCurrentPressure; - internal double BrakePipeNormalPressure; - internal double BrakePipeChargeRate; - internal double BrakePipeServiceRate; - internal double BrakePipeEmergencyRate; - internal double AuxillaryReservoirCurrentPressure; - internal double AuxillaryReservoirMaximumPressure; - internal double AuxillaryReservoirChargeRate; - internal double AuxillaryReservoirBrakePipeCoefficient; - internal double AuxillaryReservoirBrakeCylinderCoefficient; - internal double BrakeCylinderCurrentPressure; - internal double BrakeCylinderEmergencyMaximumPressure; - internal double BrakeCylinderServiceMaximumPressure; - internal double BrakeCylinderEmergencyChargeRate; - internal double BrakeCylinderServiceChargeRate; - internal double BrakeCylinderReleaseRate; - internal double BrakeCylinderSoundPlayedForPressure; - internal double StraightAirPipeCurrentPressure; - internal double StraightAirPipeReleaseRate; - internal double StraightAirPipeServiceRate; - internal double StraightAirPipeEmergencyRate; - } - - - - - - - - // train - - // train specs - - internal struct TrainAirBrake - { - internal AirBrakeHandle Handle; - } internal enum DoorMode { AutomaticManualOverride = 0, @@ -94,72 +27,81 @@ internal enum DoorMode /// The absolute on-disk path to the train folder. /// The automatically detected or manually set encoding of the panel configuration file. /// The base train on which to apply the panel configuration. - internal static void ParsePanelConfig(string TrainPath, System.Text.Encoding Encoding, TrainManager.Train Train) + internal static void ParsePanelConfig(string TrainPath, System.Text.Encoding Encoding, Train Train) { + Train.Cars[Train.DriverCar].CarSections = new CarSection[1]; + Train.Cars[Train.DriverCar].CarSections[0] = new CarSection + { + Elements = new ObjectManager.AnimatedObject[] { }, + Overlay = true + }; string File = OpenBveApi.Path.CombineFile(TrainPath, "panel.animated"); if (System.IO.File.Exists(File)) { Program.AppendToLogFile("Loading train panel: " + File); ObjectManager.AnimatedObjectCollection a = AnimatedObjectParser.ReadObject(File, Encoding, ObjectManager.ObjectLoadMode.DontAllowUnloadOfTextures); - try + if (a != null) { - for (int i = 0; i < a.Objects.Length; i++) + //HACK: If a == null , loading our animated object completely failed (Missing objects?). Fallback to trying the panel2.cfg + try { - a.Objects[i].ObjectIndex = ObjectManager.CreateDynamicObject(); + for (int i = 0; i < a.Objects.Length; i++) + { + a.Objects[i].ObjectIndex = ObjectManager.CreateDynamicObject(); + } + Train.Cars[Train.DriverCar].CarSections[0].Elements = a.Objects; + Train.Cars[Train.DriverCar].CameraRestrictionMode = Camera.RestrictionMode.NotAvailable; + World.CameraRestriction = Camera.RestrictionMode.NotAvailable; + World.UpdateViewingDistances(); + return; + } + catch + { + var currentError = Interface.GetInterfaceString("errors_critical_file"); + currentError = currentError.Replace("[file]", "panel.animated"); + MessageBox.Show(currentError, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); + Program.RestartArguments = " "; + Loading.Cancel = true; + return; } - Train.Cars[Train.DriverCar].CarSections[0].Elements = a.Objects; - Train.Cars[Train.DriverCar].CameraRestrictionMode = World.CameraRestrictionMode.NotAvailable; - World.CameraRestriction = World.CameraRestrictionMode.NotAvailable; - World.UpdateViewingDistances(); - } - catch - { - var currentError = Interface.GetInterfaceString("error_critical_file"); - currentError = currentError.Replace("[file]", "panel.animated"); - MessageBox.Show(currentError, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); - Program.RestartArguments = " "; - Loading.Cancel = true; } } - else + + var Panel2 = false; + try { - var Panel2 = false; - try + File = OpenBveApi.Path.CombineFile(TrainPath, "panel2.cfg"); + if (System.IO.File.Exists(File)) + { + Program.AppendToLogFile("Loading train panel: " + File); + Panel2 = true; + Panel2CfgParser.ParsePanel2Config("panel2.cfg", TrainPath, Encoding, Train, Train.DriverCar); + Train.Cars[Train.DriverCar].CameraRestrictionMode = Camera.RestrictionMode.On; + World.CameraRestriction = Camera.RestrictionMode.On; + } + else { - File = OpenBveApi.Path.CombineFile(TrainPath, "panel2.cfg"); + File = OpenBveApi.Path.CombineFile(TrainPath, "panel.cfg"); if (System.IO.File.Exists(File)) { Program.AppendToLogFile("Loading train panel: " + File); - Panel2 = true; - Panel2CfgParser.ParsePanel2Config("panel2.cfg", TrainPath, Encoding, Train, Train.DriverCar); - Train.Cars[Train.DriverCar].CameraRestrictionMode = World.CameraRestrictionMode.On; - World.CameraRestriction = World.CameraRestrictionMode.On; + PanelCfgParser.ParsePanelConfig(TrainPath, Encoding, Train); + Train.Cars[Train.DriverCar].CameraRestrictionMode = Camera.RestrictionMode.On; + World.CameraRestriction = Camera.RestrictionMode.On; } else { - File = OpenBveApi.Path.CombineFile(TrainPath, "panel.cfg"); - if (System.IO.File.Exists(File)) - { - Program.AppendToLogFile("Loading train panel: " + File); - PanelCfgParser.ParsePanelConfig(TrainPath, Encoding, Train); - Train.Cars[Train.DriverCar].CameraRestrictionMode = World.CameraRestrictionMode.On; - World.CameraRestriction = World.CameraRestrictionMode.On; - } - else - { - World.CameraRestriction = World.CameraRestrictionMode.NotAvailable; - } + World.CameraRestriction = Camera.RestrictionMode.NotAvailable; } } - catch - { - var currentError = Interface.GetInterfaceString("errors_critical_file"); - currentError = currentError.Replace("[file]", Panel2 == true ? "panel2.cfg" : "panel.cfg"); - MessageBox.Show(currentError, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); - Program.RestartArguments = " "; - Loading.Cancel = true; - } - + } + catch + { + var currentError = Interface.GetInterfaceString("errors_critical_file"); + currentError = currentError.Replace("[file]", Panel2 == true ? "panel2.cfg" : "panel.cfg"); + MessageBox.Show(currentError, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); + Program.RestartArguments = " "; + Loading.Cancel = true; } } diff --git a/source/OpenBVE/OldCode/World.cs b/source/OpenBVE/OldCode/World.cs index e46d43a3f..f480e37cb 100644 --- a/source/OpenBVE/OldCode/World.cs +++ b/source/OpenBVE/OldCode/World.cs @@ -288,7 +288,7 @@ internal struct DriverBody { internal ObjectManager.Damping PitchDamping; internal void Update(double TimeElapsed) { - if (CameraRestriction == CameraRestrictionMode.NotAvailable) { + if (CameraRestriction == Camera.RestrictionMode.NotAvailable) { { // pitch double targetY = TrainManager.PlayerTrain.Specs.CurrentAverageAcceleration; @@ -427,6 +427,7 @@ internal CameraAlignment(Vector3 Position, double Yaw, double Pitch, double Roll } } internal static TrackManager.TrackFollower CameraTrackFollower; + internal static bool CameraAtWorldEnd; internal static CameraAlignment CameraCurrentAlignment; internal static CameraAlignment CameraAlignmentDirection; internal static CameraAlignment CameraAlignmentSpeed; @@ -448,18 +449,8 @@ internal enum CameraViewMode { Interior, InteriorLookAhead, Exterior, Track, Fly // camera restriction internal static Vector3 CameraRestrictionBottomLeft = new Vector3(-1.0, -1.0, 1.0); internal static Vector3 CameraRestrictionTopRight = new Vector3(1.0, 1.0, 1.0); - internal enum CameraRestrictionMode { - /// Represents a 3D cab. - NotAvailable = -1, - /// Represents a 2D cab with camera restriction disabled. - Off = 0, - /// Represents a 2D cab with camera restriction enabled. - On = 1, - /// The camera restriction mode is not specified (Used by parsers) - NotSpecified = 3 - - } - internal static CameraRestrictionMode CameraRestriction = CameraRestrictionMode.NotAvailable; + + internal static Camera.RestrictionMode CameraRestriction = Camera.RestrictionMode.NotAvailable; // absolute camera internal static Vector3 AbsoluteCameraPosition; @@ -469,7 +460,7 @@ internal enum CameraRestrictionMode { // camera restriction internal static void InitializeCameraRestriction() { - if ((CameraMode == CameraViewMode.Interior | CameraMode == CameraViewMode.InteriorLookAhead) & CameraRestriction == CameraRestrictionMode.On) { + if ((CameraMode == CameraViewMode.Interior | CameraMode == CameraViewMode.InteriorLookAhead) & CameraRestriction == Camera.RestrictionMode.On) { CameraAlignmentSpeed = new CameraAlignment(); UpdateAbsoluteCamera(0.0); if (!PerformCameraRestrictionTest()) { @@ -505,7 +496,7 @@ internal static void InitializeCameraRestriction() { } } internal static bool PerformProgressiveAdjustmentForCameraRestriction(ref double Source, double Target, bool Zoom) { - if ((CameraMode != CameraViewMode.Interior & CameraMode != CameraViewMode.InteriorLookAhead) | CameraRestriction != CameraRestrictionMode.On) { + if ((CameraMode != CameraViewMode.Interior & CameraMode != CameraViewMode.InteriorLookAhead) | CameraRestriction != Camera.RestrictionMode.On) { Source = Target; return true; } @@ -553,7 +544,7 @@ internal static bool PerformBoundingBoxTest(ref ObjectManager.StaticObject bound internal static bool PerformCameraRestrictionTest() { - if (World.CameraRestriction == CameraRestrictionMode.On) { + if (World.CameraRestriction == Camera.RestrictionMode.On) { Vector3[] p = new Vector3[] { CameraRestrictionBottomLeft, CameraRestrictionTopRight }; Vector2[] r = new Vector2[2]; for (int j = 0; j < 2; j++) { @@ -737,7 +728,7 @@ internal static void UpdateAbsoluteCamera(double TimeElapsed) { AdjustAlignment(ref World.CameraCurrentAlignment.Position.X, World.CameraAlignmentDirection.Position.X, ref World.CameraAlignmentSpeed.Position.X, TimeElapsed); AdjustAlignment(ref World.CameraCurrentAlignment.Position.Y, World.CameraAlignmentDirection.Position.Y, ref World.CameraAlignmentSpeed.Position.Y, TimeElapsed); AdjustAlignment(ref World.CameraCurrentAlignment.Position.Z, World.CameraAlignmentDirection.Position.Z, ref World.CameraAlignmentSpeed.Position.Z, TimeElapsed); - if ((CameraMode == CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead) & CameraRestriction == CameraRestrictionMode.On) { + if ((CameraMode == CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead) & CameraRestriction == Camera.RestrictionMode.On) { if (CameraCurrentAlignment.Position.Z > 0.75) { CameraCurrentAlignment.Position.Z = 0.75; } @@ -848,7 +839,7 @@ internal static void UpdateAbsoluteCamera(double TimeElapsed) { double bodyRoll = 0.0; double headRoll = World.CameraCurrentAlignment.Roll; // rotation - if (CameraRestriction == CameraRestrictionMode.NotAvailable & (CameraMode == CameraViewMode.Interior | CameraMode == CameraViewMode.InteriorLookAhead)) { + if (CameraRestriction == Camera.RestrictionMode.NotAvailable & (CameraMode == CameraViewMode.Interior | CameraMode == CameraViewMode.InteriorLookAhead)) { // with body and head bodyPitch += CurrentDriverBody.Pitch; headPitch -= 0.2 * CurrentDriverBody.Pitch; diff --git a/source/OpenBVE/OpenBve.csproj b/source/OpenBVE/OpenBve.csproj index bfd24110a..e852ea0fe 100644 --- a/source/OpenBVE/OpenBve.csproj +++ b/source/OpenBVE/OpenBve.csproj @@ -174,6 +174,20 @@ + + + Camera.cs + + + + HUD.cs + + + HUD.cs + + + HUD.cs + @@ -228,8 +242,9 @@ - - + + + True True @@ -240,9 +255,24 @@ True Resources.resx + + + + + + + + + + + + + + + @@ -255,7 +285,6 @@ - @@ -277,6 +306,7 @@ + @@ -331,7 +361,6 @@ - Sounds.cs @@ -451,6 +480,7 @@ + diff --git a/source/OpenBVE/Parsers/Object/BVE/AnimatedObjectParser.cs b/source/OpenBVE/Parsers/Object/BVE/AnimatedObjectParser.cs index d14d14261..255c38b29 100644 --- a/source/OpenBVE/Parsers/Object/BVE/AnimatedObjectParser.cs +++ b/source/OpenBVE/Parsers/Object/BVE/AnimatedObjectParser.cs @@ -1371,6 +1371,16 @@ internal static ObjectManager.AnimatedObjectCollection ReadObject(string FileNam } break; default: + if (Lines.Length == 1 && Encoding.Equals(System.Text.Encoding.Unicode)) + { + /* + * If only one line, there's a good possibility that our file is NOT Unicode at all + * and that the misdetection has turned it into garbage + * + * Try again with ASCII instead + */ + return ReadObject(FileName, System.Text.Encoding.GetEncoding(1252), LoadMode); + } Interface.AddMessage(Interface.MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName); return null; } @@ -1385,7 +1395,7 @@ private static void ApplyStaticRotation(ref World.Mesh Mesh, Vector3 RotationDir //Update co-ords for (int i = 0; i < Mesh.Vertices.Length; i++) { - World.Rotate(ref Mesh.Vertices[i].Coordinates, RotationDirection, Math.Cos(Angle), Math.Sin(Angle)); + Mesh.Vertices[i].Coordinates.Rotate(RotationDirection, Math.Cos(Angle), Math.Sin(Angle)); } //Update normals for (int i = 0; i < Mesh.Faces.Length; i++) @@ -1393,7 +1403,7 @@ private static void ApplyStaticRotation(ref World.Mesh Mesh, Vector3 RotationDir for(int j = 0; j < Mesh.Faces[i].Vertices.Length; j++) if (!Vector3.IsZero(Mesh.Faces[i].Vertices[j].Normal)) { - World.Rotate(ref Mesh.Faces[i].Vertices[j].Normal, RotationDirection, Math.Cos(Angle), Math.Sin(Angle)); + Mesh.Faces[i].Vertices[j].Normal.Rotate(RotationDirection, Math.Cos(Angle), Math.Sin(Angle)); } } } diff --git a/source/OpenBVE/Parsers/Object/BVE/CsvB3dObjectParser.cs b/source/OpenBVE/Parsers/Object/BVE/CsvB3dObjectParser.cs index 1e79f6e28..8d04248d8 100644 --- a/source/OpenBVE/Parsers/Object/BVE/CsvB3dObjectParser.cs +++ b/source/OpenBVE/Parsers/Object/BVE/CsvB3dObjectParser.cs @@ -635,9 +635,9 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te y *= t; z *= t; a *= 0.0174532925199433; - ApplyRotation(Builder, x, y, z, a); + ApplyRotation(Builder, new Vector3(x,y,z), a); if (cmd == "rotateall") { - Object.ApplyRotation(x, y, z, a); + Object.ApplyRotation(new Vector3(x,y,z), a); } } } break; @@ -1131,10 +1131,10 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te int.TryParse(Arguments[0], out r); int.TryParse(Arguments[1], out g); int.TryParse(Arguments[2], out b); - Color textColor = Color.FromArgb(r, g, b); + Color backgroundColor = Color.FromArgb(r, g, b); for (int j = 0; j < Builder.Materials.Length; j++) { - Builder.Materials[j].BackgroundColor = textColor; + Builder.Materials[j].BackgroundColor = backgroundColor; } } break; @@ -1422,15 +1422,15 @@ private static void ApplyScale(MeshBuilder Builder, double x, double y, double z // apply rotation - private static void ApplyRotation(MeshBuilder Builder, double x, double y, double z, double a) { - double cosa = Math.Cos(a); - double sina = Math.Sin(a); + private static void ApplyRotation(MeshBuilder Builder, Vector3 Rotation, double Angle) { + double cosa = Math.Cos(Angle); + double sina = Math.Sin(Angle); for (int i = 0; i < Builder.Vertices.Length; i++) { - World.Rotate(ref Builder.Vertices[i].Coordinates, x, y, z, cosa, sina); + Builder.Vertices[i].Coordinates.Rotate(Rotation, cosa, sina); } for (int i = 0; i < Builder.Faces.Length; i++) { for (int j = 0; j < Builder.Faces[i].Vertices.Length; j++) { - World.Rotate(ref Builder.Faces[i].Vertices[j].Normal, x, y, z, cosa, sina); + Builder.Faces[i].Vertices[j].Normal.Rotate(Rotation, cosa, sina); } } } diff --git a/source/OpenBVE/Parsers/Object/Generic/WavefrontObjParser.cs b/source/OpenBVE/Parsers/Object/Generic/WavefrontObjParser.cs index 4eb8fdf63..f6c73aa06 100644 --- a/source/OpenBVE/Parsers/Object/Generic/WavefrontObjParser.cs +++ b/source/OpenBVE/Parsers/Object/Generic/WavefrontObjParser.cs @@ -52,7 +52,7 @@ internal MeshBuilder() /// Loads a Wavefront object from a file. /// The text file to load the animated object from. Must be an absolute file name. - /// The encoding the file is saved in. If the file uses a byte order mark, the encoding indicated by the byte order mark is used and the Encoding parameter is ignored. + /// The encoding the file is saved in. /// The texture load mode. /// Whether to force TextureWrapMode.Repeat for referenced textures on the X-axis /// Whether to force TextureWrapMode.Repeat for referenced textures on the Y-axis @@ -82,7 +82,7 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te int currentMaterial = -1; //Read the contents of the file - string[] Lines = File.ReadAllLines(FileName); + string[] Lines = File.ReadAllLines(FileName, Encoding); //Preprocess for (int i = 0; i < Lines.Length; i++) @@ -137,8 +137,6 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te { Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid X co-ordinate in Texture Co-Ordinates at Line " + i); } - //Wavefront obj texture co-ords Y axis appear inverted v.s. BVE standard - coords.Y = -coords.Y; tempCoords.Add(coords); break; case "vn": @@ -218,6 +216,10 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te currentCoord++; currentCoord += idx; } + else + { + currentCoord = idx; + } if (currentCoord > tempCoords.Count) { Interface.AddMessage(Interface.MessageType.Warning, false, "Texture Co-ordinate index " + currentCoord + " was greater than the available number of texture co-ordinates in Face " + f + " at Line " + i); @@ -252,6 +254,10 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te currentNormal++; currentNormal += idx; } + else + { + currentNormal = idx; + } if (currentNormal > tempNormals.Count) { Interface.AddMessage(Interface.MessageType.Warning, false, "Vertex Normal index " + currentNormal + " was greater than the available number of normals in Face " + f + " at Line " + i); diff --git a/source/OpenBVE/Parsers/Object/Generic/XObjectParser.cs b/source/OpenBVE/Parsers/Object/Generic/XObjectParser.cs index 7a5b889f1..10f2e51df 100644 --- a/source/OpenBVE/Parsers/Object/Generic/XObjectParser.cs +++ b/source/OpenBVE/Parsers/Object/Generic/XObjectParser.cs @@ -39,7 +39,7 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te return LoadTextualX(FileName, System.IO.File.ReadAllText(FileName), Encoding, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); } else if (Data[8] == 98 & Data[9] == 105 & Data[10] == 110 & Data[11] == 32) { // binary flavor - return LoadBinaryX(FileName, Data, 16, Encoding, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); + return LoadBinaryX(FileName, Data, 16, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); } else if (Data[8] == 116 & Data[9] == 122 & Data[10] == 105 & Data[11] == 112) { // compressed textual flavor #if !DEBUG @@ -60,7 +60,7 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te try { #endif byte[] Uncompressed = Decompress(Data); - return LoadBinaryX(FileName, Uncompressed, 0, Encoding, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); + return LoadBinaryX(FileName, Uncompressed, 0, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Error, false, "An unexpected error occured (" + ex.Message + ") while attempting to decompress the binary X object file encountered in " + FileName); @@ -844,7 +844,7 @@ private static bool ReadTextualTemplate(string FileName, string Content, ref int // ================================ // load binary x - private static ObjectManager.StaticObject LoadBinaryX(string FileName, byte[] Data, int StartingPosition, System.Text.Encoding Encoding, int FloatingPointSize, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { + private static ObjectManager.StaticObject LoadBinaryX(string FileName, byte[] Data, int StartingPosition, int FloatingPointSize, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { // parse file AlternateStructure = false; LoadedMaterials = new Structure[] {}; diff --git a/source/OpenBVE/Parsers/Object/MSTS/ShapeParser.cs b/source/OpenBVE/Parsers/Object/MSTS/ShapeParser.cs index d2d56db56..5958c0177 100644 --- a/source/OpenBVE/Parsers/Object/MSTS/ShapeParser.cs +++ b/source/OpenBVE/Parsers/Object/MSTS/ShapeParser.cs @@ -16,7 +16,7 @@ // ReSharper disable NotAccessedField.Local // ReSharper disable RedundantAssignment // ReSharper disable UnusedVariable -#pragma warning disable 2019 +#pragma warning disable 0219 namespace OpenBve { class MsTsShapeParser @@ -630,7 +630,7 @@ private static void ParseBlock(Block block, ref MsTsShape shape, ref Vertex vert break; case KujuTokenID.texture: - int imageIDX = (int) block.ReadUInt32(); + int imageIDX = block.ReadInt32(); int filterMode = (int) block.ReadUInt32(); float mipmapLODBias = block.ReadSingle(); uint borderColor = 0xff000000U; @@ -1077,4 +1077,4 @@ private static void ParseBlock(Block block, ref MsTsShape shape, ref Vertex vert } } } -#pragma warning restore 2019 +#pragma warning restore 0219 diff --git a/source/OpenBVE/Parsers/Panel/Panel2CfgParser.cs b/source/OpenBVE/Parsers/Panel/Panel2CfgParser.cs index 9cfd25c58..609b8ee6d 100644 --- a/source/OpenBVE/Parsers/Panel/Panel2CfgParser.cs +++ b/source/OpenBVE/Parsers/Panel/Panel2CfgParser.cs @@ -3,7 +3,6 @@ using OpenBveApi.Colors; using OpenBveApi.Math; using OpenBveApi.Objects; -using OpenBveApi.Textures; namespace OpenBve { internal static class Panel2CfgParser { @@ -25,7 +24,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste string trainName = new System.IO.DirectoryInfo(TrainPath).Name.ToUpperInvariant(); // read lines System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture; - string FileName = OpenBveApi.Path.CombineFile(TrainPath, PanelFile); + string FileName = Path.CombineFile(TrainPath, PanelFile); string[] Lines = System.IO.File.ReadAllLines(FileName, Encoding); for (int i = 0; i < Lines.Length; i++) { Lines[i] = Lines[i].Trim(); @@ -38,8 +37,8 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste double PanelResolution = 1024.0; double PanelLeft = 0.0, PanelRight = 1024.0; double PanelTop = 0.0, PanelBottom = 1024.0; - double PanelCenterX = 0.0, PanelCenterY = 512.0; - double PanelOriginX = 0.0, PanelOriginY = 512.0; + Vector2 PanelCenter = new Vector2(0, 512); + Vector2 PanelOrigin = new Vector2(0, 512); double PanelBitmapWidth = 1024.0, PanelBitmapHeight = 1024.0; string PanelDaytimeImage = null; string PanelNighttimeImage = null; @@ -108,7 +107,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - PanelDaytimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + PanelDaytimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(PanelDaytimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + PanelDaytimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); PanelDaytimeImage = null; @@ -120,7 +119,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - PanelNighttimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + PanelNighttimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(PanelNighttimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + PanelNighttimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); PanelNighttimeImage = null; @@ -137,15 +136,15 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (k >= 0) { string a = Value.Substring(0, k).TrimEnd(); string b = Value.Substring(k + 1).TrimStart(); - if (a.Length != 0 && !NumberFormats.TryParseDoubleVb6(a, out PanelCenterX)) { + if (a.Length != 0 && !NumberFormats.TryParseDoubleVb6(a, out PanelCenter.X)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } - if (b.Length != 0 && !NumberFormats.TryParseDoubleVb6(b, out PanelCenterY)) { + if (b.Length != 0 && !NumberFormats.TryParseDoubleVb6(b, out PanelCenter.Y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } if (Interface.CurrentOptions.EnableBveTsHacks) { - switch ((int)PanelCenterY) + switch ((int)PanelCenter.Y) { case 180: switch (trainName.ToUpperInvariant()) @@ -153,7 +152,16 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste case "LT_C69_77": case "LT_C69_77_V2": // Broken initial zoom - PanelCenterY = 350; + PanelCenter.Y = 350; + break; + } + break; + case 200: + switch (trainName.ToUpperInvariant()) + { + case "HM05": + // Broken initial zoom + PanelCenter.Y = 350; break; } break; @@ -161,7 +169,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (PanelBottom == 768 && PanelResolution == 1024) { // Martin Finken's BVE4 trams: Broken initial zoom - PanelCenterY = 350; + PanelCenter.Y = 350; } break; case 255: @@ -177,12 +185,12 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste case "LT1938": case "LT1973 UNREFURB": // Broken initial zoom - PanelCenterY = 350; + PanelCenter.Y = 350; break; case "LT_A60_62": case "LT1972 MKII": // Broken initial zoom and black patch at bottom of panel - PanelCenterY = 350; + PanelCenter.Y = 350; PanelBottom = 792; break; } @@ -201,10 +209,10 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (k >= 0) { string a = Value.Substring(0, k).TrimEnd(); string b = Value.Substring(k + 1).TrimStart(); - if (a.Length != 0 && !NumberFormats.TryParseDoubleVb6(a, out PanelOriginX)) { + if (a.Length != 0 && !NumberFormats.TryParseDoubleVb6(a, out PanelOrigin.X)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } - if (b.Length != 0 && !NumberFormats.TryParseDoubleVb6(b, out PanelOriginY)) { + if (b.Length != 0 && !NumberFormats.TryParseDoubleVb6(b, out PanelOrigin.Y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } if (Interface.CurrentOptions.EnableBveTsHacks) @@ -212,10 +220,10 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste switch (trainName) { case "8171BETA": - if (PanelResolution == 768 && PanelOriginY == 256) + if (PanelResolution == 768 && PanelOrigin.Y == 256) { // 81-71: Bust panel origin means a flying cab.... - PanelOriginY = 0; + PanelOrigin.Y = 0; } break; } @@ -240,14 +248,14 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste WorldHeight = 2.0 * Math.Tan(0.5 * World.VerticalViewingAngle) * EyeDistance / World.AspectRatio; WorldWidth = WorldHeight * World.AspectRatio; } - double x0 = (PanelLeft - PanelCenterX) / PanelResolution; - double x1 = (PanelRight - PanelCenterX) / PanelResolution; - double y0 = (PanelCenterY - PanelBottom) / PanelResolution * World.AspectRatio; - double y1 = (PanelCenterY - PanelTop) / PanelResolution * World.AspectRatio; + double x0 = (PanelLeft - PanelCenter.X) / PanelResolution; + double x1 = (PanelRight - PanelCenter.X) / PanelResolution; + double y0 = (PanelCenter.Y - PanelBottom) / PanelResolution * World.AspectRatio; + double y1 = (PanelCenter.Y - PanelTop) / PanelResolution * World.AspectRatio; World.CameraRestrictionBottomLeft = new Vector3(x0 * WorldWidth, y0 * WorldHeight, EyeDistance); World.CameraRestrictionTopRight = new Vector3(x1 * WorldWidth, y1 * WorldHeight, EyeDistance); - Train.Cars[Car].DriverYaw = Math.Atan((PanelCenterX - PanelOriginX) * WorldWidth / PanelResolution); - Train.Cars[Car].DriverPitch = Math.Atan((PanelOriginY - PanelCenterY) * WorldWidth / PanelResolution); + Train.Cars[Car].DriverYaw = Math.Atan((PanelCenter.X - PanelOrigin.X) * WorldWidth / PanelResolution); + Train.Cars[Car].DriverPitch = Math.Atan((PanelOrigin.Y - PanelCenter.Y) * WorldWidth / PanelResolution); } // create panel if (PanelDaytimeImage != null) { @@ -271,7 +279,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste }); PanelBitmapWidth = (double)tday.Width; PanelBitmapHeight = (double)tday.Height; - CreateElement(Train.Cars[Car].CarSections[0], 0.0, 0.0, PanelBitmapWidth, PanelBitmapHeight, 0.5, 0.5, 0.0, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenterX, PanelCenterY, PanelOriginX, PanelOriginY, Train.Cars[Car].Driver, tday, tnight, new Color32(255, 255, 255, 255), false); + CreateElement(Train.Cars[Car].CarSections[0], 0.0, 0.0, PanelBitmapWidth, PanelBitmapHeight, new Vector2(0.5, 0.5), 0.0, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenter, PanelOrigin, Train.Cars[Car].Driver, tday, tnight, new Color32(255, 255, 255, 255), false); } } // parse lines for rest @@ -322,7 +330,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - DaytimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + DaytimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(DaytimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + DaytimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); DaytimeImage = null; @@ -334,7 +342,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - NighttimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + NighttimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(NighttimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + NighttimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); NighttimeImage = null; @@ -369,7 +377,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste }); int w = tday.Width; int h = tday.Height; - int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, w, h, 0.5, 0.5, (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenterX, PanelCenterY, PanelOriginX, PanelOriginY, Train.Cars[Car].Driver, tday, tnight, new Color32(255, 255, 255, 255), false); + int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, w, h, new Vector2(0.5, 0.5), (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenter, PanelOrigin, Train.Cars[Car].Driver, tday, tnight, new Color32(255, 255, 255, 255), false); string f = GetStackLanguageFromSubject(Train, Subject, Section + " in " + FileName); Train.Cars[Car].CarSections[0].Elements[j].StateFunction = FunctionScripts.GetFunctionScriptFromPostfixNotation(f + " 1 == --"); } @@ -426,7 +434,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - DaytimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + DaytimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(DaytimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + DaytimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); DaytimeImage = null; @@ -438,7 +446,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - NighttimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + NighttimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(NighttimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + NighttimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); NighttimeImage = null; @@ -552,7 +560,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste double n = Radius == 0.0 | OriginY == 0.0 ? 1.0 : Radius / OriginY; double nx = n * w; double ny = n * h; - int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX - ox * nx, LocationY - oy * ny, nx, ny, ox, oy, (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenterX, PanelCenterY, PanelOriginX, PanelOriginY, Train.Cars[Car].Driver, tday, tnight, Color, false); + int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX - ox * nx, LocationY - oy * ny, nx, ny, new Vector2(ox, oy), (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenter, PanelOrigin, Train.Cars[Car].Driver, tday, tnight, Color, false); Train.Cars[Car].CarSections[0].Elements[j].RotateZDirection = new Vector3(0.0, 0.0, -1.0); Train.Cars[Car].CarSections[0].Elements[j].RotateXDirection = new Vector3(1.0, 0.0, 0.0); Train.Cars[Car].CarSections[0].Elements[j].RotateYDirection = Vector3.Cross(Train.Cars[Car].CarSections[0].Elements[j].RotateZDirection, Train.Cars[Car].CarSections[0].Elements[j].RotateXDirection); @@ -667,7 +675,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - DaytimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + DaytimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(DaytimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + DaytimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); DaytimeImage = null; @@ -679,7 +687,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - NighttimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + NighttimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(NighttimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + NighttimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); NighttimeImage = null; @@ -714,7 +722,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste }); int w = tday.Width; int h = tday.Height; - int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, w, h, 0.5, 0.5, (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenterX, PanelCenterY, PanelOriginX, PanelOriginY, Train.Cars[Car].Driver, tday, tnight, new Color32(255, 255, 255, 255), false); + int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, w, h, new Vector2(0.5, 0.5), (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenter, PanelOrigin, Train.Cars[Car].Driver, tday, tnight, new Color32(255, 255, 255, 255), false); if (Maximum < Minimum) { Interface.AddMessage(Interface.MessageType.Error, false, "Maximum value must be greater than minimum value " + Section + " in " + FileName); @@ -764,7 +772,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - DaytimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + DaytimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(DaytimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + DaytimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); DaytimeImage = null; @@ -776,7 +784,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste if (Path.ContainsInvalidChars(Value)) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); } else { - NighttimeImage = OpenBveApi.Path.CombineFile(TrainPath, Value); + NighttimeImage = Path.CombineFile(TrainPath, Value); if (!System.IO.File.Exists(NighttimeImage)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + NighttimeImage + " could not be found in " + Key + " in " + Section + " at line " + (i + 1).ToString(Culture) + " in " + FileName); NighttimeImage = null; @@ -886,7 +894,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste } int j = -1; for (int k = 0; k < tday.Length; k++) { - int l = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, (double)wday, (double)Interval, 0.5, 0.5, (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenterX, PanelCenterY, PanelOriginX, PanelOriginY, Train.Cars[Car].Driver, tday[k], tnight[k], new Color32(255, 255, 255, 255), k != 0); + int l = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, (double)wday, (double)Interval, new Vector2(0.5, 0.5), (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenter, PanelOrigin, Train.Cars[Car].Driver, tday[k], tnight[k], new Color32(255, 255, 255, 255), k != 0); if (k == 0) j = l; } string f = GetStackLanguageFromSubject(Train, Subject, Section + " in " + FileName); @@ -982,7 +990,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste } if (Radius != 0.0) { // create element - int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX - Radius, LocationY - Radius, 2.0 * Radius, 2.0 * Radius, 0.5, 0.5, (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenterX, PanelCenterY, PanelOriginX, PanelOriginY, Train.Cars[Car].Driver, null, null, Color, false); + int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX - Radius, LocationY - Radius, 2.0 * Radius, 2.0 * Radius, new Vector2(0.5, 0.5), (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenter, PanelOrigin, Train.Cars[Car].Driver, null, null, Color, false); InitialAngle = InitialAngle + Math.PI; LastAngle = LastAngle + Math.PI; double x0 = Train.Cars[Car].CarSections[0].Elements[j].States[0].Object.Mesh.Vertices[0].Coordinates.X; @@ -1099,7 +1107,7 @@ internal static void ParsePanel2Config(string PanelFile, string TrainPath, Syste Interface.AddMessage(Interface.MessageType.Error, false, "Height is required to be specified in " + Section + " in " + FileName); } if (Width > 0.0 & Height > 0.0) { - int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, Width, Height, 0.5, 0.5, (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenterX, PanelCenterY, PanelOriginX, PanelOriginY, Train.Cars[Car].Driver, null, null, new Color32(255, 255, 255, 255), false); + int j = CreateElement(Train.Cars[Car].CarSections[0], LocationX, LocationY, Width, Height, new Vector2(0.5, 0.5), (double)Layer * StackDistance, PanelResolution, PanelLeft, PanelRight, PanelTop, PanelBottom, PanelBitmapWidth, PanelBitmapHeight, PanelCenter, PanelOrigin, Train.Cars[Car].Driver, null, null, new Color32(255, 255, 255, 255), false); Train.Cars[Car].CarSections[0].Elements[j].StateFunction = FunctionScripts.GetFunctionScriptFromPostfixNotation("timetable"); Timetable.AddObjectForCustomTimetable(Train.Cars[Car].CarSections[0].Elements[j]); } @@ -1401,7 +1409,7 @@ private static string GetStackLanguageFromSubject(TrainManager.Train Train, stri - private static int CreateElement(TrainManager.CarSection Section, double Left, double Top, double Width, double Height, double RelativeRotationCenterX, double RelativeRotationCenterY, double Distance, double PanelResolution, double PanelLeft, double PanelRight, double PanelTop, double PanelBottom, double PanelBitmapWidth, double PanelBitmapHeight, double PanelCenterX, double PanelCenterY, double PanelOriginX, double PanelOriginY, Vector3 Driver, Textures.Texture DaytimeTexture, Textures.Texture NighttimeTexture, Color32 Color, bool AddStateToLastElement) { + private static int CreateElement(TrainManager.CarSection Section, double Left, double Top, double Width, double Height, Vector2 RelativeRotationCenter, double Distance, double PanelResolution, double PanelLeft, double PanelRight, double PanelTop, double PanelBottom, double PanelBitmapWidth, double PanelBitmapHeight, Vector2 PanelCenter, Vector2 PanelOrigin, Vector3 Driver, Textures.Texture DaytimeTexture, Textures.Texture NighttimeTexture, Color32 Color, bool AddStateToLastElement) { double WorldWidth, WorldHeight; if (Screen.Width >= Screen.Height) { WorldWidth = 2.0 * Math.Tan(0.5 * World.HorizontalViewingAngle) * EyeDistance; @@ -1414,17 +1422,17 @@ private static int CreateElement(TrainManager.CarSection Section, double Left, d double x1 = (Left + Width) / PanelResolution; double y0 = (PanelBottom - Top) / PanelResolution * World.AspectRatio; double y1 = (PanelBottom - (Top + Height)) / PanelResolution * World.AspectRatio; - double xd = 0.5 - PanelCenterX / PanelResolution; + double xd = 0.5 - PanelCenter.X / PanelResolution; x0 += xd; x1 += xd; double yt = PanelBottom - PanelResolution / World.AspectRatio; - double yd = (PanelCenterY - yt) / (PanelBottom - yt) - 0.5; + double yd = (PanelCenter.Y - yt) / (PanelBottom - yt) - 0.5; y0 += yd; y1 += yd; x0 = (x0 - 0.5) * WorldWidth; x1 = (x1 - 0.5) * WorldWidth; y0 = (y0 - 0.5) * WorldHeight; y1 = (y1 - 0.5) * WorldHeight; - double xm = x0 * (1.0 - RelativeRotationCenterX) + x1 * RelativeRotationCenterX; - double ym = y0 * (1.0 - RelativeRotationCenterY) + y1 * RelativeRotationCenterY; + double xm = x0 * (1.0 - RelativeRotationCenter.X) + x1 * RelativeRotationCenter.X; + double ym = y0 * (1.0 - RelativeRotationCenter.Y) + y1 * RelativeRotationCenter.Y; Vector3[] v = new Vector3[4]; v[0] = new Vector3(x0 - xm, y1 - ym, 0); v[1] = new Vector3(x0 - xm, y0 - ym, 0); @@ -1435,7 +1443,7 @@ private static int CreateElement(TrainManager.CarSection Section, double Left, d Vertex t2 = new Vertex(v[2], new Vector2(1.0f, 0.0f)); Vertex t3 = new Vertex(v[3], new Vector2(1.0f, 1.0f)); ObjectManager.StaticObject Object = new ObjectManager.StaticObject(); - Object.Mesh.Vertices = new Vertex[] { t0, t1, t2, t3 }; + Object.Mesh.Vertices = new VertexTemplate[] { t0, t1, t2, t3 }; Object.Mesh.Faces = new World.MeshFace[] { new World.MeshFace(new int[] { 0, 1, 2, 3 }) }; Object.Mesh.Materials = new World.MeshMaterial[1]; Object.Mesh.Materials[0].Flags = (byte)(DaytimeTexture != null ? World.MeshMaterial.TransparentColorMask : 0); diff --git a/source/OpenBVE/Parsers/Panel/PanelCfgParser.cs b/source/OpenBVE/Parsers/Panel/PanelCfgParser.cs index 90a95891c..ab154479b 100644 --- a/source/OpenBVE/Parsers/Panel/PanelCfgParser.cs +++ b/source/OpenBVE/Parsers/Panel/PanelCfgParser.cs @@ -1103,7 +1103,7 @@ internal static void ParsePanelConfig(string TrainPath, System.Text.Encoding Enc CreateElement(Train, CornerX, CornerY + SemiHeight, (double)Width, (double)h, FullWidth, FullHeight, WorldLeft, WorldTop, WorldWidth, WorldHeight, WorldZ + EyeDistance - StackDistance, Train.Cars[Train.DriverCar].Driver, t, new Color32(255, 255, 255, 255), true); } } - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { int maxpow = Train.Handles.Power.MaximumNotch; int em = maxpow + 3; Train.Cars[Train.DriverCar].CarSections[0].Elements[k].StateFunction = FunctionScripts.GetFunctionScriptFromPostfixNotation("emergencyBrake " + em.ToString(Culture) + " brakeNotch 0 > " + maxpow.ToString(Culture) + " BrakeNotch + " + maxpow.ToString(Culture) + " powerNotch - ? ?"); diff --git a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.ApplyRouteData.cs b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.ApplyRouteData.cs index d92314acf..746473cc3 100644 --- a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.ApplyRouteData.cs +++ b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.ApplyRouteData.cs @@ -3,6 +3,7 @@ using OpenBveApi.Colors; using OpenBveApi.Math; using OpenBveApi.Runtime; +using OpenBveApi.World; namespace OpenBve { @@ -28,7 +29,6 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre if (!PreviewOnly) { //TODO: These need to be shifted into the main compatibility manager - string CompatibilityFolder = Program.FileSystem.GetDataFolder("Compatibility"); // load compatibility objects SignalPath = OpenBveApi.Path.CombineDirectory(CompatibilityFolder, "Signals"); SignalPost = ObjectManager.LoadStaticObject(OpenBveApi.Path.CombineFile(SignalPath, "signal_post.csv"), System.Text.Encoding.UTF8, ObjectManager.ObjectLoadMode.Normal, false, false, false); @@ -138,10 +138,10 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre { for (int i = Data.FirstUsedBlock; i < Data.Blocks.Length; i++) { - if (Data.Blocks[i].Brightness != null && Data.Blocks[i].Brightness.Length != 0) + if (Data.Blocks[i].BrightnessChanges != null && Data.Blocks[i].BrightnessChanges.Length != 0) { - CurrentBrightnessValue = Data.Blocks[i].Brightness[0].Value; - CurrentBrightnessTrackPosition = Data.Blocks[i].Brightness[0].Value; + CurrentBrightnessValue = Data.Blocks[i].BrightnessChanges[0].Value; + CurrentBrightnessTrackPosition = Data.Blocks[i].BrightnessChanges[0].Value; break; } } @@ -179,13 +179,13 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre { if (Data.Blocks[i].Cycle.Length == 1 && Data.Blocks[i].Cycle[0] == -1) { - if (Data.Structure.Cycle.Length == 0 || Data.Structure.Cycle[0] == null) + if (Data.Structure.Cycles.Length == 0 || Data.Structure.Cycles[0] == null) { Data.Blocks[i].Cycle = new int[] { 0 }; } else { - Data.Blocks[i].Cycle = Data.Structure.Cycle[0]; + Data.Blocks[i].Cycle = Data.Structure.Cycles[0]; } } } @@ -200,7 +200,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre TrackManager.CurrentTrack.Elements[n].WorldPosition = Position; TrackManager.CurrentTrack.Elements[n].WorldDirection = Vector3.GetVector3(Direction, Data.Blocks[i].Pitch); TrackManager.CurrentTrack.Elements[n].WorldSide = new Vector3(Direction.Y, 0.0, -Direction.X); - World.Cross(TrackManager.CurrentTrack.Elements[n].WorldDirection, TrackManager.CurrentTrack.Elements[n].WorldSide, out TrackManager.CurrentTrack.Elements[n].WorldUp); + TrackManager.CurrentTrack.Elements[n].WorldUp = Vector3.Cross(TrackManager.CurrentTrack.Elements[n].WorldDirection, TrackManager.CurrentTrack.Elements[n].WorldSide); TrackManager.CurrentTrack.Elements[n].StartingTrackPosition = StartingDistance; TrackManager.CurrentTrack.Elements[n].Events = new TrackManager.GeneralEvent[] { }; TrackManager.CurrentTrack.Elements[n].AdhesionMultiplier = Data.Blocks[i].AdhesionMultiplier; @@ -238,22 +238,22 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre // brightness if (!PreviewOnly) { - for (int j = 0; j < Data.Blocks[i].Brightness.Length; j++) + for (int j = 0; j < Data.Blocks[i].BrightnessChanges.Length; j++) { int m = TrackManager.CurrentTrack.Elements[n].Events.Length; Array.Resize(ref TrackManager.CurrentTrack.Elements[n].Events, m + 1); - double d = Data.Blocks[i].Brightness[j].TrackPosition - StartingDistance; - TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.BrightnessChangeEvent(d, Data.Blocks[i].Brightness[j].Value, CurrentBrightnessValue, Data.Blocks[i].Brightness[j].TrackPosition - CurrentBrightnessTrackPosition); + double d = Data.Blocks[i].BrightnessChanges[j].TrackPosition - StartingDistance; + TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.BrightnessChangeEvent(d, Data.Blocks[i].BrightnessChanges[j].Value, CurrentBrightnessValue, Data.Blocks[i].BrightnessChanges[j].TrackPosition - CurrentBrightnessTrackPosition); if (CurrentBrightnessElement >= 0 & CurrentBrightnessEvent >= 0) { TrackManager.BrightnessChangeEvent bce = (TrackManager.BrightnessChangeEvent)TrackManager.CurrentTrack.Elements[CurrentBrightnessElement].Events[CurrentBrightnessEvent]; - bce.NextBrightness = Data.Blocks[i].Brightness[j].Value; - bce.NextDistance = Data.Blocks[i].Brightness[j].TrackPosition - CurrentBrightnessTrackPosition; + bce.NextBrightness = Data.Blocks[i].BrightnessChanges[j].Value; + bce.NextDistance = Data.Blocks[i].BrightnessChanges[j].TrackPosition - CurrentBrightnessTrackPosition; } CurrentBrightnessElement = n; CurrentBrightnessEvent = m; - CurrentBrightnessValue = Data.Blocks[i].Brightness[j].Value; - CurrentBrightnessTrackPosition = Data.Blocks[i].Brightness[j].TrackPosition; + CurrentBrightnessValue = Data.Blocks[i].BrightnessChanges[j].Value; + CurrentBrightnessTrackPosition = Data.Blocks[i].BrightnessChanges[j].TrackPosition; } } // fog @@ -330,12 +330,12 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre if (i < Data.Blocks.Length - 1) { bool q = false; - for (int j = 0; j < Data.Blocks[i].Rail.Length; j++) + for (int j = 0; j < Data.Blocks[i].Rails.Length; j++) { - if (Data.Blocks[i].Rail[j].RailStart & Data.Blocks[i + 1].Rail.Length > j) + if (Data.Blocks[i].Rails[j].RailStart & Data.Blocks[i + 1].Rails.Length > j) { - bool qx = Math.Sign(Data.Blocks[i].Rail[j].RailStartX) != Math.Sign(Data.Blocks[i + 1].Rail[j].RailEndX); - bool qy = Data.Blocks[i].Rail[j].RailStartY * Data.Blocks[i + 1].Rail[j].RailEndY <= 0.0; + bool qx = Math.Sign(Data.Blocks[i].Rails[j].RailStartX) != Math.Sign(Data.Blocks[i + 1].Rails[j].RailEndX); + bool qy = Data.Blocks[i].Rails[j].RailStartY * Data.Blocks[i + 1].Rails[j].RailEndY <= 0.0; if (qx & qy) { q = true; @@ -395,15 +395,15 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre } } // stop - for (int j = 0; j < Data.Blocks[i].Stop.Length; j++) + for (int j = 0; j < Data.Blocks[i].StopPositions.Length; j++) { - int s = Data.Blocks[i].Stop[j].Station; + int s = Data.Blocks[i].StopPositions[j].Station; int t = Game.Stations[s].Stops.Length; Array.Resize(ref Game.Stations[s].Stops, t + 1); - Game.Stations[s].Stops[t].TrackPosition = Data.Blocks[i].Stop[j].TrackPosition; - Game.Stations[s].Stops[t].ForwardTolerance = Data.Blocks[i].Stop[j].ForwardTolerance; - Game.Stations[s].Stops[t].BackwardTolerance = Data.Blocks[i].Stop[j].BackwardTolerance; - Game.Stations[s].Stops[t].Cars = Data.Blocks[i].Stop[j].Cars; + Game.Stations[s].Stops[t].TrackPosition = Data.Blocks[i].StopPositions[j].TrackPosition; + Game.Stations[s].Stops[t].ForwardTolerance = Data.Blocks[i].StopPositions[j].ForwardTolerance; + Game.Stations[s].Stops[t].BackwardTolerance = Data.Blocks[i].StopPositions[j].BackwardTolerance; + Game.Stations[s].Stops[t].Cars = Data.Blocks[i].StopPositions[j].Cars; double dx, dy = 2.0; if (Game.Stations[s].OpenLeftDoors & !Game.Stations[s].OpenRightDoors) { @@ -422,13 +422,13 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre Game.Stations[s].SoundOrigin.Z = Position.Z + dx * TrackManager.CurrentTrack.Elements[n].WorldSide.Z + dy * TrackManager.CurrentTrack.Elements[n].WorldUp.Z; } // limit - for (int j = 0; j < Data.Blocks[i].Limit.Length; j++) + for (int j = 0; j < Data.Blocks[i].Limits.Length; j++) { int m = TrackManager.CurrentTrack.Elements[n].Events.Length; Array.Resize(ref TrackManager.CurrentTrack.Elements[n].Events, m + 1); - double d = Data.Blocks[i].Limit[j].TrackPosition - StartingDistance; - TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.LimitChangeEvent(d, CurrentSpeedLimit, Data.Blocks[i].Limit[j].Speed); - CurrentSpeedLimit = Data.Blocks[i].Limit[j].Speed; + double d = Data.Blocks[i].Limits[j].TrackPosition - StartingDistance; + TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.LimitChangeEvent(d, CurrentSpeedLimit, Data.Blocks[i].Limits[j].Speed); + CurrentSpeedLimit = Data.Blocks[i].Limits[j].Speed; } // marker if (!PreviewOnly) @@ -460,20 +460,20 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre // sound if (!PreviewOnly) { - for (int j = 0; j < Data.Blocks[i].Sound.Length; j++) + for (int j = 0; j < Data.Blocks[i].SoundEvents.Length; j++) { - if (Data.Blocks[i].Sound[j].Type == SoundType.TrainStatic | Data.Blocks[i].Sound[j].Type == SoundType.TrainDynamic) + if (Data.Blocks[i].SoundEvents[j].Type == SoundType.TrainStatic | Data.Blocks[i].SoundEvents[j].Type == SoundType.TrainDynamic) { int m = TrackManager.CurrentTrack.Elements[n].Events.Length; Array.Resize(ref TrackManager.CurrentTrack.Elements[n].Events, m + 1); - double d = Data.Blocks[i].Sound[j].TrackPosition - StartingDistance; - switch (Data.Blocks[i].Sound[j].Type) + double d = Data.Blocks[i].SoundEvents[j].TrackPosition - StartingDistance; + switch (Data.Blocks[i].SoundEvents[j].Type) { case SoundType.TrainStatic: - TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.SoundEvent(d, Data.Blocks[i].Sound[j].SoundBuffer, true, true, false, new Vector3(0.0, 0.0, 0.0), 0.0); + TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.SoundEvent(d, Data.Blocks[i].SoundEvents[j].SoundBuffer, true, true, false, new Vector3(0.0, 0.0, 0.0), 0.0); break; case SoundType.TrainDynamic: - TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.SoundEvent(d, Data.Blocks[i].Sound[j].SoundBuffer, false, false, true, new Vector3(0.0, 0.0, 0.0), Data.Blocks[i].Sound[j].Speed); + TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.SoundEvent(d, Data.Blocks[i].SoundEvents[j].SoundBuffer, false, false, true, new Vector3(0.0, 0.0, 0.0), Data.Blocks[i].SoundEvents[j].Speed); break; } } @@ -485,10 +485,10 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double ag = -Math.Atan(Data.Blocks[i].Turn); double cosag = Math.Cos(ag); double sinag = Math.Sin(ag); - World.Rotate(ref Direction, cosag, sinag); + Direction.Rotate(cosag, sinag); World.RotatePlane(ref TrackManager.CurrentTrack.Elements[n].WorldDirection, cosag, sinag); World.RotatePlane(ref TrackManager.CurrentTrack.Elements[n].WorldSide, cosag, sinag); - World.Cross(TrackManager.CurrentTrack.Elements[n].WorldDirection, TrackManager.CurrentTrack.Elements[n].WorldSide, out TrackManager.CurrentTrack.Elements[n].WorldUp); + TrackManager.CurrentTrack.Elements[n].WorldUp = Vector3.Cross(TrackManager.CurrentTrack.Elements[n].WorldDirection, TrackManager.CurrentTrack.Elements[n].WorldSide); } //Pitch if (Data.Blocks[i].Pitch != 0.0) @@ -513,7 +513,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double b = s / Math.Abs(r); c = Math.Sqrt(2.0 * r * r * (1.0 - Math.Cos(b))); a = 0.5 * (double)Math.Sign(r) * b; - World.Rotate(ref Direction, Math.Cos(-a), Math.Sin(-a)); + Direction.Rotate(Math.Cos(-a), Math.Sin(-a)); } else if (WorldTrackElement.CurveRadius != 0.0) { @@ -522,7 +522,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double b = d / Math.Abs(r); c = Math.Sqrt(2.0 * r * r * (1.0 - Math.Cos(b))); a = 0.5 * (double)Math.Sign(r) * b; - World.Rotate(ref Direction, Math.Cos(-a), Math.Sin(-a)); + Direction.Rotate(Math.Cos(-a), Math.Sin(-a)); } else if (Data.Blocks[i].Pitch != 0.0) { @@ -533,9 +533,9 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre } double TrackYaw = Math.Atan2(Direction.X, Direction.Y); double TrackPitch = Math.Atan(Data.Blocks[i].Pitch); - World.Transformation GroundTransformation = new World.Transformation(TrackYaw, 0.0, 0.0); - World.Transformation TrackTransformation = new World.Transformation(TrackYaw, TrackPitch, 0.0); - World.Transformation NullTransformation = new World.Transformation(0.0, 0.0, 0.0); + Transformation GroundTransformation = new Transformation(TrackYaw, 0.0, 0.0); + Transformation TrackTransformation = new Transformation(TrackYaw, TrackPitch, 0.0); + Transformation NullTransformation = new Transformation(0.0, 0.0, 0.0); // ground if (!PreviewOnly) { @@ -558,36 +558,36 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double dy = Data.Blocks[i].GroundFreeObj[j].Y; Vector3 wpos = Position + new Vector3(Direction.X * d + Direction.Y * dx, dy - Data.Blocks[i].Height, Direction.Y * d - Direction.X * dx); double tpos = Data.Blocks[i].GroundFreeObj[j].TrackPosition; - Data.Structure.FreeObjects[sttype].CreateObject(wpos, GroundTransformation, new World.Transformation(Data.Blocks[i].GroundFreeObj[j].Yaw, Data.Blocks[i].GroundFreeObj[j].Pitch, Data.Blocks[i].GroundFreeObj[j].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); + Data.Structure.FreeObjects[sttype].CreateObject(wpos, GroundTransformation, new Transformation(Data.Blocks[i].GroundFreeObj[j].Yaw, Data.Blocks[i].GroundFreeObj[j].Pitch, Data.Blocks[i].GroundFreeObj[j].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); } } // rail-aligned objects if (!PreviewOnly) { - for (int j = 0; j < Data.Blocks[i].Rail.Length; j++) + for (int j = 0; j < Data.Blocks[i].Rails.Length; j++) { - if (j > 0 && !Data.Blocks[i].Rail[j].RailStart) continue; + if (j > 0 && !Data.Blocks[i].Rails[j].RailStart) continue; // rail Vector3 pos; - World.Transformation RailTransformation; + Transformation RailTransformation; double planar, updown; if (j == 0) { // rail 0 planar = 0.0; updown = 0.0; - RailTransformation = new World.Transformation(TrackTransformation, planar, updown, 0.0); + RailTransformation = new Transformation(TrackTransformation, planar, updown, 0.0); pos = Position; } else { // rails 1-infinity - double x = Data.Blocks[i].Rail[j].RailStartX; - double y = Data.Blocks[i].Rail[j].RailStartY; + double x = Data.Blocks[i].Rails[j].RailStartX; + double y = Data.Blocks[i].Rails[j].RailStartY; Vector3 offset = new Vector3(Direction.Y * x, y, -Direction.X * x); pos = Position + offset; double dh; - if (i < Data.Blocks.Length - 1 && Data.Blocks[i + 1].Rail.Length > j) + if (i < Data.Blocks.Length - 1 && Data.Blocks[i + 1].Rails.Length > j) { // take orientation of upcoming block into account Vector2 Direction2 = Direction; @@ -597,14 +597,14 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre Position2.Z += Direction.Y * c; if (a != 0.0) { - World.Rotate(ref Direction2, Math.Cos(-a), Math.Sin(-a)); + Direction2.Rotate(Math.Cos(-a), Math.Sin(-a)); } if (Data.Blocks[i + 1].Turn != 0.0) { double ag = -Math.Atan(Data.Blocks[i + 1].Turn); double cosag = Math.Cos(ag); double sinag = Math.Sin(ag); - World.Rotate(ref Direction2, cosag, sinag); + Direction2.Rotate(cosag, sinag); } double a2 = 0.0; // double c2 = Data.BlockInterval; @@ -619,7 +619,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double b2 = s2 / Math.Abs(r2); // c2 = Math.Sqrt(2.0 * r2 * r2 * (1.0 - Math.Cos(b2))); a2 = 0.5 * (double)Math.Sign(r2) * b2; - World.Rotate(ref Direction2, Math.Cos(-a2), Math.Sin(-a2)); + Direction2.Rotate(Math.Cos(-a2), Math.Sin(-a2)); } else if (Data.Blocks[i + 1].CurrentTrackState.CurveRadius != 0.0) { @@ -628,7 +628,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double b2 = d2 / Math.Abs(r2); // c2 = Math.Sqrt(2.0 * r2 * r2 * (1.0 - Math.Cos(b2))); a2 = 0.5 * (double)Math.Sign(r2) * b2; - World.Rotate(ref Direction2, Math.Cos(-a2), Math.Sin(-a2)); + Direction2.Rotate(Math.Cos(-a2), Math.Sin(-a2)); } // else if (Data.Blocks[i + 1].Pitch != 0.0) { // double p2 = Data.Blocks[i + 1].Pitch; @@ -643,11 +643,11 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre /* double TrackYaw2 = Math.Atan2(Direction2.X, Direction2.Y); double TrackPitch2 = Math.Atan(Data.Blocks[i + 1].Pitch); - World.Transformation GroundTransformation2 = new World.Transformation(TrackYaw2, 0.0, 0.0); - World.Transformation TrackTransformation2 = new World.Transformation(TrackYaw2, TrackPitch2, 0.0); + Transformation GroundTransformation2 = new Transformation(TrackYaw2, 0.0, 0.0); + Transformation TrackTransformation2 = new Transformation(TrackYaw2, TrackPitch2, 0.0); */ - double x2 = Data.Blocks[i + 1].Rail[j].RailEndX; - double y2 = Data.Blocks[i + 1].Rail[j].RailEndY; + double x2 = Data.Blocks[i + 1].Rails[j].RailEndX; + double y2 = Data.Blocks[i + 1].Rails[j].RailEndY; Vector3 offset2 = new Vector3(Direction2.Y * x2, y2, -Direction2.X * x2); Vector3 pos2 = Position2 + offset2; double rx = pos2.X - pos.X; @@ -658,8 +658,8 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre RailTransformation.X = new Vector3(rz, 0.0, -rx); World.Normalize(ref RailTransformation.X.X, ref RailTransformation.X.Z); RailTransformation.Y = Vector3.Cross(RailTransformation.Z, RailTransformation.X); - double dx = Data.Blocks[i + 1].Rail[j].RailEndX - Data.Blocks[i].Rail[j].RailStartX; - double dy = Data.Blocks[i + 1].Rail[j].RailEndY - Data.Blocks[i].Rail[j].RailStartY; + double dx = Data.Blocks[i + 1].Rails[j].RailEndX - Data.Blocks[i].Rails[j].RailStartX; + double dy = Data.Blocks[i + 1].Rails[j].RailEndY - Data.Blocks[i].Rails[j].RailStartY; planar = Math.Atan(dx / c); dh = dy / c; updown = Math.Atan(dh); @@ -669,7 +669,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre planar = 0.0; dh = 0.0; updown = 0.0; - RailTransformation = new World.Transformation(TrackTransformation, 0.0, 0.0, 0.0); + RailTransformation = new Transformation(TrackTransformation, 0.0, 0.0, 0.0); } } if (Data.Structure.RailObjects.ContainsKey(Data.Blocks[i].RailType[j])) @@ -690,18 +690,18 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre int m = Game.PointsOfInterest.Length; Array.Resize(ref Game.PointsOfInterest, m + 1); Game.PointsOfInterest[m].TrackPosition = Data.Blocks[i].PointsOfInterest[k].TrackPosition; - if (i < Data.Blocks.Length - 1 && Data.Blocks[i + 1].Rail.Length > j) + if (i < Data.Blocks.Length - 1 && Data.Blocks[i + 1].Rails.Length > j) { - double dx = Data.Blocks[i + 1].Rail[j].RailEndX - Data.Blocks[i].Rail[j].RailStartX; - double dy = Data.Blocks[i + 1].Rail[j].RailEndY - Data.Blocks[i].Rail[j].RailStartY; - dx = Data.Blocks[i].Rail[j].RailStartX + d / Data.BlockInterval * dx; - dy = Data.Blocks[i].Rail[j].RailStartY + d / Data.BlockInterval * dy; + double dx = Data.Blocks[i + 1].Rails[j].RailEndX - Data.Blocks[i].Rails[j].RailStartX; + double dy = Data.Blocks[i + 1].Rails[j].RailEndY - Data.Blocks[i].Rails[j].RailStartY; + dx = Data.Blocks[i].Rails[j].RailStartX + d / Data.BlockInterval * dx; + dy = Data.Blocks[i].Rails[j].RailStartY + d / Data.BlockInterval * dy; Game.PointsOfInterest[m].TrackOffset = new Vector3(x + dx, y + dy, 0.0); } else { - double dx = Data.Blocks[i].Rail[j].RailStartX; - double dy = Data.Blocks[i].Rail[j].RailStartY; + double dx = Data.Blocks[i].Rails[j].RailStartX; + double dy = Data.Blocks[i].Rails[j].RailStartY; Game.PointsOfInterest[m].TrackOffset = new Vector3(x + dx, y + dy, 0.0); } Game.PointsOfInterest[m].TrackYaw = Data.Blocks[i].PointsOfInterest[k].Yaw + planar; @@ -774,15 +774,15 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre // sounds if (j == 0) { - for (int k = 0; k < Data.Blocks[i].Sound.Length; k++) + for (int k = 0; k < Data.Blocks[i].SoundEvents.Length; k++) { - if (Data.Blocks[i].Sound[k].Type == SoundType.World) + if (Data.Blocks[i].SoundEvents[k].Type == SoundType.World) { - if (Data.Blocks[i].Sound[k].SoundBuffer != null) + if (Data.Blocks[i].SoundEvents[k].SoundBuffer != null) { - double d = Data.Blocks[i].Sound[k].TrackPosition - StartingDistance; - double dx = Data.Blocks[i].Sound[k].X; - double dy = Data.Blocks[i].Sound[k].Y; + double d = Data.Blocks[i].SoundEvents[k].TrackPosition - StartingDistance; + double dx = Data.Blocks[i].SoundEvents[k].X; + double dy = Data.Blocks[i].SoundEvents[k].Y; double wa = Math.Atan2(Direction.Y, Direction.X) - planar; double wx = Math.Cos(wa); double wy = Math.Tan(updown); @@ -794,207 +794,207 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double ux, uy, uz; World.Cross(wx, wy, wz, sx, sy, sz, out ux, out uy, out uz); Vector3 wpos = pos + new Vector3(sx * dx + ux * dy + wx * d, sy * dx + uy * dy + wy * d, sz * dx + uz * dy + wz * d); - Sounds.PlaySound(Data.Blocks[i].Sound[k].SoundBuffer, 1.0, 1.0, wpos, true); + Sounds.PlaySound(Data.Blocks[i].SoundEvents[k].SoundBuffer, 1.0, 1.0, wpos, true); } } } } // forms - for (int k = 0; k < Data.Blocks[i].Form.Length; k++) + for (int k = 0; k < Data.Blocks[i].Forms.Length; k++) { // primary rail - if (Data.Blocks[i].Form[k].PrimaryRail == j) + if (Data.Blocks[i].Forms[k].PrimaryRail == j) { - if (Data.Blocks[i].Form[k].SecondaryRail == Form.SecondaryRailStub) + if (Data.Blocks[i].Forms[k].SecondaryRail == Form.SecondaryRailStub) { - if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.FormL[Data.Blocks[i].Form[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); - if (Data.Blocks[i].Form[k].RoofType > 0) + Data.Structure.FormL[Data.Blocks[i].Forms[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + if (Data.Blocks[i].Forms[k].RoofType > 0) { - if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.RoofL[Data.Blocks[i].Form[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.RoofL[Data.Blocks[i].Forms[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } } } - else if (Data.Blocks[i].Form[k].SecondaryRail == Form.SecondaryRailL) + else if (Data.Blocks[i].Forms[k].SecondaryRail == Form.SecondaryRailL) { - if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.FormL[Data.Blocks[i].Form[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.FormL[Data.Blocks[i].Forms[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.FormCL.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormCL.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormCL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.FormCL[Data.Blocks[i].Form[k].FormType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.FormCL[Data.Blocks[i].Forms[k].FormType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (Data.Blocks[i].Form[k].RoofType > 0) + if (Data.Blocks[i].Forms[k].RoofType > 0) { - if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.RoofL[Data.Blocks[i].Form[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.RoofL[Data.Blocks[i].Forms[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.RoofCL.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofCL.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofCL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCL[Data.Blocks[i].Form[k].RoofType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCL[Data.Blocks[i].Forms[k].RoofType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } } - else if (Data.Blocks[i].Form[k].SecondaryRail == Form.SecondaryRailR) + else if (Data.Blocks[i].Forms[k].SecondaryRail == Form.SecondaryRailR) { - if (!Data.Structure.FormR.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormR.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.FormR[Data.Blocks[i].Form[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.FormR[Data.Blocks[i].Forms[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.FormCR.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormCR.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormCR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.FormCR[Data.Blocks[i].Form[k].FormType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.FormCR[Data.Blocks[i].Forms[k].FormType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (Data.Blocks[i].Form[k].RoofType > 0) + if (Data.Blocks[i].Forms[k].RoofType > 0) { - if (!Data.Structure.RoofR.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofR.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.RoofR[Data.Blocks[i].Form[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.RoofR[Data.Blocks[i].Forms[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.RoofCR.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofCR.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofCR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCR[Data.Blocks[i].Form[k].RoofType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + ObjectManager.CreateStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCR[Data.Blocks[i].Forms[k].RoofType], pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } } - else if (Data.Blocks[i].Form[k].SecondaryRail > 0) + else if (Data.Blocks[i].Forms[k].SecondaryRail > 0) { - int p = Data.Blocks[i].Form[k].PrimaryRail; - double px0 = p > 0 ? Data.Blocks[i].Rail[p].RailStartX : 0.0; - double px1 = p > 0 ? Data.Blocks[i + 1].Rail[p].RailEndX : 0.0; - int s = Data.Blocks[i].Form[k].SecondaryRail; - if (s < 0 || s >= Data.Blocks[i].Rail.Length || !Data.Blocks[i].Rail[s].RailStart) + int p = Data.Blocks[i].Forms[k].PrimaryRail; + double px0 = p > 0 ? Data.Blocks[i].Rails[p].RailStartX : 0.0; + double px1 = p > 0 ? Data.Blocks[i + 1].Rails[p].RailEndX : 0.0; + int s = Data.Blocks[i].Forms[k].SecondaryRail; + if (s < 0 || s >= Data.Blocks[i].Rails.Length || !Data.Blocks[i].Rails[s].RailStart) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex2 is out of range in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName); } else { - double sx0 = Data.Blocks[i].Rail[s].RailStartX; - double sx1 = Data.Blocks[i + 1].Rail[s].RailEndX; + double sx0 = Data.Blocks[i].Rails[s].RailStartX; + double sx1 = Data.Blocks[i + 1].Rails[s].RailEndX; double d0 = sx0 - px0; double d1 = sx1 - px1; if (d0 < 0.0) { - if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.FormL[Data.Blocks[i].Form[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.FormL[Data.Blocks[i].Forms[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.FormCL.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormCL.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormCL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.StaticObject FormC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.FormCL[Data.Blocks[i].Form[k].FormType], d0, d1); + ObjectManager.StaticObject FormC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.FormCL[Data.Blocks[i].Forms[k].FormType], d0, d1); ObjectManager.CreateStaticObject(FormC, pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (Data.Blocks[i].Form[k].RoofType > 0) + if (Data.Blocks[i].Forms[k].RoofType > 0) { - if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.RoofL[Data.Blocks[i].Form[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.RoofL[Data.Blocks[i].Forms[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.RoofCL.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofCL.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofCL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.StaticObject RoofC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCL[Data.Blocks[i].Form[k].RoofType], d0, d1); + ObjectManager.StaticObject RoofC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCL[Data.Blocks[i].Forms[k].RoofType], d0, d1); ObjectManager.CreateStaticObject(RoofC, pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } } else if (d0 > 0.0) { - if (!Data.Structure.FormR.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormR.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.FormR[Data.Blocks[i].Form[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.FormR[Data.Blocks[i].Forms[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.FormCR.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormCR.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormCR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.StaticObject FormC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.FormCR[Data.Blocks[i].Form[k].FormType], d0, d1); + ObjectManager.StaticObject FormC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.FormCR[Data.Blocks[i].Forms[k].FormType], d0, d1); ObjectManager.CreateStaticObject(FormC, pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (Data.Blocks[i].Form[k].RoofType > 0) + if (Data.Blocks[i].Forms[k].RoofType > 0) { - if (!Data.Structure.RoofR.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofR.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.RoofR[Data.Blocks[i].Form[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.RoofR[Data.Blocks[i].Forms[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (!Data.Structure.RoofCR.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofCR.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofCR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.StaticObject RoofC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCR[Data.Blocks[i].Form[k].RoofType], d0, d1); + ObjectManager.StaticObject RoofC = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.RoofCR[Data.Blocks[i].Forms[k].RoofType], d0, d1); ObjectManager.CreateStaticObject(RoofC, pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } @@ -1003,99 +1003,99 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre } } // secondary rail - if (Data.Blocks[i].Form[k].SecondaryRail == j) + if (Data.Blocks[i].Forms[k].SecondaryRail == j) { - int p = Data.Blocks[i].Form[k].PrimaryRail; - double px = p > 0 ? Data.Blocks[i].Rail[p].RailStartX : 0.0; - int s = Data.Blocks[i].Form[k].SecondaryRail; - double sx = Data.Blocks[i].Rail[s].RailStartX; + int p = Data.Blocks[i].Forms[k].PrimaryRail; + double px = p > 0 ? Data.Blocks[i].Rails[p].RailStartX : 0.0; + int s = Data.Blocks[i].Forms[k].SecondaryRail; + double sx = Data.Blocks[i].Rails[s].RailStartX; double d = px - sx; if (d < 0.0) { - if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormL.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.FormL[Data.Blocks[i].Form[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.FormL[Data.Blocks[i].Forms[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (Data.Blocks[i].Form[k].RoofType > 0) + if (Data.Blocks[i].Forms[k].RoofType > 0) { - if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofL.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofL not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.RoofL[Data.Blocks[i].Form[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.RoofL[Data.Blocks[i].Forms[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } } else { - if (!Data.Structure.FormR.ContainsKey(Data.Blocks[i].Form[k].FormType)) + if (!Data.Structure.FormR.ContainsKey(Data.Blocks[i].Forms[k].FormType)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references a FormR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.FormR[Data.Blocks[i].Form[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.FormR[Data.Blocks[i].Forms[k].FormType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } - if (Data.Blocks[i].Form[k].RoofType > 0) + if (Data.Blocks[i].Forms[k].RoofType > 0) { - if (!Data.Structure.RoofR.ContainsKey(Data.Blocks[i].Form[k].RoofType)) + if (!Data.Structure.RoofR.ContainsKey(Data.Blocks[i].Forms[k].RoofType)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references a RoofR not loaded in Track.Form at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - Data.Structure.RoofR[Data.Blocks[i].Form[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); + Data.Structure.RoofR[Data.Blocks[i].Forms[k].RoofType].CreateObject(pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } } } } // cracks - for (int k = 0; k < Data.Blocks[i].Crack.Length; k++) + for (int k = 0; k < Data.Blocks[i].Cracks.Length; k++) { - if (Data.Blocks[i].Crack[k].PrimaryRail == j) + if (Data.Blocks[i].Cracks[k].PrimaryRail == j) { - int p = Data.Blocks[i].Crack[k].PrimaryRail; - double px0 = p > 0 ? Data.Blocks[i].Rail[p].RailStartX : 0.0; - double px1 = p > 0 ? Data.Blocks[i + 1].Rail[p].RailEndX : 0.0; - int s = Data.Blocks[i].Crack[k].SecondaryRail; - if (s < 0 || s >= Data.Blocks[i].Rail.Length || !Data.Blocks[i].Rail[s].RailStart) + int p = Data.Blocks[i].Cracks[k].PrimaryRail; + double px0 = p > 0 ? Data.Blocks[i].Rails[p].RailStartX : 0.0; + double px1 = p > 0 ? Data.Blocks[i + 1].Rails[p].RailEndX : 0.0; + int s = Data.Blocks[i].Cracks[k].SecondaryRail; + if (s < 0 || s >= Data.Blocks[i].Rails.Length || !Data.Blocks[i].Rails[s].RailStart) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex2 is out of range in Track.Crack at track position " + StartingDistance.ToString(Culture) + " in file " + FileName); } else { - double sx0 = Data.Blocks[i].Rail[s].RailStartX; - double sx1 = Data.Blocks[i + 1].Rail[s].RailEndX; + double sx0 = Data.Blocks[i].Rails[s].RailStartX; + double sx1 = Data.Blocks[i + 1].Rails[s].RailEndX; double d0 = sx0 - px0; double d1 = sx1 - px1; if (d0 < 0.0) { - if (!Data.Structure.CrackL.ContainsKey(Data.Blocks[i].Crack[k].Type)) + if (!Data.Structure.CrackL.ContainsKey(Data.Blocks[i].Cracks[k].Type)) { Interface.AddMessage(Interface.MessageType.Error, false, "CrackStructureIndex references a CrackL not loaded in Track.Crack at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.StaticObject Crack = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.CrackL[Data.Blocks[i].Crack[k].Type], d0, d1); + ObjectManager.StaticObject Crack = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.CrackL[Data.Blocks[i].Cracks[k].Type], d0, d1); ObjectManager.CreateStaticObject(Crack, pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } else if (d0 > 0.0) { - if (!Data.Structure.CrackR.ContainsKey(Data.Blocks[i].Crack[k].Type)) + if (!Data.Structure.CrackR.ContainsKey(Data.Blocks[i].Cracks[k].Type)) { Interface.AddMessage(Interface.MessageType.Error, false, "CrackStructureIndex references a CrackR not loaded in Track.Crack at track position " + StartingDistance.ToString(Culture) + " in file " + FileName + "."); } else { - ObjectManager.StaticObject Crack = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.CrackR[Data.Blocks[i].Crack[k].Type], d0, d1); + ObjectManager.StaticObject Crack = GetTransformedStaticObject((ObjectManager.StaticObject)Data.Structure.CrackR[Data.Blocks[i].Cracks[k].Type], d0, d1); ObjectManager.CreateStaticObject(Crack, pos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, StartingDistance); } } @@ -1118,18 +1118,18 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre double tpos = Data.Blocks[i].RailFreeObj[j][k].TrackPosition; ObjectManager.UnifiedObject obj; Data.Structure.FreeObjects.TryGetValue(sttype, out obj); - obj.CreateObject(wpos, RailTransformation, new World.Transformation(Data.Blocks[i].RailFreeObj[j][k].Yaw, Data.Blocks[i].RailFreeObj[j][k].Pitch, Data.Blocks[i].RailFreeObj[j][k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); + obj.CreateObject(wpos, RailTransformation, new Transformation(Data.Blocks[i].RailFreeObj[j][k].Yaw, Data.Blocks[i].RailFreeObj[j][k].Pitch, Data.Blocks[i].RailFreeObj[j][k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); } } // transponder objects if (j == 0) { - for (int k = 0; k < Data.Blocks[i].Transponder.Length; k++) + for (int k = 0; k < Data.Blocks[i].Transponders.Length; k++) { ObjectManager.UnifiedObject obj = null; - if (Data.Blocks[i].Transponder[k].ShowDefaultObject) + if (Data.Blocks[i].Transponders[k].ShowDefaultObject) { - switch (Data.Blocks[i].Transponder[k].Type) + switch (Data.Blocks[i].Transponders[k].Type) { case 0: obj = TransponderS; break; case 1: obj = TransponderSN; break; @@ -1140,7 +1140,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre } else { - int b = Data.Blocks[i].Transponder[k].BeaconStructureIndex; + int b = Data.Blocks[i].Transponders[k].BeaconStructureIndex; if (b >= 0 & Data.Structure.Beacon.ContainsKey(b)) { obj = Data.Structure.Beacon[b]; @@ -1148,22 +1148,22 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre } if (obj != null) { - double dx = Data.Blocks[i].Transponder[k].X; - double dy = Data.Blocks[i].Transponder[k].Y; - double dz = Data.Blocks[i].Transponder[k].TrackPosition - StartingDistance; + double dx = Data.Blocks[i].Transponders[k].X; + double dy = Data.Blocks[i].Transponders[k].Y; + double dz = Data.Blocks[i].Transponders[k].TrackPosition - StartingDistance; Vector3 wpos = pos; wpos.X += dx * RailTransformation.X.X + dy * RailTransformation.Y.X + dz * RailTransformation.Z.X; wpos.Y += dx * RailTransformation.X.Y + dy * RailTransformation.Y.Y + dz * RailTransformation.Z.Y; wpos.Z += dx * RailTransformation.X.Z + dy * RailTransformation.Y.Z + dz * RailTransformation.Z.Z; - double tpos = Data.Blocks[i].Transponder[k].TrackPosition; - if (Data.Blocks[i].Transponder[k].ShowDefaultObject) + double tpos = Data.Blocks[i].Transponders[k].TrackPosition; + if (Data.Blocks[i].Transponders[k].ShowDefaultObject) { double b = 0.25 + 0.75 * GetBrightness(ref Data, tpos); - obj.CreateObject(wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Transponder[k].Yaw, Data.Blocks[i].Transponder[k].Pitch, Data.Blocks[i].Transponder[k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); + obj.CreateObject(wpos, RailTransformation, new Transformation(Data.Blocks[i].Transponders[k].Yaw, Data.Blocks[i].Transponders[k].Pitch, Data.Blocks[i].Transponders[k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } else { - obj.CreateObject(wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Transponder[k].Yaw, Data.Blocks[i].Transponder[k].Pitch, Data.Blocks[i].Transponder[k].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); + obj.CreateObject(wpos, RailTransformation, new Transformation(Data.Blocks[i].Transponders[k].Yaw, Data.Blocks[i].Transponders[k].Pitch, Data.Blocks[i].Transponders[k].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); } } } @@ -1185,7 +1185,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre wpos.Y += dx * RailTransformation.X.Y + dy * RailTransformation.Y.Y + dz * RailTransformation.Z.Y; wpos.Z += dx * RailTransformation.X.Z + dy * RailTransformation.Y.Z + dz * RailTransformation.Z.Z; double tpos = Data.Blocks[i].DestinationChanges[k].TrackPosition; - obj.CreateObject(wpos, RailTransformation, new World.Transformation(Data.Blocks[i].DestinationChanges[k].Yaw, Data.Blocks[i].DestinationChanges[k].Pitch, Data.Blocks[i].DestinationChanges[k].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); + obj.CreateObject(wpos, RailTransformation, new Transformation(Data.Blocks[i].DestinationChanges[k].Yaw, Data.Blocks[i].DestinationChanges[k].Pitch, Data.Blocks[i].DestinationChanges[k].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); } } } @@ -1193,45 +1193,45 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre if (j == 0) { // signals - for (int k = 0; k < Data.Blocks[i].Signal.Length; k++) + for (int k = 0; k < Data.Blocks[i].Signals.Length; k++) { SignalData sd; - if (Data.Blocks[i].Signal[k].SignalCompatibilityObjectIndex >= 0) + if (Data.Blocks[i].Signals[k].SignalCompatibilityObjectIndex >= 0) { - sd = Data.CompatibilitySignals[Data.Blocks[i].Signal[k].SignalCompatibilityObjectIndex]; + sd = Data.CompatibilitySignals[Data.Blocks[i].Signals[k].SignalCompatibilityObjectIndex]; } else { - sd = Data.Signals[Data.Blocks[i].Signal[k].SignalObjectIndex]; + sd = Data.Signals[Data.Blocks[i].Signals[k].SignalObjectIndex]; } // objects - double dz = Data.Blocks[i].Signal[k].TrackPosition - StartingDistance; - if (Data.Blocks[i].Signal[k].ShowPost) + double dz = Data.Blocks[i].Signals[k].TrackPosition - StartingDistance; + if (Data.Blocks[i].Signals[k].ShowPost) { // post - double dx = Data.Blocks[i].Signal[k].X; + double dx = Data.Blocks[i].Signals[k].X; Vector3 wpos = pos; wpos.X += dx * RailTransformation.X.X + dz * RailTransformation.Z.X; wpos.Y += dx * RailTransformation.X.Y + dz * RailTransformation.Z.Y; wpos.Z += dx * RailTransformation.X.Z + dz * RailTransformation.Z.Z; - double tpos = Data.Blocks[i].Signal[k].TrackPosition; + double tpos = Data.Blocks[i].Signals[k].TrackPosition; double b = 0.25 + 0.75 * GetBrightness(ref Data, tpos); ObjectManager.CreateStaticObject(SignalPost, wpos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } - if (Data.Blocks[i].Signal[k].ShowObject) + if (Data.Blocks[i].Signals[k].ShowObject) { // signal object - double dx = Data.Blocks[i].Signal[k].X; - double dy = Data.Blocks[i].Signal[k].Y; + double dx = Data.Blocks[i].Signals[k].X; + double dy = Data.Blocks[i].Signals[k].Y; Vector3 wpos = pos; wpos.X += dx * RailTransformation.X.X + dy * RailTransformation.Y.X + dz * RailTransformation.Z.X; wpos.Y += dx * RailTransformation.X.Y + dy * RailTransformation.Y.Y + dz * RailTransformation.Z.Y; wpos.Z += dx * RailTransformation.X.Z + dy * RailTransformation.Y.Z + dz * RailTransformation.Z.Z; - double tpos = Data.Blocks[i].Signal[k].TrackPosition; + double tpos = Data.Blocks[i].Signals[k].TrackPosition; if (sd is AnimatedObjectSignalData) { AnimatedObjectSignalData aosd = (AnimatedObjectSignalData)sd; - aosd.Objects.CreateObject(wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); + aosd.Objects.CreateObject(wpos, RailTransformation, new Transformation(Data.Blocks[i].Signals[k].Yaw, Data.Blocks[i].Signals[k].Pitch, Data.Blocks[i].Signals[k].Roll), Data.Blocks[i].Signals[k].SectionIndex, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); } else if (sd is CompatibilitySignalData) { @@ -1259,7 +1259,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre } aoc.Objects[0].StateFunction = FunctionScripts.GetFunctionScriptFromPostfixNotation(expr); aoc.Objects[0].RefreshRate = 1.0 + 0.01 * Program.RandomNumberGenerator.NextDouble(); - aoc.CreateObject(wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, brightness, false); + aoc.CreateObject(wpos, RailTransformation, new Transformation(Data.Blocks[i].Signals[k].Yaw, Data.Blocks[i].Signals[k].Pitch, Data.Blocks[i].Signals[k].Roll), Data.Blocks[i].Signals[k].SectionIndex, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, brightness, false); } } else if (sd is Bve4SignalData) @@ -1322,47 +1322,47 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre } aoc.Objects[0].StateFunction = FunctionScripts.GetFunctionScriptFromPostfixNotation(expr); aoc.Objects[0].RefreshRate = 1.0 + 0.01 * Program.RandomNumberGenerator.NextDouble(); - aoc.CreateObject(wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); + aoc.CreateObject(wpos, RailTransformation, new Transformation(Data.Blocks[i].Signals[k].Yaw, Data.Blocks[i].Signals[k].Pitch, Data.Blocks[i].Signals[k].Roll), Data.Blocks[i].Signals[k].SectionIndex, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); } } } } // sections - for (int k = 0; k < Data.Blocks[i].Section.Length; k++) + for (int k = 0; k < Data.Blocks[i].Sections.Length; k++) { int m = Game.Sections.Length; Array.Resize(ref Game.Sections, m + 1); // create associated transponders for (int g = 0; g <= i; g++) { - for (int l = 0; l < Data.Blocks[g].Transponder.Length; l++) + for (int l = 0; l < Data.Blocks[g].Transponders.Length; l++) { - if (Data.Blocks[g].Transponder[l].Type != -1 & Data.Blocks[g].Transponder[l].Section == m) + if (Data.Blocks[g].Transponders[l].Type != -1 & Data.Blocks[g].Transponders[l].SectionIndex == m) { int o = TrackManager.CurrentTrack.Elements[n - i + g].Events.Length; Array.Resize(ref TrackManager.CurrentTrack.Elements[n - i + g].Events, o + 1); - double dt = Data.Blocks[g].Transponder[l].TrackPosition - StartingDistance + (double)(i - g) * Data.BlockInterval; - TrackManager.CurrentTrack.Elements[n - i + g].Events[o] = new TrackManager.TransponderEvent(dt, Data.Blocks[g].Transponder[l].Type, Data.Blocks[g].Transponder[l].Data, m, Data.Blocks[g].Transponder[l].ClipToFirstRedSection); - Data.Blocks[g].Transponder[l].Type = -1; + double dt = Data.Blocks[g].Transponders[l].TrackPosition - StartingDistance + (double)(i - g) * Data.BlockInterval; + TrackManager.CurrentTrack.Elements[n - i + g].Events[o] = new TrackManager.TransponderEvent(dt, Data.Blocks[g].Transponders[l].Type, Data.Blocks[g].Transponders[l].Data, m, Data.Blocks[g].Transponders[l].ClipToFirstRedSection); + Data.Blocks[g].Transponders[l].Type = -1; } } } // create section - Game.Sections[m].TrackPosition = Data.Blocks[i].Section[k].TrackPosition; - Game.Sections[m].Aspects = new Game.SectionAspect[Data.Blocks[i].Section[k].Aspects.Length]; - for (int l = 0; l < Data.Blocks[i].Section[k].Aspects.Length; l++) + Game.Sections[m].TrackPosition = Data.Blocks[i].Sections[k].TrackPosition; + Game.Sections[m].Aspects = new Game.SectionAspect[Data.Blocks[i].Sections[k].Aspects.Length]; + for (int l = 0; l < Data.Blocks[i].Sections[k].Aspects.Length; l++) { - Game.Sections[m].Aspects[l].Number = Data.Blocks[i].Section[k].Aspects[l]; - if (Data.Blocks[i].Section[k].Aspects[l] >= 0 & Data.Blocks[i].Section[k].Aspects[l] < Data.SignalSpeeds.Length) + Game.Sections[m].Aspects[l].Number = Data.Blocks[i].Sections[k].Aspects[l]; + if (Data.Blocks[i].Sections[k].Aspects[l] >= 0 & Data.Blocks[i].Sections[k].Aspects[l] < Data.SignalSpeeds.Length) { - Game.Sections[m].Aspects[l].Speed = Data.SignalSpeeds[Data.Blocks[i].Section[k].Aspects[l]]; + Game.Sections[m].Aspects[l].Speed = Data.SignalSpeeds[Data.Blocks[i].Sections[k].Aspects[l]]; } else { Game.Sections[m].Aspects[l].Speed = double.PositiveInfinity; } } - Game.Sections[m].Type = Data.Blocks[i].Section[k].Type; + Game.Sections[m].Type = Data.Blocks[i].Sections[k].Type; Game.Sections[m].CurrentAspect = -1; if (m > 0) { @@ -1374,28 +1374,28 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre Game.Sections[m].PreviousSection = -1; } Game.Sections[m].NextSection = -1; - Game.Sections[m].StationIndex = Data.Blocks[i].Section[k].DepartureStationIndex; - Game.Sections[m].Invisible = Data.Blocks[i].Section[k].Invisible; + Game.Sections[m].StationIndex = Data.Blocks[i].Sections[k].DepartureStationIndex; + Game.Sections[m].Invisible = Data.Blocks[i].Sections[k].Invisible; Game.Sections[m].Trains = new TrainManager.Train[] { }; // create section change event - double d = Data.Blocks[i].Section[k].TrackPosition - StartingDistance; + double d = Data.Blocks[i].Sections[k].TrackPosition - StartingDistance; int p = TrackManager.CurrentTrack.Elements[n].Events.Length; Array.Resize(ref TrackManager.CurrentTrack.Elements[n].Events, p + 1); TrackManager.CurrentTrack.Elements[n].Events[p] = new TrackManager.SectionChangeEvent(d, m - 1, m); } // transponders introduced after corresponding sections - for (int l = 0; l < Data.Blocks[i].Transponder.Length; l++) + for (int l = 0; l < Data.Blocks[i].Transponders.Length; l++) { - if (Data.Blocks[i].Transponder[l].Type != -1) + if (Data.Blocks[i].Transponders[l].Type != -1) { - int t = Data.Blocks[i].Transponder[l].Section; + int t = Data.Blocks[i].Transponders[l].SectionIndex; if (t >= 0 & t < Game.Sections.Length) { int m = TrackManager.CurrentTrack.Elements[n].Events.Length; Array.Resize(ref TrackManager.CurrentTrack.Elements[n].Events, m + 1); - double dt = Data.Blocks[i].Transponder[l].TrackPosition - StartingDistance; - TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.TransponderEvent(dt, Data.Blocks[i].Transponder[l].Type, Data.Blocks[i].Transponder[l].Data, t, Data.Blocks[i].Transponder[l].ClipToFirstRedSection); - Data.Blocks[i].Transponder[l].Type = -1; + double dt = Data.Blocks[i].Transponders[l].TrackPosition - StartingDistance; + TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.TransponderEvent(dt, Data.Blocks[i].Transponders[l].Type, Data.Blocks[i].Transponders[l].Data, t, Data.Blocks[i].Transponders[l].ClipToFirstRedSection); + Data.Blocks[i].Transponders[l].Type = -1; } } } @@ -1403,29 +1403,29 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre // limit if (j == 0) { - for (int k = 0; k < Data.Blocks[i].Limit.Length; k++) + for (int k = 0; k < Data.Blocks[i].Limits.Length; k++) { - if (Data.Blocks[i].Limit[k].Direction != 0) + if (Data.Blocks[i].Limits[k].Direction != 0) { - double dx = 2.2 * (double)Data.Blocks[i].Limit[k].Direction; - double dz = Data.Blocks[i].Limit[k].TrackPosition - StartingDistance; + double dx = 2.2 * (double)Data.Blocks[i].Limits[k].Direction; + double dz = Data.Blocks[i].Limits[k].TrackPosition - StartingDistance; Vector3 wpos = pos; wpos.X += dx * RailTransformation.X.X + dz * RailTransformation.Z.X; wpos.Y += dx * RailTransformation.X.Y + dz * RailTransformation.Z.Y; wpos.Z += dx * RailTransformation.X.Z + dz * RailTransformation.Z.Z; - double tpos = Data.Blocks[i].Limit[k].TrackPosition; + double tpos = Data.Blocks[i].Limits[k].TrackPosition; double b = 0.25 + 0.75 * GetBrightness(ref Data, tpos); - if (Data.Blocks[i].Limit[k].Speed <= 0.0 | Data.Blocks[i].Limit[k].Speed >= 1000.0) + if (Data.Blocks[i].Limits[k].Speed <= 0.0 | Data.Blocks[i].Limits[k].Speed >= 1000.0) { ObjectManager.CreateStaticObject(LimitPostInfinite, wpos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } else { - if (Data.Blocks[i].Limit[k].Cource < 0) + if (Data.Blocks[i].Limits[k].Cource < 0) { ObjectManager.CreateStaticObject(LimitPostLeft, wpos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } - else if (Data.Blocks[i].Limit[k].Cource > 0) + else if (Data.Blocks[i].Limits[k].Cource > 0) { ObjectManager.CreateStaticObject(LimitPostRight, wpos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } @@ -1433,7 +1433,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre { ObjectManager.CreateStaticObject(LimitPostStraight, wpos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } - double lim = Data.Blocks[i].Limit[k].Speed / Data.UnitOfSpeed; + double lim = Data.Blocks[i].Limits[k].Speed / Data.UnitOfSpeed; if (lim < 10.0) { int d0 = (int)Math.Round(lim); @@ -1485,17 +1485,17 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre // stop if (j == 0) { - for (int k = 0; k < Data.Blocks[i].Stop.Length; k++) + for (int k = 0; k < Data.Blocks[i].StopPositions.Length; k++) { - if (Data.Blocks[i].Stop[k].Direction != 0) + if (Data.Blocks[i].StopPositions[k].Direction != 0) { - double dx = 1.8 * (double)Data.Blocks[i].Stop[k].Direction; - double dz = Data.Blocks[i].Stop[k].TrackPosition - StartingDistance; + double dx = 1.8 * (double)Data.Blocks[i].StopPositions[k].Direction; + double dz = Data.Blocks[i].StopPositions[k].TrackPosition - StartingDistance; Vector3 wpos = pos; wpos.X += dx * RailTransformation.X.X + dz * RailTransformation.Z.X; wpos.Y += dx * RailTransformation.X.Y + dz * RailTransformation.Z.Y; wpos.Z += dx * RailTransformation.X.Z + dz * RailTransformation.Z.Z; - double tpos = Data.Blocks[i].Stop[k].TrackPosition; + double tpos = Data.Blocks[i].StopPositions[k].TrackPosition; double b = 0.25 + 0.75 * GetBrightness(ref Data, tpos); ObjectManager.CreateStaticObject(StopPost, wpos, RailTransformation, NullTransformation, Data.AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } @@ -1509,7 +1509,7 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre Position.Z += Direction.Y * c; if (a != 0.0) { - World.Rotate(ref Direction, Math.Cos(-a), Math.Sin(-a)); + Direction.Rotate(Math.Cos(-a), Math.Sin(-a)); } } // orphaned transponders @@ -1517,18 +1517,18 @@ private static void ApplyRouteData(string FileName, ref RouteData Data, bool Pre { for (int i = Data.FirstUsedBlock; i < Data.Blocks.Length; i++) { - for (int j = 0; j < Data.Blocks[i].Transponder.Length; j++) + for (int j = 0; j < Data.Blocks[i].Transponders.Length; j++) { - if (Data.Blocks[i].Transponder[j].Type != -1) + if (Data.Blocks[i].Transponders[j].Type != -1) { int n = i - Data.FirstUsedBlock; int m = TrackManager.CurrentTrack.Elements[n].Events.Length; Array.Resize(ref TrackManager.CurrentTrack.Elements[n].Events, m + 1); - double d = Data.Blocks[i].Transponder[j].TrackPosition - TrackManager.CurrentTrack.Elements[n].StartingTrackPosition; - int s = Data.Blocks[i].Transponder[j].Section; + double d = Data.Blocks[i].Transponders[j].TrackPosition - TrackManager.CurrentTrack.Elements[n].StartingTrackPosition; + int s = Data.Blocks[i].Transponders[j].SectionIndex; if (s >= 0) s = -1; - TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.TransponderEvent(d, Data.Blocks[i].Transponder[j].Type, Data.Blocks[i].Transponder[j].Data, s, Data.Blocks[i].Transponder[j].ClipToFirstRedSection); - Data.Blocks[i].Transponder[j].Type = -1; + TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.TransponderEvent(d, Data.Blocks[i].Transponders[j].Type, Data.Blocks[i].Transponders[j].Data, s, Data.Blocks[i].Transponders[j].ClipToFirstRedSection); + Data.Blocks[i].Transponders[j].Type = -1; } } // Destination Change Events @@ -2084,8 +2084,8 @@ private static void SmoothenOutTurns(int subdivisions) { double cosa = Math.Cos(b); double sina = Math.Sin(b); - World.Rotate(ref TrackManager.CurrentTrack.Elements[i].WorldDirection, TrackManager.CurrentTrack.Elements[i].WorldSide, cosa, sina); - World.Rotate(ref TrackManager.CurrentTrack.Elements[i].WorldUp, TrackManager.CurrentTrack.Elements[i].WorldSide, cosa, sina); + TrackManager.CurrentTrack.Elements[i].WorldDirection.Rotate(TrackManager.CurrentTrack.Elements[i].WorldSide, cosa, sina); + TrackManager.CurrentTrack.Elements[i].WorldUp.Rotate(TrackManager.CurrentTrack.Elements[i].WorldSide, cosa, sina); } } } diff --git a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Functions.cs b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Functions.cs index b64a91a2a..56139e640 100644 --- a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Functions.cs +++ b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Functions.cs @@ -31,23 +31,23 @@ private static double GetBrightness(ref RouteData Data, double TrackPosition) double bmin = 1.0, bmax = 1.0; for (int i = 0; i < Data.Blocks.Length; i++) { - for (int j = 0; j < Data.Blocks[i].Brightness.Length; j++) + for (int j = 0; j < Data.Blocks[i].BrightnessChanges.Length; j++) { - if (Data.Blocks[i].Brightness[j].TrackPosition <= TrackPosition) + if (Data.Blocks[i].BrightnessChanges[j].TrackPosition <= TrackPosition) { - tmin = Data.Blocks[i].Brightness[j].TrackPosition; - bmin = (double)Data.Blocks[i].Brightness[j].Value; + tmin = Data.Blocks[i].BrightnessChanges[j].TrackPosition; + bmin = (double)Data.Blocks[i].BrightnessChanges[j].Value; } } } for (int i = Data.Blocks.Length - 1; i >= 0; i--) { - for (int j = Data.Blocks[i].Brightness.Length - 1; j >= 0; j--) + for (int j = Data.Blocks[i].BrightnessChanges.Length - 1; j >= 0; j--) { - if (Data.Blocks[i].Brightness[j].TrackPosition >= TrackPosition) + if (Data.Blocks[i].BrightnessChanges[j].TrackPosition >= TrackPosition) { - tmax = Data.Blocks[i].Brightness[j].TrackPosition; - bmax = (double)Data.Blocks[i].Brightness[j].Value; + tmax = Data.Blocks[i].BrightnessChanges[j].TrackPosition; + bmax = (double)Data.Blocks[i].BrightnessChanges[j].Value; } } } diff --git a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.RouteData.cs b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.RouteData.cs index b913e59e1..ea6c0c38d 100644 --- a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.RouteData.cs +++ b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.RouteData.cs @@ -50,11 +50,11 @@ internal void CreateMissingBlocks(ref int BlocksUsed, int ToIndex, bool PreviewO if (!PreviewOnly) { Blocks[i].Background = -1; - Blocks[i].Brightness = new Brightness[] { }; + Blocks[i].BrightnessChanges = new Brightness[] { }; Blocks[i].Fog = Blocks[i - 1].Fog; Blocks[i].FogDefined = false; Blocks[i].Cycle = Blocks[i - 1].Cycle; - Blocks[i].RailCycle = Blocks[i - 1].RailCycle; + Blocks[i].RailCycles = Blocks[i - 1].RailCycles; Blocks[i].Height = double.NaN; } Blocks[i].RailType = new int[Blocks[i - 1].RailType.Length]; @@ -63,23 +63,23 @@ internal void CreateMissingBlocks(ref int BlocksUsed, int ToIndex, bool PreviewO for (int j = 0; j < Blocks[i].RailType.Length; j++) { int rc = -1; - if (Blocks[i].RailCycle.Length > j) + if (Blocks[i].RailCycles.Length > j) { - rc = Blocks[i].RailCycle[j].RailCycleIndex; + rc = Blocks[i].RailCycles[j].RailCycleIndex; } - if (rc != -1 && Structure.RailCycle.Length > rc && Structure.RailCycle[rc].Length > 1) + if (rc != -1 && Structure.RailCycles.Length > rc && Structure.RailCycles[rc].Length > 1) { - int cc = Blocks[i].RailCycle[j].CurrentCycle; - if (cc == Structure.RailCycle[rc].Length - 1) + int cc = Blocks[i].RailCycles[j].CurrentCycle; + if (cc == Structure.RailCycles[rc].Length - 1) { - Blocks[i].RailType[j] = Structure.RailCycle[rc][0]; - Blocks[i].RailCycle[j].CurrentCycle = 0; + Blocks[i].RailType[j] = Structure.RailCycles[rc][0]; + Blocks[i].RailCycles[j].CurrentCycle = 0; } else { cc++; - Blocks[i].RailType[j] = Structure.RailCycle[rc][cc]; - Blocks[i].RailCycle[j].CurrentCycle++; + Blocks[i].RailType[j] = Structure.RailCycles[rc][cc]; + Blocks[i].RailCycles[j].CurrentCycle++; } } else @@ -88,16 +88,16 @@ internal void CreateMissingBlocks(ref int BlocksUsed, int ToIndex, bool PreviewO } } } - Blocks[i].Rail = new Rail[Blocks[i - 1].Rail.Length]; - for (int j = 0; j < Blocks[i].Rail.Length; j++) + Blocks[i].Rails = new Rail[Blocks[i - 1].Rails.Length]; + for (int j = 0; j < Blocks[i].Rails.Length; j++) { - Blocks[i].Rail[j].RailStart = Blocks[i - 1].Rail[j].RailStart; - Blocks[i].Rail[j].RailStartX = Blocks[i - 1].Rail[j].RailStartX; - Blocks[i].Rail[j].RailStartY = Blocks[i - 1].Rail[j].RailStartY; - Blocks[i].Rail[j].RailStartRefreshed = false; - Blocks[i].Rail[j].RailEnd = false; - Blocks[i].Rail[j].RailEndX = Blocks[i - 1].Rail[j].RailStartX; - Blocks[i].Rail[j].RailEndY = Blocks[i - 1].Rail[j].RailStartY; + Blocks[i].Rails[j].RailStart = Blocks[i - 1].Rails[j].RailStart; + Blocks[i].Rails[j].RailStartX = Blocks[i - 1].Rails[j].RailStartX; + Blocks[i].Rails[j].RailStartY = Blocks[i - 1].Rails[j].RailStartY; + Blocks[i].Rails[j].RailStartRefreshed = false; + Blocks[i].Rails[j].RailEnd = false; + Blocks[i].Rails[j].RailEndX = Blocks[i - 1].Rails[j].RailStartX; + Blocks[i].Rails[j].RailEndY = Blocks[i - 1].Rails[j].RailStartY; } if (!PreviewOnly) { @@ -116,20 +116,20 @@ internal void CreateMissingBlocks(ref int BlocksUsed, int ToIndex, bool PreviewO { Blocks[i].RailPole[j] = Blocks[i - 1].RailPole[j]; } - Blocks[i].Form = new Form[] { }; - Blocks[i].Crack = new Crack[] { }; - Blocks[i].Signal = new Signal[] { }; - Blocks[i].Section = new Section[] { }; - Blocks[i].Sound = new Sound[] { }; - Blocks[i].Transponder = new Transponder[] { }; + Blocks[i].Forms = new Form[] { }; + Blocks[i].Cracks = new Crack[] { }; + Blocks[i].Signals = new Signal[] { }; + Blocks[i].Sections = new Section[] { }; + Blocks[i].SoundEvents = new Sound[] { }; + Blocks[i].Transponders = new Transponder[] { }; Blocks[i].DestinationChanges = new DestinationEvent[] { }; Blocks[i].RailFreeObj = new FreeObj[][] { }; Blocks[i].GroundFreeObj = new FreeObj[] { }; Blocks[i].PointsOfInterest = new PointOfInterest[] { }; } Blocks[i].Pitch = Blocks[i - 1].Pitch; - Blocks[i].Limit = new Limit[] { }; - Blocks[i].Stop = new Stop[] { }; + Blocks[i].Limits = new Limit[] { }; + Blocks[i].StopPositions = new Stop[] { }; Blocks[i].Station = -1; Blocks[i].StationPassAlarm = false; Blocks[i].CurrentTrackState = Blocks[i - 1].CurrentTrackState; diff --git a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Structures.cs b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Structures.cs index a606ad428..9bec41c67 100644 --- a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Structures.cs +++ b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.Structures.cs @@ -68,7 +68,7 @@ private struct Crack private struct Signal { internal double TrackPosition; - internal int Section; + internal int SectionIndex; internal int SignalCompatibilityObjectIndex; internal int SignalObjectIndex; internal double X; @@ -139,7 +139,9 @@ private struct Sound //This is always set to a constant 15.0 on loading a sound, and never touched again //I presume Michelle intended to have sounds with different radii available //This would require a custom or extended command which allowed the radius value to be set +#pragma warning disable 414 internal double Radius; +#pragma warning restore 414 internal double Speed; } private struct Transponder @@ -149,7 +151,7 @@ private struct Transponder internal bool ShowDefaultObject; internal int BeaconStructureIndex; internal int Data; - internal int Section; + internal int SectionIndex; internal bool ClipToFirstRedSection; internal double X; internal double Y; @@ -189,27 +191,27 @@ private struct RailCycle { private class Block { internal int Background; - internal Brightness[] Brightness; + internal Brightness[] BrightnessChanges; internal Game.Fog Fog; internal bool FogDefined; internal int[] Cycle; - internal RailCycle[] RailCycle; + internal RailCycle[] RailCycles; internal double Height; - internal Rail[] Rail; + internal Rail[] Rails; internal int[] RailType; internal WallDike[] RailWall; internal WallDike[] RailDike; internal Pole[] RailPole; internal FreeObj[][] RailFreeObj; internal FreeObj[] GroundFreeObj; - internal Form[] Form; - internal Crack[] Crack; - internal Signal[] Signal; - internal Section[] Section; - internal Limit[] Limit; - internal Stop[] Stop; - internal Sound[] Sound; - internal Transponder[] Transponder; + internal Form[] Forms; + internal Crack[] Cracks; + internal Signal[] Signals; + internal Section[] Sections; + internal Limit[] Limits; + internal Stop[] StopPositions; + internal Sound[] SoundEvents; + internal Transponder[] Transponders; internal DestinationEvent[] DestinationChanges; internal PointOfInterest[] PointsOfInterest; internal TrackManager.TrackElement CurrentTrackState; @@ -220,30 +222,55 @@ private class Block internal double Accuracy; internal double AdhesionMultiplier; } + + /// Holds the base structures for a route: These are cloned and transformed for final world placement private struct StructureData { + /// All currently defined Structure.Rail objects internal ObjectDictionary RailObjects; + /// All currently defined Structure.Pole objects internal ObjectManager.UnifiedObject[][] Poles; + /// All currently defined Structure.Ground objects internal ObjectDictionary Ground; + /// All currently defined Structure.WallL objects internal ObjectDictionary WallL; + /// All currently defined Structure.WallR objects internal ObjectDictionary WallR; + /// All currently defined Structure.DikeL objects internal ObjectDictionary DikeL; + /// All currently defined Structure.DikeR objects internal ObjectDictionary DikeR; + /// All currently defined Structure.FormL objects internal ObjectDictionary FormL; + /// All currently defined Structure.FormR objects internal ObjectDictionary FormR; + /// All currently defined Structure.FormCL objects internal ObjectDictionary FormCL; + /// All currently defined Structure.FormCR objects internal ObjectDictionary FormCR; + /// All currently defined Structure.RoofL objects internal ObjectDictionary RoofL; + /// All currently defined Structure.RoofR objects internal ObjectDictionary RoofR; + /// All currently defined Structure.RoofCL objects internal ObjectDictionary RoofCL; + /// All currently defined Structure.RoofCR objects internal ObjectDictionary RoofCR; + /// All currently defined Structure.CrackL objects internal ObjectDictionary CrackL; + /// All currently defined Structure.CrackR objects internal ObjectDictionary CrackR; + /// All currently defined Structure.FreeObj objects internal ObjectDictionary FreeObjects; + /// All currently defined Structure.Beacon objects internal ObjectDictionary Beacon; - internal int[][] Cycle; - internal int[][] RailCycle; + /// All currently defined cycles + internal int[][] Cycles; + /// All currently defined RailCycles + internal int[][] RailCycles; + /// The Run sound index to be played for each railtype idx internal int[] Run; + /// The flange sound index to be played for each railtype idx internal int[] Flange; } } diff --git a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.cs b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.cs index 1abb88576..9c1d17bf3 100644 --- a/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.cs +++ b/source/OpenBVE/Parsers/Route/BVE/CsvRwRouteParser.cs @@ -42,11 +42,11 @@ internal static void ParseRoute(string FileName, bool IsRW, System.Text.Encoding Blocks = new Block[1] }; Data.Blocks[0] = new Block(); - Data.Blocks[0].Rail = new Rail[1]; - Data.Blocks[0].Rail[0].RailStart = true; + Data.Blocks[0].Rails = new Rail[1]; + Data.Blocks[0].Rails[0].RailStart = true; Data.Blocks[0].RailType = new int[] { 0 }; - Data.Blocks[0].Limit = new Limit[] { }; - Data.Blocks[0].Stop = new Stop[] { }; + Data.Blocks[0].Limits = new Limit[] { }; + Data.Blocks[0].StopPositions = new Stop[] { }; Data.Blocks[0].Station = -1; Data.Blocks[0].StationPassAlarm = false; Data.Blocks[0].Accuracy = 2.0; @@ -55,25 +55,25 @@ internal static void ParseRoute(string FileName, bool IsRW, System.Text.Encoding if (!PreviewOnly) { Data.Blocks[0].Background = 0; - Data.Blocks[0].Brightness = new Brightness[] {}; + Data.Blocks[0].BrightnessChanges = new Brightness[] {}; Data.Blocks[0].Fog.Start = Game.NoFogStart; Data.Blocks[0].Fog.End = Game.NoFogEnd; Data.Blocks[0].Fog.Color = new Color24(128, 128, 128); Data.Blocks[0].Cycle = new int[] {-1}; - Data.Blocks[0].RailCycle = new RailCycle[1]; - Data.Blocks[0].RailCycle[0].RailCycleIndex = -1; + Data.Blocks[0].RailCycles = new RailCycle[1]; + Data.Blocks[0].RailCycles[0].RailCycleIndex = -1; Data.Blocks[0].Height = IsRW ? 0.3 : 0.0; Data.Blocks[0].RailFreeObj = new FreeObj[][] {}; Data.Blocks[0].GroundFreeObj = new FreeObj[] {}; Data.Blocks[0].RailWall = new WallDike[] {}; Data.Blocks[0].RailDike = new WallDike[] {}; Data.Blocks[0].RailPole = new Pole[] {}; - Data.Blocks[0].Form = new Form[] {}; - Data.Blocks[0].Crack = new Crack[] {}; - Data.Blocks[0].Signal = new Signal[] {}; - Data.Blocks[0].Section = new Section[] {}; - Data.Blocks[0].Sound = new Sound[] {}; - Data.Blocks[0].Transponder = new Transponder[] {}; + Data.Blocks[0].Forms = new Form[] {}; + Data.Blocks[0].Cracks = new Crack[] {}; + Data.Blocks[0].Signals = new Signal[] {}; + Data.Blocks[0].Sections = new Section[] {}; + Data.Blocks[0].SoundEvents = new Sound[] {}; + Data.Blocks[0].Transponders = new Transponder[] {}; Data.Blocks[0].DestinationChanges = new DestinationEvent[] {}; Data.Blocks[0].PointsOfInterest = new PointOfInterest[] {}; Data.Markers = new Marker[] {}; @@ -121,8 +121,8 @@ internal static void ParseRoute(string FileName, bool IsRW, System.Text.Encoding Data.Structure.CrackR = new ObjectDictionary(); Data.Structure.FreeObjects = new ObjectDictionary(); Data.Structure.Beacon = new ObjectDictionary(); - Data.Structure.Cycle = new int[][] {}; - Data.Structure.RailCycle = new int[][] { }; + Data.Structure.Cycles = new int[][] {}; + Data.Structure.RailCycles = new int[][] { }; Data.Structure.Run = new int[] {}; Data.Structure.Flange = new int[] {}; Data.Backgrounds = new BackgroundManager.BackgroundHandle[] {}; @@ -1719,7 +1719,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } break; case "train.destination": { - if (PreviewOnly) + if (!PreviewOnly) { if (Arguments.Length < 1) { @@ -2567,10 +2567,10 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En // cycle case "cycle.ground": if (!PreviewOnly) { - if (CommandIndex1 >= Data.Structure.Cycle.Length) { - Array.Resize(ref Data.Structure.Cycle, CommandIndex1 + 1); + if (CommandIndex1 >= Data.Structure.Cycles.Length) { + Array.Resize(ref Data.Structure.Cycles, CommandIndex1 + 1); } - Data.Structure.Cycle[CommandIndex1] = new int[Arguments.Length]; + Data.Structure.Cycles[CommandIndex1] = new int[Arguments.Length]; for (int k = 0; k < Arguments.Length; k++) { int ix = 0; if (Arguments[k].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[k], out ix)) { @@ -2581,18 +2581,18 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "GroundStructureIndex " + (k + 1).ToString(Culture) + " is out of range in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); ix = 0; } - Data.Structure.Cycle[CommandIndex1][k] = ix; + Data.Structure.Cycles[CommandIndex1][k] = ix; } } break; // rail cycle case "cycle.rail": if (!PreviewOnly) { - if (CommandIndex1 >= Data.Structure.RailCycle.Length) + if (CommandIndex1 >= Data.Structure.RailCycles.Length) { - Array.Resize(ref Data.Structure.RailCycle, CommandIndex1 + 1); + Array.Resize(ref Data.Structure.RailCycles, CommandIndex1 + 1); } - Data.Structure.RailCycle[CommandIndex1] = new int[Arguments.Length]; + Data.Structure.RailCycles[CommandIndex1] = new int[Arguments.Length]; for (int k = 0; k < Arguments.Length; k++) { int ix = 0; @@ -2606,7 +2606,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex " + (k + 1).ToString(Culture) + " is out of range in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); ix = 0; } - Data.Structure.RailCycle[CommandIndex1][k] = ix; + Data.Structure.RailCycles[CommandIndex1][k] = ix; } } break; } @@ -2858,27 +2858,27 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } if (string.Compare(Command, "track.railstart", StringComparison.OrdinalIgnoreCase) == 0) { - if (idx < Data.Blocks[BlockIndex].Rail.Length && Data.Blocks[BlockIndex].Rail[idx].RailStart) + if (idx < Data.Blocks[BlockIndex].Rails.Length && Data.Blocks[BlockIndex].Rails[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex " + idx + " is required to reference a non-existing rail in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } } - if (Data.Blocks[BlockIndex].Rail.Length <= idx) + if (Data.Blocks[BlockIndex].Rails.Length <= idx) { - Array.Resize(ref Data.Blocks[BlockIndex].Rail, idx + 1); - int ol = Data.Blocks[BlockIndex].RailCycle.Length; - Array.Resize(ref Data.Blocks[BlockIndex].RailCycle, idx + 1); - for (int rc = ol; rc < Data.Blocks[BlockIndex].RailCycle.Length; rc++) + Array.Resize(ref Data.Blocks[BlockIndex].Rails, idx + 1); + int ol = Data.Blocks[BlockIndex].RailCycles.Length; + Array.Resize(ref Data.Blocks[BlockIndex].RailCycles, idx + 1); + for (int rc = ol; rc < Data.Blocks[BlockIndex].RailCycles.Length; rc++) { - Data.Blocks[BlockIndex].RailCycle[rc].RailCycleIndex = -1; + Data.Blocks[BlockIndex].RailCycles[rc].RailCycleIndex = -1; } } - if (Data.Blocks[BlockIndex].Rail[idx].RailStartRefreshed) + if (Data.Blocks[BlockIndex].Rails[idx].RailStartRefreshed) { - Data.Blocks[BlockIndex].Rail[idx].RailEnd = true; + Data.Blocks[BlockIndex].Rails[idx].RailEnd = true; } - Data.Blocks[BlockIndex].Rail[idx].RailStart = true; - Data.Blocks[BlockIndex].Rail[idx].RailStartRefreshed = true; + Data.Blocks[BlockIndex].Rails[idx].RailStart = true; + Data.Blocks[BlockIndex].Rails[idx].RailStartRefreshed = true; if (Arguments.Length >= 2) { if (Arguments[1].Length > 0) @@ -2889,11 +2889,11 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } - Data.Blocks[BlockIndex].Rail[idx].RailStartX = x; + Data.Blocks[BlockIndex].Rails[idx].RailStartX = x; } - if (!Data.Blocks[BlockIndex].Rail[idx].RailEnd) + if (!Data.Blocks[BlockIndex].Rails[idx].RailEnd) { - Data.Blocks[BlockIndex].Rail[idx].RailEndX = Data.Blocks[BlockIndex].Rail[idx].RailStartX; + Data.Blocks[BlockIndex].Rails[idx].RailEndX = Data.Blocks[BlockIndex].Rails[idx].RailStartX; } } if (Arguments.Length >= 3) @@ -2906,11 +2906,11 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } - Data.Blocks[BlockIndex].Rail[idx].RailStartY = y; + Data.Blocks[BlockIndex].Rails[idx].RailStartY = y; } - if (!Data.Blocks[BlockIndex].Rail[idx].RailEnd) + if (!Data.Blocks[BlockIndex].Rails[idx].RailEnd) { - Data.Blocks[BlockIndex].Rail[idx].RailEndY = Data.Blocks[BlockIndex].Rail[idx].RailStartY; + Data.Blocks[BlockIndex].Rails[idx].RailEndY = Data.Blocks[BlockIndex].Rails[idx].RailStartY; } } if (Data.Blocks[BlockIndex].RailType.Length <= idx) @@ -2935,16 +2935,16 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } else { - if (sttype < Data.Structure.RailCycle.Length && Data.Structure.RailCycle[sttype] != null) + if (sttype < Data.Structure.RailCycles.Length && Data.Structure.RailCycles[sttype] != null) { - Data.Blocks[BlockIndex].RailType[idx] = Data.Structure.RailCycle[sttype][0]; - Data.Blocks[BlockIndex].RailCycle[idx].RailCycleIndex = sttype; - Data.Blocks[BlockIndex].RailCycle[idx].CurrentCycle = 0; + Data.Blocks[BlockIndex].RailType[idx] = Data.Structure.RailCycles[sttype][0]; + Data.Blocks[BlockIndex].RailCycles[idx].RailCycleIndex = sttype; + Data.Blocks[BlockIndex].RailCycles[idx].CurrentCycle = 0; } else { Data.Blocks[BlockIndex].RailType[idx] = sttype; - Data.Blocks[BlockIndex].RailCycle[idx].RailCycleIndex = -1; + Data.Blocks[BlockIndex].RailCycles[idx].RailCycleIndex = -1; } } } @@ -2960,18 +2960,18 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex " + idx + " is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); break; } - if (idx < 0 || idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) + if (idx < 0 || idx >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex " + idx + " references a non-existing rail in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); break; } if (Data.Blocks[BlockIndex].RailType.Length <= idx) { - Array.Resize(ref Data.Blocks[BlockIndex].Rail, idx + 1); + Array.Resize(ref Data.Blocks[BlockIndex].Rails, idx + 1); } - Data.Blocks[BlockIndex].Rail[idx].RailStart = false; - Data.Blocks[BlockIndex].Rail[idx].RailStartRefreshed = false; - Data.Blocks[BlockIndex].Rail[idx].RailEnd = true; + Data.Blocks[BlockIndex].Rails[idx].RailStart = false; + Data.Blocks[BlockIndex].Rails[idx].RailStartRefreshed = false; + Data.Blocks[BlockIndex].Rails[idx].RailEnd = true; if (Arguments.Length >= 2 && Arguments[1].Length > 0) { double x; @@ -2980,7 +2980,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } - Data.Blocks[BlockIndex].Rail[idx].RailEndX = x; + Data.Blocks[BlockIndex].Rails[idx].RailEndX = x; } if (Arguments.Length >= 3 && Arguments[2].Length > 0) { @@ -2990,7 +2990,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } - Data.Blocks[BlockIndex].Rail[idx].RailEndY = y; + Data.Blocks[BlockIndex].Rails[idx].RailEndY = y; } } } break; @@ -3010,7 +3010,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { + if (idx >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx + " could be out of range in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (sttype < 0) { @@ -3020,21 +3020,21 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } else { if (Data.Blocks[BlockIndex].RailType.Length <= idx) { Array.Resize(ref Data.Blocks[BlockIndex].RailType, idx + 1); - int ol = Data.Blocks[BlockIndex].RailCycle.Length; - Array.Resize(ref Data.Blocks[BlockIndex].RailCycle, idx + 1); - for (int rc = ol; rc < Data.Blocks[BlockIndex].RailCycle.Length; rc++) + int ol = Data.Blocks[BlockIndex].RailCycles.Length; + Array.Resize(ref Data.Blocks[BlockIndex].RailCycles, idx + 1); + for (int rc = ol; rc < Data.Blocks[BlockIndex].RailCycles.Length; rc++) { - Data.Blocks[BlockIndex].RailCycle[rc].RailCycleIndex = -1; + Data.Blocks[BlockIndex].RailCycles[rc].RailCycleIndex = -1; } } - if (sttype < Data.Structure.RailCycle.Length && Data.Structure.RailCycle[sttype] != null) { - Data.Blocks[BlockIndex].RailType[idx] = Data.Structure.RailCycle[sttype][0]; - Data.Blocks[BlockIndex].RailCycle[idx].RailCycleIndex = sttype; - Data.Blocks[BlockIndex].RailCycle[idx].CurrentCycle = 0; + if (sttype < Data.Structure.RailCycles.Length && Data.Structure.RailCycles[sttype] != null) { + Data.Blocks[BlockIndex].RailType[idx] = Data.Structure.RailCycles[sttype][0]; + Data.Blocks[BlockIndex].RailCycles[idx].RailCycleIndex = sttype; + Data.Blocks[BlockIndex].RailCycles[idx].CurrentCycle = 0; } else { Data.Blocks[BlockIndex].RailType[idx] = sttype; - Data.Blocks[BlockIndex].RailCycle[idx].RailCycleIndex = -1; + Data.Blocks[BlockIndex].RailCycles[idx].RailCycleIndex = -1; } } } @@ -3121,10 +3121,10 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En value /= 255.0f; if (value < 0.0f) value = 0.0f; if (value > 1.0f) value = 1.0f; - int n = Data.Blocks[BlockIndex].Brightness.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Brightness, n + 1); - Data.Blocks[BlockIndex].Brightness[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Brightness[n].Value = value; + int n = Data.Blocks[BlockIndex].BrightnessChanges.Length; + Array.Resize(ref Data.Blocks[BlockIndex].BrightnessChanges, n + 1); + Data.Blocks[BlockIndex].BrightnessChanges[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].BrightnessChanges[n].Value = value; } } break; case "track.fog": @@ -3218,15 +3218,15 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En if (valueBased) { Array.Sort(aspects); } - int n = Data.Blocks[BlockIndex].Section.Length; - Array.Resize
(ref Data.Blocks[BlockIndex].Section, n + 1); - Data.Blocks[BlockIndex].Section[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Section[n].Aspects = aspects; - Data.Blocks[BlockIndex].Section[n].Type = valueBased ? Game.SectionType.ValueBased : Game.SectionType.IndexBased; - Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = -1; + int n = Data.Blocks[BlockIndex].Sections.Length; + Array.Resize
(ref Data.Blocks[BlockIndex].Sections, n + 1); + Data.Blocks[BlockIndex].Sections[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Sections[n].Aspects = aspects; + Data.Blocks[BlockIndex].Sections[n].Type = valueBased ? Game.SectionType.ValueBased : Game.SectionType.IndexBased; + Data.Blocks[BlockIndex].Sections[n].DepartureStationIndex = -1; if (CurrentStation >= 0 && Game.Stations[CurrentStation].ForceStopSignal) { if (CurrentStation >= 0 & CurrentStop >= 0 & !DepartureSignalUsed) { - Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = CurrentStation; + Data.Blocks[BlockIndex].Sections[n].DepartureStationIndex = CurrentStation; DepartureSignalUsed = true; } } @@ -3270,19 +3270,19 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } - int n = Data.Blocks[BlockIndex].Signal.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Signal, n + 1); - Data.Blocks[BlockIndex].Signal[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Signal[n].Section = CurrentSection + section; - Data.Blocks[BlockIndex].Signal[n].SignalCompatibilityObjectIndex = -1; - Data.Blocks[BlockIndex].Signal[n].SignalObjectIndex = objidx; - Data.Blocks[BlockIndex].Signal[n].X = x; - Data.Blocks[BlockIndex].Signal[n].Y = y < 0.0 ? 4.8 : y; - Data.Blocks[BlockIndex].Signal[n].Yaw = 0.0174532925199433 * yaw; - Data.Blocks[BlockIndex].Signal[n].Pitch = 0.0174532925199433 * pitch; - Data.Blocks[BlockIndex].Signal[n].Roll = 0.0174532925199433 * roll; - Data.Blocks[BlockIndex].Signal[n].ShowObject = true; - Data.Blocks[BlockIndex].Signal[n].ShowPost = y < 0.0; + int n = Data.Blocks[BlockIndex].Signals.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Signals, n + 1); + Data.Blocks[BlockIndex].Signals[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Signals[n].SectionIndex = CurrentSection + section; + Data.Blocks[BlockIndex].Signals[n].SignalCompatibilityObjectIndex = -1; + Data.Blocks[BlockIndex].Signals[n].SignalObjectIndex = objidx; + Data.Blocks[BlockIndex].Signals[n].X = x; + Data.Blocks[BlockIndex].Signals[n].Y = y < 0.0 ? 4.8 : y; + Data.Blocks[BlockIndex].Signals[n].Yaw = 0.0174532925199433 * yaw; + Data.Blocks[BlockIndex].Signals[n].Pitch = 0.0174532925199433 * pitch; + Data.Blocks[BlockIndex].Signals[n].Roll = 0.0174532925199433 * roll; + Data.Blocks[BlockIndex].Signals[n].ShowObject = true; + Data.Blocks[BlockIndex].Signals[n].ShowPost = y < 0.0; } else { Interface.AddMessage(Interface.MessageType.Error, false, "SignalIndex " + objidx + " references a signal object not loaded in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } @@ -3341,33 +3341,33 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En case 6: aspects = new int[] { 0, 1, 2, 3, 4, 5 }; comp = 7; break; default: aspects = new int[] { 0, 2 }; comp = 0; break; } - int n = Data.Blocks[BlockIndex].Section.Length; - Array.Resize
(ref Data.Blocks[BlockIndex].Section, n + 1); - Data.Blocks[BlockIndex].Section[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Section[n].Aspects = aspects; - Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = -1; - Data.Blocks[BlockIndex].Section[n].Invisible = x == 0.0; - Data.Blocks[BlockIndex].Section[n].Type = Game.SectionType.ValueBased; + int n = Data.Blocks[BlockIndex].Sections.Length; + Array.Resize
(ref Data.Blocks[BlockIndex].Sections, n + 1); + Data.Blocks[BlockIndex].Sections[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Sections[n].Aspects = aspects; + Data.Blocks[BlockIndex].Sections[n].DepartureStationIndex = -1; + Data.Blocks[BlockIndex].Sections[n].Invisible = x == 0.0; + Data.Blocks[BlockIndex].Sections[n].Type = Game.SectionType.ValueBased; if (CurrentStation >= 0 && Game.Stations[CurrentStation].ForceStopSignal) { if (CurrentStation >= 0 & CurrentStop >= 0 & !DepartureSignalUsed) { - Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = CurrentStation; + Data.Blocks[BlockIndex].Sections[n].DepartureStationIndex = CurrentStation; DepartureSignalUsed = true; } } CurrentSection++; - n = Data.Blocks[BlockIndex].Signal.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Signal, n + 1); - Data.Blocks[BlockIndex].Signal[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Signal[n].Section = CurrentSection; - Data.Blocks[BlockIndex].Signal[n].SignalCompatibilityObjectIndex = comp; - Data.Blocks[BlockIndex].Signal[n].SignalObjectIndex = -1; - Data.Blocks[BlockIndex].Signal[n].X = x; - Data.Blocks[BlockIndex].Signal[n].Y = y < 0.0 ? 4.8 : y; - Data.Blocks[BlockIndex].Signal[n].Yaw = 0.0174532925199433 * yaw; - Data.Blocks[BlockIndex].Signal[n].Pitch = 0.0174532925199433 * pitch; - Data.Blocks[BlockIndex].Signal[n].Roll = 0.0174532925199433 * roll; - Data.Blocks[BlockIndex].Signal[n].ShowObject = x != 0.0; - Data.Blocks[BlockIndex].Signal[n].ShowPost = x != 0.0 & y < 0.0; + n = Data.Blocks[BlockIndex].Signals.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Signals, n + 1); + Data.Blocks[BlockIndex].Signals[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Signals[n].SectionIndex = CurrentSection; + Data.Blocks[BlockIndex].Signals[n].SignalCompatibilityObjectIndex = comp; + Data.Blocks[BlockIndex].Signals[n].SignalObjectIndex = -1; + Data.Blocks[BlockIndex].Signals[n].X = x; + Data.Blocks[BlockIndex].Signals[n].Y = y < 0.0 ? 4.8 : y; + Data.Blocks[BlockIndex].Signals[n].Yaw = 0.0174532925199433 * yaw; + Data.Blocks[BlockIndex].Signals[n].Pitch = 0.0174532925199433 * pitch; + Data.Blocks[BlockIndex].Signals[n].Roll = 0.0174532925199433 * roll; + Data.Blocks[BlockIndex].Signals[n].ShowObject = x != 0.0; + Data.Blocks[BlockIndex].Signals[n].ShowPost = x != 0.0 & y < 0.0; } } break; case "track.relay": @@ -3395,19 +3395,19 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.Relay at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } - int n = Data.Blocks[BlockIndex].Signal.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Signal, n + 1); - Data.Blocks[BlockIndex].Signal[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Signal[n].Section = CurrentSection + 1; - Data.Blocks[BlockIndex].Signal[n].SignalCompatibilityObjectIndex = 8; - Data.Blocks[BlockIndex].Signal[n].SignalObjectIndex = -1; - Data.Blocks[BlockIndex].Signal[n].X = x; - Data.Blocks[BlockIndex].Signal[n].Y = y < 0.0 ? 4.8 : y; - Data.Blocks[BlockIndex].Signal[n].Yaw = yaw * 0.0174532925199433; - Data.Blocks[BlockIndex].Signal[n].Pitch = pitch * 0.0174532925199433; - Data.Blocks[BlockIndex].Signal[n].Roll = roll * 0.0174532925199433; - Data.Blocks[BlockIndex].Signal[n].ShowObject = x != 0.0; - Data.Blocks[BlockIndex].Signal[n].ShowPost = x != 0.0 & y < 0.0; + int n = Data.Blocks[BlockIndex].Signals.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Signals, n + 1); + Data.Blocks[BlockIndex].Signals[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Signals[n].SectionIndex = CurrentSection + 1; + Data.Blocks[BlockIndex].Signals[n].SignalCompatibilityObjectIndex = 8; + Data.Blocks[BlockIndex].Signals[n].SignalObjectIndex = -1; + Data.Blocks[BlockIndex].Signals[n].X = x; + Data.Blocks[BlockIndex].Signals[n].Y = y < 0.0 ? 4.8 : y; + Data.Blocks[BlockIndex].Signals[n].Yaw = yaw * 0.0174532925199433; + Data.Blocks[BlockIndex].Signals[n].Pitch = pitch * 0.0174532925199433; + Data.Blocks[BlockIndex].Signals[n].Roll = roll * 0.0174532925199433; + Data.Blocks[BlockIndex].Signals[n].ShowObject = x != 0.0; + Data.Blocks[BlockIndex].Signals[n].ShowPost = x != 0.0 & y < 0.0; } } break; case "track.destination": @@ -3567,19 +3567,19 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } - int n = Data.Blocks[BlockIndex].Transponder.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Transponder, n + 1); - Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Transponder[n].Type = type; - Data.Blocks[BlockIndex].Transponder[n].Data = optional; - Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = structure; - Data.Blocks[BlockIndex].Transponder[n].Section = section; - Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = false; - Data.Blocks[BlockIndex].Transponder[n].X = x; - Data.Blocks[BlockIndex].Transponder[n].Y = y; - Data.Blocks[BlockIndex].Transponder[n].Yaw = yaw * 0.0174532925199433; - Data.Blocks[BlockIndex].Transponder[n].Pitch = pitch * 0.0174532925199433; - Data.Blocks[BlockIndex].Transponder[n].Roll = roll * 0.0174532925199433; + int n = Data.Blocks[BlockIndex].Transponders.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Transponders, n + 1); + Data.Blocks[BlockIndex].Transponders[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Transponders[n].Type = type; + Data.Blocks[BlockIndex].Transponders[n].Data = optional; + Data.Blocks[BlockIndex].Transponders[n].BeaconStructureIndex = structure; + Data.Blocks[BlockIndex].Transponders[n].SectionIndex = section; + Data.Blocks[BlockIndex].Transponders[n].ShowDefaultObject = false; + Data.Blocks[BlockIndex].Transponders[n].X = x; + Data.Blocks[BlockIndex].Transponders[n].Y = y; + Data.Blocks[BlockIndex].Transponders[n].Yaw = yaw * 0.0174532925199433; + Data.Blocks[BlockIndex].Transponders[n].Pitch = pitch * 0.0174532925199433; + Data.Blocks[BlockIndex].Transponders[n].Roll = roll * 0.0174532925199433; } } } break; @@ -3626,48 +3626,48 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } - int n = Data.Blocks[BlockIndex].Transponder.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Transponder, n + 1); - Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Transponder[n].Type = type; - Data.Blocks[BlockIndex].Transponder[n].Data = work; - Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = true; - Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; - Data.Blocks[BlockIndex].Transponder[n].X = x; - Data.Blocks[BlockIndex].Transponder[n].Y = y; - Data.Blocks[BlockIndex].Transponder[n].Yaw = yaw * 0.0174532925199433; - Data.Blocks[BlockIndex].Transponder[n].Pitch = pitch * 0.0174532925199433; - Data.Blocks[BlockIndex].Transponder[n].Roll = roll * 0.0174532925199433; - Data.Blocks[BlockIndex].Transponder[n].Section = CurrentSection + oversig + 1; - Data.Blocks[BlockIndex].Transponder[n].ClipToFirstRedSection = true; + int n = Data.Blocks[BlockIndex].Transponders.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Transponders, n + 1); + Data.Blocks[BlockIndex].Transponders[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Transponders[n].Type = type; + Data.Blocks[BlockIndex].Transponders[n].Data = work; + Data.Blocks[BlockIndex].Transponders[n].ShowDefaultObject = true; + Data.Blocks[BlockIndex].Transponders[n].BeaconStructureIndex = -1; + Data.Blocks[BlockIndex].Transponders[n].X = x; + Data.Blocks[BlockIndex].Transponders[n].Y = y; + Data.Blocks[BlockIndex].Transponders[n].Yaw = yaw * 0.0174532925199433; + Data.Blocks[BlockIndex].Transponders[n].Pitch = pitch * 0.0174532925199433; + Data.Blocks[BlockIndex].Transponders[n].Roll = roll * 0.0174532925199433; + Data.Blocks[BlockIndex].Transponders[n].SectionIndex = CurrentSection + oversig + 1; + Data.Blocks[BlockIndex].Transponders[n].ClipToFirstRedSection = true; } } break; case "track.atssn": { if (!PreviewOnly) { - int n = Data.Blocks[BlockIndex].Transponder.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Transponder, n + 1); - Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Transponder[n].Type = 0; - Data.Blocks[BlockIndex].Transponder[n].Data = 0; - Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = true; - Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; - Data.Blocks[BlockIndex].Transponder[n].Section = CurrentSection + 1; - Data.Blocks[BlockIndex].Transponder[n].ClipToFirstRedSection = true; + int n = Data.Blocks[BlockIndex].Transponders.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Transponders, n + 1); + Data.Blocks[BlockIndex].Transponders[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Transponders[n].Type = 0; + Data.Blocks[BlockIndex].Transponders[n].Data = 0; + Data.Blocks[BlockIndex].Transponders[n].ShowDefaultObject = true; + Data.Blocks[BlockIndex].Transponders[n].BeaconStructureIndex = -1; + Data.Blocks[BlockIndex].Transponders[n].SectionIndex = CurrentSection + 1; + Data.Blocks[BlockIndex].Transponders[n].ClipToFirstRedSection = true; } } break; case "track.atsp": { if (!PreviewOnly) { - int n = Data.Blocks[BlockIndex].Transponder.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Transponder, n + 1); - Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Transponder[n].Type = 3; - Data.Blocks[BlockIndex].Transponder[n].Data = 0; - Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = true; - Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; - Data.Blocks[BlockIndex].Transponder[n].Section = CurrentSection + 1; - Data.Blocks[BlockIndex].Transponder[n].ClipToFirstRedSection = true; + int n = Data.Blocks[BlockIndex].Transponders.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Transponders, n + 1); + Data.Blocks[BlockIndex].Transponders[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Transponders[n].Type = 3; + Data.Blocks[BlockIndex].Transponders[n].Data = 0; + Data.Blocks[BlockIndex].Transponders[n].ShowDefaultObject = true; + Data.Blocks[BlockIndex].Transponders[n].BeaconStructureIndex = -1; + Data.Blocks[BlockIndex].Transponders[n].SectionIndex = CurrentSection + 1; + Data.Blocks[BlockIndex].Transponders[n].ClipToFirstRedSection = true; } } break; case "track.pattern": @@ -3683,18 +3683,18 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); speed = 0.0; } - int n = Data.Blocks[BlockIndex].Transponder.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Transponder, n + 1); - Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; + int n = Data.Blocks[BlockIndex].Transponders.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Transponders, n + 1); + Data.Blocks[BlockIndex].Transponders[n].TrackPosition = Data.TrackPosition; if (type == 0) { - Data.Blocks[BlockIndex].Transponder[n].Type = TrackManager.SpecialTransponderTypes.InternalAtsPTemporarySpeedLimit; - Data.Blocks[BlockIndex].Transponder[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); + Data.Blocks[BlockIndex].Transponders[n].Type = TrackManager.SpecialTransponderTypes.InternalAtsPTemporarySpeedLimit; + Data.Blocks[BlockIndex].Transponders[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); } else { - Data.Blocks[BlockIndex].Transponder[n].Type = TrackManager.SpecialTransponderTypes.AtsPPermanentSpeedLimit; - Data.Blocks[BlockIndex].Transponder[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); + Data.Blocks[BlockIndex].Transponders[n].Type = TrackManager.SpecialTransponderTypes.AtsPPermanentSpeedLimit; + Data.Blocks[BlockIndex].Transponders[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); } - Data.Blocks[BlockIndex].Transponder[n].Section = -1; - Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; + Data.Blocks[BlockIndex].Transponders[n].SectionIndex = -1; + Data.Blocks[BlockIndex].Transponders[n].BeaconStructureIndex = -1; } } break; case "track.plimit": @@ -3705,13 +3705,13 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); speed = 0.0; } - int n = Data.Blocks[BlockIndex].Transponder.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Transponder, n + 1); - Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Transponder[n].Type = TrackManager.SpecialTransponderTypes.AtsPPermanentSpeedLimit; - Data.Blocks[BlockIndex].Transponder[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); - Data.Blocks[BlockIndex].Transponder[n].Section = -1; - Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; + int n = Data.Blocks[BlockIndex].Transponders.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Transponders, n + 1); + Data.Blocks[BlockIndex].Transponders[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Transponders[n].Type = TrackManager.SpecialTransponderTypes.AtsPPermanentSpeedLimit; + Data.Blocks[BlockIndex].Transponders[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); + Data.Blocks[BlockIndex].Transponders[n].SectionIndex = -1; + Data.Blocks[BlockIndex].Transponders[n].BeaconStructureIndex = -1; } } break; case "track.limit": @@ -3730,12 +3730,12 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Cource is invalid in Track.Limit at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); cource = 0; } - int n = Data.Blocks[BlockIndex].Limit.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Limit, n + 1); - Data.Blocks[BlockIndex].Limit[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Limit[n].Speed = limit <= 0.0 ? double.PositiveInfinity : Data.UnitOfSpeed * limit; - Data.Blocks[BlockIndex].Limit[n].Direction = direction; - Data.Blocks[BlockIndex].Limit[n].Cource = cource; + int n = Data.Blocks[BlockIndex].Limits.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Limits, n + 1); + Data.Blocks[BlockIndex].Limits[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].Limits[n].Speed = limit <= 0.0 ? double.PositiveInfinity : Data.UnitOfSpeed * limit; + Data.Blocks[BlockIndex].Limits[n].Direction = direction; + Data.Blocks[BlockIndex].Limits[n].Cource = cource; } break; case "track.stop": if (CurrentStation == -1) { @@ -3766,14 +3766,14 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Cars is invalid in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); cars = 0; } - int n = Data.Blocks[BlockIndex].Stop.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Stop, n + 1); - Data.Blocks[BlockIndex].Stop[n].TrackPosition = Data.TrackPosition; - Data.Blocks[BlockIndex].Stop[n].Station = CurrentStation; - Data.Blocks[BlockIndex].Stop[n].Direction = dir; - Data.Blocks[BlockIndex].Stop[n].ForwardTolerance = forw; - Data.Blocks[BlockIndex].Stop[n].BackwardTolerance = backw; - Data.Blocks[BlockIndex].Stop[n].Cars = cars; + int n = Data.Blocks[BlockIndex].StopPositions.Length; + Array.Resize(ref Data.Blocks[BlockIndex].StopPositions, n + 1); + Data.Blocks[BlockIndex].StopPositions[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].StopPositions[n].Station = CurrentStation; + Data.Blocks[BlockIndex].StopPositions[n].Direction = dir; + Data.Blocks[BlockIndex].StopPositions[n].ForwardTolerance = forw; + Data.Blocks[BlockIndex].StopPositions[n].BackwardTolerance = backw; + Data.Blocks[BlockIndex].StopPositions[n].Cars = cars; CurrentStop = cars; } break; case "track.sta": @@ -4166,10 +4166,10 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } else if (idx2 < 0 & idx2 != Form.SecondaryRailStub & idx2 != Form.SecondaryRailL & idx2 != Form.SecondaryRailR) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex2 is expected to be greater or equal to -2 in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx1 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx1].RailStart) { + if (idx1 >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx1].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex1 could be out of range in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } - if (idx2 != Form.SecondaryRailStub & idx2 != Form.SecondaryRailL & idx2 != Form.SecondaryRailR && (idx2 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx2].RailStart)) { + if (idx2 != Form.SecondaryRailStub & idx2 != Form.SecondaryRailL & idx2 != Form.SecondaryRailR && (idx2 >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx2].RailStart)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex2 could be out of range in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } int roof = 0, pf = 0; @@ -4187,12 +4187,12 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En if (pf < 0 | (!Data.Structure.FormL.ContainsKey(pf) & !Data.Structure.FormR.ContainsKey(pf))) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex " + pf + " references an object not loaded in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } - int n = Data.Blocks[BlockIndex].Form.Length; - Array.Resize
(ref Data.Blocks[BlockIndex].Form, n + 1); - Data.Blocks[BlockIndex].Form[n].PrimaryRail = idx1; - Data.Blocks[BlockIndex].Form[n].SecondaryRail = idx2; - Data.Blocks[BlockIndex].Form[n].FormType = pf; - Data.Blocks[BlockIndex].Form[n].RoofType = roof; + int n = Data.Blocks[BlockIndex].Forms.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Forms, n + 1); + Data.Blocks[BlockIndex].Forms[n].PrimaryRail = idx1; + Data.Blocks[BlockIndex].Forms[n].SecondaryRail = idx2; + Data.Blocks[BlockIndex].Forms[n].FormType = pf; + Data.Blocks[BlockIndex].Forms[n].RoofType = roof; } } } @@ -4208,7 +4208,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { + if (idx >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx +" could be out of range in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx >= Data.Blocks[BlockIndex].RailPole.Length) { @@ -4271,7 +4271,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En if (idx < 0 | idx >= Data.Blocks[BlockIndex].RailPole.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex " + idx + " does not reference an existing pole in Track.PoleEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx >= Data.Blocks[BlockIndex].Rail.Length || (!Data.Blocks[BlockIndex].Rail[idx].RailStart & !Data.Blocks[BlockIndex].Rail[idx].RailEnd)) { + if (idx >= Data.Blocks[BlockIndex].Rails.Length || (!Data.Blocks[BlockIndex].Rails[idx].RailStart & !Data.Blocks[BlockIndex].Rails[idx].RailEnd)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx + " could be out of range in Track.PoleEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } Data.Blocks[BlockIndex].RailPole[idx].Exists = false; @@ -4354,7 +4354,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En dir = -1; } } - if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { + if (idx >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx + " could be out of range in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx >= Data.Blocks[BlockIndex].RailWall.Length) { @@ -4378,7 +4378,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En if (idx < 0 | idx >= Data.Blocks[BlockIndex].RailWall.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex " + idx + " does not reference an existing wall in Track.WallEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx >= Data.Blocks[BlockIndex].Rail.Length || (!Data.Blocks[BlockIndex].Rail[idx].RailStart & !Data.Blocks[BlockIndex].Rail[idx].RailEnd)) { + if (idx >= Data.Blocks[BlockIndex].Rails.Length || (!Data.Blocks[BlockIndex].Rails[idx].RailStart & !Data.Blocks[BlockIndex].Rails[idx].RailEnd)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx + " could be out of range in Track.WallEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } Data.Blocks[BlockIndex].RailWall[idx].Exists = false; @@ -4462,7 +4462,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En dir = -1; } } - if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { + if (idx >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx + " could be out of range in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx >= Data.Blocks[BlockIndex].RailDike.Length) { @@ -4486,7 +4486,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En if (idx < 0 | idx >= Data.Blocks[BlockIndex].RailDike.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex " + idx +" does not reference an existing dike in Track.DikeEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx >= Data.Blocks[BlockIndex].Rail.Length || (!Data.Blocks[BlockIndex].Rail[idx].RailStart & !Data.Blocks[BlockIndex].Rail[idx].RailEnd)) { + if (idx >= Data.Blocks[BlockIndex].Rails.Length || (!Data.Blocks[BlockIndex].Rails[idx].RailStart & !Data.Blocks[BlockIndex].Rails[idx].RailEnd)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx + " could be out of range in Track.DikeEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } Data.Blocks[BlockIndex].RailDike[idx].Exists = false; @@ -4618,8 +4618,8 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "CycleIndex is invalid in Track.Ground at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); cytype = 0; } - if (cytype < Data.Structure.Cycle.Length && Data.Structure.Cycle[cytype] != null) { - Data.Blocks[BlockIndex].Cycle = Data.Structure.Cycle[cytype]; + if (cytype < Data.Structure.Cycles.Length && Data.Structure.Cycles[cytype] != null) { + Data.Blocks[BlockIndex].Cycle = Data.Structure.Cycles[cytype]; } else { if (!Data.Structure.Ground.ContainsKey(cytype)) { Interface.AddMessage(Interface.MessageType.Error, false, "CycleIndex " + cytype + " references an object not loaded in Track.Ground at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); @@ -4656,17 +4656,17 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } else if (idx1 == idx2) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex1 is expected to be unequal to Index2 in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx1 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx1].RailStart) { + if (idx1 >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx1].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex1 " + idx1 + " could be out of range in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } - if (idx2 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx2].RailStart) { + if (idx2 >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx2].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex2 " + idx2 + " could be out of range in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } - int n = Data.Blocks[BlockIndex].Crack.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Crack, n + 1); - Data.Blocks[BlockIndex].Crack[n].PrimaryRail = idx1; - Data.Blocks[BlockIndex].Crack[n].SecondaryRail = idx2; - Data.Blocks[BlockIndex].Crack[n].Type = sttype; + int n = Data.Blocks[BlockIndex].Cracks.Length; + Array.Resize(ref Data.Blocks[BlockIndex].Cracks, n + 1); + Data.Blocks[BlockIndex].Cracks[n].PrimaryRail = idx1; + Data.Blocks[BlockIndex].Cracks[n].SecondaryRail = idx2; + Data.Blocks[BlockIndex].Cracks[n].Type = sttype; } } } @@ -4688,7 +4688,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } else if (sttype < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FreeObjStructureIndex is expected to be non-negative in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { - if (idx >= 0 && (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart)) { + if (idx >= 0 && (idx >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx].RailStart)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex " + idx + " could be out of range in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (!Data.Structure.FreeObjects.ContainsKey(sttype)) { @@ -4828,13 +4828,13 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); speed = 0.0; } - int n = Data.Blocks[BlockIndex].Sound.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Sound, n + 1); - Data.Blocks[BlockIndex].Sound[n].TrackPosition = Data.TrackPosition; + int n = Data.Blocks[BlockIndex].SoundEvents.Length; + Array.Resize(ref Data.Blocks[BlockIndex].SoundEvents, n + 1); + Data.Blocks[BlockIndex].SoundEvents[n].TrackPosition = Data.TrackPosition; const double radius = 15.0; - Data.Blocks[BlockIndex].Sound[n].SoundBuffer = Sounds.RegisterBuffer(f, radius); - Data.Blocks[BlockIndex].Sound[n].Type = speed == 0.0 ? SoundType.TrainStatic : SoundType.TrainDynamic; - Data.Blocks[BlockIndex].Sound[n].Speed = speed * Data.UnitOfSpeed; + Data.Blocks[BlockIndex].SoundEvents[n].SoundBuffer = Sounds.RegisterBuffer(f, radius); + Data.Blocks[BlockIndex].SoundEvents[n].Type = speed == 0.0 ? SoundType.TrainStatic : SoundType.TrainDynamic; + Data.Blocks[BlockIndex].SoundEvents[n].Speed = speed * Data.UnitOfSpeed; } } } @@ -4862,15 +4862,15 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } - int n = Data.Blocks[BlockIndex].Sound.Length; - Array.Resize(ref Data.Blocks[BlockIndex].Sound, n + 1); - Data.Blocks[BlockIndex].Sound[n].TrackPosition = Data.TrackPosition; + int n = Data.Blocks[BlockIndex].SoundEvents.Length; + Array.Resize(ref Data.Blocks[BlockIndex].SoundEvents, n + 1); + Data.Blocks[BlockIndex].SoundEvents[n].TrackPosition = Data.TrackPosition; const double radius = 15.0; - Data.Blocks[BlockIndex].Sound[n].SoundBuffer = Sounds.RegisterBuffer(f, radius); - Data.Blocks[BlockIndex].Sound[n].Type = SoundType.World; - Data.Blocks[BlockIndex].Sound[n].X = x; - Data.Blocks[BlockIndex].Sound[n].Y = y; - Data.Blocks[BlockIndex].Sound[n].Radius = radius; + Data.Blocks[BlockIndex].SoundEvents[n].SoundBuffer = Sounds.RegisterBuffer(f, radius); + Data.Blocks[BlockIndex].SoundEvents[n].Type = SoundType.World; + Data.Blocks[BlockIndex].SoundEvents[n].X = x; + Data.Blocks[BlockIndex].SoundEvents[n].Y = y; + Data.Blocks[BlockIndex].SoundEvents[n].Radius = radius; } } } @@ -4910,7 +4910,7 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } - if (idx >= 0 && (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart)) { + if (idx >= 0 && (idx >= Data.Blocks[BlockIndex].Rails.Length || !Data.Blocks[BlockIndex].Rails[idx].RailStart)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex " + idx + " references a non-existing rail in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } double x = 0.0, y = 0.0; @@ -4959,24 +4959,6 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } } } - if (!PreviewOnly) { - // timetable - Timetable.CustomTextures = new Textures.Texture[Data.TimetableDaytime.Length + Data.TimetableNighttime.Length]; - int n = 0; - for (int i = 0; i < Data.TimetableDaytime.Length; i++) { - if (Data.TimetableDaytime[i] != null) { - Timetable.CustomTextures[n] = Data.TimetableDaytime[i]; - n++; - } - } - for (int i = 0; i < Data.TimetableNighttime.Length; i++) { - if (Data.TimetableNighttime[i] != null) { - Timetable.CustomTextures[n] = Data.TimetableNighttime[i]; - n++; - } - } - Array.Resize(ref Timetable.CustomTextures, n); - } // blocks Array.Resize(ref Data.Blocks, BlocksUsed); } diff --git a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Ats.cs b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Ats.cs index dcc1687e1..fae581756 100644 --- a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Ats.cs +++ b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Ats.cs @@ -7,7 +7,7 @@ internal static partial class SoundCfgParser /// Loads the default ATS plugin sound set /// The train /// The absolute on-disk path to the train's folder - internal static void LoadDefaultATSSounds(TrainManager.Train train, string trainFolder) + private static void LoadDefaultATSSounds(TrainManager.Train train, string trainFolder) { Vector3 position = new Vector3(train.Cars[train.DriverCar].Driver.X, train.Cars[train.DriverCar].Driver.Y, train.Cars[train.DriverCar].Driver.Z + 1.0); const double radius = 2.0; diff --git a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve2.cs b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve2.cs index f6428d9c4..1b21e65e2 100644 --- a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve2.cs +++ b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve2.cs @@ -1,4 +1,5 @@ -using OpenBveApi.Math; +using OpenBve.BrakeSystems; +using OpenBveApi.Math; namespace OpenBve { @@ -43,7 +44,7 @@ internal static void Parse(string trainFolder, TrainManager.Train train) train.Cars[i].Sounds.Air = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Air.wav"), center, SoundCfgParser.smallRadius); train.Cars[i].Sounds.AirHigh = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "AirHigh.wav"), center, SoundCfgParser.smallRadius); train.Cars[i].Sounds.AirZero = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "AirZero.wav"), center, SoundCfgParser.smallRadius); - if (train.Cars[i].Specs.AirBrake.Type == TrainManager.AirBrakeType.Main) + if (train.Cars[i].CarBrake.brakeType == BrakeType.Main) { train.Cars[i].Sounds.CpEnd = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpEnd.wav"), center, SoundCfgParser.mediumRadius); train.Cars[i].Sounds.CpLoop = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpLoop.wav"), center, SoundCfgParser.mediumRadius); diff --git a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve4.cs b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve4.cs index eab1b2db8..22e3417ba 100644 --- a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve4.cs +++ b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Bve4.cs @@ -1,4 +1,5 @@ using System; +using OpenBve.BrakeSystems; using OpenBveApi; using OpenBveApi.Math; @@ -304,7 +305,7 @@ internal static void Parse(string FileName, string trainFolder, System.Text.Enco { for (int c = 0; c < train.Cars.Length; c++) { - if (train.Cars[c].Specs.AirBrake.Type == TrainManager.AirBrakeType.Main) + if (train.Cars[c].CarBrake.brakeType == BrakeType.Main) { switch (a.ToLowerInvariant()) { diff --git a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Xml.cs b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Xml.cs index 0608df42d..a7be81d4a 100644 --- a/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Xml.cs +++ b/source/OpenBVE/Parsers/SoundConfiguration/SoundCfg.Xml.cs @@ -2,6 +2,7 @@ using System.Xml; using OpenBveApi.Math; using System.Linq; +using OpenBve.BrakeSystems; namespace OpenBve { @@ -13,7 +14,7 @@ internal static bool ParseTrain(string fileName, TrainManager.Train train) { try { - Parse(fileName, ref train.Cars[i]); + Parse(fileName, ref train.Cars[i], i == train.DriverCar); } catch { @@ -23,8 +24,8 @@ internal static bool ParseTrain(string fileName, TrainManager.Train train) return true; } - internal static string currentPath; - internal static void Parse(string fileName, ref TrainManager.Car car) + private static string currentPath; + internal static void Parse(string fileName, ref TrainManager.Car car, bool isDriverCar) { //3D center of the car Vector3 center = new Vector3(0.0, 0.0, 0.0); @@ -68,7 +69,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of plugin sounds was defined in in XML file " + fileName); break; } - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } @@ -116,7 +117,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of brake handle sounds was defined in in XML file " + fileName); break; } - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } @@ -150,7 +151,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of breaker sounds was defined in in XML file " + fileName); break; } - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } @@ -171,7 +172,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) } break; case "buzzer": - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } @@ -183,7 +184,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of compressor sounds was defined in in XML file " + fileName); break; } - if (car.Specs.AirBrake.Type != TrainManager.AirBrakeType.Main) + if (car.CarBrake.brakeType != BrakeType.Main) { break; } @@ -258,7 +259,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of horn sounds was defined in in XML file " + fileName); break; } - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } @@ -295,7 +296,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of power handle sounds was defined in in XML file " + fileName); break; } - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } @@ -338,7 +339,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of pilot-lamp sounds was defined in in XML file " + fileName); break; } - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } @@ -383,7 +384,7 @@ internal static void Parse(string fileName, ref TrainManager.Car car) Interface.AddMessage(Interface.MessageType.Error, false, "An empty list of reverser sounds was defined in in XML file " + fileName); break; } - if (!car.Specs.IsDriverCar) + if (!isDriverCar) { break; } diff --git a/source/OpenBVE/Parsers/Train/ExtensionsCfgParser.cs b/source/OpenBVE/Parsers/Train/ExtensionsCfgParser.cs index f93fb4e52..ba89740db 100644 --- a/source/OpenBVE/Parsers/Train/ExtensionsCfgParser.cs +++ b/source/OpenBVE/Parsers/Train/ExtensionsCfgParser.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using OpenBveApi; namespace OpenBve { @@ -400,6 +401,17 @@ internal static void ParseExtensionsConfig(string TrainPath, System.Text.Encodin else { // default + if (Lines.Length == 1 && Encoding.Equals(Encoding.Unicode)) + { + /* + * If only one line, there's a good possibility that our file is NOT Unicode at all + * and that the misdetection has turned it into garbage + * + * Try again with ASCII instead + */ + ParseExtensionsConfig(TrainPath, Encoding.GetEncoding(1252), ref CarObjects, ref BogieObjects, Train, LoadObjects); + return; + } Interface.AddMessage(Interface.MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName); } break; diff --git a/source/OpenBVE/Parsers/Train/TrainDatParser.cs b/source/OpenBVE/Parsers/Train/TrainDatParser.cs index e3b2d213a..3ff51e2f6 100644 --- a/source/OpenBVE/Parsers/Train/TrainDatParser.cs +++ b/source/OpenBVE/Parsers/Train/TrainDatParser.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Windows.Forms; +using OpenBve.BrakeSystems; using OpenBveApi.Math; namespace OpenBve { @@ -91,15 +92,14 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi } } // initialize - Train.Cars = new TrainManager.Car[] { }; - Train.Couplers = null; double BrakeCylinderServiceMaximumPressure = 440000.0; double BrakeCylinderEmergencyMaximumPressure = 440000.0; double MainReservoirMinimumPressure = 690000.0; double MainReservoirMaximumPressure = 780000.0; double BrakePipePressure = 0.0; - TrainManager.CarBrakeType BrakeType = TrainManager.CarBrakeType.ElectromagneticStraightAirBrake; - TrainManager.EletropneumaticBrakeType ElectropneumaticType = TrainManager.EletropneumaticBrakeType.None; + BrakeSystemType trainBrakeType = BrakeSystemType.ElectromagneticStraightAirBrake; + BrakeSystemType locomotiveBrakeType = BrakeSystemType.ElectromagneticStraightAirBrake; + EletropneumaticBrakeType ElectropneumaticType = EletropneumaticBrakeType.None; double BrakeControlSpeed = 0.0; double BrakeDeceleration = 0.277777777777778; double JerkPowerUp = 10.0; @@ -123,12 +123,9 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi double CarExposedFrontalArea = 0.6 * CarWidth * CarHeight; double CarUnexposedFrontalArea = 0.2 * CarWidth * CarHeight; bool FrontCarIsMotorCar = true; - int ReAdhesionDevice = 0; - Train.Specs.PassAlarm = TrainManager.PassAlarmType.None; - Train.Specs.DoorOpenMode = TrainManager.DoorMode.AutomaticManualOverride; - Train.Specs.DoorCloseMode = TrainManager.DoorMode.AutomaticManualOverride; + TrainManager.ReadhesionDeviceType ReAdhesionDevice = TrainManager.ReadhesionDeviceType.TypeA; + Train.Handles.EmergencyBrake = new TrainManager.EmergencyHandle(); - Train.Handles.AirBrake.Handle = new TrainManager.AirBrakeHandle(); Train.Handles.HasLocoBrake = false; double[] powerDelayUp = { }, powerDelayDown = { }, brakeDelayUp = { }, brakeDelayDown = { }, locoBrakeDelayUp = { }, locoBrakeDelayDown = { }; int powerNotches = 0, brakeNotches = 0, locoBrakeNotches = 0, powerReduceSteps = -1, locoBrakeType = 0; @@ -258,7 +255,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi case 0: if (currentFormat == TrainDatFormats.openBVE && myVersion >= 1534) { - powerDelayUp = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + powerDelayUp = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); } else { @@ -269,7 +266,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi case 1: if (currentFormat == TrainDatFormats.openBVE && myVersion >= 1534) { - powerDelayDown = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + powerDelayDown = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); } else { @@ -280,7 +277,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi case 2: if (currentFormat == TrainDatFormats.openBVE && myVersion >= 1534) { - brakeDelayUp = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + brakeDelayUp = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); } else { @@ -291,7 +288,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi case 3: if (currentFormat == TrainDatFormats.openBVE && myVersion >= 1534) { - brakeDelayDown = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + brakeDelayDown = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); } else { @@ -301,13 +298,21 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi case 4: if (currentFormat == TrainDatFormats.openBVE && myVersion >= 1534) { - Train.Handles.LocoBrake.DelayUp = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + locoBrakeDelayUp = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); + } + else + { + locoBrakeDelayUp = new[] {a}; } break; case 5: if (currentFormat == TrainDatFormats.openBVE && myVersion >= 1534) { - Train.Handles.LocoBrake.DelayDown = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + locoBrakeDelayDown = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); + } + else + { + locoBrakeDelayDown = new[] {a}; } break; } @@ -382,42 +387,65 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi } i--; break; case "#brake": i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) { - double a; if (NumberFormats.TryParseDoubleVb6(Lines[i], out a)) { - switch (n) { + double a; int b; if (NumberFormats.TryParseDoubleVb6(Lines[i], out a)) { + switch (n) + { case 0: + b = (int) Math.Round(a); + if (b >= 0 & b <= 2) { - int b = (int)Math.Round(a); - if (b >= 0 & b <= 2) { - BrakeType = (TrainManager.CarBrakeType)b; - } else { - Interface.AddMessage(Interface.MessageType.Error, false, "The setting for BrakeType is invalid at line " + (i + 1).ToString(Culture) + " in " + FileName); - BrakeType = TrainManager.CarBrakeType.ElectromagneticStraightAirBrake; - } - } break; + trainBrakeType = (BrakeSystemType) b; + } + else + { + Interface.AddMessage(Interface.MessageType.Error, false, "The setting for BrakeType is invalid at line " + (i + 1).ToString(Culture) + " in " + FileName); + trainBrakeType = BrakeSystemType.ElectromagneticStraightAirBrake; + } + break; case 1: + b = (int) Math.Round(a); + if (b >= 0 & b <= 2) { - int b = (int)Math.Round(a); - if (b >= 0 & b <= 2) { - ElectropneumaticType = (TrainManager.EletropneumaticBrakeType)b; - } else { - Interface.AddMessage(Interface.MessageType.Error, false, "The setting for ElectropneumaticType is invalid at line " + (i + 1).ToString(Culture) + " in " + FileName); - ElectropneumaticType = TrainManager.EletropneumaticBrakeType.None; - } - } break; - case 2: - if (a < 0) - { - Interface.AddMessage(Interface.MessageType.Error, false, "BrakeControlSpeed must be non-negative at line " + (i + 1).ToString(Culture) + " in " + FileName); + ElectropneumaticType = (EletropneumaticBrakeType) b; + } + else + { + Interface.AddMessage(Interface.MessageType.Error, false, "The setting for ElectropneumaticType is invalid at line " + (i + 1).ToString(Culture) + " in " + FileName); + ElectropneumaticType = EletropneumaticBrakeType.None; + } + break; + case 2: + if (a < 0) + { + Interface.AddMessage(Interface.MessageType.Error, false, "BrakeControlSpeed must be non-negative at line " + (i + 1).ToString(Culture) + " in " + FileName); + break; + } + if (a != 0 && trainBrakeType == BrakeSystemType.AutomaticAirBrake || ElectropneumaticType == EletropneumaticBrakeType.DelayFillingControl) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "BrakeControlSpeed will be ignored due to the current brake setup at line " + (i + 1).ToString(Culture) + " in " + FileName); + break; + } + BrakeControlSpeed = a * 0.277777777777778; //Convert to m/s + break; + case 3: + b = (int) Math.Round(a); + switch (b) + { + case 0: + //Not fitted break; - } - - if (a != 0 && BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake || ElectropneumaticType == TrainManager.EletropneumaticBrakeType.DelayFillingControl) - { - Interface.AddMessage(Interface.MessageType.Warning, false, "BrakeControlSpeed will be ignored due to the current brake setup at line " + (i + 1).ToString(Culture) + " in " + FileName); + case 1: + //Notched air brake + Train.Handles.HasLocoBrake = true; + locomotiveBrakeType = BrakeSystemType.ElectromagneticStraightAirBrake; break; - } - BrakeControlSpeed = a * 0.277777777777778; //Convert to m/s - break; + case 2: + //Automatic air brake + Train.Handles.HasLocoBrake = true; + locomotiveBrakeType = BrakeSystemType.AutomaticAirBrake; + break; + } + break; } } i++; n++; } i--; break; @@ -497,7 +525,6 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi Train.Handles.EmergencyBrake.OtherHandlesBehaviour = (TrainManager.EbHandleBehaviour) a; break; case 5: - Train.Handles.HasLocoBrake = true; if (a >= 0) { @@ -618,7 +645,17 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi case 4: Train.Handles.HasHoldBrake = a == 1.0; break; case 5: - ReAdhesionDevice = (int)Math.Round(a); break; + int dt = (int) Math.Round(a); + if (dt < 3 && dt > -1) + { + ReAdhesionDevice = (TrainManager.ReadhesionDeviceType)dt; + } + else + { + ReAdhesionDevice = TrainManager.ReadhesionDeviceType.NotFitted; + Interface.AddMessage(Interface.MessageType.Error, false, "ReAdhesionDeviceType is invalid at line " + (i + 1).ToString(Culture) + " in " + FileName); + } + break; case 7: { int b = (int)Math.Round(a); @@ -700,6 +737,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi } break; } } + if (TrailerCars > 0 & TrailerCarMass <= 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "TrailerCarMass is expected to be positive in " + FileName); TrailerCarMass = 1.0; @@ -715,14 +753,33 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi Interface.AddMessage(Interface.MessageType.Error, false, "NumberOfBrakeNotches was not set in " + FileName); brakeNotches = 8; } + Train.Handles.Reverser = new TrainManager.ReverserHandle(); Train.Handles.Power = new TrainManager.PowerHandle(powerNotches, powerDelayUp, powerDelayDown); if (powerReduceSteps != -1) { Train.Handles.Power.ReduceSteps = powerReduceSteps; } - Train.Handles.Brake = new TrainManager.BrakeHandle(brakeNotches, Train.Handles.EmergencyBrake, brakeDelayUp, brakeDelayDown); - Train.Handles.LocoBrake = new TrainManager.LocoBrakeHandle(locoBrakeNotches, Train.Handles.EmergencyBrake, locoBrakeDelayUp, locoBrakeDelayDown); - Train.Handles.LocoBrake.BrakeType = (TrainManager.LocoBrakeType) locoBrakeType; + + if (trainBrakeType == BrakeSystemType.AutomaticAirBrake) + { + Train.Handles.Brake = new TrainManager.AirBrakeHandle(); + } + else + { + Train.Handles.Brake = new TrainManager.BrakeHandle(brakeNotches, Train.Handles.EmergencyBrake, brakeDelayUp, brakeDelayDown); + + } + + if (locomotiveBrakeType == BrakeSystemType.AutomaticAirBrake) + { + Train.Handles.LocoBrake = new TrainManager.LocoAirBrakeHandle(); + } + else + { + Train.Handles.LocoBrake = new TrainManager.LocoBrakeHandle(locoBrakeNotches, Train.Handles.EmergencyBrake, locoBrakeDelayUp, locoBrakeDelayDown); + } + Train.Handles.LocoBrakeType = (TrainManager.LocoBrakeType)locoBrakeType; + // apply data if (MotorCars < 1) MotorCars = 1; if (TrailerCars < 0) TrailerCars = 0; @@ -735,19 +792,17 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi Train.Cars[i].RearBogie = new TrainManager.Bogie(Train, Train.Cars[i]); } double DistanceBetweenTheCars = 0.3; + if (DriverCar < 0 | DriverCar >= Cars) { Interface.AddMessage(Interface.MessageType.Error, false, "DriverCar must point to an existing car in " + FileName); DriverCar = 0; - Train.Cars[0].Specs.IsDriverCar = true; - } - else - { - Train.Cars[DriverCar].Specs.IsDriverCar = true; + } + Train.DriverCar = DriverCar; // brake system double OperatingPressure; if (BrakePipePressure <= 0.0) { - if (BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (trainBrakeType == BrakeSystemType.AutomaticAirBrake) { OperatingPressure = BrakeCylinderEmergencyMaximumPressure + 0.75 * (MainReservoirMinimumPressure - BrakeCylinderEmergencyMaximumPressure); if (OperatingPressure > MainReservoirMinimumPressure) { OperatingPressure = MainReservoirMinimumPressure; @@ -808,65 +863,116 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi MaximumAcceleration = AccelerationCurves[i].StageOneAcceleration; } } + // assign motor cars + if (MotorCars == 1) { + if (FrontCarIsMotorCar | TrailerCars == 0) { + Train.Cars[0].Specs.IsMotorCar = true; + } else { + Train.Cars[Cars - 1].Specs.IsMotorCar = true; + } + } else if (MotorCars == 2) { + if (FrontCarIsMotorCar | TrailerCars == 0) { + Train.Cars[0].Specs.IsMotorCar = true; + Train.Cars[Cars - 1].Specs.IsMotorCar = true; + } else if (TrailerCars == 1) { + Train.Cars[1].Specs.IsMotorCar = true; + Train.Cars[2].Specs.IsMotorCar = true; + } else { + int i = (int)Math.Ceiling(0.25 * (double)(Cars - 1)); + int j = (int)Math.Floor(0.75 * (double)(Cars - 1)); + Train.Cars[i].Specs.IsMotorCar = true; + Train.Cars[j].Specs.IsMotorCar = true; + } + } else if (MotorCars > 0) { + if (FrontCarIsMotorCar) { + Train.Cars[0].Specs.IsMotorCar = true; + double t = 1.0 + (double)TrailerCars / (double)(MotorCars - 1); + double r = 0.0; + double x = 0.0; + while (true) { + double y = x + t - r; + x = Math.Ceiling(y); + r = x - y; + int i = (int)x; + if (i >= Cars) break; + Train.Cars[i].Specs.IsMotorCar = true; + } + } else { + Train.Cars[1].Specs.IsMotorCar = true; + double t = 1.0 + (double)(TrailerCars - 1) / (double)(MotorCars - 1); + double r = 0.0; + double x = 1.0; + while (true) { + double y = x + t - r; + x = Math.Ceiling(y); + r = x - y; + int i = (int)x; + if (i >= Cars) break; + Train.Cars[i].Specs.IsMotorCar = true; + } + } + } double MotorDeceleration = Math.Sqrt(MaximumAcceleration * BrakeDeceleration); // apply brake-specific attributes for all cars for (int i = 0; i < Cars; i++) { - Train.Cars[i].Specs.BrakeType = BrakeType; - Train.Cars[i].Specs.ElectropneumaticType = ElectropneumaticType; - Train.Cars[i].Specs.BrakeControlSpeed = BrakeControlSpeed; - Train.Cars[i].Specs.DecelerationCurves = new TrainManager.AccelerationCurve[] + TrainManager.AccelerationCurve[] DecelerationCurves = new TrainManager.AccelerationCurve[] { new TrainManager.BveDecelerationCurve(BrakeDeceleration), }; Train.Cars[i].Specs.MotorDeceleration = MotorDeceleration; - Train.Cars[i].Specs.AirBrake.AirCompressorEnabled = false; - Train.Cars[i].Specs.AirBrake.AirCompressorMinimumPressure = MainReservoirMinimumPressure; - Train.Cars[i].Specs.AirBrake.AirCompressorMaximumPressure = MainReservoirMaximumPressure; - Train.Cars[i].Specs.AirBrake.AirCompressorRate = 5000.0; - Train.Cars[i].Specs.AirBrake.MainReservoirCurrentPressure = Train.Cars[i].Specs.AirBrake.AirCompressorMinimumPressure + (Train.Cars[i].Specs.AirBrake.AirCompressorMaximumPressure - Train.Cars[i].Specs.AirBrake.AirCompressorMinimumPressure) * Program.RandomNumberGenerator.NextDouble(); - Train.Cars[i].Specs.AirBrake.MainReservoirEqualizingReservoirCoefficient = 0.01; - Train.Cars[i].Specs.AirBrake.MainReservoirBrakePipeCoefficient = (BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake ? 0.25 : 0.075) / Cars; - Train.Cars[i].Specs.AirBrake.EqualizingReservoirCurrentPressure = 0.0; - Train.Cars[i].Specs.AirBrake.EqualizingReservoirNormalPressure = 1.005 * OperatingPressure; - /* - * These values are all constants, and are expressed in pascals per second - * Presumably, Michelle intended for them to be editable in v2.0 - */ - Train.Cars[i].Specs.AirBrake.EqualizingReservoirServiceRate = 50000.0; - Train.Cars[i].Specs.AirBrake.EqualizingReservoirEmergencyRate = 250000.0; - Train.Cars[i].Specs.AirBrake.EqualizingReservoirChargeRate = 200000.0; - Train.Cars[i].Specs.AirBrake.BrakePipeNormalPressure = OperatingPressure; - Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure = BrakeType == TrainManager.CarBrakeType.ElectricCommandBrake ? 0.0 : Train.Cars[i].Specs.AirBrake.BrakePipeNormalPressure; - Train.Cars[i].Specs.AirBrake.BrakePipeChargeRate = 10000000.0; - Train.Cars[i].Specs.AirBrake.BrakePipeServiceRate = 1500000.0; - Train.Cars[i].Specs.AirBrake.BrakePipeEmergencyRate = 5000000.0; - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirMaximumPressure = 0.975 * OperatingPressure; - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirCurrentPressure = Train.Cars[i].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirChargeRate = 200000.0; - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirBrakePipeCoefficient = 0.5; + if (i == Train.DriverCar && Train.Handles.HasLocoBrake) + { + switch (locomotiveBrakeType) + { + case BrakeSystemType.AutomaticAirBrake: + Train.Cars[i].CarBrake = new AutomaticAirBrake(ElectropneumaticType, Train.Handles.EmergencyBrake, Train.Handles.Reverser, Train.Cars[i].Specs.IsMotorCar, BrakeControlSpeed, MotorDeceleration, DecelerationCurves); + break; + case BrakeSystemType.ElectricCommandBrake: + Train.Cars[i].CarBrake = new ElectricCommandBrake(ElectropneumaticType, Train.Handles.EmergencyBrake, Train.Handles.Reverser, Train.Cars[i].Specs.IsMotorCar, BrakeControlSpeed, MotorDeceleration, DecelerationCurves); + break; + case BrakeSystemType.ElectromagneticStraightAirBrake: + Train.Cars[i].CarBrake = new ElectromagneticStraightAirBrake(ElectropneumaticType, Train.Handles.EmergencyBrake, Train.Handles.Reverser, Train.Cars[i].Specs.IsMotorCar, BrakeControlSpeed, MotorDeceleration, DecelerationCurves); + break; + } + } + else + { + switch (trainBrakeType) + { + case BrakeSystemType.AutomaticAirBrake: + Train.Cars[i].CarBrake = new AutomaticAirBrake(ElectropneumaticType, Train.Handles.EmergencyBrake, Train.Handles.Reverser, Train.Cars[i].Specs.IsMotorCar, BrakeControlSpeed, MotorDeceleration, DecelerationCurves); + break; + case BrakeSystemType.ElectricCommandBrake: + Train.Cars[i].CarBrake = new ElectricCommandBrake(ElectropneumaticType, Train.Handles.EmergencyBrake, Train.Handles.Reverser, Train.Cars[i].Specs.IsMotorCar, BrakeControlSpeed, MotorDeceleration, DecelerationCurves); + break; + case BrakeSystemType.ElectromagneticStraightAirBrake: + Train.Cars[i].CarBrake = new ElectromagneticStraightAirBrake(ElectropneumaticType, Train.Handles.EmergencyBrake, Train.Handles.Reverser, Train.Cars[i].Specs.IsMotorCar, BrakeControlSpeed, MotorDeceleration, DecelerationCurves); + break; + } + } + + if (Train.Cars[i].Specs.IsMotorCar || Train == TrainManager.PlayerTrain && i == Train.DriverCar || trainBrakeType == BrakeSystemType.ElectricCommandBrake) + { + Train.Cars[i].CarBrake.brakeType = BrakeType.Main; + } + else + { + Train.Cars[i].CarBrake.brakeType = BrakeType.Auxiliary; + } + Train.Cars[i].CarBrake.airCompressor = new Compressor(5000.0); + Train.Cars[i].CarBrake.mainReservoir = new MainReservoir(MainReservoirMinimumPressure, MainReservoirMaximumPressure, 0.01, (trainBrakeType == BrakeSystemType.AutomaticAirBrake ? 0.25 : 0.075) / Cars); + Train.Cars[i].CarBrake.equalizingReservoir = new EqualizingReservoir(50000.0, 250000.0, 200000.0); + Train.Cars[i].CarBrake.equalizingReservoir.NormalPressure = 1.005 * OperatingPressure; + + Train.Cars[i].CarBrake.brakePipe = new BrakePipe(OperatingPressure, 10000000.0, 1500000.0, 5000000.0, trainBrakeType == BrakeSystemType.ElectricCommandBrake); { - double r = Train.Cars[i].Specs.AirBrake.AuxillaryReservoirMaximumPressure / BrakeCylinderEmergencyMaximumPressure - 1.0; + double r = 200000.0 / BrakeCylinderEmergencyMaximumPressure - 1.0; if (r < 0.1) r = 0.1; if (r > 1.0) r = 1.0; - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirBrakeCylinderCoefficient = r; + Train.Cars[i].CarBrake.auxiliaryReservoir = new AuxiliaryReservoir(0.975 * OperatingPressure, 200000.0, 0.5, r); } - Train.Cars[i].Specs.AirBrake.BrakeCylinderCurrentPressure = BrakeCylinderEmergencyMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakeCylinderServiceMaximumPressure = BrakeCylinderServiceMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure = BrakeCylinderEmergencyMaximumPressure; - if (BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { - Train.Cars[i].Specs.AirBrake.BrakeCylinderServiceChargeRate = BrakeCylinderUp; - Train.Cars[i].Specs.AirBrake.BrakeCylinderEmergencyChargeRate = BrakeCylinderUp; - Train.Cars[i].Specs.AirBrake.BrakeCylinderReleaseRate = BrakeCylinderDown; - } else { - Train.Cars[i].Specs.AirBrake.BrakeCylinderServiceChargeRate = 0.3 * BrakeCylinderUp; - Train.Cars[i].Specs.AirBrake.BrakeCylinderEmergencyChargeRate = BrakeCylinderUp; - Train.Cars[i].Specs.AirBrake.BrakeCylinderReleaseRate = BrakeCylinderDown; - } - Train.Cars[i].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = BrakeCylinderEmergencyMaximumPressure; - Train.Cars[i].Specs.AirBrake.StraightAirPipeCurrentPressure = 0.0; - Train.Cars[i].Specs.AirBrake.StraightAirPipeReleaseRate = 200000.0; - Train.Cars[i].Specs.AirBrake.StraightAirPipeServiceRate = 300000.0; - Train.Cars[i].Specs.AirBrake.StraightAirPipeEmergencyRate = 400000.0; + Train.Cars[i].CarBrake.brakeCylinder = new BrakeCylinder(BrakeCylinderServiceMaximumPressure, BrakeCylinderEmergencyMaximumPressure, trainBrakeType == BrakeSystemType.AutomaticAirBrake ? BrakeCylinderUp : 0.3 * BrakeCylinderUp, BrakeCylinderUp, BrakeCylinderDown); + Train.Cars[i].CarBrake.straightAirPipe = new StraightAirPipe(300000.0, 400000.0, 200000.0); } if (Train.Handles.HasHoldBrake & Train.Handles.Brake.MaximumNotch > 1) { Train.Handles.Brake.MaximumNotch--; @@ -881,67 +987,91 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi Train.Handles.Brake.Driver = 0; Train.Handles.Brake.Safety = 0; Train.Handles.Brake.Actual = 0; - Train.Handles.Brake.DelayedChanges = new TrainManager.HandleChange[] { }; Train.Handles.EmergencyBrake.ApplicationTime = double.MaxValue; - if (BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (trainBrakeType == BrakeSystemType.AutomaticAirBrake) { Train.Handles.SingleHandle = false; Train.Handles.HasHoldBrake = false; } - // starting mode - if (Game.TrainStart == Game.TrainStartMode.ServiceBrakesAts) { - for (int i = 0; i < Cars; i++) { - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirCurrentPressure = Train.Cars[i].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakeCylinderCurrentPressure = Train.Cars[i].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure = Train.Cars[i].Specs.AirBrake.BrakePipeNormalPressure; - Train.Cars[i].Specs.AirBrake.StraightAirPipeCurrentPressure = Train.Cars[i].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - Train.Cars[i].Specs.AirBrake.EqualizingReservoirCurrentPressure = Train.Cars[i].Specs.AirBrake.EqualizingReservoirNormalPressure; - } - Train.Handles.AirBrake.Handle.Driver = TrainManager.AirBrakeHandleState.Service; - Train.Handles.AirBrake.Handle.Safety = TrainManager.AirBrakeHandleState.Service; - Train.Handles.AirBrake.Handle.Actual = TrainManager.AirBrakeHandleState.Service; - int notch = (int)Math.Round(0.7 * Train.Handles.Brake.MaximumNotch); - Train.Handles.Brake.Driver = notch; - Train.Handles.Brake.Safety = notch; - Train.Handles.Brake.Actual = notch; - Train.Handles.EmergencyBrake.Driver = false; - Train.Handles.EmergencyBrake.Safety = false; - Train.Handles.EmergencyBrake.Actual = false; - Train.Handles.Reverser.Driver = TrainManager.ReverserPosition.Forwards; - Train.Handles.Reverser.Actual = TrainManager.ReverserPosition.Forwards; - } else if (Game.TrainStart == Game.TrainStartMode.EmergencyBrakesAts) { - for (int i = 0; i < Cars; i++) { - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirCurrentPressure = Train.Cars[i].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakeCylinderCurrentPressure = Train.Cars[i].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure = 0.0; - Train.Cars[i].Specs.AirBrake.StraightAirPipeCurrentPressure = 0.0; - Train.Cars[i].Specs.AirBrake.EqualizingReservoirCurrentPressure = 0.0; - } - Train.Handles.AirBrake.Handle.Driver = TrainManager.AirBrakeHandleState.Service; - Train.Handles.AirBrake.Handle.Safety = TrainManager.AirBrakeHandleState.Service; - Train.Handles.AirBrake.Handle.Actual = TrainManager.AirBrakeHandleState.Service; - Train.Handles.Brake.Driver = Train.Handles.Brake.MaximumNotch; - Train.Handles.Brake.Safety = Train.Handles.Brake.MaximumNotch; - Train.Handles.Brake.Actual = Train.Handles.Brake.MaximumNotch; - Train.Handles.EmergencyBrake.Driver = true; - Train.Handles.EmergencyBrake.Safety = true; - Train.Handles.EmergencyBrake.Actual = true; - } else { - for (int i = 0; i < Cars; i++) { - Train.Cars[i].Specs.AirBrake.AuxillaryReservoirCurrentPressure = Train.Cars[i].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakeCylinderCurrentPressure = Train.Cars[i].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure = 0.0; - Train.Cars[i].Specs.AirBrake.StraightAirPipeCurrentPressure = 0.0; - Train.Cars[i].Specs.AirBrake.EqualizingReservoirCurrentPressure = 0.0; - } - Train.Handles.AirBrake.Handle.Driver = TrainManager.AirBrakeHandleState.Service; - Train.Handles.AirBrake.Handle.Safety = TrainManager.AirBrakeHandleState.Service; - Train.Handles.AirBrake.Handle.Actual = TrainManager.AirBrakeHandleState.Service; - Train.Handles.Brake.Driver = Train.Handles.Brake.MaximumNotch; - Train.Handles.Brake.Safety = Train.Handles.Brake.MaximumNotch; - Train.Handles.Brake.Actual = Train.Handles.Brake.MaximumNotch; - Train.Handles.EmergencyBrake.Driver = true; - Train.Handles.EmergencyBrake.Safety = true; - Train.Handles.EmergencyBrake.Actual = true; + + switch (Game.TrainStart) + { + // starting mode + case Game.TrainStartMode.ServiceBrakesAts: + for (int i = 0; i < Cars; i++) { + Train.Cars[i].CarBrake.brakeCylinder.CurrentPressure = Train.Cars[i].CarBrake.brakeCylinder.ServiceMaximumPressure; + Train.Cars[i].CarBrake.brakePipe.CurrentPressure = Train.Cars[i].CarBrake.brakePipe.NormalPressure; + Train.Cars[i].CarBrake.straightAirPipe.CurrentPressure = Train.Cars[i].CarBrake.brakeCylinder.ServiceMaximumPressure; + Train.Cars[i].CarBrake.equalizingReservoir.CurrentPressure = Train.Cars[i].CarBrake.equalizingReservoir.NormalPressure; + } + + if (trainBrakeType == BrakeSystemType.AutomaticAirBrake) + { + Train.Handles.Brake.Driver = (int)TrainManager.AirBrakeHandleState.Service; + Train.Handles.Brake.Safety = (int)TrainManager.AirBrakeHandleState.Service; + Train.Handles.Brake.Actual = (int)TrainManager.AirBrakeHandleState.Service; + } + else + { + int notch = (int)Math.Round(0.7 * Train.Handles.Brake.MaximumNotch); + Train.Handles.Brake.Driver = notch; + Train.Handles.Brake.Safety = notch; + Train.Handles.Brake.Actual = notch; + } + Train.Handles.EmergencyBrake.Driver = false; + Train.Handles.EmergencyBrake.Safety = false; + Train.Handles.EmergencyBrake.Actual = false; + Train.Handles.Reverser.Driver = TrainManager.ReverserPosition.Forwards; + Train.Handles.Reverser.Actual = TrainManager.ReverserPosition.Forwards; + break; + case Game.TrainStartMode.EmergencyBrakesAts: + for (int i = 0; i < Cars; i++) { + Train.Cars[i].CarBrake.brakeCylinder.CurrentPressure = Train.Cars[i].CarBrake.brakeCylinder.EmergencyMaximumPressure; + Train.Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0; + Train.Cars[i].CarBrake.straightAirPipe.CurrentPressure = 0.0; + Train.Cars[i].CarBrake.equalizingReservoir.CurrentPressure = 0.0; + } + + if (trainBrakeType == BrakeSystemType.AutomaticAirBrake) + { + Train.Handles.Brake.Driver = (int)TrainManager.AirBrakeHandleState.Service; + Train.Handles.Brake.Safety = (int)TrainManager.AirBrakeHandleState.Service; + Train.Handles.Brake.Actual = (int)TrainManager.AirBrakeHandleState.Service; + } + else + { + Train.Handles.Brake.Driver = Train.Handles.Brake.MaximumNotch; + Train.Handles.Brake.Safety = Train.Handles.Brake.MaximumNotch; + Train.Handles.Brake.Actual = Train.Handles.Brake.MaximumNotch; + } + + Train.Handles.EmergencyBrake.Driver = true; + Train.Handles.EmergencyBrake.Safety = true; + Train.Handles.EmergencyBrake.Actual = true; + break; + default: + for (int i = 0; i < Cars; i++) { + Train.Cars[i].CarBrake.brakeCylinder.CurrentPressure = Train.Cars[i].CarBrake.brakeCylinder.EmergencyMaximumPressure; + Train.Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0; + Train.Cars[i].CarBrake.straightAirPipe.CurrentPressure = 0.0; + Train.Cars[i].CarBrake.equalizingReservoir.CurrentPressure = 0.0; + } + + if (trainBrakeType == BrakeSystemType.AutomaticAirBrake) + { + Train.Handles.Brake.Driver = (int)TrainManager.AirBrakeHandleState.Service; + Train.Handles.Brake.Safety = (int)TrainManager.AirBrakeHandleState.Service; + Train.Handles.Brake.Actual = (int)TrainManager.AirBrakeHandleState.Service; + } + else + { + Train.Handles.Brake.Driver = Train.Handles.Brake.MaximumNotch; + Train.Handles.Brake.Safety = Train.Handles.Brake.MaximumNotch; + Train.Handles.Brake.Actual = Train.Handles.Brake.MaximumNotch; + } + Train.Handles.EmergencyBrake.Driver = true; + Train.Handles.EmergencyBrake.Safety = true; + Train.Handles.EmergencyBrake.Actual = true; + break; } // apply other attributes for all cars double AxleDistance = 0.4 * CarLength; @@ -958,7 +1088,6 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi Train.Cars[i].RearAxle.Follower.CarIndex = i; Train.Cars[i].FrontAxle.Position = AxleDistance; Train.Cars[i].RearAxle.Position = -AxleDistance; - Train.Cars[i].Specs.IsMotorCar = false; Train.Cars[i].Specs.JerkPowerUp = JerkPowerUp; Train.Cars[i].Specs.JerkPowerDown = JerkPowerDown; Train.Cars[i].Specs.JerkBrakeUp = JerkBrakeUp; @@ -981,63 +1110,15 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi Train.Cars[i].Length = CarLength; Train.Cars[i].Specs.CriticalTopplingAngle = 0.5 * Math.PI - Math.Atan(2 * Train.Cars[i].Specs.CenterOfGravityHeight / Train.Cars[i].Width); } - // assign motor cars - if (MotorCars == 1) { - if (FrontCarIsMotorCar | TrailerCars == 0) { - Train.Cars[0].Specs.IsMotorCar = true; - } else { - Train.Cars[Cars - 1].Specs.IsMotorCar = true; - } - } else if (MotorCars == 2) { - if (FrontCarIsMotorCar | TrailerCars == 0) { - Train.Cars[0].Specs.IsMotorCar = true; - Train.Cars[Cars - 1].Specs.IsMotorCar = true; - } else if (TrailerCars == 1) { - Train.Cars[1].Specs.IsMotorCar = true; - Train.Cars[2].Specs.IsMotorCar = true; - } else { - int i = (int)Math.Ceiling(0.25 * (double)(Cars - 1)); - int j = (int)Math.Floor(0.75 * (double)(Cars - 1)); - Train.Cars[i].Specs.IsMotorCar = true; - Train.Cars[j].Specs.IsMotorCar = true; - } - } else if (MotorCars > 0) { - if (FrontCarIsMotorCar) { - Train.Cars[0].Specs.IsMotorCar = true; - double t = 1.0 + (double)TrailerCars / (double)(MotorCars - 1); - double r = 0.0; - double x = 0.0; - while (true) { - double y = x + t - r; - x = Math.Ceiling(y); - r = x - y; - int i = (int)x; - if (i >= Cars) break; - Train.Cars[i].Specs.IsMotorCar = true; - } - } else { - Train.Cars[1].Specs.IsMotorCar = true; - double t = 1.0 + (double)(TrailerCars - 1) / (double)(MotorCars - 1); - double r = 0.0; - double x = 1.0; - while (true) { - double y = x + t - r; - x = Math.Ceiling(y); - r = x - y; - int i = (int)x; - if (i >= Cars) break; - Train.Cars[i].Specs.IsMotorCar = true; - } - } - } + + Train.Specs.ReadhesionDeviceType = ReAdhesionDevice; // assign motor/trailer-specific settings for (int i = 0; i < Cars; i++) { - Train.Cars[i].Specs.ReAdhesionDevice = new TrainManager.CarReAdhesionDevice(Train.Cars[i]); Train.Cars[i].Specs.ConstSpeed = new TrainManager.CarConstSpeed(Train.Cars[i]); Train.Cars[i].Specs.HoldBrake = new TrainManager.CarHoldBrake(Train.Cars[i]); + Train.Cars[i].Specs.ReAdhesionDevice = new TrainManager.CarReAdhesionDevice(Train.Cars[i]); if (Train.Cars[i].Specs.IsMotorCar) { // motor car - Train.Cars[i].Specs.AirBrake.Type = TrainManager.AirBrakeType.Main; Train.Cars[i].Specs.MassEmpty = MotorCarMass; Train.Cars[i].Specs.MassCurrent = MotorCarMass; Array.Resize(ref Train.Cars[i].Specs.AccelerationCurves, AccelerationCurves.Length); @@ -1047,31 +1128,31 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi } Train.Cars[i].Specs.AccelerationCurveMaximum = MaximumAcceleration; switch (ReAdhesionDevice) { - case 0: // type a: + case TrainManager.ReadhesionDeviceType.TypeA: Train.Cars[i].Specs.ReAdhesionDevice.UpdateInterval = 1.0; Train.Cars[i].Specs.ReAdhesionDevice.ApplicationFactor = 0.0; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseInterval = 1.0; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseFactor = 8.0; break; - case 1: // type b: + case TrainManager.ReadhesionDeviceType.TypeB: Train.Cars[i].Specs.ReAdhesionDevice.UpdateInterval = 0.1; Train.Cars[i].Specs.ReAdhesionDevice.ApplicationFactor = 0.9935; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseInterval = 4.0; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseFactor = 1.125; break; - case 2: // type c: + case TrainManager.ReadhesionDeviceType.TypeC: Train.Cars[i].Specs.ReAdhesionDevice.UpdateInterval = 0.1; Train.Cars[i].Specs.ReAdhesionDevice.ApplicationFactor = 0.965; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseInterval = 2.0; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseFactor = 1.5; break; - case 3: // type d: + case TrainManager.ReadhesionDeviceType.TypeD: Train.Cars[i].Specs.ReAdhesionDevice.UpdateInterval = 0.05; Train.Cars[i].Specs.ReAdhesionDevice.ApplicationFactor = 0.935; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseInterval = 0.3; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseFactor = 2.0; break; - default: // no readhesion device + default: Train.Cars[i].Specs.ReAdhesionDevice.UpdateInterval = 1.0; Train.Cars[i].Specs.ReAdhesionDevice.ApplicationFactor = 1.0; Train.Cars[i].Specs.ReAdhesionDevice.ReleaseInterval = 1.0; @@ -1089,7 +1170,6 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi } } else { // trailer car - Train.Cars[i].Specs.AirBrake.Type = Train == TrainManager.PlayerTrain & i == Train.DriverCar | BrakeType == TrainManager.CarBrakeType.ElectricCommandBrake ? TrainManager.AirBrakeType.Main : TrainManager.AirBrakeType.Auxillary; Train.Cars[i].Specs.MassEmpty = TrailerCarMass; Train.Cars[i].Specs.MassCurrent = TrailerCarMass; Train.Cars[i].Specs.AccelerationCurves = new TrainManager.AccelerationCurve[] { }; @@ -1102,7 +1182,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi } } // driver - Train.DriverCar = DriverCar; + Train.Cars[Train.DriverCar].Driver.X = Driver.X; Train.Cars[Train.DriverCar].Driver.Y = Driver.Y; Train.Cars[Train.DriverCar].Driver.Z = 0.5 * CarLength + Driver.Z; @@ -1117,10 +1197,7 @@ internal static void ParseTrainData(string FileName, System.Text.Encoding Encodi Train.Couplers[i].MaximumDistanceBetweenCars = 1.1 * DistanceBetweenTheCars; } // finish - Train.Station = -1; - Train.RouteLimits = new double[] { double.PositiveInfinity }; - Train.CurrentRouteLimit = double.PositiveInfinity; - Train.CurrentSectionLimit = double.PositiveInfinity; + } } diff --git a/source/OpenBVE/Parsers/Train/XML/TrainXmlParser.BrakeNode.cs b/source/OpenBVE/Parsers/Train/XML/TrainXmlParser.BrakeNode.cs new file mode 100644 index 000000000..0e51da9f2 --- /dev/null +++ b/source/OpenBVE/Parsers/Train/XML/TrainXmlParser.BrakeNode.cs @@ -0,0 +1,245 @@ +using System.Linq; +using System.Xml; +using OpenBveApi.Math; +using OpenBve.BrakeSystems; + +namespace OpenBve.Parsers.Train +{ + partial class TrainXmlParser + { + private static void ParseBrakeNode(XmlNode Node, string fileName, int Car, ref TrainManager.Train Train) + { + double compressorRate = 5000.0, compressorMinimumPressure = 690000.0, compressorMaximumPressure = 780000.0; + double auxiliaryReservoirChargeRate = 200000.0; + double equalizingReservoirChargeRate = 200000.0, equalizingReservoirServiceRate = 50000.0, equalizingReservoirEmergencyRate = 250000.0; + double brakePipeNormalPressure = 0.0, brakePipeChargeRate = 10000000.0, brakePipeServiceRate = 1500000.0, brakePipeEmergencyRate = 5000000.0; + double straightAirPipeServiceRate = 300000.0, straightAirPipeEmergencyRate = 400000.0, straightAirPipeReleaseRate = 200000.0; + double brakeCylinderServiceMaximumPressure = 440000.0, brakeCylinderEmergencyMaximumPressure = 440000.0, brakeCylinderEmergencyRate = 300000.0, brakeCylinderReleaseRate = 200000.0; + foreach (XmlNode c in Node.ChildNodes) + { + //Note: Don't use the short-circuiting operator, as otherwise we need another if + switch (c.Name.ToLowerInvariant()) + { + case "compressor": + Train.Cars[Car].CarBrake.brakeType = BrakeType.Main; //We have a compressor so must be a main brake type + if (c.ChildNodes.OfType().Any()) + { + foreach (XmlNode cc in c.ChildNodes) + { + switch (cc.Name.ToLowerInvariant()) + { + case "rate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out compressorRate) | compressorRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid compression rate defined for Car " + Car + " in XML file " + fileName); + compressorRate = 5000.0; + } + break; + } + } + } + break; + case "mainreservoir": + if (c.ChildNodes.OfType().Any()) + { + foreach (XmlNode cc in c.ChildNodes) + { + switch (cc.Name.ToLowerInvariant()) + { + case "minimumpressure": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out compressorMinimumPressure) | compressorMinimumPressure <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid main reservoir minumum pressure defined for Car " + Car + " in XML file " + fileName); + compressorMinimumPressure = 690000.0; + } + break; + case "maximumpressure": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out compressorMaximumPressure) | compressorMaximumPressure <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid main reservoir maximum pressure defined for Car " + Car + " in XML file " + fileName); + compressorMaximumPressure = 780000.0; + } + break; + } + } + } + break; + case "auxiliaryreservoir": + if (c.ChildNodes.OfType().Any()) + { + foreach (XmlNode cc in c.ChildNodes) + { + switch (cc.Name.ToLowerInvariant()) + { + case "chargerate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out auxiliaryReservoirChargeRate) | auxiliaryReservoirChargeRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid auxiliary reservoir charge rate defined for Car " + Car + " in XML file " + fileName); + auxiliaryReservoirChargeRate = 200000.0; + } + break; + } + } + } + break; + case "equalizingreservoir": + if (c.ChildNodes.OfType().Any()) + { + foreach (XmlNode cc in c.ChildNodes) + { + switch (cc.Name.ToLowerInvariant()) + { + case "chargerate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out equalizingReservoirChargeRate) | equalizingReservoirChargeRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid equalizing reservoir charge rate defined for Car " + Car + " in XML file " + fileName); + equalizingReservoirChargeRate = 50000.0; + } + break; + case "servicerate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out equalizingReservoirServiceRate) | equalizingReservoirServiceRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid equalizing reservoir service rate defined for Car " + Car + " in XML file " + fileName); + equalizingReservoirServiceRate = 50000.0; + } + break; + case "emergencyrate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out equalizingReservoirEmergencyRate) | equalizingReservoirEmergencyRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid equalizing reservoir emergency rate defined for Car " + Car + " in XML file " + fileName); + equalizingReservoirEmergencyRate = 50000.0; + } + break; + } + } + } + break; + case "brakepipe": + if (c.ChildNodes.OfType().Any()) + { + foreach (XmlNode cc in c.ChildNodes) + { + switch (cc.Name.ToLowerInvariant()) + { + case "normalpressure": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakePipeNormalPressure) | brakePipeNormalPressure <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake pipe normal pressure defined for Car " + Car + " in XML file " + fileName); + brakePipeNormalPressure = 0.0; + } + break; + case "chargerate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakePipeChargeRate) | brakePipeChargeRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake pipe charge rate defined for Car " + Car + " in XML file " + fileName); + brakePipeChargeRate = 10000000.0; + } + break; + case "servicerate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakePipeServiceRate) | brakePipeServiceRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake pipe service rate defined for Car " + Car + " in XML file " + fileName); + brakePipeServiceRate = 1500000.0; + } + break; + case "emergencyrate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakePipeEmergencyRate) | brakePipeEmergencyRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake pipe emergency rate defined for Car " + Car + " in XML file " + fileName); + brakePipeEmergencyRate = 400000.0; + } + break; + } + } + } + break; + case "straightairpipe": + if (c.ChildNodes.OfType().Any()) + { + foreach (XmlNode cc in c.ChildNodes) + { + switch (cc.Name.ToLowerInvariant()) + { + case "servicerate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out straightAirPipeServiceRate) | straightAirPipeServiceRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid straight air pipe service rate defined for Car " + Car + " in XML file " + fileName); + straightAirPipeServiceRate = 300000.0; + } + break; + case "emergencyrate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out straightAirPipeEmergencyRate) | straightAirPipeEmergencyRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid straight air pipe emergency rate defined for Car " + Car + " in XML file " + fileName); + straightAirPipeEmergencyRate = 400000.0; + } + break; + case "releaserate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out straightAirPipeReleaseRate) | straightAirPipeReleaseRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid straight air pipe emergency rate defined for Car " + Car + " in XML file " + fileName); + straightAirPipeReleaseRate = 200000.0; + } + break; + } + } + } + break; + case "brakecylinder": + if (c.ChildNodes.OfType().Any()) + { + foreach (XmlNode cc in c.ChildNodes) + { + switch (cc.Name.ToLowerInvariant()) + { + case "servicemaximumpressure": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakeCylinderServiceMaximumPressure) | brakeCylinderServiceMaximumPressure <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake cylinder service pressure defined for Car " + Car + " in XML file " + fileName); + brakeCylinderServiceMaximumPressure = 440000.0; + } + break; + case "emergencymaximumpressure": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakeCylinderEmergencyMaximumPressure) | brakeCylinderEmergencyMaximumPressure <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake cylinder emergency pressure defined for Car " + Car + " in XML file " + fileName); + brakeCylinderEmergencyMaximumPressure = 440000.0; + } + break; + case "emergencyrate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakeCylinderEmergencyRate) | brakeCylinderEmergencyRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake cylinder emergency pressure defined for Car " + Car + " in XML file " + fileName); + brakeCylinderEmergencyRate = 300000.0; + } + break; + case "releaserate": + if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out brakeCylinderReleaseRate) | brakeCylinderReleaseRate <= 0.0) + { + Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid brake cylinder emergency pressure defined for Car " + Car + " in XML file " + fileName); + brakeCylinderReleaseRate = 200000.0; + } + break; + } + } + } + break; + } + } + Train.Cars[Car].CarBrake.airCompressor = new Compressor(compressorRate); + Train.Cars[Car].CarBrake.mainReservoir = new MainReservoir(compressorMinimumPressure, compressorMaximumPressure, 0.01, (Train.Handles.Brake is TrainManager.AirBrakeHandle ? 0.25 : 0.075) / Train.Cars.Length); + Train.Cars[Car].CarBrake.equalizingReservoir = new EqualizingReservoir(equalizingReservoirServiceRate, equalizingReservoirEmergencyRate, equalizingReservoirChargeRate); + Train.Cars[Car].CarBrake.equalizingReservoir.NormalPressure = 1.005 * brakePipeNormalPressure; + + Train.Cars[Car].CarBrake.brakePipe = new BrakePipe(brakePipeNormalPressure, brakePipeChargeRate, brakePipeServiceRate, brakePipeEmergencyRate, Train.Cars[0].CarBrake is ElectricCommandBrake); + { + double r = 200000.0 / brakeCylinderEmergencyMaximumPressure - 1.0; + if (r < 0.1) r = 0.1; + if (r > 1.0) r = 1.0; + Train.Cars[Car].CarBrake.auxiliaryReservoir = new AuxiliaryReservoir(0.975 * brakePipeNormalPressure, auxiliaryReservoirChargeRate, 0.5, r); + } + Train.Cars[Car].CarBrake.brakeCylinder = new BrakeCylinder(brakeCylinderServiceMaximumPressure, brakeCylinderEmergencyMaximumPressure, Train.Handles.Brake is TrainManager.AirBrakeHandle ? brakeCylinderEmergencyRate : 0.3 * brakeCylinderEmergencyRate, brakeCylinderEmergencyRate, brakeCylinderReleaseRate); + Train.Cars[Car].CarBrake.straightAirPipe = new StraightAirPipe(straightAirPipeServiceRate, straightAirPipeEmergencyRate, straightAirPipeReleaseRate); + } + } +} diff --git a/source/OpenBVE/Parsers/Train/TrainXmlParser.CarNode.cs b/source/OpenBVE/Parsers/Train/XML/TrainXmlParser.CarNode.cs similarity index 71% rename from source/OpenBVE/Parsers/Train/TrainXmlParser.CarNode.cs rename to source/OpenBVE/Parsers/Train/XML/TrainXmlParser.CarNode.cs index e4310ed15..49fa7867e 100644 --- a/source/OpenBVE/Parsers/Train/TrainXmlParser.CarNode.cs +++ b/source/OpenBVE/Parsers/Train/XML/TrainXmlParser.CarNode.cs @@ -1,12 +1,12 @@ using System.Xml; using OpenBveApi.Math; using System.Linq; +using System; +using System.Text; +using OpenBve.BrakeSystems; namespace OpenBve.Parsers.Train { - using System; - using System.Text; - partial class TrainXmlParser { private static void ParseCarNode(XmlNode Node, string fileName, int Car, ref TrainManager.Train Train, ref ObjectManager.UnifiedObject[] CarObjects, ref ObjectManager.UnifiedObject[] BogieObjects) @@ -18,6 +18,32 @@ private static void ParseCarNode(XmlNode Node, string fileName, int Car, ref Tra //Note: Don't use the short-circuiting operator, as otherwise we need another if switch (c.Name.ToLowerInvariant()) { + case "brake": + Train.Cars[Car].CarBrake.brakeType = BrakeType.Auxiliary; + if (c.ChildNodes.OfType().Any()) + { + ParseBrakeNode(c, fileName, Car, ref Train); + } + else if (!String.IsNullOrEmpty(c.InnerText)) + { + try + { + string childFile = OpenBveApi.Path.CombineFile(currentPath, c.InnerText); + XmlDocument childXML = new XmlDocument(); + childXML.Load(childFile); + XmlNodeList childNodes = childXML.DocumentElement.SelectNodes("/openBVE/Brake"); + //We need to save and restore the current path to make relative paths within the child file work correctly + string savedPath = currentPath; + currentPath = System.IO.Path.GetDirectoryName(childFile); + ParseBrakeNode(childNodes[0], fileName, Car, ref Train); + currentPath = savedPath; + } + catch + { + Interface.AddMessage(Interface.MessageType.Error, false, "Failed to load the child Brake XML file specified in " +c.InnerText); + } + } + break; case "length": double l; if (!NumberFormats.TryParseDoubleVb6(c.InnerText, out l) | l <= 0.0) @@ -49,10 +75,51 @@ private static void ParseCarNode(XmlNode Node, string fileName, int Car, ref Tra if (c.InnerText.ToLowerInvariant() == "1" || c.InnerText.ToLowerInvariant() == "true") { Train.Cars[Car].Specs.IsMotorCar = true; + Train.Cars[Car].Specs.AccelerationCurves = new TrainManager.AccelerationCurve[AccelerationCurves.Length]; + for (int i = 0; i < AccelerationCurves.Length; i++) + { + Train.Cars[Car].Specs.AccelerationCurves[i] = AccelerationCurves[i].Clone(AccelerationCurves[i].Multiplier); + } + switch (Train.Specs.ReadhesionDeviceType) + { + case TrainManager.ReadhesionDeviceType.TypeA: + Train.Cars[Car].Specs.ReAdhesionDevice.UpdateInterval = 1.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ApplicationFactor = 0.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseInterval = 1.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseFactor = 8.0; + break; + case TrainManager.ReadhesionDeviceType.TypeB: + Train.Cars[Car].Specs.ReAdhesionDevice.UpdateInterval = 0.1; + Train.Cars[Car].Specs.ReAdhesionDevice.ApplicationFactor = 0.9935; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseInterval = 4.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseFactor = 1.125; + break; + case TrainManager.ReadhesionDeviceType.TypeC: + + Train.Cars[Car].Specs.ReAdhesionDevice.UpdateInterval = 0.1; + Train.Cars[Car].Specs.ReAdhesionDevice.ApplicationFactor = 0.965; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseInterval = 2.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseFactor = 1.5; + break; + case TrainManager.ReadhesionDeviceType.TypeD: + Train.Cars[Car].Specs.ReAdhesionDevice.UpdateInterval = 0.05; + Train.Cars[Car].Specs.ReAdhesionDevice.ApplicationFactor = 0.935; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseInterval = 0.3; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseFactor = 2.0; + break; + default: // no readhesion device + Train.Cars[Car].Specs.ReAdhesionDevice.UpdateInterval = 1.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ApplicationFactor = 1.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseInterval = 1.0; + Train.Cars[Car].Specs.ReAdhesionDevice.ReleaseFactor = 99.0; + break; + } } else { + Train.Cars[Car].Specs.AccelerationCurves = new TrainManager.AccelerationCurve[] { }; Train.Cars[Car].Specs.IsMotorCar = false; + Train.Cars[Car].Specs.ReAdhesionDevice = new TrainManager.CarReAdhesionDevice(Train.Cars[Car]); } break; case "mass": @@ -210,7 +277,7 @@ private static void ParseCarNode(XmlNode Node, string fileName, int Car, ref Tra { //Only supports panel2.cfg format Panel2CfgParser.ParsePanel2Config(System.IO.Path.GetFileName(interiorFile), System.IO.Path.GetDirectoryName(interiorFile), Encoding.UTF8, Train, Car); - Train.Cars[Car].CameraRestrictionMode = World.CameraRestrictionMode.On; + Train.Cars[Car].CameraRestrictionMode = Camera.RestrictionMode.On; } else if (interiorFile.ToLowerInvariant().EndsWith(".animated")) { @@ -222,7 +289,7 @@ private static void ParseCarNode(XmlNode Node, string fileName, int Car, ref Tra a.Objects[i].ObjectIndex = ObjectManager.CreateDynamicObject(); } Train.Cars[Car].CarSections[0].Elements = a.Objects; - Train.Cars[Car].CameraRestrictionMode = World.CameraRestrictionMode.NotAvailable; + Train.Cars[Car].CameraRestrictionMode = Camera.RestrictionMode.NotAvailable; } catch { diff --git a/source/OpenBVE/Parsers/Train/TrainXmlParser.cs b/source/OpenBVE/Parsers/Train/XML/TrainXmlParser.cs similarity index 91% rename from source/OpenBVE/Parsers/Train/TrainXmlParser.cs rename to source/OpenBVE/Parsers/Train/XML/TrainXmlParser.cs index 285ffce6f..48538413c 100644 --- a/source/OpenBVE/Parsers/Train/TrainXmlParser.cs +++ b/source/OpenBVE/Parsers/Train/XML/TrainXmlParser.cs @@ -10,6 +10,7 @@ partial class TrainXmlParser private static string currentPath; private static bool[] CarObjectsReversed; private static bool[] BogieObjectsReversed; + private static TrainManager.BveAccelerationCurve[] AccelerationCurves; internal static void Parse(string fileName, TrainManager.Train Train, ref ObjectManager.UnifiedObject[] CarObjects, ref ObjectManager.UnifiedObject[] BogieObjects) { //The current XML file to load @@ -17,6 +18,21 @@ internal static void Parse(string fileName, TrainManager.Train Train, ref Object //Load the marker's XML file currentXML.Load(fileName); currentPath = System.IO.Path.GetDirectoryName(fileName); + if (System.IO.File.Exists(OpenBveApi.Path.CombineFile(currentPath, "train.dat"))) + { + for (int i = 0; i < Train.Cars.Length; i++) + { + if (Train.Cars[i].Specs.IsMotorCar) + { + AccelerationCurves = new TrainManager.BveAccelerationCurve[Train.Cars[i].Specs.AccelerationCurves.Length]; + for (int j = 0; j < Train.Cars[i].Specs.AccelerationCurves.Length; j++) + { + TrainManager.BveAccelerationCurve c = (TrainManager.BveAccelerationCurve)Train.Cars[i].Specs.AccelerationCurves[j]; + AccelerationCurves[j] = c.Clone(c.Multiplier); + } + } + } + } CarObjectsReversed = new bool[Train.Cars.Length]; BogieObjectsReversed = new bool[Train.Cars.Length * 2]; if (currentXML.DocumentElement != null) @@ -66,7 +82,7 @@ internal static void Parse(string fileName, TrainManager.Train Train, ref Object Interface.AddMessage(Interface.MessageType.Warning, false, "WARNING: The number of cars specified in the train.xml file does not match that in the train.dat- Some properties may be invalid."); } } - if (Train.Cars[Train.DriverCar].CameraRestrictionMode != World.CameraRestrictionMode.NotSpecified) + if (Train.Cars[Train.DriverCar].CameraRestrictionMode != Camera.RestrictionMode.NotSpecified) { World.CameraRestriction = Train.Cars[Train.DriverCar].CameraRestrictionMode; World.UpdateViewingDistances(); diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/AirSound.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/AirSound.cs new file mode 100644 index 000000000..c6a68ede5 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/AirSound.cs @@ -0,0 +1,14 @@ +namespace OpenBve.BrakeSystems +{ + enum AirSound + { + /// No sound + None = -1, + /// Played when the pressure in the brake cylinder is decreased to zero + AirZero = 0, + /// Played when the pressure in the brake cylinder is decreased from a non-high to a non-zero value + Air = 1, + /// Played when the pressure in the brake cylinder is decreased from a high value + AirHigh = 2 + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/AutomaticAirBrake.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/AutomaticAirBrake.cs new file mode 100644 index 000000000..f27f5acbb --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/AutomaticAirBrake.cs @@ -0,0 +1,244 @@ +namespace OpenBve.BrakeSystems +{ + class AutomaticAirBrake : CarBrake + { + internal AutomaticAirBrake(EletropneumaticBrakeType type, TrainManager.EmergencyHandle EmergencyHandle, TrainManager.ReverserHandle ReverserHandle, bool IsMotorCar, double BrakeControlSpeed, double MotorDeceleration, TrainManager.AccelerationCurve[] DecelerationCurves) + { + electropneumaticBrakeType = type; + emergencyHandle = EmergencyHandle; + reverserHandle = ReverserHandle; + isMotorCar = IsMotorCar; + brakeControlSpeed = BrakeControlSpeed; + motorDeceleration = MotorDeceleration; + decelerationCurves = DecelerationCurves; + } + + internal override void Update(double TimeElapsed, double currentSpeed, TrainManager.AbstractHandle brakeHandle, out double deceleration) + { + airSound = AirSound.None; + if (emergencyHandle.Actual == true) + { + if (brakeType == BrakeType.Main) + { + double r = equalizingReservoir.EmergencyRate; + double d = equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > equalizingReservoir.CurrentPressure) + { + r = equalizingReservoir.CurrentPressure; + } + equalizingReservoir.CurrentPressure -= r; + } + } + //First update the main reservoir pressure from the equalizing reservoir + TrainManager.AirBrakeHandleState state = (TrainManager.AirBrakeHandleState)brakeHandle.Actual; + switch (state) + { + case TrainManager.AirBrakeHandleState.Service: + { + double r = equalizingReservoir.ServiceRate; //50000 + double d = equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; //1.05 * max service pressure from train.dat in pascals + r = GetRate(d / m, r * TimeElapsed); + if (r > equalizingReservoir.CurrentPressure) + { + r = equalizingReservoir.CurrentPressure; + } + + equalizingReservoir.CurrentPressure -= r; + break; + } + + case TrainManager.AirBrakeHandleState.Release: + { + double r = equalizingReservoir.ChargeRate; + double d = equalizingReservoir.NormalPressure - equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > d) + { + r = d; + } + + d = mainReservoir.CurrentPressure - equalizingReservoir.CurrentPressure; + if (r > d) + { + r = d; + } + + double f = mainReservoir.EqualizingReservoirCoefficient; + double s = r * f * TimeElapsed; + if (s > mainReservoir.CurrentPressure) + { + r *= mainReservoir.CurrentPressure / s; + s = mainReservoir.CurrentPressure; + } + + equalizingReservoir.CurrentPressure += 0.5 * r; + mainReservoir.CurrentPressure -= 0.5 * s; + break; + } + } + //Fill the brake pipe from the main reservoir + if (brakeType == BrakeType.Main) + { + if (brakePipe.CurrentPressure > equalizingReservoir.CurrentPressure + Tolerance) + { + // brake pipe exhaust valve + double r = emergencyHandle.Actual ? brakePipe.EmergencyRate : brakePipe.ServiceRate; + double d = brakePipe.CurrentPressure - equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = (0.5 + 1.5 * d / m) * r * TimeElapsed; + if (r > d) r = d; + brakePipe.CurrentPressure -= r; + } + else if (brakePipe.CurrentPressure + Tolerance < equalizingReservoir.CurrentPressure) + { + // fill brake pipe from main reservoir + double r = brakePipe.ChargeRate; + double d = equalizingReservoir.CurrentPressure - brakePipe.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = (0.5 + 1.5 * d / m) * r * TimeElapsed; + if (r > d) r = d; + d = brakePipe.NormalPressure - brakePipe.CurrentPressure; + if (r > d) r = d; + double f = mainReservoir.BrakePipeCoefficient; + double s = r * f; + if (s > mainReservoir.CurrentPressure) + { + r *= mainReservoir.CurrentPressure / s; + s = mainReservoir.CurrentPressure; + } + brakePipe.CurrentPressure += 0.5 * r; + mainReservoir.CurrentPressure -= 0.5 * s; + } + } + + if (brakePipe.CurrentPressure + Tolerance < auxiliaryReservoir.CurrentPressure) + { + if (auxiliaryReservoir.CurrentPressure + Tolerance < brakeCylinder.CurrentPressure) + { + // back-flow from brake cylinder to auxillary reservoir + double u = (brakeCylinder.CurrentPressure - auxiliaryReservoir.CurrentPressure - Tolerance) / Tolerance; + if (u > 1.0) u = 1.0; + double f = auxiliaryReservoir.BrakeCylinderCoefficient; + double r = brakeCylinder.ServiceChargeRate * f; + double d = brakeCylinder.CurrentPressure - auxiliaryReservoir.CurrentPressure; + double m = auxiliaryReservoir.MaximumPressure; + r = GetRate(d * u / m, r * TimeElapsed); + if (auxiliaryReservoir.CurrentPressure + r > m) + { + r = m - auxiliaryReservoir.CurrentPressure; + } + if (r > d) r = d; + double s = r / f; + if (s > d) + { + r *= d / s; + s = d; + } + if (s > brakeCylinder.CurrentPressure) + { + r *= brakeCylinder.CurrentPressure / s; + s = brakeCylinder.CurrentPressure; + } + auxiliaryReservoir.CurrentPressure += 0.5 * r; + brakeCylinder.CurrentPressure -= 0.5 * s; + } + else if (auxiliaryReservoir.CurrentPressure > brakeCylinder.CurrentPressure + Tolerance) + { + // refill brake cylinder from auxillary reservoir + double u = (auxiliaryReservoir.CurrentPressure - brakeCylinder.CurrentPressure - Tolerance) / Tolerance; + if (u > 1.0) u = 1.0; + double f = auxiliaryReservoir.BrakeCylinderCoefficient; + double r = brakeCylinder.ServiceChargeRate * f; + double d = auxiliaryReservoir.CurrentPressure - brakeCylinder.CurrentPressure; + double m = auxiliaryReservoir.MaximumPressure; + r = GetRate(d * u / m, r * TimeElapsed); + if (r > auxiliaryReservoir.CurrentPressure) + { + r = auxiliaryReservoir.CurrentPressure; + } + if (r > d) r = d; + double s = r / f; + if (s > d) + { + r *= d / s; + s = d; + } + d = brakeCylinder.EmergencyMaximumPressure - brakeCylinder.CurrentPressure; + if (s > d) + { + r *= d / s; + s = d; + } + auxiliaryReservoir.CurrentPressure -= 0.5 * r; + brakeCylinder.CurrentPressure += 0.5 * s; + } + // air sound + brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure; + } + else if (brakePipe.CurrentPressure > auxiliaryReservoir.CurrentPressure + Tolerance) + { + double u = (brakePipe.CurrentPressure - auxiliaryReservoir.CurrentPressure - Tolerance) / Tolerance; + if (u > 1.0) u = 1.0; + { + // refill auxillary reservoir from brake pipe + double r = auxiliaryReservoir.ChargeRate; + double d = brakePipe.CurrentPressure - auxiliaryReservoir.CurrentPressure; + double m = auxiliaryReservoir.MaximumPressure; + r = GetRate(d * u / m, r * TimeElapsed); + if (r > brakePipe.CurrentPressure) + { + r = brakePipe.CurrentPressure; + } + + if (r > d) r = d; + d = auxiliaryReservoir.MaximumPressure - auxiliaryReservoir.CurrentPressure; + if (r > d) r = d; + double f = auxiliaryReservoir.BrakePipeCoefficient; + double s = r / f; + if (s > brakePipe.CurrentPressure) + { + r *= brakePipe.CurrentPressure / s; + s = brakePipe.CurrentPressure; + } + + if (s > d) + { + r *= d / s; + s = d; + } + + auxiliaryReservoir.CurrentPressure += 0.5 * r; + brakePipe.CurrentPressure -= 0.5 * s; + } + { + // brake cylinder release + double r = brakeCylinder.ReleaseRate; + double d = brakeCylinder.CurrentPressure; + double m = brakeCylinder.EmergencyMaximumPressure; + r = GetRate(d * u / m, r * TimeElapsed); + if (r > brakeCylinder.CurrentPressure) r = brakeCylinder.CurrentPressure; + brakeCylinder.CurrentPressure -= r; + // air sound + if (r > 0.0 & brakeCylinder.CurrentPressure < brakeCylinder.SoundPlayedForPressure) + { + double p = 0.8 * brakeCylinder.CurrentPressure - 0.2 * brakeCylinder.EmergencyMaximumPressure; + if (p < 0.0) p = 0.0; + brakeCylinder.SoundPlayedForPressure = p; + airSound = p < Tolerance ? AirSound.AirZero : brakeCylinder.CurrentPressure > m - Tolerance ? AirSound.AirHigh : AirSound.Air; + } + } + } + else + { + // air sound + brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure; + } + double pressureratio = brakeCylinder.CurrentPressure / brakeCylinder.ServiceMaximumPressure; + deceleration = pressureratio * DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed); + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/AirCompressor.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/AirCompressor.cs new file mode 100644 index 000000000..700d27277 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/AirCompressor.cs @@ -0,0 +1,18 @@ +namespace OpenBve.BrakeSystems +{ + /// An air compressor + class Compressor + { + /// Whether this compressor is currently active + internal bool Enabled; + + /// The compression rate in Pa/s + internal readonly double Rate; + + internal Compressor(double rate) + { + Rate = rate; + Enabled = false; + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/BrakeCylinder.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/BrakeCylinder.cs new file mode 100644 index 000000000..3abda199e --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/BrakeCylinder.cs @@ -0,0 +1,31 @@ +namespace OpenBve.BrakeSystems +{ + /// A brake cylinder + class BrakeCylinder + { + /// The current pressure + internal double CurrentPressure; + /// The maximum pressure when an EB application is made + internal readonly double EmergencyMaximumPressure; + /// The maximum pressure when full service brakes are applied + internal readonly double ServiceMaximumPressure; + /// The pressure increase in Pa/s when making an EB application + internal readonly double EmergencyChargeRate; + /// The pressure increase in Pa/s when making a service brake application + internal readonly double ServiceChargeRate; + /// The pressure release rate in Pa/s + internal readonly double ReleaseRate; + internal double SoundPlayedForPressure; + + internal BrakeCylinder(double serviceMaximumPressure, double emergencyMaximumPressure, double serviceChargeRate, double emergencyChargeRate, double releaseRate) + { + ServiceMaximumPressure = serviceMaximumPressure; + EmergencyMaximumPressure = emergencyMaximumPressure; + ServiceChargeRate = serviceChargeRate; + EmergencyChargeRate = emergencyChargeRate; + ReleaseRate = releaseRate; + SoundPlayedForPressure = emergencyMaximumPressure; + CurrentPressure = EmergencyMaximumPressure; + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/BrakePipe.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/BrakePipe.cs new file mode 100644 index 000000000..7678f5a5b --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/BrakePipe.cs @@ -0,0 +1,26 @@ +namespace OpenBve.BrakeSystems +{ + /// A brake pipe + class BrakePipe + { + /// The current pressure + internal double CurrentPressure; + /// The normal working pressure + internal readonly double NormalPressure; + /// The charge rate in Pa/s + internal readonly double ChargeRate; + /// The rate in Pa/s when making a service brake application + internal readonly double ServiceRate; + /// The rate in Pa/s when making an EB brake application + internal readonly double EmergencyRate; + + internal BrakePipe(double normalPressure, double chargeRate, double serviceRate, double emergencyRate, bool electricCommand) + { + ChargeRate = chargeRate; + ServiceRate = serviceRate; + NormalPressure = normalPressure; + EmergencyRate = emergencyRate; + CurrentPressure = electricCommand ? 0.0 : normalPressure; + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/Reservoirs.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/Reservoirs.cs new file mode 100644 index 000000000..5f32b321f --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/Reservoirs.cs @@ -0,0 +1,73 @@ +namespace OpenBve.BrakeSystems +{ + /// An auxiliary reservoir + class AuxiliaryReservoir + { + /// The charge rate in Pa/s + internal readonly double ChargeRate; + /// The current pressure + internal double CurrentPressure; + /// The maximum pressure + internal readonly double MaximumPressure; + /// The co-efficient used when transferring pressure to the brake pipe + internal readonly double BrakePipeCoefficient; + /// The co-efficient used when transferring pressure to the brake cylinder + internal readonly double BrakeCylinderCoefficient; + + internal AuxiliaryReservoir(double maximumPressure, double chargeRate, double brakePipeCoefficient, double brakeCylinderCoefficent) + { + ChargeRate = chargeRate; + MaximumPressure = maximumPressure; + CurrentPressure = maximumPressure; + BrakePipeCoefficient = brakePipeCoefficient; + BrakeCylinderCoefficient = brakeCylinderCoefficent; + } + } + + /// An equalising reservoir + class EqualizingReservoir + { + /// The rate when service brakes are applied in Pa/s + internal readonly double ServiceRate; + /// The rate when EB brakes are applied in Pa/s + internal readonly double EmergencyRate; + /// The charge rate in Pa/s + internal readonly double ChargeRate; + /// The current pressure + internal double CurrentPressure; + /// The normal pressure + internal double NormalPressure; + + internal EqualizingReservoir(double serviceRate, double emergencyRate, double chargeRate) + { + ServiceRate = serviceRate; + EmergencyRate = emergencyRate; + ChargeRate = chargeRate; + CurrentPressure = 0.0; + } + } + + /// A main reservoir + class MainReservoir + { + /// The current pressure + internal double CurrentPressure; + /// The minimum pressure + internal readonly double MinimumPressure; + /// The maximum pressure + internal readonly double MaximumPressure; + /// The co-efficient used when transferring pressure to the equalizing reservoir + internal readonly double EqualizingReservoirCoefficient; + /// The co-efficient used when transferring pressure to the brake pipe + internal readonly double BrakePipeCoefficient; + + internal MainReservoir(double minimumPressure, double maximumPressure, double equalizingReservoirCoefficient, double brakePipeCoefficient) + { + MinimumPressure = minimumPressure; + MaximumPressure = maximumPressure; + EqualizingReservoirCoefficient = equalizingReservoirCoefficient; + BrakePipeCoefficient = brakePipeCoefficient; + CurrentPressure = MinimumPressure + (MaximumPressure - MinimumPressure) * Program.RandomNumberGenerator.NextDouble(); + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/StraightAirPipe.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/StraightAirPipe.cs new file mode 100644 index 000000000..f51aeabaf --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/Components/StraightAirPipe.cs @@ -0,0 +1,24 @@ +namespace OpenBve.BrakeSystems +{ + /// A straight air pipe + class StraightAirPipe + { + /// The current pressure + internal double CurrentPressure; + /// The rate in Pa/s when making a service brake application + internal readonly double ServiceRate; + /// The rate in Pa/s when making an EB application + internal readonly double EmergencyRate; + /// The release rate in Pa/s + internal readonly double ReleaseRate; + + internal StraightAirPipe(double serviceRate, double emergencyRate, double releaseRate) + { + CurrentPressure = 0.0; + ServiceRate = serviceRate; + EmergencyRate = emergencyRate; + ReleaseRate = releaseRate; + } + + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/ElectricCommandBrake.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/ElectricCommandBrake.cs new file mode 100644 index 000000000..006cf03c3 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/ElectricCommandBrake.cs @@ -0,0 +1,151 @@ +using System; + +namespace OpenBve.BrakeSystems +{ + class ElectricCommandBrake : CarBrake + { + internal ElectricCommandBrake(EletropneumaticBrakeType type, TrainManager.EmergencyHandle EmergencyHandle, TrainManager.ReverserHandle ReverserHandle, bool IsMotorCar, double BrakeControlSpeed, double MotorDeceleration, TrainManager.AccelerationCurve[] DecelerationCurves) + { + electropneumaticBrakeType = type; + emergencyHandle = EmergencyHandle; + reverserHandle = ReverserHandle; + isMotorCar = IsMotorCar; + brakeControlSpeed = BrakeControlSpeed; + motorDeceleration = MotorDeceleration; + decelerationCurves = DecelerationCurves; + } + + internal override void Update(double TimeElapsed, double currentSpeed, TrainManager.AbstractHandle brakeHandle, out double deceleration) + { + airSound = AirSound.None; + double targetPressure; + if (emergencyHandle.Actual == true) + { + if (brakeType == BrakeType.Main) + { + double r = equalizingReservoir.EmergencyRate; + double d = equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > equalizingReservoir.CurrentPressure) + { + r = equalizingReservoir.CurrentPressure; + } + + equalizingReservoir.CurrentPressure -= r; + } + targetPressure = brakeCylinder.EmergencyMaximumPressure; + } + else + { + targetPressure = (double) brakeHandle.Actual / (double) brakeHandle.MaximumNotch; + targetPressure *= brakeCylinder.ServiceMaximumPressure; + } + + if (!emergencyHandle.Actual & reverserHandle.Actual != 0) + { + // brake control system + if (isMotorCar & Math.Abs(currentSpeed) > brakeControlSpeed) + { + switch (electropneumaticBrakeType) + { + case EletropneumaticBrakeType.ClosingElectromagneticValve: + // closing electromagnetic valve (lock-out valve) + targetPressure = 0.0; + break; + case EletropneumaticBrakeType.DelayFillingControl: + // delay-filling control + double a = motorDeceleration; + double pr = targetPressure / brakeCylinder.ServiceMaximumPressure; + double b; + b = pr * DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed); + double d = b - a; + if (d > 0.0) + { + targetPressure = d / DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed); + if (targetPressure > 1.0) targetPressure = 1.0; + targetPressure *= brakeCylinder.ServiceMaximumPressure; + } + else + { + targetPressure = 0.0; + } + + break; + } + } + } + + if (brakeCylinder.CurrentPressure > targetPressure + Tolerance | targetPressure == 0.0) + { + // brake cylinder exhaust valve + double r = brakeCylinder.ReleaseRate; + double d = brakeCylinder.CurrentPressure; + double m = brakeCylinder.EmergencyMaximumPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > d) r = d; + // air sound + if (r > 0.0 & brakeCylinder.CurrentPressure < brakeCylinder.SoundPlayedForPressure) + { + brakeCylinder.SoundPlayedForPressure = targetPressure; + airSound = targetPressure < Tolerance ? AirSound.AirZero : brakeCylinder.CurrentPressure > m - Tolerance ? AirSound.AirHigh : AirSound.Air; + } + + // pressure change + brakeCylinder.CurrentPressure -= r; + } + else if ((brakeCylinder.CurrentPressure + Tolerance < targetPressure | targetPressure == brakeCylinder.EmergencyMaximumPressure) & brakeCylinder.CurrentPressure + Tolerance < mainReservoir.CurrentPressure) + { + // fill brake cylinder from main reservoir + double r; + if (emergencyHandle.Actual) + { + r = 2.0 * brakeCylinder.EmergencyChargeRate; + } + else + { + r = 2.0 * brakeCylinder.ServiceChargeRate; + } + + double pm = targetPressure < mainReservoir.CurrentPressure ? targetPressure : mainReservoir.CurrentPressure; + double d = pm - brakeCylinder.CurrentPressure; + double m = brakeCylinder.EmergencyMaximumPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > d) r = d; + double f1 = auxiliaryReservoir.BrakeCylinderCoefficient; + double f2 = mainReservoir.BrakePipeCoefficient; + double f3 = auxiliaryReservoir.BrakePipeCoefficient; + double f = f1 * f2 / f3; // MainReservoirBrakeCylinderCoefficient + double s = r * f; + if (s > mainReservoir.CurrentPressure) + { + r *= mainReservoir.CurrentPressure / s; + s = mainReservoir.CurrentPressure; + } + + brakeCylinder.CurrentPressure += 0.5 * r; + mainReservoir.CurrentPressure -= 0.5 * s; + // air sound + brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure; + } + else + { + // air sound + brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure; + } + double pp; + if (emergencyHandle.Actual) + { + pp = brakeCylinder.EmergencyMaximumPressure; + } + else + { + pp = (double)brakeHandle.Actual / (double)brakeHandle.MaximumNotch; + pp *= brakeCylinder.ServiceMaximumPressure; + } + straightAirPipe.CurrentPressure = pp; + double pressureratio = brakeCylinder.CurrentPressure / brakeCylinder.ServiceMaximumPressure; + deceleration = pressureratio * DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed); + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/ElectromagneticStraightAirBrake.cs b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/ElectromagneticStraightAirBrake.cs new file mode 100644 index 000000000..cf1495f13 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/AirBrake/ElectromagneticStraightAirBrake.cs @@ -0,0 +1,294 @@ +using System; + +namespace OpenBve.BrakeSystems +{ + class ElectromagneticStraightAirBrake : CarBrake + { + internal ElectromagneticStraightAirBrake(EletropneumaticBrakeType type, TrainManager.EmergencyHandle EmergencyHandle, TrainManager.ReverserHandle ReverserHandle, bool IsMotorCar, double BrakeControlSpeed, double MotorDeceleration, TrainManager.AccelerationCurve[] DecelerationCurves) + { + electropneumaticBrakeType = type; + emergencyHandle = EmergencyHandle; + reverserHandle = ReverserHandle; + isMotorCar = IsMotorCar; + brakeControlSpeed = BrakeControlSpeed; + motorDeceleration = MotorDeceleration; + decelerationCurves = DecelerationCurves; + } + + internal override void Update(double TimeElapsed, double currentSpeed, TrainManager.AbstractHandle brakeHandle, out double deceleration) + { + airSound = AirSound.None; + if (emergencyHandle.Actual == true) + { + if (brakeType == BrakeType.Main) + { + double r = equalizingReservoir.EmergencyRate; + double d = equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > equalizingReservoir.CurrentPressure) + { + r = equalizingReservoir.CurrentPressure; + } + equalizingReservoir.CurrentPressure -= r; + } + } + //First update the main reservoir pressure + { + double r = equalizingReservoir.ChargeRate; + double d = equalizingReservoir.NormalPressure - equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > d) r = d; + d = mainReservoir.CurrentPressure - equalizingReservoir.CurrentPressure; + if (r > d) r = d; + double f = mainReservoir.EqualizingReservoirCoefficient; + double s = r * f * TimeElapsed; + if (s > mainReservoir.CurrentPressure) + { + r *= mainReservoir.CurrentPressure / s; + s = mainReservoir.CurrentPressure; + } + + equalizingReservoir.CurrentPressure += 0.5 * r; + mainReservoir.CurrentPressure -= 0.5 * s; + } + //Fill the brake pipe from the main reservoir + if (brakeType == BrakeType.Main) + { + if (brakePipe.CurrentPressure > equalizingReservoir.CurrentPressure + Tolerance) + { + // brake pipe exhaust valve + double r = emergencyHandle.Actual ? brakePipe.EmergencyRate : brakePipe.ServiceRate; + double d = brakePipe.CurrentPressure - equalizingReservoir.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = (0.5 + 1.5 * d / m) * r * TimeElapsed; + if (r > d) r = d; + brakePipe.CurrentPressure -= r; + } + else if (brakePipe.CurrentPressure + Tolerance < equalizingReservoir.CurrentPressure) + { + // fill brake pipe from main reservoir + double r = brakePipe.ChargeRate; + double d = equalizingReservoir.CurrentPressure - brakePipe.CurrentPressure; + double m = equalizingReservoir.NormalPressure; + r = (0.5 + 1.5 * d / m) * r * TimeElapsed; + if (r > d) r = d; + d = brakePipe.NormalPressure - brakePipe.CurrentPressure; + if (r > d) r = d; + double f = mainReservoir.BrakePipeCoefficient; + double s = r * f; + if (s > mainReservoir.CurrentPressure) + { + r *= mainReservoir.CurrentPressure / s; + s = mainReservoir.CurrentPressure; + } + brakePipe.CurrentPressure += 0.5 * r; + mainReservoir.CurrentPressure -= 0.5 * s; + } + } + + // refill auxillary reservoir from brake pipe + if (brakePipe.CurrentPressure > auxiliaryReservoir.CurrentPressure + Tolerance) + { + double r = 2.0 * auxiliaryReservoir.ChargeRate; + double d = brakePipe.CurrentPressure - auxiliaryReservoir.CurrentPressure; + double m = auxiliaryReservoir.MaximumPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > brakePipe.CurrentPressure) + { + r = brakePipe.CurrentPressure; + } + + if (r > d) r = d; + d = auxiliaryReservoir.MaximumPressure - auxiliaryReservoir.CurrentPressure; + if (r > d) r = d; + double f = auxiliaryReservoir.BrakePipeCoefficient; + double s = r / f; + if (s > brakePipe.CurrentPressure) + { + r *= brakePipe.CurrentPressure / s; + s = brakePipe.CurrentPressure; + } + + if (s > d) + { + r *= d / s; + s = d; + } + + auxiliaryReservoir.CurrentPressure += 0.5 * r; + brakePipe.CurrentPressure -= 0.5 * s; + } + + // electric command + bool emergency; + if (brakePipe.CurrentPressure + Tolerance < auxiliaryReservoir.CurrentPressure) + { + emergency = true; + } + else + { + emergency = emergencyHandle.Actual; + } + + double targetPressure; + if (emergency) + { + //If EB is selected, then target pressure must be that required for EB + targetPressure = brakeCylinder.EmergencyMaximumPressure; + } + else + { + //Otherwise [BVE2 / BVE4 train.dat format] work out target pressure as a proportion of the max notch: + targetPressure = (double) brakeHandle.Actual / (double) brakeHandle.MaximumNotch; + targetPressure *= brakeCylinder.ServiceMaximumPressure; + } + + if (isMotorCar & !emergencyHandle.Actual & reverserHandle.Actual != 0) + { + //If we meet the conditions for brake control system to activate + if (Math.Abs(currentSpeed) > brakeControlSpeed) + { + if (electropneumaticBrakeType == EletropneumaticBrakeType.ClosingElectromagneticValve) + { + //When above the brake control speed, pressure to the BC is nil & electric brakes are used + //Thus target pressure must be zero + targetPressure = 0.0; + } + else if (electropneumaticBrakeType == EletropneumaticBrakeType.DelayFillingControl) + { + //Motor is used to brake the train, until not enough deceleration, at which point the air brake is also used + double a = motorDeceleration; + double pr = targetPressure / brakeCylinder.ServiceMaximumPressure; + double b; + b = pr * DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed); + + double d = b - a; + if (d > 0.0) + { + //Deceleration provided by the motor is not enough, so increase the BC target pressure + targetPressure = d / DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed); + if (targetPressure > 1.0) targetPressure = 1.0; + targetPressure *= brakeCylinder.ServiceMaximumPressure; + } + else + { + //Motor deceleration is enough, BC target pressure to zero + targetPressure = 0.0; + } + } + } + } + + if (brakeCylinder.CurrentPressure > targetPressure + Tolerance | targetPressure == 0.0) + { + //BC pressure is greater than the target pressure, so release pressure + double r = brakeCylinder.ReleaseRate; + double d = brakeCylinder.CurrentPressure - targetPressure; + double m = brakeCylinder.EmergencyMaximumPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > brakeCylinder.CurrentPressure) r = brakeCylinder.CurrentPressure; + if (r > d) r = d; + // air sound + if (r > 0.0 & brakeCylinder.CurrentPressure < brakeCylinder.SoundPlayedForPressure) + { + brakeCylinder.SoundPlayedForPressure = targetPressure; + airSound = targetPressure < Tolerance ? AirSound.AirZero : brakeCylinder.CurrentPressure > m - Tolerance ? AirSound.AirHigh : AirSound.Air; + } + + // pressure change + brakeCylinder.CurrentPressure -= r; + } + else if (brakeCylinder.CurrentPressure + Tolerance < targetPressure) + { + //BC pressure is less than target pressure, so increase pressure + double f = auxiliaryReservoir.BrakeCylinderCoefficient; + double r; + if (emergency) + { + r = 2.0 * brakeCylinder.EmergencyChargeRate * f; + } + else + { + r = 2.0 * brakeCylinder.ServiceChargeRate * f; + } + + double d = auxiliaryReservoir.CurrentPressure - brakeCylinder.CurrentPressure; + double m = brakeCylinder.EmergencyMaximumPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > auxiliaryReservoir.CurrentPressure) + { + r = auxiliaryReservoir.CurrentPressure; + } + + if (r > d) r = d; + double s = r / f; + if (s > d) + { + r *= d / s; + s = d; + } + + d = brakeCylinder.EmergencyMaximumPressure - brakeCylinder.CurrentPressure; + if (s > d) + { + r *= d / s; + s = d; + } + + auxiliaryReservoir.CurrentPressure -= 0.5 * r; + brakeCylinder.CurrentPressure += 0.5 * s; + // air sound + brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure; + } + else + { + // air sound + brakeCylinder.SoundPlayedForPressure = brakeCylinder.EmergencyMaximumPressure; + } + + double p; + if (emergencyHandle.Actual) + { + p = 0.0; + } + else + { + p = (double) brakeHandle.Actual / (double) brakeHandle.MaximumNotch; + p *= brakeCylinder.ServiceMaximumPressure; + } + + if (p + Tolerance < straightAirPipe.CurrentPressure) + { + double r; + if (emergencyHandle.Actual) + { + r = straightAirPipe.EmergencyRate; + } + else + { + r = straightAirPipe.ReleaseRate; + } + + double d = straightAirPipe.CurrentPressure - p; + double m = brakeCylinder.EmergencyMaximumPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > d) r = d; + straightAirPipe.CurrentPressure -= r; + } + else if (p > straightAirPipe.CurrentPressure + Tolerance) + { + double r = straightAirPipe.ServiceRate; + double d = p - straightAirPipe.CurrentPressure; + double m = brakeCylinder.EmergencyMaximumPressure; + r = GetRate(d / m, r * TimeElapsed); + if (r > d) r = d; + straightAirPipe.CurrentPressure += r; + } + + double pressureratio = brakeCylinder.CurrentPressure / brakeCylinder.ServiceMaximumPressure; + deceleration = pressureratio * DecelerationAtServiceMaximumPressure(brakeHandle.Actual, currentSpeed); + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/BrakeSystemType.cs b/source/OpenBVE/Simulation/TrainManager/Brake/BrakeSystemType.cs new file mode 100644 index 000000000..4959e6d86 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/BrakeSystemType.cs @@ -0,0 +1,13 @@ +namespace OpenBve.BrakeSystems +{ + /// Defines the different types of brake system types + enum BrakeSystemType + { + /// The brake command is synchronized on all cars, however the brake pipe is used to distribute air + ElectromagneticStraightAirBrake = 0, + /// Each car is an independant brake unit, and the brake command is synchronized + ElectricCommandBrake = 1, + /// The brake pipe distributes air and regulates the appplication throughout the train + AutomaticAirBrake = 2 + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/CarBrake.BrakeType.cs b/source/OpenBVE/Simulation/TrainManager/Brake/CarBrake.BrakeType.cs new file mode 100644 index 000000000..1e87df38b --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/CarBrake.BrakeType.cs @@ -0,0 +1,10 @@ +namespace OpenBve.BrakeSystems +{ + internal enum BrakeType + { + /// The brake system has an air compressor + Main = 0, + /// The brake system has no air compressor + Auxiliary = 1 + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/CarBrake.cs b/source/OpenBVE/Simulation/TrainManager/Brake/CarBrake.cs new file mode 100644 index 000000000..854ddddbe --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/CarBrake.cs @@ -0,0 +1,77 @@ +namespace OpenBve.BrakeSystems +{ + abstract class CarBrake + { + internal const double Tolerance = 5000.0; + + /// Contains a reference to the EB handle of the controlling train + internal TrainManager.EmergencyHandle emergencyHandle; + + /// Contains a reference to the reverser handle of the controlling train + internal TrainManager.ReverserHandle reverserHandle; + + /// Whether this is a main or auxiliary brake system + internal BrakeType brakeType; + + internal EqualizingReservoir equalizingReservoir; + + internal MainReservoir mainReservoir; + + internal AuxiliaryReservoir auxiliaryReservoir; + + internal BrakePipe brakePipe; + + internal BrakeCylinder brakeCylinder; + + internal Compressor airCompressor; + + internal EletropneumaticBrakeType electropneumaticBrakeType; + + internal StraightAirPipe straightAirPipe; + + /// Stores whether the car is a motor car + internal bool isMotorCar; + + /// The speed at which the brake control system activates in m/s + internal double brakeControlSpeed; + + /// The current deceleration provided by the electric motor + internal double motorDeceleration; + + /// The index of the air sound currently playing + internal AirSound airSound; + + internal TrainManager.AccelerationCurve[] decelerationCurves; + + /// Updates the brake system + /// The frame time elapsed + /// The current speed of the train + /// The controlling brake handle (NOTE: May either be the loco brake if fitted or the train brake) + /// The deceleration output provided + internal abstract void Update(double TimeElapsed, double currentSpeed, TrainManager.AbstractHandle brakeHandle, out double Deceleration); + + internal double GetRate(double Ratio, double Factor) + { + Ratio = Ratio < 0.0 ? 0.0 : Ratio > 1.0 ? 1.0 : Ratio; + Ratio = 1.0 - Ratio; + return 1.5 * Factor * (1.01 - Ratio * Ratio); + } + + /// Calculates the max possible deceleration given a brake notch and speed + /// The brake notch + /// The speed + /// The deceleration in m/s + internal double DecelerationAtServiceMaximumPressure(int Notch, double currentSpeed) + { + if (Notch == 0) + { + return this.decelerationCurves[0].GetAccelerationOutput(currentSpeed, 1.0); + } + if (this.decelerationCurves.Length >= Notch) + { + return this.decelerationCurves[Notch - 1].GetAccelerationOutput(currentSpeed, 1.0); + } + return this.decelerationCurves[this.decelerationCurves.Length - 1].GetAccelerationOutput(currentSpeed, 1.0); + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Brake/ElectropnuematicBrakeType.cs b/source/OpenBVE/Simulation/TrainManager/Brake/ElectropnuematicBrakeType.cs new file mode 100644 index 000000000..700e2e7d8 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Brake/ElectropnuematicBrakeType.cs @@ -0,0 +1,19 @@ +namespace OpenBve.BrakeSystems +{ + /// The types of electropnuematic control system available for a train with dynamic (motor assisted) braking + internal enum EletropneumaticBrakeType + { + /// The motor will always brake in addition to the physical brake, leading to a stronger braking force at all times. + None = 0, + /// The pressure to the brake cylinder is interrupted when the train travels above the brake control speed, and the electric brake is used instead. + /// When below the control speed, the physical brake operates normally, while the electric brake is not used. + /// + ClosingElectromagneticValve = 1, + /// The motor is used to brake the train with the deceleration setting as specified in the Performance section. + /// If the motor cannot provide this deceleration on its own, the physical brake is additionally used. + /// When the train travels below the brake control speed, the physical brakes are used. + /// However, as the physical brakes need time to fill the brake cylinder, the electric brake is still used to compensate for this delay. + /// + DelayFillingControl = 2 + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Car/Car.Brightness.cs b/source/OpenBVE/Simulation/TrainManager/Car/Car.Brightness.cs new file mode 100644 index 000000000..1a38c9ff3 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Car/Car.Brightness.cs @@ -0,0 +1,17 @@ +namespace OpenBve +{ + public static partial class TrainManager + { + /// The base class containing the properties of a train car + internal partial class Car + { + internal struct CarBrightness + { + internal float PreviousBrightness; + internal double PreviousTrackPosition; + internal float NextBrightness; + internal double NextTrackPosition; + } + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Car/Car.Specs.cs b/source/OpenBVE/Simulation/TrainManager/Car/Car.Specs.cs index 42de5d526..b23d08567 100644 --- a/source/OpenBVE/Simulation/TrainManager/Car/Car.Specs.cs +++ b/source/OpenBVE/Simulation/TrainManager/Car/Car.Specs.cs @@ -5,24 +5,9 @@ public static partial class TrainManager { internal struct CarSpecs { - internal bool IsDriverCar; /// motor internal bool IsMotorCar; internal AccelerationCurve[] AccelerationCurves; - internal AccelerationCurve[] DecelerationCurves; - - internal double BrakeDecelerationAtServiceMaximumPressure(int Notch) - { - if (Notch == 0) - { - return this.DecelerationCurves[0].GetAccelerationOutput(this.CurrentSpeed, 1.0); - } - if (this.DecelerationCurves.Length >= Notch) - { - return this.DecelerationCurves[Notch - 1].GetAccelerationOutput(this.CurrentSpeed, 1.0); - } - return this.DecelerationCurves[this.DecelerationCurves.Length - 1].GetAccelerationOutput(this.CurrentSpeed, 1.0); - } internal double AccelerationCurveMaximum; internal double JerkPowerUp; @@ -30,7 +15,6 @@ internal double BrakeDecelerationAtServiceMaximumPressure(int Notch) internal double JerkBrakeUp; internal double JerkBrakeDown; /// brake - internal double BrakeControlSpeed; internal double MotorDeceleration; /// physical properties internal double MassEmpty; @@ -63,9 +47,7 @@ internal double BrakeDecelerationAtServiceMaximumPressure(int Notch) internal CarHoldBrake HoldBrake; internal CarConstSpeed ConstSpeed; internal CarReAdhesionDevice ReAdhesionDevice; - internal CarBrakeType BrakeType; - internal EletropneumaticBrakeType ElectropneumaticType; - internal CarAirBrake AirBrake; + /// doors internal double DoorOpenFrequency; diff --git a/source/OpenBVE/Simulation/TrainManager/Car/Car.cs b/source/OpenBVE/Simulation/TrainManager/Car/Car.cs index 3722e6875..95e00c9fa 100644 --- a/source/OpenBVE/Simulation/TrainManager/Car/Car.cs +++ b/source/OpenBVE/Simulation/TrainManager/Car/Car.cs @@ -1,4 +1,5 @@ -using System; +using System; +using OpenBve.BrakeSystems; using OpenBveApi.Math; namespace OpenBve @@ -6,7 +7,7 @@ namespace OpenBve public static partial class TrainManager { /// The base class containing the properties of a train car - internal class Car + internal partial class Car { /// Width in meters internal double Width; @@ -26,7 +27,8 @@ internal class Car internal Horn[] Horns; /// The doors for this car internal Door[] Doors; - + /// The car brake for this car + internal CarBrake CarBrake; internal Vector3 Up; /// The car sections (objects) attached to the car internal CarSection[] CarSections; @@ -50,24 +52,16 @@ internal class Car internal double BeaconReceiverPosition; internal TrackManager.TrackFollower BeaconReceiver; /// A reference to the base train - internal Train baseTrain; + private readonly Train baseTrain; /// The index of the car within the train - internal int Index; + internal readonly int Index; /// Stores the camera restriction mode for the interior view of this car - internal World.CameraRestrictionMode CameraRestrictionMode = World.CameraRestrictionMode.NotSpecified; + internal Camera.RestrictionMode CameraRestrictionMode = Camera.RestrictionMode.NotSpecified; /// Stores the camera interior camera alignment for this car internal World.CameraAlignment InteriorCamera; internal bool HasInteriorView = false; - - internal struct CarBrightness - { - internal float PreviousBrightness; - internal double PreviousTrackPosition; - internal float NextBrightness; - internal double NextTrackPosition; - } - + internal Car(Train train, int index) { baseTrain = train; @@ -159,18 +153,15 @@ internal void CreateWorldCoordinates(double CarX, double CarY, double CarZ, out { t = 1.0 / Math.Sqrt(t); DirectionX *= t; DirectionY *= t; DirectionZ *= t; - double ux = Up.X; - double uy = Up.Y; - double uz = Up.Z; - double sx = DirectionZ * uy - DirectionY * uz; - double sy = DirectionX * uz - DirectionZ * ux; - double sz = DirectionY * ux - DirectionX * uy; + double sx = DirectionZ * Up.Y - DirectionY * Up.Z; + double sy = DirectionX * Up.Z - DirectionZ * Up.X; + double sz = DirectionY * Up.X - DirectionX * Up.Y; double rx = 0.5 * (FrontAxle.Follower.WorldPosition.X + RearAxle.Follower.WorldPosition.X); double ry = 0.5 * (FrontAxle.Follower.WorldPosition.Y + RearAxle.Follower.WorldPosition.Y); double rz = 0.5 * (FrontAxle.Follower.WorldPosition.Z + RearAxle.Follower.WorldPosition.Z); - PositionX = rx + sx * CarX + ux * CarY + DirectionX * CarZ; - PositionY = ry + sy * CarX + uy * CarY + DirectionY * CarZ; - PositionZ = rz + sz * CarX + uz * CarY + DirectionZ * CarZ; + PositionX = rx + sx * CarX + Up.X * CarY + DirectionX * CarZ; + PositionY = ry + sy * CarX + Up.Y * CarY + DirectionY * CarZ; + PositionZ = rz + sz * CarX + Up.Z * CarY + DirectionZ * CarZ; } else { @@ -331,7 +322,7 @@ internal void UpdateMotorSounds(double TimeElapsed) else if (ndir == -1) { // brake - double max = Specs.BrakeDecelerationAtServiceMaximumPressure(this.baseTrain.Handles.Brake.Actual); + double max = CarBrake.DecelerationAtServiceMaximumPressure(baseTrain.Handles.Brake.Actual, Specs.CurrentSpeed); if (max != 0.0) { double cur = -Specs.CurrentAccelerationOutput; @@ -594,7 +585,7 @@ internal void UpdateObjects(double TimeElapsed, bool ForceUpdate, bool EnableDam internal void UpdateCarSectionElement(int SectionIndex, int ElementIndex, Vector3 Position, Vector3 Direction, Vector3 Up, Vector3 Side, bool Show, double TimeElapsed, bool ForceUpdate, bool EnableDamping) { Vector3 p; - if (CarSections[SectionIndex].Overlay & World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) + if (CarSections[SectionIndex].Overlay & World.CameraRestriction != Camera.RestrictionMode.NotAvailable) { p = new Vector3(Driver.X, Driver.Y, Driver.Z); } diff --git a/source/OpenBVE/Simulation/TrainManager/Car/CarSound.cs b/source/OpenBVE/Simulation/TrainManager/Car/CarSound.cs index d4884a4a1..ecf445b87 100644 --- a/source/OpenBVE/Simulation/TrainManager/Car/CarSound.cs +++ b/source/OpenBVE/Simulation/TrainManager/Car/CarSound.cs @@ -9,7 +9,7 @@ public static partial class TrainManager internal struct CarSound { /// The sound buffer to play - internal Sounds.SoundBuffer Buffer; + internal readonly Sounds.SoundBuffer Buffer; /// The source of the sound within the car internal Sounds.SoundSource Source; /// A Vector3 describing the position of the sound source diff --git a/source/OpenBVE/Simulation/TrainManager/Car/ConstantSpeedDevice.cs b/source/OpenBVE/Simulation/TrainManager/Car/ConstantSpeedDevice.cs index 24e5b45e1..bd11f75a8 100644 --- a/source/OpenBVE/Simulation/TrainManager/Car/ConstantSpeedDevice.cs +++ b/source/OpenBVE/Simulation/TrainManager/Car/ConstantSpeedDevice.cs @@ -30,17 +30,15 @@ internal void Update(ref double Acceleration, bool Enabled, ReverserPosition Rev this.CurrentAccelerationOutput = Acceleration; return; } - if (Game.SecondsSinceMidnight < this.NextUpdateTime) + if (Game.SecondsSinceMidnight >= this.NextUpdateTime) { - return; - } - this.NextUpdateTime = Game.SecondsSinceMidnight + UpdateInterval; - this.CurrentAccelerationOutput -= 0.8 * this.Car.Specs.CurrentAcceleration * (double)ReverserPosition; - if (this.CurrentAccelerationOutput < 0.0) - { - this.CurrentAccelerationOutput = 0.0; + this.NextUpdateTime = Game.SecondsSinceMidnight + UpdateInterval; + this.CurrentAccelerationOutput -= 0.8 * this.Car.Specs.CurrentAcceleration * (double)ReverserPosition; + if (this.CurrentAccelerationOutput < 0.0) + { + this.CurrentAccelerationOutput = 0.0; + } } - if (Acceleration > CurrentAccelerationOutput) { Acceleration = CurrentAccelerationOutput; diff --git a/source/OpenBVE/Simulation/TrainManager/Car/ReadhesionDevice.Types.cs b/source/OpenBVE/Simulation/TrainManager/Car/ReadhesionDevice.Types.cs new file mode 100644 index 000000000..0e842a70d --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Car/ReadhesionDevice.Types.cs @@ -0,0 +1,22 @@ +namespace OpenBve +{ + /// The TrainManager is the root class containing functions to load and manage trains within the simulation world. + public static partial class TrainManager + { + /// Defines the differing types of readhesion device which may be fitted to a car + /// See for further details + internal enum ReadhesionDeviceType + { + /// No readhesion device is fitted + NotFitted = -1, + /// Cuts off power instantly and rebuilds it up fast in steps. + TypeA = 0, + /// Updates not so often and adapts slowly. Wheel slip can persist longer and power is regained slower. The behavior is smoother. + TypeB = 1, + /// The behavior is somewhere in-between type B and type D. + TypeC = 2, + /// Updates fast and adapts fast. Wheel slip only occurs briefly and power is regained fast. The behavior is more abrupt. + TypeD = 3, + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Functions.cs b/source/OpenBVE/Simulation/TrainManager/Functions.cs index e10b57b69..8325ec2b6 100644 --- a/source/OpenBVE/Simulation/TrainManager/Functions.cs +++ b/source/OpenBVE/Simulation/TrainManager/Functions.cs @@ -101,7 +101,7 @@ internal static void JumpTrain(Train train, int stationIndex) else { train.ApplyNotch(0, false, train.Handles.Brake.MaximumNotch, false); - TrainManager.ApplyAirBrakeHandle(train, TrainManager.AirBrakeHandleState.Service); + train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); } if (Game.Sections.Length > 0) { diff --git a/source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.AirBrake.cs b/source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.AirBrake.cs deleted file mode 100644 index 8c0359f2a..000000000 --- a/source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.AirBrake.cs +++ /dev/null @@ -1,105 +0,0 @@ -namespace OpenBve -{ - public static partial class TrainManager - { - /// Moves the air brake handle - /// The train - /// The direction: -1 for decrease, 1 for increase - internal static void ApplyAirBrakeHandle(Train Train, int RelativeDirection) - { - if (Train.Cars[Train.DriverCar].Specs.BrakeType == CarBrakeType.AutomaticAirBrake) - { - if (RelativeDirection == -1) - { - if (Train.Handles.AirBrake.Handle.Driver == AirBrakeHandleState.Service) - { - ApplyAirBrakeHandle(Train, AirBrakeHandleState.Lap); - } - else - { - ApplyAirBrakeHandle(Train, AirBrakeHandleState.Release); - } - } - else if (RelativeDirection == 1) - { - if (Train.Handles.AirBrake.Handle.Driver == AirBrakeHandleState.Release) - { - ApplyAirBrakeHandle(Train, AirBrakeHandleState.Lap); - } - else - { - ApplyAirBrakeHandle(Train, AirBrakeHandleState.Service); - } - } - Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); - } - } - - /// Moves the air brake handle to the specified state - /// The train - /// The state - internal static void ApplyAirBrakeHandle(Train Train, AirBrakeHandleState State) - { - if (Train.Cars[Train.DriverCar].Specs.BrakeType == CarBrakeType.AutomaticAirBrake) - { - if (State != Train.Handles.AirBrake.Handle.Driver) - { - // sound when moved to service - if (State == AirBrakeHandleState.Service) - { - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.Brake.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.Brake.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - } - // sound - if ((int)State < (int)Train.Handles.AirBrake.Handle.Driver) - { - // brake release - if ((int)State > 0) - { - // brake release (not min) - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleRelease.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleRelease.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - } - else - { - // brake min - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleMin.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleMin.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - } - } - else if ((int)State > (int)Train.Handles.AirBrake.Handle.Driver) - { - // brake - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleApply.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleApply.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - } - // apply - Train.Handles.AirBrake.Handle.Driver = State; - Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); - // plugin - if (Train.Plugin != null) - { - Train.Plugin.UpdatePower(); - Train.Plugin.UpdateBrake(); - } - } - } - } - } -} diff --git a/source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.cs b/source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.cs index b6ba92669..da3bbc4ac 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/BrakeSystem.cs @@ -1,990 +1,322 @@ using System; +using OpenBve.BrakeSystems; namespace OpenBve { public static partial class TrainManager { - /// Updates the brake system for a complete train - /// The train to update the brake system values for - /// The frame time elapsed - /// An array containing the deceleration due to brakes for each car in the train - /// An array containing the deceleration due to motor retardation for each car in the train - private static void UpdateBrakeSystem(Train Train, double TimeElapsed, out double[] DecelerationDueToBrake, out double[] DecelerationDueToMotor) + public partial class Train { - // individual brake systems - DecelerationDueToBrake = new double[Train.Cars.Length]; - DecelerationDueToMotor = new double[Train.Cars.Length]; - for (int i = 0; i < Train.Cars.Length; i++) + /// Updates the brake system for the entire train + /// The frame time elapsed + /// An array containing the deceleration figures generated by the brake system of each car in the train + /// An array containing the deceleration figures generated by the motor of each car in the train (If it is a motor car) + private void UpdateBrakeSystem(double TimeElapsed, out double[] DecelerationDueToBrake, out double[] DecelerationDueToMotor) { - UpdateBrakeSystem(Train, i, TimeElapsed, out DecelerationDueToBrake[i], out DecelerationDueToMotor[i]); - } - // brake pipe pressure distribution dummy (just averages) - double TotalPressure = 0.0; - for (int i = 0; i < Train.Cars.Length; i++) - { - if (i > 0) + // individual brake systems + DecelerationDueToBrake = new double[Cars.Length]; + DecelerationDueToMotor = new double[Cars.Length]; + for (int i = 0; i < Cars.Length; i++) { - if (Train.Cars[i - 1].Derailed | Train.Cars[i].Derailed) - { - Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure -= Game.BrakePipeLeakRate * TimeElapsed; - if (Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure < 0.0) Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure = 0.0; - } + UpdateBrakeSystem(i, TimeElapsed, out DecelerationDueToBrake[i], out DecelerationDueToMotor[i]); } - if (i < Train.Cars.Length - 1) - { - if (Train.Cars[i].Derailed | Train.Cars[i + 1].Derailed) - { - Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure -= Game.BrakePipeLeakRate * TimeElapsed; - if (Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure < 0.0) Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure = 0.0; - } - } - TotalPressure += Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure; - } - double AveragePressure = TotalPressure / (double)Train.Cars.Length; - for (int i = 0; i < Train.Cars.Length; i++) - { - Train.Cars[i].Specs.AirBrake.BrakePipeCurrentPressure = AveragePressure; - } - } - - /// Updates the brake system for a car within a train - /// The train - /// The induvidual car - /// The frame time elapsed - /// The total brake deceleration this car provides - /// The total motor deceleration this car provides - private static void UpdateBrakeSystem(Train Train, int CarIndex, double TimeElapsed, out double DecelerationDueToBrake, out double DecelerationDueToMotor) - { - // air compressor - if (Train.Cars[CarIndex].Specs.AirBrake.Type == AirBrakeType.Main) - { - if (Train.Cars[CarIndex].Specs.AirBrake.AirCompressorEnabled) + // brake pipe pressure distribution dummy (just averages) + double TotalPressure = 0.0; + for (int i = 0; i < Cars.Length; i++) { - if (Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure > Train.Cars[CarIndex].Specs.AirBrake.AirCompressorMaximumPressure) + if (i > 0) { - Train.Cars[CarIndex].Specs.AirBrake.AirCompressorEnabled = false; - Train.Cars[CarIndex].Sounds.CpLoopStarted = false; - Sounds.SoundBuffer buffer = Train.Cars[CarIndex].Sounds.CpEnd.Buffer; - if (buffer != null) + if (Cars[i - 1].Derailed | Cars[i].Derailed) { - OpenBveApi.Math.Vector3 pos = Train.Cars[CarIndex].Sounds.CpEnd.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, CarIndex, false); - } - buffer = Train.Cars[CarIndex].Sounds.CpLoop.Buffer; - if (buffer != null) - { - Sounds.StopSound(Train.Cars[CarIndex].Sounds.CpLoop.Source); + Cars[i].CarBrake.brakePipe.CurrentPressure -= Game.BrakePipeLeakRate * TimeElapsed; + if (Cars[i].CarBrake.brakePipe.CurrentPressure < 0.0) Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0; } } - else + if (i < Cars.Length - 1) { - Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure += Train.Cars[CarIndex].Specs.AirBrake.AirCompressorRate * TimeElapsed; - if (!Train.Cars[CarIndex].Sounds.CpLoopStarted && Game.SecondsSinceMidnight > Train.Cars[CarIndex].Sounds.CpStartTimeStarted + 5.0) + if (Cars[i].Derailed | Cars[i + 1].Derailed) { - Train.Cars[CarIndex].Sounds.CpLoopStarted = true; - Sounds.SoundBuffer buffer = Train.Cars[CarIndex].Sounds.CpLoop.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[CarIndex].Sounds.CpLoop.Position; - Train.Cars[CarIndex].Sounds.CpLoop.Source = Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, CarIndex, true); - } + Cars[i].CarBrake.brakePipe.CurrentPressure -= Game.BrakePipeLeakRate * TimeElapsed; + if (Cars[i].CarBrake.brakePipe.CurrentPressure < 0.0) Cars[i].CarBrake.brakePipe.CurrentPressure = 0.0; } } + TotalPressure += Cars[i].CarBrake.brakePipe.CurrentPressure; } - else + double AveragePressure = TotalPressure / (double)Cars.Length; + for (int i = 0; i < Cars.Length; i++) { - if (Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure < Train.Cars[CarIndex].Specs.AirBrake.AirCompressorMinimumPressure) - { - Train.Cars[CarIndex].Specs.AirBrake.AirCompressorEnabled = true; - Train.Cars[CarIndex].Sounds.CpStartTimeStarted = Game.SecondsSinceMidnight; - Sounds.SoundBuffer buffer = Train.Cars[CarIndex].Sounds.CpStart.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[CarIndex].Sounds.CpStart.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, CarIndex, false); - } - } + Cars[i].CarBrake.brakePipe.CurrentPressure = AveragePressure; } } - // initialize - const double Tolerance = 5000.0; - int airsound = -1; - // equalizing reservoir - if (Train.Cars[CarIndex].Specs.AirBrake.Type == AirBrakeType.Main) + + /// Updates the brake system for a car within this train + /// This must remain a property of the train, for easy access to various base properties + /// The induvidual car + /// The frame time elapsed + /// The total brake deceleration this car provides + /// The total motor deceleration this car provides + private void UpdateBrakeSystem(int CarIndex, double TimeElapsed, out double DecelerationDueToBrake, out double DecelerationDueToMotor) { - if (Train.Handles.EmergencyBrake.Actual) - { - double r = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirEmergencyRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure) r = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure -= r; - } - else + DecelerationDueToBrake = 0.0; + // air compressor + if (Cars[CarIndex].CarBrake.brakeType == BrakeType.Main) { - if (Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.AutomaticAirBrake) + if (Cars[CarIndex].CarBrake.airCompressor.Enabled) { - // automatic air brake - if (Train.Handles.AirBrake.Handle.Actual == AirBrakeHandleState.Service) + if (Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure > Cars[CarIndex].CarBrake.mainReservoir.MaximumPressure) { - double r = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirServiceRate; //50000 - double d = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure; //1.05 * max service pressure from train.dat in pascals - r = GetRate(d / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure) r = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure -= r; - } - else if (Train.Handles.AirBrake.Handle.Actual == AirBrakeHandleState.Release) - { - double r = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirChargeRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > d) r = d; - d = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - if (r > d) r = d; - double f = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirEqualizingReservoirCoefficient; - double s = r * f * TimeElapsed; - if (s > Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure) + Cars[CarIndex].CarBrake.airCompressor.Enabled = false; + Cars[CarIndex].Sounds.CpLoopStarted = false; + Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpEnd.Buffer; + if (buffer != null) { - r *= Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure / s; - s = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure; + OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpEnd.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); + } + + buffer = Cars[CarIndex].Sounds.CpLoop.Buffer; + if (buffer != null) + { + Sounds.StopSound(Cars[CarIndex].Sounds.CpLoop.Source); } - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure += 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure -= 0.5 * s; - } - } - else if (Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.ElectromagneticStraightAirBrake) - { - // electromagnetic straight air brake - double r = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirChargeRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > d) r = d; - d = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - if (r > d) r = d; - double f = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirEqualizingReservoirCoefficient; - double s = r * f * TimeElapsed; - if (s > Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure) - { - r *= Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure / s; - s = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure; - } - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure += 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure -= 0.5 * s; - } - } - } - // brake pipe (main reservoir) - if ((Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.AutomaticAirBrake | Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.ElectromagneticStraightAirBrake) & Train.Cars[CarIndex].Specs.AirBrake.Type == AirBrakeType.Main) - { - if (Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure > Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure + Tolerance) - { - // brake pipe exhaust valve - double r = Train.Handles.EmergencyBrake.Actual ? Train.Cars[CarIndex].Specs.AirBrake.BrakePipeEmergencyRate : Train.Cars[CarIndex].Specs.AirBrake.BrakePipeServiceRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure; - r = (0.5 + 1.5 * d / m) * r * TimeElapsed; - if (r > d) r = d; - Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure -= r; - } - else if (Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure + Tolerance < Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure) - { - // fill brake pipe from main reservoir - double r = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeChargeRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.EqualizingReservoirNormalPressure; - r = (0.5 + 1.5 * d / m) * r * TimeElapsed; - if (r > d) r = d; - d = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeNormalPressure - Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; - if (r > d) r = d; - double f = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirBrakePipeCoefficient; - double s = r * f; - if (s > Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure) - { - r *= Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure / s; - s = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure; - } - Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure += 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure -= 0.5 * s; - } - } - // triple valve (auxillary reservoir, brake pipe, brake cylinder) - if (Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.AutomaticAirBrake) - { - if (Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure + Tolerance < Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure) - { - if (Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure + Tolerance < Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure) - { - // back-flow from brake cylinder to auxillary reservoir - double u = (Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure - Tolerance) / Tolerance; - if (u > 1.0) u = 1.0; - double f = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirBrakeCylinderCoefficient; - double r = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceChargeRate * f; - double d = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - r = GetRate(d * u / m, r * TimeElapsed); - if (Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure + r > m) - { - r = m - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - } - if (r > d) r = d; - double s = r / f; - if (s > d) - { - r *= d / s; - s = d; } - if (s > Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure) + else { - r *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure / s; - s = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; + Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure += Cars[CarIndex].CarBrake.airCompressor.Rate * TimeElapsed; + if (!Cars[CarIndex].Sounds.CpLoopStarted && Game.SecondsSinceMidnight > Cars[CarIndex].Sounds.CpStartTimeStarted + 5.0) + { + Cars[CarIndex].Sounds.CpLoopStarted = true; + Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpLoop.Buffer; + if (buffer != null) + { + OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpLoop.Position; + Cars[CarIndex].Sounds.CpLoop.Source = Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, true); + } + } } - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure += 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure -= 0.5 * s; } - else if (Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure > Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure + Tolerance) + else { - // refill brake cylinder from auxillary reservoir - double u = (Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure - Tolerance) / Tolerance; - if (u > 1.0) u = 1.0; - double f = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirBrakeCylinderCoefficient; - double r = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceChargeRate * f; - double d = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - r = GetRate(d * u / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure) - { - r = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - } - if (r > d) r = d; - double s = r / f; - if (s > d) + if (Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure < Cars[CarIndex].CarBrake.mainReservoir.MinimumPressure) { - r *= d / s; - s = d; - } - d = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - if (s > d) - { - r *= d / s; - s = d; - } - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure -= 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure += 0.5 * s; - } - // air sound - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - else if (Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure > Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure + Tolerance) - { - double u = (Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure - Tolerance) / Tolerance; - if (u > 1.0) u = 1.0; - { // refill auxillary reservoir from brake pipe - double r = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirChargeRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - r = GetRate(d * u / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure) - { - r = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; - } - if (r > d) r = d; - d = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirMaximumPressure - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - if (r > d) r = d; - double f = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirBrakePipeCoefficient; - double s = r / f; - if (s > Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure) - { - r *= Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure / s; - s = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; - } - if (s > d) - { - r *= d / s; - s = d; - } - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure += 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure -= 0.5 * s; - } - { // brake cylinder release - double r = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderReleaseRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - r = GetRate(d * u / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure) r = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure -= r; - // air sound - if (r > 0.0 & Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure < Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure) - { - double p = 0.8 * Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure - 0.2 * Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - if (p < 0.0) p = 0.0; - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = p; - airsound = p < Tolerance ? 0 : Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure > m - Tolerance ? 2 : 1; + Cars[CarIndex].CarBrake.airCompressor.Enabled = true; + Cars[CarIndex].Sounds.CpStartTimeStarted = Game.SecondsSinceMidnight; + Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpStart.Buffer; + if (buffer != null) + { + OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpStart.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); + } } } } - else - { - // air sound - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - } - // solenoid valve for electromagnetic straight air brake (auxillary reservoir, electric command, brake cylinder) - if (Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.ElectromagneticStraightAirBrake) - { - // refill auxillary reservoir from brake pipe - if (Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure > Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure + Tolerance) + + if (CarIndex == DriverCar && Handles.HasLocoBrake) { - double r = 2.0 * Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirChargeRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirMaximumPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure) - { - r = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; - } - if (r > d) r = d; - d = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirMaximumPressure - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - if (r > d) r = d; - double f = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirBrakePipeCoefficient; - double s = r / f; - if (s > Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure) - { - r *= Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure / s; - s = Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; - } - if (s > d) - { - r *= d / s; - s = d; - } - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure += 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure -= 0.5 * s; - } - { // electric command - bool emergency; - if (Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure + Tolerance < Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure) + switch (Handles.LocoBrakeType) { - emergency = true; - } - else - { - emergency = Train.Handles.EmergencyBrake.Actual; - } - double targetPressure; - if (emergency) - { - //If EB is selected, then target pressure must be that required for EB - targetPressure = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - else - { - //Otherwise [BVE2 / BVE4 train.dat format] work out target pressure as a proportion of the max notch: - targetPressure = (double)Train.Handles.Brake.Actual / (double)Train.Handles.Brake.MaximumNotch; - switch (Train.Handles.LocoBrake.BrakeType) - { - case LocoBrakeType.Combined: - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) + case LocoBrakeType.Independant: + //With an independant Loco brake, we always want to use this handle + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); + break; + case LocoBrakeType.Combined: + if (Handles.LocoBrake is LocoBrakeHandle && Handles.Brake is NotchedHandle) + { + //Both handles are of the notched type + if (Handles.Brake.MaximumNotch == Handles.LocoBrake.MaximumNotch) { - double locoTargetPressure = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - targetPressure = Math.Max(locoTargetPressure, targetPressure); + //Identical number of notches, so return the handle with the higher setting + if (Handles.LocoBrake.Actual >= Handles.Brake.Actual) + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); + } + else + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); + } } - break; - case LocoBrakeType.Independant: - if (CarIndex == Train.DriverCar) + else if (Handles.Brake.MaximumNotch > Handles.LocoBrake.MaximumNotch) { - //The locomotive brake is independant, so if the driver car return it's - targetPressure = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; + double nc = ((double) Handles.LocoBrake.Actual / Handles.LocoBrake.MaximumNotch) * Handles.Brake.MaximumNotch; + if (nc > Handles.Brake.Actual) + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); + } + else + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); + } } - break; - case LocoBrakeType.Blocking: - if (Train.Handles.LocoBrake.Actual != 0) + else { - //The locomotive brake application has blocked the release of the train brakes - targetPressure = 1.0; + double nc = ((double) Handles.Brake.Actual / Handles.Brake.MaximumNotch) * Handles.LocoBrake.MaximumNotch; + if (nc > Handles.LocoBrake.Actual) + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); + } + else + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); + } } - break; - } - targetPressure *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - } - if (Train.Cars[CarIndex].Specs.IsMotorCar & !Train.Handles.EmergencyBrake.Actual & Train.Handles.Reverser.Actual != 0) - { - //If we meet the conditions for brake control system to activate - if (Math.Abs(Train.Cars[CarIndex].Specs.CurrentSpeed) > Train.Cars[CarIndex].Specs.BrakeControlSpeed) - { - if (Train.Cars[CarIndex].Specs.ElectropneumaticType == EletropneumaticBrakeType.ClosingElectromagneticValve) + } + else if (Handles.LocoBrake is LocoAirBrakeHandle && Handles.Brake is AirBrakeHandle) { - //When above the brake control speed, pressure to the BC is nil & electric brakes are used - //Thus target pressure must be zero - targetPressure = 0.0; + if (Handles.LocoBrake.Actual < Handles.Brake.Actual) + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); + } + else + { + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); + } } - else if (Train.Cars[CarIndex].Specs.ElectropneumaticType == EletropneumaticBrakeType.DelayFillingControl) + else { - //Motor is used to brake the train, until not enough deceleration, at which point the air brake is also used - double a = Train.Cars[CarIndex].Specs.MotorDeceleration; - double pr = targetPressure / Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - double b; - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) + double p, tp; + //Calculate the pressure differentials for the two handles + if (Handles.LocoBrake is LocoAirBrakeHandle) { - b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.LocoBrake.Actual); + //Air brake handle + p = Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure; + tp = (Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure / Handles.Brake.MaximumNotch) * Handles.Brake.Actual; } else { - b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.Brake.Actual); + //Notched handle + p = Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure; + tp = (Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure / Handles.LocoBrake.MaximumNotch) * Handles.LocoBrake.Actual; } - double d = b - a; - if (d > 0.0) + if (p < tp) { - //Deceleration provided by the motor is not enough, so increase the BC target pressure - targetPressure = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.Brake.Actual);; - switch (Train.Handles.LocoBrake.BrakeType) - { - case LocoBrakeType.Combined: - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) - { - double locoTargetPressure = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.LocoBrake.Actual);; - targetPressure = Math.Max(locoTargetPressure, targetPressure); - } - - break; - case LocoBrakeType.Independant: - if (CarIndex == Train.DriverCar) - { - //The locomotive brake is independant, so if the driver car return it's - targetPressure = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.LocoBrake.Actual);; - } - - break; - case LocoBrakeType.Blocking: - if (Train.Handles.LocoBrake.Actual != 0) - { - //The locomotive brake application has blocked the release of the train brakes - targetPressure = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.LocoBrake.Actual); - } - break; - } - if (targetPressure > 1.0) targetPressure = 1.0; - targetPressure *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } else { - //Motor deceleration is enough, BC target pressure to zero - targetPressure = 0.0; + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } } - } - } - if (Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure > targetPressure + Tolerance | targetPressure == 0.0) - { - //BC pressure is greater than the target pressure, so release pressure - double r = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderReleaseRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure - targetPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure) r = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - if (r > d) r = d; - // air sound - if (r > 0.0 & Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure < Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure) - { - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = targetPressure; - airsound = targetPressure < Tolerance ? 0 : Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure > m - Tolerance ? 2 : 1; - } - // pressure change - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure -= r; - } - else if (Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure + Tolerance < targetPressure) - { - //BC pressure is less than target pressure, so increase pressure - double f = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirBrakeCylinderCoefficient; - double r; - if (emergency) - { - r = 2.0 * Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyChargeRate * f; - } - else - { - r = 2.0 * Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceChargeRate * f; - } - double d = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure) - { - r = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure; - } - if (r > d) r = d; - double s = r / f; - if (s > d) - { - r *= d / s; - s = d; - } - d = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - if (s > d) - { - r *= d / s; - s = d; - } - Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirCurrentPressure -= 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure += 0.5 * s; - // air sound - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - else - { - // air sound - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - } - } - // valves for electric command brake (main reservoir, electric command, brake cylinder) - if (Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.ElectricCommandBrake) - { - double p; if (Train.Handles.EmergencyBrake.Actual) - { - p = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - else - { - p = (double)Train.Handles.Brake.Actual / (double)Train.Handles.Brake.MaximumNotch; - switch (Train.Handles.LocoBrake.BrakeType) - { - case LocoBrakeType.Combined: - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) - { - double locoTargetPressure = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - p = Math.Max(locoTargetPressure, p); - } - - break; - case LocoBrakeType.Independant: - if (CarIndex == Train.DriverCar) - { - //The locomotive brake is independant, so if the driver car return it's - p = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - } - break; case LocoBrakeType.Blocking: - if (Train.Handles.LocoBrake.Actual != 0) - { - //The locomotive brake application has blocked the release of the train brakes - p = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - } - break; - } - p *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - } - if (!Train.Handles.EmergencyBrake.Actual & Train.Handles.Reverser.Actual != 0) - { - // brake control system - if (Train.Cars[CarIndex].Specs.IsMotorCar & Math.Abs(Train.Cars[CarIndex].Specs.CurrentSpeed) > Train.Cars[CarIndex].Specs.BrakeControlSpeed) - { - if (Train.Cars[CarIndex].Specs.ElectropneumaticType == EletropneumaticBrakeType.ClosingElectromagneticValve) - { - // closing electromagnetic valve (lock-out valve) - p = 0.0; - } - else if (Train.Cars[CarIndex].Specs.ElectropneumaticType == EletropneumaticBrakeType.DelayFillingControl) - { - // delay-filling control - double a = Train.Cars[CarIndex].Specs.MotorDeceleration; - double pr = p / Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - double b; - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) + if (Handles.LocoBrake.Actual != 0) { - b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.LocoBrake.Actual); + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake); } else { - b = pr * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.Brake.Actual); + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } - double d = b - a; - if (d > 0.0) - { - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) - { - p = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.LocoBrake.Actual); - } - else - { - p = d / Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.Brake.Actual); - } - if (p > 1.0) p = 1.0; - p *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - } - else - { - p = 0.0; - } - } + break; } + } - if (Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure > p + Tolerance | p == 0.0) + else { - // brake cylinder exhaust valve - double r = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderReleaseRate; - double d = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > d) r = d; - // air sound - if (r > 0.0 & Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure < Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure) - { - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = p; - airsound = p < Tolerance ? 0 : Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure > m - Tolerance ? 2 : 1; - } - // pressure change - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure -= r; + Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake); } - else if ((Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure + Tolerance < p | p == Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure) & Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure + Tolerance < Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure) + + + switch (Cars[CarIndex].CarBrake.airSound) { - // fill brake cylinder from main reservoir - double r; - if (Train.Handles.EmergencyBrake.Actual) + case AirSound.AirZero: { - r = 2.0 * Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyChargeRate; + Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.AirZero.Buffer; + if (buffer != null) + { + OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.AirZero.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); + } + + break; } - else + case AirSound.Air: { - r = 2.0 * Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceChargeRate; + Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.Air.Buffer; + if (buffer != null) + { + OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.Air.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); + } + break; } - double pm = p < Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure ? p : Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure; - double d = pm - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > d) r = d; - double f1 = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirBrakeCylinderCoefficient; - double f2 = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirBrakePipeCoefficient; - double f3 = Train.Cars[CarIndex].Specs.AirBrake.AuxillaryReservoirBrakePipeCoefficient; - double f = f1 * f2 / f3; // MainReservoirBrakeCylinderCoefficient - double s = r * f; - if (s > Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure) + case AirSound.AirHigh: { - r *= Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure / s; - s = Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure; + Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.AirHigh.Buffer; + if (buffer != null) + { + OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.AirHigh.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false); + } + break; } - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure += 0.5 * r; - Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure -= 0.5 * s; - // air sound - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; } - else - { - // air sound - Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderSoundPlayedForPressure = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - } - // straight air pipe (for compatibility needle only) - if (Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.ElectromagneticStraightAirBrake & Train.Cars[CarIndex].Specs.AirBrake.Type == AirBrakeType.Main) - { - double p; if (Train.Handles.EmergencyBrake.Actual) - { - p = 0.0; - } - else - { - p = (double)Train.Handles.Brake.Actual / (double)Train.Handles.Brake.MaximumNotch; - switch (Train.Handles.LocoBrake.BrakeType) - { - case LocoBrakeType.Combined: - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) - { - double locoTargetPressure = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - p = Math.Max(locoTargetPressure, p); - } - - break; - case LocoBrakeType.Independant: - if (CarIndex == Train.DriverCar) - { - //The locomotive brake is independant, so if the driver car return it's - p = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - } - break; - case LocoBrakeType.Blocking: - if (Train.Handles.LocoBrake.Actual != 0) - { - //The locomotive brake application has blocked the release of the train brakes - p = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - } - break; - } - p *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - } - if (p + Tolerance < Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure) + // deceleration provided by motor + if (!(Cars[CarIndex].CarBrake is AutomaticAirBrake) && Math.Abs(Cars[CarIndex].Specs.CurrentSpeed) >= Cars[CarIndex].CarBrake.brakeControlSpeed & Handles.Reverser.Actual != 0 & !Handles.EmergencyBrake.Actual) { - double r; - if (Train.Handles.EmergencyBrake.Actual) + double f; + if (Handles.LocoBrake.Actual != 0 && CarIndex == DriverCar) { - r = Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeEmergencyRate; + f = (double) Handles.LocoBrake.Actual / (double) Handles.Brake.MaximumNotch; } else { - r = Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeReleaseRate; + f = (double) Handles.Brake.Actual / (double) Handles.Brake.MaximumNotch; } - double d = Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure - p; - double m = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > d) r = d; - Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure -= r; - } - else if (p > Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure + Tolerance) - { - double r = Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeServiceRate; - double d = p - Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure; - double m = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - r = GetRate(d / m, r * TimeElapsed); - if (r > d) r = d; - Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure += r; - } - } - else if (Train.Cars[CarIndex].Specs.BrakeType == CarBrakeType.ElectricCommandBrake) - { - double p; - if (Train.Handles.EmergencyBrake.Actual) - { - p = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderEmergencyMaximumPressure; - } - else - { - p = (double)Train.Handles.Brake.Actual / (double)Train.Handles.Brake.MaximumNotch; - switch (Train.Handles.LocoBrake.BrakeType) - { - case LocoBrakeType.Combined: - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) - { - double locoTargetPressure = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - p = Math.Max(locoTargetPressure, p); - } - break; - case LocoBrakeType.Independant: - if (CarIndex == Train.DriverCar) - { - //The locomotive brake is independant, so if the driver car return it's - p = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - } - - break; - case LocoBrakeType.Blocking: - if (Train.Handles.LocoBrake.Actual != 0) - { - //The locomotive brake application has blocked the release of the train brakes - p = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.LocoBrake.MaximumNotch; - } - break; - } - p *= Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - } - Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure = p; - } - // air sound - if (airsound == 0) - { - // air zero - Sounds.SoundBuffer buffer = Train.Cars[CarIndex].Sounds.AirZero.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[CarIndex].Sounds.AirZero.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, CarIndex, false); - } - } - else if (airsound == 1) - { - // air - Sounds.SoundBuffer buffer = Train.Cars[CarIndex].Sounds.Air.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[CarIndex].Sounds.Air.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, CarIndex, false); - } - } - else if (airsound == 2) - { - // air high - Sounds.SoundBuffer buffer = Train.Cars[CarIndex].Sounds.AirHigh.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[CarIndex].Sounds.AirHigh.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, CarIndex, false); - } - } - // deceleration provided by brake - double pressureratio = Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure / Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderServiceMaximumPressure; - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) - { - DecelerationDueToBrake = pressureratio * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.LocoBrake.Actual); - } - else - { - DecelerationDueToBrake = pressureratio * Train.Cars[CarIndex].Specs.BrakeDecelerationAtServiceMaximumPressure(Train.Handles.Brake.Actual); - } - - // deceleration provided by motor - if (Train.Cars[CarIndex].Specs.BrakeType != CarBrakeType.AutomaticAirBrake && Math.Abs(Train.Cars[CarIndex].Specs.CurrentSpeed) >= Train.Cars[CarIndex].Specs.BrakeControlSpeed & Train.Handles.Reverser.Actual != 0 & !Train.Handles.EmergencyBrake.Actual) - { - double f; - if (Train.Handles.LocoBrake.Actual != 0 && CarIndex == Train.DriverCar) - { - f = (double)Train.Handles.LocoBrake.Actual / (double)Train.Handles.Brake.MaximumNotch; + double a = Cars[CarIndex].Specs.MotorDeceleration; + DecelerationDueToMotor = f * a; } else { - f = (double)Train.Handles.Brake.Actual / (double)Train.Handles.Brake.MaximumNotch; + DecelerationDueToMotor = 0.0; } - - double a = Train.Cars[CarIndex].Specs.MotorDeceleration; - DecelerationDueToMotor = f * a; - } - else - { - DecelerationDueToMotor = 0.0; - } - // hold brake - Train.Cars[CarIndex].Specs.HoldBrake.Update(ref DecelerationDueToMotor, Train.Handles.HoldBrake.Actual); - { // rub sound - Sounds.SoundBuffer buffer = Train.Cars[CarIndex].Sounds.Rub.Buffer; - if (buffer != null) + + // hold brake + Cars[CarIndex].Specs.HoldBrake.Update(ref DecelerationDueToMotor, Handles.HoldBrake.Actual); { - double spd = Math.Abs(Train.Cars[CarIndex].Specs.CurrentSpeed); - double pitch = 1.0 / (spd + 1.0) + 1.0; - double gain = Train.Cars[CarIndex].Derailed ? 0.0 : pressureratio; - if (spd < 1.38888888888889) - { - double t = spd * spd; - gain *= 1.5552 * t - 0.746496 * spd * t; - } - else if (spd > 12.5) - { - double t = spd - 12.5; - const double fadefactor = 0.1; - gain *= 1.0 / (fadefactor * t * t + 1.0); - } - if (Sounds.IsPlaying(Train.Cars[CarIndex].Sounds.Rub.Source)) + // rub sound + Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.Rub.Buffer; + if (buffer != null) { - if (pitch > 0.01 & gain > 0.001) + double spd = Math.Abs(Cars[CarIndex].Specs.CurrentSpeed); + double pitch = 1.0 / (spd + 1.0) + 1.0; + double gain = Cars[CarIndex].Derailed ? 0.0 : Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure; + if (spd < 1.38888888888889) { - Train.Cars[CarIndex].Sounds.Rub.Source.Pitch = pitch; - Train.Cars[CarIndex].Sounds.Rub.Source.Volume = gain; + double t = spd * spd; + gain *= 1.5552 * t - 0.746496 * spd * t; } - else + else if (spd > 12.5) { - Sounds.StopSound(Train.Cars[CarIndex].Sounds.Rub.Source); + double t = spd - 12.5; + const double fadefactor = 0.1; + gain *= 1.0 / (fadefactor * t * t + 1.0); } - } - else if (pitch > 0.02 & gain > 0.01) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[CarIndex].Sounds.Rub.Position; - Train.Cars[CarIndex].Sounds.Rub.Source = Sounds.PlaySound(buffer, pitch, gain, pos, Train, CarIndex, true); - } - } - } - } - private static double GetRate(double Ratio, double Factor) - { - Ratio = Ratio < 0.0 ? 0.0 : Ratio > 1.0 ? 1.0 : Ratio; - Ratio = 1.0 - Ratio; - return 1.5 * Factor * (1.01 - Ratio * Ratio); - } - /// Applies the emergency brake - /// The train - internal static void ApplyEmergencyBrake(Train Train) - { - // sound - if (!Train.Handles.EmergencyBrake.Driver) - { - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleMax.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleMax.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - for (int i = 0; i < Train.Cars.Length; i++) - { - buffer = Train.Cars[Train.DriverCar].Sounds.EmrBrake.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[i].Sounds.EmrBrake.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - } - } - // apply - Train.ApplyNotch(0, !Train.Handles.SingleHandle, Train.Handles.Brake.MaximumNotch, true); - ApplyAirBrakeHandle(Train, AirBrakeHandleState.Service); - Train.Handles.EmergencyBrake.Driver = true; - Train.Handles.HoldBrake.Driver = false; - Train.Specs.CurrentConstSpeed = false; - if (Train.Handles.EmergencyBrake.Driver) - { - switch (Train.Handles.EmergencyBrake.OtherHandlesBehaviour) - { - case EbHandleBehaviour.PowerNeutral: - if (!Train.Handles.SingleHandle) + if (Sounds.IsPlaying(Cars[CarIndex].Sounds.Rub.Source)) { - Train.ApplyNotch(0, false, 0, true); + if (pitch > 0.01 & gain > 0.001) + { + Cars[CarIndex].Sounds.Rub.Source.Pitch = pitch; + Cars[CarIndex].Sounds.Rub.Source.Volume = gain; + } + else + { + Sounds.StopSound(Cars[CarIndex].Sounds.Rub.Source); + } } - break; - case EbHandleBehaviour.ReverserNeutral: - TrainManager.ApplyReverser(Train, 0, false); - break; - case EbHandleBehaviour.PowerReverserNeutral: - if (!Train.Handles.SingleHandle) + else if (pitch > 0.02 & gain > 0.01) { - Train.ApplyNotch(0, false, 0, true); + OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.Rub.Position; + Cars[CarIndex].Sounds.Rub.Source = Sounds.PlaySound(buffer, pitch, gain, pos, this, CarIndex, true); } - TrainManager.ApplyReverser(Train, 0, false); - break; - } - } - - // plugin - if (Train.Plugin == null) return; - Train.Plugin.UpdatePower(); - Train.Plugin.UpdateBrake(); - } - - /// Releases the emergency brake - /// The train - internal static void UnapplyEmergencyBrake(Train Train) - { - if (Train.Handles.EmergencyBrake.Driver) - { - // sound - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleRelease.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleRelease.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); + } } - // apply - Train.ApplyNotch(0, !Train.Handles.SingleHandle, Train.Handles.Brake.MaximumNotch, true); - ApplyAirBrakeHandle(Train, AirBrakeHandleState.Service); - Train.Handles.EmergencyBrake.Driver = false; - // plugin - if (Train.Plugin == null) return; - Train.Plugin.UpdatePower(); - Train.Plugin.UpdateBrake(); } - } - /// Applies or releases the hold brake - /// The train - /// Whether to apply (TRUE) or release (FALSE) - internal static void ApplyHoldBrake(Train Train, bool Value) - { - Train.Handles.HoldBrake.Driver = Value; - if (Train.Plugin == null) return; - Train.Plugin.UpdatePower(); - Train.Plugin.UpdateBrake(); } } } diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Abstract.cs b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Abstract.cs index 7c3f1f530..86abddcae 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Abstract.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Abstract.cs @@ -9,21 +9,26 @@ namespace OpenBve */ public static partial class TrainManager { - /// Represents an abstract handle with a set number of notches - internal abstract class NotchedHandle + internal abstract class AbstractHandle { - /// The maximum notch this handle can be increased to - internal int MaximumNotch; - /// The notch set by the driver internal int Driver; - /// The notch set by the safety system (Train plugin) + internal int Safety; - /// The actual notch + internal int Actual; + + internal int MaximumNotch; + + internal HandleChange[] DelayedChanges; + + internal abstract void Update(); + } + /// Represents an abstract handle with a set number of notches + internal abstract class NotchedHandle : AbstractHandle + { + /// The number of steps this handle must be reduced by for a change to take effect internal int ReduceSteps; - /// The delayed handle state changes - internal HandleChange[] DelayedChanges; /// The list of delay values for each notch increase internal double[] DelayUp; /// The list of delay values for each notch decrease @@ -50,7 +55,6 @@ internal void RemoveChanges(int Count) Array.Resize(ref DelayedChanges, n - Count); } - internal abstract void Update(); /// Gets the delay value for this handle /// Whether this is an increase or a decrease @@ -82,6 +86,7 @@ internal double GetDelay(bool Increase) return DelayUp[DelayUp.Length - 1]; } + } } } diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.AirBrake.cs b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.AirBrake.cs index 1f39418e0..ab9c825e9 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.AirBrake.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.AirBrake.cs @@ -3,42 +3,36 @@ public static partial class TrainManager { /// Represents an air-brake handle - internal class AirBrakeHandle + internal class AirBrakeHandle : AbstractHandle { - /// The position set by the driver - internal AirBrakeHandleState Driver; - /// The position set by the safety system (Train plugin) - internal AirBrakeHandleState Safety; - /// The actual position - internal AirBrakeHandleState Actual; private AirBrakeHandleState DelayedValue; private double DelayedTime; - internal void Update() + internal override void Update() { if (DelayedValue != AirBrakeHandleState.Invalid) { if (DelayedTime <= Game.SecondsSinceMidnight) { - Actual = DelayedValue; + Actual = (int)DelayedValue; DelayedValue = AirBrakeHandleState.Invalid; } } else { - if (Safety == AirBrakeHandleState.Release & Actual != AirBrakeHandleState.Release) + if (Safety == (int)AirBrakeHandleState.Release & Actual != (int)AirBrakeHandleState.Release) { DelayedValue = AirBrakeHandleState.Release; DelayedTime = Game.SecondsSinceMidnight; } - else if (Safety == AirBrakeHandleState.Service & Actual != AirBrakeHandleState.Service) + else if (Safety == (int)AirBrakeHandleState.Service & Actual != (int)AirBrakeHandleState.Service) { DelayedValue = AirBrakeHandleState.Service; DelayedTime = Game.SecondsSinceMidnight; } - else if (Safety == AirBrakeHandleState.Lap) + else if (Safety == (int)AirBrakeHandleState.Lap) { - Actual = AirBrakeHandleState.Lap; + Actual = (int)AirBrakeHandleState.Lap; } } } diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Brake.cs b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Brake.cs index d2476a3a1..e74808d74 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Brake.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Brake.cs @@ -1,6 +1,4 @@ -using System; - -namespace OpenBve +namespace OpenBve { public static partial class TrainManager { @@ -13,6 +11,7 @@ internal BrakeHandle(int max, EmergencyHandle eb, double[] delayUp, double[] del this.EmergencyBrake = eb; this.DelayUp = delayUp; this.DelayDown = delayDown; + this.DelayedChanges = new HandleChange[] { }; } /// Provides a reference to the associated EB handle diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Eb.Behaviour.cs b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Eb.Behaviour.cs index 943d2a31b..56af6132a 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Eb.Behaviour.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Eb.Behaviour.cs @@ -3,7 +3,7 @@ /// The TrainManager is the root class containing functions to load and manage trains within the simulation world. public static partial class TrainManager { - /// Defines the behaviour of the other handles (Power & brake) when the EB is activated + /// Defines the behaviour of the other handles (Power and brake) when the EB is activated internal enum EbHandleBehaviour { /// No action is taken diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.LocoBrake.cs b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.LocoBrake.cs index ace5feded..d8402761b 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.LocoBrake.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.LocoBrake.cs @@ -15,8 +15,6 @@ internal LocoBrakeHandle(int max, EmergencyHandle eb, double[] delayUp, double[] /// Provides a reference to the associated EB handle private readonly EmergencyHandle EmergencyBrake; - /// The type of locomotive brake fitted - internal LocoBrakeType BrakeType = LocoBrakeType.Combined; internal override void Update() { @@ -54,5 +52,40 @@ internal override void Update() } } } + + internal class LocoAirBrakeHandle : AbstractHandle + { + private AirBrakeHandleState DelayedValue; + private double DelayedTime; + + internal override void Update() + { + if (DelayedValue != AirBrakeHandleState.Invalid) + { + if (DelayedTime <= Game.SecondsSinceMidnight) + { + Actual = (int)DelayedValue; + DelayedValue = AirBrakeHandleState.Invalid; + } + } + else + { + if (Safety == (int)AirBrakeHandleState.Release & Actual != (int)AirBrakeHandleState.Release) + { + DelayedValue = AirBrakeHandleState.Release; + DelayedTime = Game.SecondsSinceMidnight; + } + else if (Safety == (int)AirBrakeHandleState.Service & Actual != (int)AirBrakeHandleState.Service) + { + DelayedValue = AirBrakeHandleState.Service; + DelayedTime = Game.SecondsSinceMidnight; + } + else if (Safety == (int)AirBrakeHandleState.Lap) + { + Actual = (int)AirBrakeHandleState.Lap; + } + } + } + } } } diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Reverser.cs b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Reverser.cs index 9fa15ce0f..36622ab85 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Reverser.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.Reverser.cs @@ -3,12 +3,18 @@ public static partial class TrainManager { /// Represnts a reverser handle - internal struct ReverserHandle + internal class ReverserHandle { /// The notch set by the driver internal ReverserPosition Driver; /// The actual notch internal ReverserPosition Actual; + + internal ReverserHandle() + { + Driver = ReverserPosition.Neutral; + Actual = ReverserPosition.Neutral; + } } } } diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.cs b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.cs index f97d4a2ef..687c9db6a 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Handles/Handles.cs @@ -10,22 +10,21 @@ internal struct Handles /// The Power internal PowerHandle Power; /// The Brake - internal BrakeHandle Brake; + internal AbstractHandle Brake; /// The Loco brake handle - internal LocoBrakeHandle LocoBrake; + internal AbstractHandle LocoBrake; /// The Emergency Brake internal EmergencyHandle EmergencyBrake; /// The Hold Brake internal HoldBrakeHandle HoldBrake; - /// The Air Brake - internal TrainAirBrake AirBrake; - /// - /// Whether the train has a combined power and brake handle + /// Whether the train has a combined power and brake handle internal bool SingleHandle; /// Whether the train has the Hold Brake fitted internal bool HasHoldBrake; /// Whether the train has a locomotive brake internal bool HasLocoBrake; + /// The loco brake type + internal LocoBrakeType LocoBrakeType; } internal struct HandleChange diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Horn.cs b/source/OpenBVE/Simulation/TrainManager/Train/Horn.cs index 3d6e32513..0999c4a9a 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Horn.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Horn.cs @@ -60,9 +60,15 @@ internal void Play() //The start sound is not currently playing, so start it Source = Sounds.PlaySound(StartSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, false); + + //Set the loop control variable to started + LoopStarted = true; + } + else + { + Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, + TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, true); } - //Set the loop control variable to started - LoopStarted = true; } } else diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Reverser.cs b/source/OpenBVE/Simulation/TrainManager/Train/Reverser.cs index af12313b8..d3c81682a 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Reverser.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Reverser.cs @@ -2,40 +2,6 @@ { public static partial class TrainManager { - /// Applies a reverser notch - /// The train - /// The notch to apply - /// Whether this is an absolute value or relative to the previous - internal static void ApplyReverser(Train Train, int Value, bool Relative) - { - int a = (int)Train.Handles.Reverser.Driver; - int r = Relative ? a + Value : Value; - if (r < -1) r = -1; - if (r > 1) r = 1; - if (a != r) - { - Train.Handles.Reverser.Driver = (ReverserPosition)r; - if (Train.Plugin != null) - { - Train.Plugin.UpdateReverser(); - } - Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); - // sound - if (a == 0 & r != 0) - { - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.ReverserOn.Buffer; - if (buffer == null) return; - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.ReverserOn.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - else if (a != 0 & r == 0) - { - Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.ReverserOff.Buffer; - if (buffer == null) return; - OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.ReverserOff.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false); - } - } - } + } } diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Train.Handles.cs b/source/OpenBVE/Simulation/TrainManager/Train/Train.Handles.cs new file mode 100644 index 000000000..5d7ce1415 --- /dev/null +++ b/source/OpenBVE/Simulation/TrainManager/Train/Train.Handles.cs @@ -0,0 +1,517 @@ +using OpenBveApi.Math; + +namespace OpenBve +{ + /// The TrainManager is the root class containing functions to load and manage trains within the simulation world. + public static partial class TrainManager + { + /// The root class for a train within the simulation + public partial class Train + { + /// Applies a power and / or brake notch to this train + /// The power notch value + /// Whether this is relative to the current notch + /// The brake notch value + /// Whether this is relative to the current notch + internal void ApplyNotch(int PowerValue, bool PowerRelative, int BrakeValue, bool BrakeRelative) + { + // determine notch + int p = PowerRelative ? PowerValue + Handles.Power.Driver : PowerValue; + if (p < 0) + { + p = 0; + } + else if (p > Handles.Power.MaximumNotch) + { + p = Handles.Power.MaximumNotch; + } + + int b = BrakeRelative ? BrakeValue + Handles.Brake.Driver : BrakeValue; + if (b < 0) + { + b = 0; + } + else if (b > Handles.Brake.MaximumNotch) + { + b = Handles.Brake.MaximumNotch; + } + + // power sound + if (p < Handles.Power.Driver) + { + if (p > 0) + { + // down (not min) + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerDown.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.MasterControllerDown.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + else + { + // min + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMin.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMin.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + else if (p > Handles.Power.Driver) + { + if (p < Handles.Power.MaximumNotch) + { + // up (not max) + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerUp.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.MasterControllerUp.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + else + { + // max + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMax.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMax.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + + // brake sound + if (b < Handles.Brake.Driver) + { + // brake release + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.Brake.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + + if (b > 0) + { + // brake release (not min) + buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + else + { + // brake min + buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + else if (b > Handles.Brake.Driver) + { + // brake + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + + // apply notch + if (Handles.SingleHandle) + { + if (b != 0) p = 0; + } + + Handles.Power.Driver = p; + Handles.Brake.Driver = b; + Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); + // plugin + if (Plugin != null) + { + Plugin.UpdatePower(); + Plugin.UpdateBrake(); + } + } + + /// Applies a loco brake notch to this train + /// The loco brake notch value + /// Whether this is relative to the current notch + internal void ApplyLocoBrakeNotch(int NotchValue, bool Relative) + { + int b = Relative ? NotchValue + Handles.LocoBrake.Driver : NotchValue; + if (b < 0) + { + b = 0; + } + else if (b > Handles.LocoBrake.MaximumNotch) + { + b = Handles.LocoBrake.MaximumNotch; + } + + // brake sound + if (b < Handles.LocoBrake.Driver) + { + // brake release + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.Brake.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + + if (b > 0) + { + // brake release (not min) + buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + else + { + // brake min + buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + else if (b > Handles.LocoBrake.Driver) + { + // brake + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + + Handles.LocoBrake.Driver = b; + Handles.LocoBrake.Actual = b; //TODO: FIXME + } + + /// Applies a reverser notch + /// The notch to apply + /// Whether this is an absolute value or relative to the previous + internal void ApplyReverser(int Value, bool Relative) + { + int a = (int)Handles.Reverser.Driver; + int r = Relative ? a + Value : Value; + if (r < -1) r = -1; + if (r > 1) r = 1; + if (a != r) + { + Handles.Reverser.Driver = (ReverserPosition)r; + if (Plugin != null) + { + Plugin.UpdateReverser(); + } + Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); + // sound + if (a == 0 & r != 0) + { + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.ReverserOn.Buffer; + if (buffer == null) return; + Vector3 pos = Cars[DriverCar].Sounds.ReverserOn.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + else if (a != 0 & r == 0) + { + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.ReverserOff.Buffer; + if (buffer == null) return; + Vector3 pos = Cars[DriverCar].Sounds.ReverserOff.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + + /// Applies the emergency brake + internal void ApplyEmergencyBrake() + { + // sound + if (!Handles.EmergencyBrake.Driver) + { + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMax.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMax.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + + for (int i = 0; i < Cars.Length; i++) + { + buffer = Cars[DriverCar].Sounds.EmrBrake.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[i].Sounds.EmrBrake.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + + // apply + ApplyNotch(0, !Handles.SingleHandle, Handles.Brake.MaximumNotch, true); + ApplyAirBrakeHandle(AirBrakeHandleState.Service); + Handles.EmergencyBrake.Driver = true; + Handles.HoldBrake.Driver = false; + Specs.CurrentConstSpeed = false; + if (Handles.EmergencyBrake.Driver) + { + switch (Handles.EmergencyBrake.OtherHandlesBehaviour) + { + case EbHandleBehaviour.PowerNeutral: + if (!Handles.SingleHandle) + { + ApplyNotch(0, false, 0, true); + } + + break; + case EbHandleBehaviour.ReverserNeutral: + ApplyReverser(0, false); + break; + case EbHandleBehaviour.PowerReverserNeutral: + if (!Handles.SingleHandle) + { + ApplyNotch(0, false, 0, true); + } + + ApplyReverser(0, false); + break; + } + } + + // plugin + if (Plugin == null) return; + Plugin.UpdatePower(); + Plugin.UpdateBrake(); + } + + /// Releases the emergency brake + internal void UnapplyEmergencyBrake() + { + if (Handles.EmergencyBrake.Driver) + { + // sound + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + + // apply + + if (Handles.Brake is AirBrakeHandle) + { + ApplyAirBrakeHandle(AirBrakeHandleState.Service); + } + else + { + ApplyNotch(0, !Handles.SingleHandle, Handles.Brake.MaximumNotch, true); + } + Handles.EmergencyBrake.Driver = false; + // plugin + if (Plugin == null) return; + Plugin.UpdatePower(); + Plugin.UpdateBrake(); + } + } + + /// Applies or releases the hold brake + /// Whether to apply (TRUE) or release (FALSE) + internal void ApplyHoldBrake(bool Value) + { + Handles.HoldBrake.Driver = Value; + if (Plugin == null) return; + Plugin.UpdatePower(); + Plugin.UpdateBrake(); + } + + /// Moves the air brake handle + /// The direction: -1 for decrease, 1 for increase + internal void ApplyAirBrakeHandle(int RelativeDirection) + { + if (Handles.Brake is AirBrakeHandle) + { + if (RelativeDirection == -1) + { + if (Handles.Brake.Driver == (int) AirBrakeHandleState.Service) + { + ApplyAirBrakeHandle(AirBrakeHandleState.Lap); + } + else + { + ApplyAirBrakeHandle(AirBrakeHandleState.Release); + } + } + else if (RelativeDirection == 1) + { + if (Handles.Brake.Driver == (int) AirBrakeHandleState.Release) + { + ApplyAirBrakeHandle(AirBrakeHandleState.Lap); + } + else + { + ApplyAirBrakeHandle(AirBrakeHandleState.Service); + } + } + + Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); + } + } + + /// Moves the air brake handle to the specified state + /// The new state + internal void ApplyAirBrakeHandle(AirBrakeHandleState newState) + { + if (Handles.Brake is AirBrakeHandle) + { + if ((int) newState != Handles.Brake.Driver) + { + // sound when moved to service + if (newState == AirBrakeHandleState.Service) + { + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.Brake.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + + // sound + if ((int) newState < (int) Handles.Brake.Driver) + { + // brake release + if ((int) newState > 0) + { + // brake release (not min) + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + else + { + // brake min + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + else if ((int) newState > (int) Handles.Brake.Driver) + { + // brake + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + + // apply + Handles.Brake.Driver = (int) newState; + Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); + // plugin + if (Plugin != null) + { + Plugin.UpdatePower(); + Plugin.UpdateBrake(); + } + } + } + } + + /// Moves the air brake handle to the specified state + /// The state + internal void ApplyLocoAirBrakeHandle(AirBrakeHandleState newState) + { + if (Handles.LocoBrake is LocoAirBrakeHandle) + { + if ((int) newState != Handles.LocoBrake.Driver) + { + // sound when moved to service + if (newState == AirBrakeHandleState.Service) + { + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.Brake.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + + // sound + if ((int) newState < (int) Handles.Brake.Driver) + { + // brake release + if ((int) newState > 0) + { + // brake release (not min) + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + else + { + // brake min + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + } + else if ((int) newState > (int) Handles.LocoBrake.Driver) + { + // brake + Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer; + if (buffer != null) + { + Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position; + Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); + } + } + + // apply + Handles.LocoBrake.Driver = (int) newState; + Handles.LocoBrake.Actual = (int) newState; //TODO: FIXME + Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); + // plugin + if (Plugin != null) + { + Plugin.UpdatePower(); + Plugin.UpdateBrake(); + } + } + } + } + } + } +} diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Train.Specs.cs b/source/OpenBVE/Simulation/TrainManager/Train/Train.Specs.cs index 59c4a55b3..7711fcd96 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Train.Specs.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Train.Specs.cs @@ -12,8 +12,8 @@ internal struct TrainSpecs internal double CurrentAirDensity; internal double CurrentAirTemperature; internal double CurrentElevation; - - + + internal ReadhesionDeviceType ReadhesionDeviceType; internal DefaultSafetySystems DefaultSafetySystems; internal bool HasConstSpeed; internal bool CurrentConstSpeed; diff --git a/source/OpenBVE/Simulation/TrainManager/Train/Train.cs b/source/OpenBVE/Simulation/TrainManager/Train/Train.cs index 2db4c8e8a..1b528d22f 100644 --- a/source/OpenBVE/Simulation/TrainManager/Train/Train.cs +++ b/source/OpenBVE/Simulation/TrainManager/Train/Train.cs @@ -1,5 +1,5 @@ using System.Globalization; -using System.Reflection; +using OpenBve.BrakeSystems; using OpenBveApi.Colors; using OpenBveApi.Runtime; using OpenBveApi.Math; @@ -12,7 +12,7 @@ namespace OpenBve public static partial class TrainManager { /// The root class for a train within the simulation - public class Train + public partial class Train { /// The plugin used by this train. internal PluginManager.Plugin Plugin; @@ -60,6 +60,20 @@ public class Train /// The absolute on-disk path to the train's folder internal string TrainFolder; + internal Train(int trainIndex, TrainState state) + { + State = state; + TrainIndex = trainIndex; + Destination = Game.InitialDestination; + Station = -1; + CurrentRouteLimit = double.PositiveInfinity; + CurrentSectionLimit = double.PositiveInfinity; + Cars = new TrainManager.Car[] { }; + Specs.PassAlarm = PassAlarmType.None; + Specs.DoorOpenMode = DoorMode.AutomaticManualOverride; + Specs.DoorCloseMode = DoorMode.AutomaticManualOverride; + } + internal void Initialize() { for (int i = 0; i < Cars.Length; i++) @@ -76,8 +90,6 @@ internal void Dispose() State = TrainState.Disposed; for (int i = 0; i < Cars.Length; i++) { - int s = Cars[i].CurrentCarSection; - Cars[i].ChangeCarSection(CarSectionType.NotVisible); Cars[i].FrontBogie.ChangeSection(-1); Cars[i].RearBogie.ChangeSection(-1); @@ -94,204 +106,7 @@ internal void Dispose() } } - /// Applies a power and / or brake notch to this train - /// The power notch value - /// Whether this is relative to the current notch - /// The brake notch value - /// Whether this is relative to the current notch - internal void ApplyNotch(int PowerValue, bool PowerRelative, int BrakeValue, bool BrakeRelative) - { - // determine notch - int p = PowerRelative ? PowerValue + Handles.Power.Driver : PowerValue; - if (p < 0) - { - p = 0; - } - else if (p > Handles.Power.MaximumNotch) - { - p = Handles.Power.MaximumNotch; - } - - int b = BrakeRelative ? BrakeValue + Handles.Brake.Driver : BrakeValue; - if (b < 0) - { - b = 0; - } - else if (b > Handles.Brake.MaximumNotch) - { - b = Handles.Brake.MaximumNotch; - } - - // power sound - if (p < Handles.Power.Driver) - { - if (p > 0) - { - // down (not min) - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerDown.Buffer; - if (buffer != null) - { - Vector3 pos = Cars[DriverCar].Sounds.MasterControllerDown.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - else - { - // min - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMin.Buffer; - if (buffer != null) - { - Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMin.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - } - else if (p > Handles.Power.Driver) - { - if (p < Handles.Power.MaximumNotch) - { - // up (not max) - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerUp.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.MasterControllerUp.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - else - { - // max - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMax.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMax.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - } - - // brake sound - if (b < Handles.Brake.Driver) - { - // brake release - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.Brake.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - - if (b > 0) - { - // brake release (not min) - buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - else - { - // brake min - buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - } - else if (b > Handles.Brake.Driver) - { - // brake - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - - // apply notch - if (Handles.SingleHandle) - { - if (b != 0) p = 0; - } - - Handles.Power.Driver = p; - Handles.Brake.Driver = b; - Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None); - // plugin - if (Plugin != null) - { - Plugin.UpdatePower(); - Plugin.UpdateBrake(); - } - } - - /// Applies a loco brake notch to this train - /// The loco brake notch value - /// Whether this is relative to the current notch - internal void ApplyLocoBrakeNotch(int NotchValue, bool Relative) - { - int b = Relative ? NotchValue + Handles.LocoBrake.Driver : NotchValue; - if (b < 0) - { - b = 0; - } - else if (b > Handles.LocoBrake.MaximumNotch) - { - b = Handles.LocoBrake.MaximumNotch; - } - - // brake sound - if (b < Handles.LocoBrake.Driver) - { - // brake release - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.Brake.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - - if (b > 0) - { - // brake release (not min) - buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - else - { - // brake min - buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - } - else if (b > Handles.LocoBrake.Driver) - { - // brake - Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer; - if (buffer != null) - { - OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position; - Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false); - } - } - - Handles.LocoBrake.Driver = b; - Handles.LocoBrake.Actual = b; - } - + /// Call this method to update the train /// The elapsed time this frame @@ -412,6 +227,8 @@ internal void Update(double TimeElapsed) } } + + /// Updates the physics and controls for this train /// The time elapsed private void UpdatePhysicsAndControls(double TimeElapsed) @@ -438,7 +255,7 @@ private void UpdatePhysicsAndControls(double TimeElapsed) // delayed handles Handles.Power.Update(); Handles.Brake.Update(); - Handles.AirBrake.Handle.Update(); + Handles.Brake.Update(); Handles.EmergencyBrake.Update(); Handles.HoldBrake.Actual = Handles.HoldBrake.Driver; // update speeds @@ -458,9 +275,9 @@ private void UpdatePhysicsAndControls(double TimeElapsed) { // breaker sound bool breaker; - if (Cars[DriverCar].Specs.BrakeType == CarBrakeType.AutomaticAirBrake) + if (Cars[DriverCar].CarBrake is AutomaticAirBrake) { - breaker = Handles.Reverser.Actual != 0 & Handles.Power.Safety >= 1 & Handles.AirBrake.Handle.Safety == AirBrakeHandleState.Release & !Handles.EmergencyBrake.Safety & !Handles.HoldBrake.Actual; + breaker = Handles.Reverser.Actual != 0 & Handles.Power.Safety >= 1 & Handles.Brake.Safety == (int)AirBrakeHandleState.Release & !Handles.EmergencyBrake.Safety & !Handles.HoldBrake.Actual; } else { @@ -531,7 +348,7 @@ private void UpdateSpeeds(double TimeElapsed) } // update brake system double[] DecelerationDueToBrake, DecelerationDueToMotor; - UpdateBrakeSystem(this, TimeElapsed, out DecelerationDueToBrake, out DecelerationDueToMotor); + UpdateBrakeSystem(TimeElapsed, out DecelerationDueToBrake, out DecelerationDueToMotor); // calculate new car speeds double[] NewSpeeds = new double[Cars.Length]; for (int i = 0; i < Cars.Length; i++) @@ -1180,6 +997,32 @@ internal void InitializeCarSounds() Cars[i].Sounds.Plugin = new TrainManager.CarSound[] { }; } } + + /// Places the cars + /// The track position of the front car + internal void PlaceCars(double TrackPosition) + { + for (int i = 0; i < Cars.Length; i++) + { + //Front axle track position + Cars[i].FrontAxle.Follower.TrackPosition = TrackPosition - 0.5 * Cars[i].Length + Cars[i].FrontAxle.Position; + //Bogie for front axle + Cars[i].FrontBogie.FrontAxle.Follower.TrackPosition = Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * Cars[i].FrontBogie.Length + Cars[i].FrontBogie.FrontAxle.Position; + Cars[i].FrontBogie.RearAxle.Follower.TrackPosition = Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * Cars[i].FrontBogie.Length + Cars[i].FrontBogie.RearAxle.Position; + //Rear axle track position + Cars[i].RearAxle.Follower.TrackPosition = TrackPosition - 0.5 * Cars[i].Length + Cars[i].RearAxle.Position; + //Bogie for rear axle + Cars[i].RearBogie.FrontAxle.Follower.TrackPosition = Cars[i].RearAxle.Follower.TrackPosition - 0.5 * Cars[i].RearBogie.Length + Cars[i].RearBogie.FrontAxle.Position; + Cars[i].RearBogie.RearAxle.Follower.TrackPosition = Cars[i].RearAxle.Follower.TrackPosition - 0.5 * Cars[i].RearBogie.Length + Cars[i].RearBogie.RearAxle.Position; + //Beacon reciever (AWS, ATC etc.) + Cars[i].BeaconReceiver.TrackPosition = TrackPosition - 0.5 * Cars[i].Length + Cars[i].BeaconReceiverPosition; + TrackPosition -= Cars[i].Length; + if (i < Cars.Length - 1) + { + TrackPosition -= 0.5 * (Couplers[i].MinimumDistanceBetweenCars + Couplers[i].MaximumDistanceBetweenCars); + } + } + } } } } diff --git a/source/OpenBVE/Simulation/World/Transformations.cs b/source/OpenBVE/Simulation/World/Transformations.cs index fd71e1596..a8bd6eb19 100644 --- a/source/OpenBVE/Simulation/World/Transformations.cs +++ b/source/OpenBVE/Simulation/World/Transformations.cs @@ -1,5 +1,6 @@ using System; using OpenBveApi.Math; +using OpenBveApi.World; namespace OpenBve { @@ -13,130 +14,6 @@ internal static void Cross(double ax, double ay, double az, double bx, double by cz = ax * by - ay * bx; } - /// Creates the cross product of two vectors - internal static void Cross(Vector3 a, Vector3 b, out Vector3 c) - { - c.X = a.Y * b.Z - a.Z * b.Y; - c.Y = a.Z * b.X - a.X * b.Z; - c.Z = a.X * b.Y - a.Y * b.X; - } - - // transformation - internal struct Transformation - { - internal Vector3 X; - internal Vector3 Y; - internal Vector3 Z; - /// Creates a new transformation, based upon yaw pitch and roll values - /// The yaw to apply - /// The pitch to apply - /// The roll to apply - internal Transformation(double Yaw, double Pitch, double Roll) - { - if (Yaw == 0.0 & Pitch == 0.0 & Roll == 0.0) - { - this.X = new Vector3(1.0, 0.0, 0.0); - this.Y = new Vector3(0.0, 1.0, 0.0); - this.Z = new Vector3(0.0, 0.0, 1.0); - } - else if (Pitch == 0.0 & Roll == 0.0) - { - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - this.X = new Vector3(cosYaw, 0.0, -sinYaw); - this.Y = new Vector3(0.0, 1.0, 0.0); - this.Z = new Vector3(sinYaw, 0.0, cosYaw); - } - else - { - double sx = 1.0, sy = 0.0, sz = 0.0; - double ux = 0.0, uy = 1.0, uz = 0.0; - double dx = 0.0, dy = 0.0, dz = 1.0; - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - double cosPitch = Math.Cos(-Pitch); - double sinPitch = Math.Sin(-Pitch); - double cosRoll = Math.Cos(-Roll); - double sinRoll = Math.Sin(-Roll); - Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosRoll, sinRoll); - Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosRoll, sinRoll); - this.X = new Vector3(sx, sy, sz); - this.Y = new Vector3(ux, uy, uz); - this.Z = new Vector3(dx, dy, dz); - } - } - /// Creates a new transformation, based upon an initial transformation, plus secondary yaw pitch and roll values - /// The initial transformation - /// The yaw to apply - /// The pitch to apply - /// The roll to apply - internal Transformation(Transformation Transformation, double Yaw, double Pitch, double Roll) - { - double sx = Transformation.X.X, sy = Transformation.X.Y, sz = Transformation.X.Z; - double ux = Transformation.Y.X, uy = Transformation.Y.Y, uz = Transformation.Y.Z; - double dx = Transformation.Z.X, dy = Transformation.Z.Y, dz = Transformation.Z.Z; - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - double cosPitch = Math.Cos(-Pitch); - double sinPitch = Math.Sin(-Pitch); - double cosRoll = Math.Cos(Roll); - double sinRoll = Math.Sin(Roll); - Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosRoll, sinRoll); - Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosRoll, sinRoll); - this.X = new Vector3(sx, sy, sz); - this.Y = new Vector3(ux, uy, uz); - this.Z = new Vector3(dx, dy, dz); - } - /// Creates a new transformation, based upon a base transformation and an auxiliary transformation - /// The base transformation - /// The auxiliary transformation - internal Transformation(Transformation BaseTransformation, Transformation AuxTransformation) - { - Vector3 x = BaseTransformation.X; - Vector3 y = BaseTransformation.Y; - Vector3 z = BaseTransformation.Z; - Vector3 s = AuxTransformation.X; - Vector3 u = AuxTransformation.Y; - Vector3 d = AuxTransformation.Z; - Rotate(ref x.X, ref x.Y, ref x.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - Rotate(ref y.X, ref y.Y, ref y.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - Rotate(ref z.X, ref z.Y, ref z.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - this.X = x; - this.Y = y; - this.Z = z; - } - } - - /// Rotates a vector - /// The vector to rotate - /// The vector to rotate by - /// The Cosine of the angle to rotate by - /// The Sine of the angle to rotate by - internal static void Rotate(ref Vector3 p, Vector3 d, double cosa, double sina) - { - double t = 1.0 / Math.Sqrt(d.X * d.X + d.Y * d.Y + d.Z * d.Z); - d.X *= t; d.Y *= t; d.Z *= t; - double oc = 1.0 - cosa; - double Opt1 = oc * d.X * d.Y; - double Opt2 = sina * d.Z; - double Opt3 = oc * d.Y * d.Z; - double Opt4 = sina * d.X; - double Opt5 = sina * d.Y; - double Opt6 = oc * d.X * d.Z; - double x = (cosa + oc * d.X * d.X) * p.X + (Opt1 - Opt2) * p.Y + (Opt6 + Opt5) * p.Z; - double y = (cosa + oc * d.Y * d.Y) * p.Y + (Opt1 + Opt2) * p.X + (Opt3 - Opt4) * p.Z; - double z = (cosa + oc * d.Z * d.Z) * p.Z + (Opt6 - Opt5) * p.X + (Opt3 + Opt4) * p.Y; - p.X = x; p.Y = y; p.Z = z; - } - /// Rotates one vector based upon a second vector, input as induvidual co-ordinates /// The vector to rotate /// The X co-ordinate of the second vector @@ -187,54 +64,6 @@ internal static void Rotate(ref double px, ref double py, ref double pz, double px = x; py = y; pz = z; } - /// Rotates one vector based upon a second vector, both input as induvidual co-ordinates - /// The X co-ordinate of the first vector - /// The Y co-ordinate of the first vector - /// The Z co-ordinate of the first vector - /// The X co-ordinate of the second vector - /// The Y co-ordinate of the second vector - /// The Z co-ordinate of the second vector - /// The Cosine of the angle to rotate by - /// The Sine of the angle to rotate by - internal static void Rotate(ref float px, ref float py, ref float pz, double dx, double dy, double dz, double cosa, double sina) - { - double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz); - dx *= t; dy *= t; dz *= t; - double oc = 1.0 - cosa; - - - - //With any luck, this removes six multiplications from the Rotation calculation.... - double Opt1 = oc * dx * dy; - double Opt2 = sina * dz; - double Opt3 = oc * dy * dz; - double Opt4 = sina * dx; - double Opt5 = sina * dy; - double Opt6 = oc * dx * dz; - double x = (cosa + oc * dx * dx) * (double)px + (Opt1 - Opt2) * (double)py + (Opt6 + Opt5) * (double)pz; - double y = (cosa + oc * dy * dy) * (double)py + (Opt1 + Opt2) * (double)px + (Opt3 - Opt4) * (double)pz; - double z = (cosa + oc * dz * dz) * (double)pz + (Opt6 - Opt5) * (double)px + (Opt3 + Opt4) * (double)py; - px = (float)x; py = (float)y; pz = (float)z; - } - - /// Rotates a 2D vector - /// The vector to rotate - /// The Cosine of the angle to rotate by - /// The Sine of the angle to rotate by - internal static void Rotate(ref Vector2 Vector, double cosa, double sina) - { - double u = Vector.X * cosa - Vector.Y * sina; - double v = Vector.X * sina + Vector.Y * cosa; - Vector.X = u; - Vector.Y = v; - } - internal static void Rotate(ref float px, ref float py, ref float pz, double dx, double dy, double dz, double ux, double uy, double uz, double sx, double sy, double sz) - { - var x = sx * (double)px + ux * (double)py + dx * (double)pz; - var y = sy * (double)px + uy * (double)py + dy * (double)pz; - var z = sz * (double)px + uz * (double)py + dz * (double)pz; - px = (float)x; py = (float)y; pz = (float)z; - } internal static void Rotate(ref double px, ref double py, ref double pz, double dx, double dy, double dz, double ux, double uy, double uz, double sx, double sy, double sz) { var x = sx * px + ux * py + dx * pz; @@ -242,13 +71,7 @@ internal static void Rotate(ref double px, ref double py, ref double pz, double var z = sz * px + uz * py + dz * pz; px = x; py = y; pz = z; } - internal static void Rotate(ref float px, ref float py, ref float pz, Transformation t) - { - var x = t.X.X * (double)px + t.Y.X * (double)py + t.Z.X * (double)pz; - var y = t.X.Y * (double)px + t.Y.Y * (double)py + t.Z.Y * (double)pz; - var z = t.X.Z * (double)px + t.Y.Z * (double)py + t.Z.Z * (double)pz; - px = (float)x; py = (float)y; pz = (float)z; - } + internal static void Rotate(ref double px, ref double py, ref double pz, Transformation t) { var x = t.X.X * px + t.Y.X * py + t.Z.X * pz; @@ -263,33 +86,5 @@ internal static void RotatePlane(ref Vector3 Vector, double cosa, double sina) Vector.X = u; Vector.Z = v; } - internal static void RotateUpDown(ref Vector3 Vector, Vector2 Direction, double cosa, double sina) - { - double dx = Direction.X, dy = Direction.Y; - double x = Vector.X, y = Vector.Y, z = Vector.Z; - double u = dy * x - dx * z; - double v = dx * x + dy * z; - Vector.X = dy * u + dx * v * cosa - dx * y * sina; - Vector.Y = y * cosa + v * sina; - Vector.Z = -dx * u + dy * v * cosa - dy * y * sina; - } - internal static void RotateUpDown(ref Vector3 Vector, double dx, double dy, double cosa, double sina) - { - double x = Vector.X, y = Vector.Y, z = Vector.Z; - double u = dy * x - dx * z; - double v = dx * x + dy * z; - Vector.X = dy * u + dx * v * cosa - dx * y * sina; - Vector.Y = y * cosa + v * sina; - Vector.Z = -dx * u + dy * v * cosa - dy * y * sina; - } - internal static void RotateUpDown(ref double px, ref double py, ref double pz, double dx, double dz, double cosa, double sina) - { - double x = px, y = py, z = pz; - double u = dz * x - dx * z; - double v = dx * x + dz * z; - px = dz * u + dx * v * cosa - dx * y * sina; - py = y * cosa + v * sina; - pz = -dx * u + dz * v * cosa - dz * y * sina; - } } } diff --git a/source/OpenBVE/System/GameWindow.cs b/source/OpenBVE/System/GameWindow.cs index 53f6da76b..b75cf0572 100644 --- a/source/OpenBVE/System/GameWindow.cs +++ b/source/OpenBVE/System/GameWindow.cs @@ -104,7 +104,7 @@ protected override void OnRenderFrame(FrameEventArgs e) //Update the camera position based upon the relative car position TrainManager.PlayerTrain.Cars[World.CameraCar].UpdateCamera(); } - if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) + if (World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { World.CurrentDriverBody.Update(TimeElapsed); } @@ -322,6 +322,13 @@ protected override void OnClosing(CancelEventArgs e) e.Cancel = true; Loading.Cancel = true; } + for (int i = 0; i < TrainManager.Trains.Length; i++) + { + if (TrainManager.Trains[i].State != TrainManager.TrainState.Bogus) + { + PluginManager.UnloadPlugin(TrainManager.Trains[i]); + } + } } /// This method is called once the route and train data have been preprocessed, in order to physically setup the simulation private void SetupSimulation() @@ -355,6 +362,7 @@ private void SetupSimulation() } // camera ObjectManager.InitializeVisibility(); + World.CurrentDriverBody = new World.DriverBody(); World.CameraTrackFollower.Update(0.0, true, false); World.CameraTrackFollower.Update(-0.1, true, false); World.CameraTrackFollower.Update(0.1, true, false); @@ -585,7 +593,7 @@ private void SetupSimulation() } // initialize camera - if (World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) + if (World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { World.CameraMode = World.CameraViewMode.InteriorLookAhead; } diff --git a/source/OpenBVE/System/Input/Commands.CommandInfo.cs b/source/OpenBVE/System/Input/Commands.CommandInfo.cs index 560c8f5c5..e9b96d57b 100644 --- a/source/OpenBVE/System/Input/Commands.CommandInfo.cs +++ b/source/OpenBVE/System/Input/Commands.CommandInfo.cs @@ -6,11 +6,11 @@ internal static partial class Interface internal struct CommandInfo { /// The actual command to be performed - internal Command Command; + internal readonly Command Command; /// Whether this is a digital or analog control - internal CommandType Type; + internal readonly CommandType Type; /// The command name - internal string Name; + internal readonly string Name; /// The command's description internal string Description; internal CommandInfo(Command Command, CommandType Type, string Name) diff --git a/source/OpenBVE/System/Input/ProcessControls.cs b/source/OpenBVE/System/Input/ProcessControls.cs index 3f0f7e05a..808359329 100644 --- a/source/OpenBVE/System/Input/ProcessControls.cs +++ b/source/OpenBVE/System/Input/ProcessControls.cs @@ -26,7 +26,7 @@ internal static void ProcessControls(double TimeElapsed) World.CameraCar = TrainManager.PlayerTrain.DriverCar; MainLoop.SaveCameraSettings(); bool lookahead = false; - if (World.CameraMode != World.CameraViewMode.InteriorLookAhead & World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) + if (World.CameraMode != World.CameraViewMode.InteriorLookAhead & World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { Game.AddMessage(Interface.GetInterfaceString("notification_interior_lookahead"), MessageManager.MessageDependency.CameraView, Interface.GameMode.Expert, @@ -84,7 +84,7 @@ internal static void ProcessControls(double TimeElapsed) UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(TimeElapsed); World.UpdateViewingDistances(); - if (World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) + if (World.CameraRestriction != Camera.RestrictionMode.NotAvailable) { if (!World.PerformCameraRestrictionTest()) { @@ -192,9 +192,7 @@ internal static void ProcessControls(double TimeElapsed) // brake half/full-axis if (!TrainManager.PlayerTrain.Handles.SingleHandle) { - int d = TrainManager.PlayerTrain.DriverCar; - if (TrainManager.PlayerTrain.Cars[d].Specs.BrakeType == - TrainManager.CarBrakeType.AutomaticAirBrake) + if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { double a = Interface.CurrentControls[i].AnalogState; if (Interface.CurrentControls[i].Command == @@ -208,25 +206,22 @@ internal static void ProcessControls(double TimeElapsed) case 0: TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver = false; - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Release); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); break; case 1: TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver = false; - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Lap); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); break; case 2: TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver = false; - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Service); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); break; case 3: if (Interface.CurrentOptions.AllowAxisEB) { - TrainManager.ApplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.ApplyEmergencyBrake(); } break; } @@ -247,15 +242,15 @@ internal static void ProcessControls(double TimeElapsed) if (b > 0) b--; if (b <= TrainManager.PlayerTrain.Handles.Brake.MaximumNotch) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); TrainManager.PlayerTrain.ApplyNotch(0, true, b, false); } else { - TrainManager.ApplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.ApplyEmergencyBrake(); } - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, q); + TrainManager.PlayerTrain.ApplyHoldBrake(q); } else { @@ -269,7 +264,7 @@ internal static void ProcessControls(double TimeElapsed) int b = (int) Math.Round(a); if (b <= TrainManager.PlayerTrain.Handles.Brake.MaximumNotch) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); TrainManager.PlayerTrain.ApplyNotch(0, true, b, false); } @@ -277,7 +272,7 @@ internal static void ProcessControls(double TimeElapsed) { if (Interface.CurrentOptions.AllowAxisEB) { - TrainManager.ApplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.ApplyEmergencyBrake(); } } } @@ -308,17 +303,17 @@ internal static void ProcessControls(double TimeElapsed) if (b > 0) b--; if (b <= TrainManager.PlayerTrain.Handles.Brake.MaximumNotch) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); TrainManager.PlayerTrain.ApplyNotch(p, false, b, false); } else { if (Interface.CurrentOptions.AllowAxisEB) { - TrainManager.ApplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.ApplyEmergencyBrake(); } } - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, q); + TrainManager.PlayerTrain.ApplyHoldBrake(q); } else { @@ -338,14 +333,14 @@ internal static void ProcessControls(double TimeElapsed) if (b < 0) b = 0; if (b <= TrainManager.PlayerTrain.Handles.Brake.MaximumNotch) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); TrainManager.PlayerTrain.ApplyNotch(p, false, b, false); } else { if (Interface.CurrentOptions.AllowAxisEB) { - TrainManager.ApplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.ApplyEmergencyBrake(); } } } @@ -356,7 +351,7 @@ internal static void ProcessControls(double TimeElapsed) { double a = Interface.CurrentControls[i].AnalogState; int r = (int) Math.Round(a); - TrainManager.ApplyReverser(TrainManager.PlayerTrain, r, false); + TrainManager.PlayerTrain.ApplyReverser(r, false); } break; case Interface.Command.CameraMoveForward: @@ -375,6 +370,11 @@ internal static void ProcessControls(double TimeElapsed) } else { + if (World.CameraAtWorldEnd) + { + //Don't let the camera run off the end of the worldspace + break; + } World.CameraAlignmentDirection.TrackPosition = World.CameraExteriorTopSpeed* Interface.CurrentControls[i] .AnalogState; @@ -494,7 +494,7 @@ internal static void ProcessControls(double TimeElapsed) // camera rotate ccw if ((World.CameraMode != World.CameraViewMode.Interior & World.CameraMode != World.CameraViewMode.InteriorLookAhead) | - World.CameraRestriction != World.CameraRestrictionMode.On) + World.CameraRestriction != Camera.RestrictionMode.On) { double s = World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead @@ -509,7 +509,7 @@ internal static void ProcessControls(double TimeElapsed) // camera rotate cw if ((World.CameraMode != World.CameraViewMode.Interior & World.CameraMode != World.CameraViewMode.InteriorLookAhead) | - World.CameraRestriction != World.CameraRestrictionMode.On) + World.CameraRestriction != Camera.RestrictionMode.On) { double s = World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead @@ -636,7 +636,7 @@ internal static void ProcessControls(double TimeElapsed) // camera: interior MainLoop.SaveCameraSettings(); bool lookahead = false; - if (World.CameraMode != World.CameraViewMode.InteriorLookAhead & World.CameraRestriction == World.CameraRestrictionMode.NotAvailable) + if (World.CameraMode != World.CameraViewMode.InteriorLookAhead & World.CameraRestriction == Camera.RestrictionMode.NotAvailable) { Game.AddMessage(Interface.GetInterfaceString("notification_interior_lookahead"), MessageManager.MessageDependency.CameraView, Interface.GameMode.Expert, @@ -690,7 +690,7 @@ internal static void ProcessControls(double TimeElapsed) UpdateViewport(MainLoop.ViewPortChangeMode.NoChange); World.UpdateAbsoluteCamera(TimeElapsed); World.UpdateViewingDistances(); - if (World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) + if (World.CameraRestriction != Camera.RestrictionMode.NotAvailable) { if (!World.PerformCameraRestrictionTest()) { @@ -921,7 +921,7 @@ internal static void ProcessControls(double TimeElapsed) World.UpdateViewingDistances(); if ((World.CameraMode == World.CameraViewMode.Interior | World.CameraMode == World.CameraViewMode.InteriorLookAhead) & - World.CameraRestriction == World.CameraRestrictionMode.On) + World.CameraRestriction == Camera.RestrictionMode.On) { if (!World.PerformCameraRestrictionTest()) { @@ -931,18 +931,18 @@ internal static void ProcessControls(double TimeElapsed) break; case Interface.Command.CameraRestriction: // camera: restriction - if (World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) + if (World.CameraRestriction != Camera.RestrictionMode.NotAvailable) { - if (World.CameraRestriction == World.CameraRestrictionMode.Off) + if (World.CameraRestriction == Camera.RestrictionMode.Off) { - World.CameraRestriction = World.CameraRestrictionMode.On; + World.CameraRestriction = Camera.RestrictionMode.On; } else { - World.CameraRestriction = World.CameraRestrictionMode.Off; + World.CameraRestriction = Camera.RestrictionMode.Off; } World.InitializeCameraRestriction(); - if (World.CameraRestriction == World.CameraRestrictionMode.Off) + if (World.CameraRestriction == Camera.RestrictionMode.Off) { Game.AddMessage( Interface.GetInterfaceString("notification_camerarestriction_off"), @@ -965,16 +965,16 @@ internal static void ProcessControls(double TimeElapsed) int b = TrainManager.PlayerTrain.Handles.Brake.Driver; if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); } else if (b == 1 & TrainManager.PlayerTrain.Handles.HasHoldBrake) { TrainManager.PlayerTrain.ApplyNotch(0, true, 0, false); - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, true); + TrainManager.PlayerTrain.ApplyHoldBrake(true); } else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, false); + TrainManager.PlayerTrain.ApplyHoldBrake(false); } else if (b > 0) { @@ -1004,16 +1004,16 @@ internal static void ProcessControls(double TimeElapsed) int b = TrainManager.PlayerTrain.Handles.Brake.Driver; if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); } else if (b == 1 & TrainManager.PlayerTrain.Handles.HasHoldBrake) { TrainManager.PlayerTrain.ApplyNotch(0, true, 0, false); - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, true); + TrainManager.PlayerTrain.ApplyHoldBrake(true); } else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, false); + TrainManager.PlayerTrain.ApplyHoldBrake(false); } else if (b > 0) { @@ -1037,12 +1037,12 @@ internal static void ProcessControls(double TimeElapsed) if (TrainManager.PlayerTrain.Handles.HasHoldBrake & b == 0 & !TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, true); + TrainManager.PlayerTrain.ApplyHoldBrake(true); } else if (b < TrainManager.PlayerTrain.Handles.Brake.MaximumNotch) { TrainManager.PlayerTrain.ApplyNotch(0, true, 1, true); - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, false); + TrainManager.PlayerTrain.ApplyHoldBrake(false); } } } @@ -1051,7 +1051,7 @@ internal static void ProcessControls(double TimeElapsed) // single emergency if (TrainManager.PlayerTrain.Handles.SingleHandle) { - TrainManager.ApplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.ApplyEmergencyBrake(); } break; case Interface.Command.PowerIncrease: @@ -1080,34 +1080,29 @@ internal static void ProcessControls(double TimeElapsed) // brake increase if (!TrainManager.PlayerTrain.Handles.SingleHandle) { - int d = TrainManager.PlayerTrain.DriverCar; - if (TrainManager.PlayerTrain.Cars[d].Specs.BrakeType == - TrainManager.CarBrakeType.AutomaticAirBrake) + if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { if (TrainManager.PlayerTrain.Handles.HasHoldBrake & - TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == - TrainManager.AirBrakeHandleState.Release & + TrainManager.PlayerTrain.Handles.Brake.Driver == + (int)TrainManager.AirBrakeHandleState.Release & !TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, true); + TrainManager.PlayerTrain.ApplyHoldBrake(true); } else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Lap); - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, false); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); + TrainManager.PlayerTrain.ApplyHoldBrake(false); } - else if (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == - TrainManager.AirBrakeHandleState.Lap) + else if (TrainManager.PlayerTrain.Handles.Brake.Driver == + (int)TrainManager.AirBrakeHandleState.Lap) { - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Service); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); } - else if (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == - TrainManager.AirBrakeHandleState.Release) + else if (TrainManager.PlayerTrain.Handles.Brake.Driver == + (int)TrainManager.AirBrakeHandleState.Release) { - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Lap); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); } } else @@ -1116,12 +1111,12 @@ internal static void ProcessControls(double TimeElapsed) if (TrainManager.PlayerTrain.Handles.HasHoldBrake & b == 0 & !TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, true); + TrainManager.PlayerTrain.ApplyHoldBrake(true); } else if (b < TrainManager.PlayerTrain.Handles.Brake.MaximumNotch) { TrainManager.PlayerTrain.ApplyNotch(0, true, 1, true); - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, false); + TrainManager.PlayerTrain.ApplyHoldBrake(false); } } } @@ -1130,39 +1125,33 @@ internal static void ProcessControls(double TimeElapsed) // brake decrease if (!TrainManager.PlayerTrain.Handles.SingleHandle) { - int d = TrainManager.PlayerTrain.DriverCar; - if (TrainManager.PlayerTrain.Cars[d].Specs.BrakeType == - TrainManager.CarBrakeType.AutomaticAirBrake) + if (TrainManager.PlayerTrain.Handles.Brake is TrainManager.AirBrakeHandle) { if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); } else if (TrainManager.PlayerTrain.Handles.HasHoldBrake & - TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == - TrainManager.AirBrakeHandleState.Lap & + TrainManager.PlayerTrain.Handles.Brake.Driver == + (int)TrainManager.AirBrakeHandleState.Lap & !TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, true); + TrainManager.PlayerTrain.ApplyHoldBrake(true); } else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Release); - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, false); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); + TrainManager.PlayerTrain.ApplyHoldBrake(false); } - else if (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == - TrainManager.AirBrakeHandleState.Lap) + else if (TrainManager.PlayerTrain.Handles.Brake.Driver == + (int)TrainManager.AirBrakeHandleState.Lap) { - TrainManager.ApplyAirBrakeHandle(TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Release); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); } - else if (TrainManager.PlayerTrain.Handles.AirBrake.Handle.Driver == - TrainManager.AirBrakeHandleState.Service) + else if (TrainManager.PlayerTrain.Handles.Brake.Driver == + (int)TrainManager.AirBrakeHandleState.Service) { - TrainManager.ApplyAirBrakeHandle( - TrainManager.PlayerTrain, - TrainManager.AirBrakeHandleState.Lap); + TrainManager.PlayerTrain.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); } } else @@ -1170,16 +1159,16 @@ internal static void ProcessControls(double TimeElapsed) int b = TrainManager.PlayerTrain.Handles.Brake.Driver; if (TrainManager.PlayerTrain.Handles.EmergencyBrake.Driver) { - TrainManager.UnapplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.UnapplyEmergencyBrake(); } else if (b == 1 & TrainManager.PlayerTrain.Handles.HasHoldBrake) { TrainManager.PlayerTrain.ApplyNotch(0, true, 0, false); - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, true); + TrainManager.PlayerTrain.ApplyHoldBrake(true); } else if (TrainManager.PlayerTrain.Handles.HoldBrake.Driver) { - TrainManager.ApplyHoldBrake(TrainManager.PlayerTrain, false); + TrainManager.PlayerTrain.ApplyHoldBrake(false); } else if (b > 0) { @@ -1189,14 +1178,43 @@ internal static void ProcessControls(double TimeElapsed) } break; case Interface.Command.LocoBrakeIncrease: - TrainManager.PlayerTrain.ApplyLocoBrakeNotch(1, true); + if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) + { + if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Lap) + { + TrainManager.PlayerTrain.ApplyLocoAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); + } + else if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Release) + { + TrainManager.PlayerTrain.ApplyLocoAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); + } + } + else + { + TrainManager.PlayerTrain.ApplyLocoBrakeNotch(1, true); + } + break; case Interface.Command.LocoBrakeDecrease: - TrainManager.PlayerTrain.ApplyLocoBrakeNotch(-1, true); + if (TrainManager.PlayerTrain.Handles.LocoBrake is TrainManager.LocoAirBrakeHandle) + { + if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Lap) + { + TrainManager.PlayerTrain.ApplyLocoAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); + } + else if (TrainManager.PlayerTrain.Handles.LocoBrake.Driver == (int)TrainManager.AirBrakeHandleState.Service) + { + TrainManager.PlayerTrain.ApplyLocoAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); + } + } + else + { + TrainManager.PlayerTrain.ApplyLocoBrakeNotch(-1, true); + } break; case Interface.Command.BrakeEmergency: // brake emergency - TrainManager.ApplyEmergencyBrake(TrainManager.PlayerTrain); + TrainManager.PlayerTrain.ApplyEmergencyBrake(); break; case Interface.Command.DeviceConstSpeed: // const speed @@ -1210,14 +1228,14 @@ internal static void ProcessControls(double TimeElapsed) // reverser forward if (TrainManager.PlayerTrain.Handles.Reverser.Driver < TrainManager.ReverserPosition.Forwards) { - TrainManager.ApplyReverser(TrainManager.PlayerTrain, 1, true); + TrainManager.PlayerTrain.ApplyReverser(1, true); } break; case Interface.Command.ReverserBackward: // reverser backward if (TrainManager.PlayerTrain.Handles.Reverser.Driver > TrainManager.ReverserPosition.Reverse) { - TrainManager.ApplyReverser(TrainManager.PlayerTrain, -1, true); + TrainManager.PlayerTrain.ApplyReverser(-1, true); } break; case Interface.Command.HornPrimary: @@ -1584,7 +1602,7 @@ internal static void ProcessControls(double TimeElapsed) else { Renderer.OptionGradient++; - if ((int)Renderer.OptionGradient >= 3) Renderer.OptionGradient = 0; + if ((int)Renderer.OptionGradient >= 4) Renderer.OptionGradient = 0; } break; case Interface.Command.MiscFps: diff --git a/source/OpenBVE/System/Loading.cs b/source/OpenBVE/System/Loading.cs index a8cc29b83..2e72b6bb1 100644 --- a/source/OpenBVE/System/Loading.cs +++ b/source/OpenBVE/System/Loading.cs @@ -203,6 +203,7 @@ private static void LoadEverythingThreaded() { } } } + if (Game.Stations.Length == 1) { //Log the fact that only a single station is present, as this is probably not right @@ -213,13 +214,17 @@ private static void LoadEverythingThreaded() { // initialize trains System.Threading.Thread.Sleep(1); if (Cancel) return; TrainManager.Trains = new TrainManager.Train[Game.PrecedingTrainTimeDeltas.Length + 1 + (Game.BogusPretrainInstructions.Length != 0 ? 1 : 0)]; - for (int k = 0; k < TrainManager.Trains.Length; k++) { - TrainManager.Trains[k] = new TrainManager.Train {TrainIndex = k, Destination = Game.InitialDestination}; - if (k == TrainManager.Trains.Length - 1 & Game.BogusPretrainInstructions.Length != 0) { - TrainManager.Trains[k].State = TrainManager.TrainState.Bogus; - } else { - TrainManager.Trains[k].State = TrainManager.TrainState.Pending; + for (int k = 0; k < TrainManager.Trains.Length; k++) + { + if (k == TrainManager.Trains.Length - 1 & Game.BogusPretrainInstructions.Length != 0) + { + TrainManager.Trains[k] = new TrainManager.Train(k, TrainManager.TrainState.Bogus); + } + else + { + TrainManager.Trains[k] = new TrainManager.Train(k, TrainManager.TrainState.Pending); } + } TrainManager.PlayerTrain = TrainManager.Trains[Game.PrecedingTrainTimeDeltas.Length]; @@ -229,7 +234,7 @@ private static void LoadEverythingThreaded() { // load trains double TrainProgressMaximum = 0.7 + 0.3 * (double)TrainManager.Trains.Length; for (int k = 0; k < TrainManager.Trains.Length; k++) { - //Sleep for 10ms to allow route loading locks to release + //Sleep for 20ms to allow route loading locks to release Thread.Sleep(20); if (TrainManager.Trains[k].State == TrainManager.TrainState.Bogus) { // bogus train @@ -316,10 +321,6 @@ private static void LoadEverythingThreaded() { } // add panel section if (k == TrainManager.PlayerTrain.TrainIndex) { - TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections = new TrainManager.CarSection[1]; - TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0] = new TrainManager.CarSection(); - TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Elements = new ObjectManager.AnimatedObject[] { }; - TrainManager.Trains[k].Cars[TrainManager.Trains[k].DriverCar].CarSections[0].Overlay = true; TrainProgressCurrentWeight = 0.7 / TrainProgressMaximum; TrainManager.ParsePanelConfig(TrainManager.Trains[k].TrainFolder, CurrentTrainEncoding, TrainManager.Trains[k]); TrainProgressCurrentSum += TrainProgressCurrentWeight; @@ -385,27 +386,8 @@ private static void LoadEverythingThreaded() { } } // place cars - { - double z = 0.0; - for (int i = 0; i < TrainManager.Trains[k].Cars.Length; i++) { - //Front axle track position - TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].FrontAxle.Position; - //Bogie for front axle - TrainManager.Trains[k].Cars[i].FrontBogie.FrontAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].FrontBogie.Length + TrainManager.Trains[k].Cars[i].FrontBogie.FrontAxle.Position; - TrainManager.Trains[k].Cars[i].FrontBogie.RearAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].FrontAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].FrontBogie.Length + TrainManager.Trains[k].Cars[i].FrontBogie.RearAxle.Position; - //Rear axle track position - TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].RearAxle.Position; - //Bogie for rear axle - TrainManager.Trains[k].Cars[i].RearBogie.FrontAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].RearBogie.Length + TrainManager.Trains[k].Cars[i].RearBogie.FrontAxle.Position; - TrainManager.Trains[k].Cars[i].RearBogie.RearAxle.Follower.TrackPosition = TrainManager.Trains[k].Cars[i].RearAxle.Follower.TrackPosition - 0.5 * TrainManager.Trains[k].Cars[i].RearBogie.Length + TrainManager.Trains[k].Cars[i].RearBogie.RearAxle.Position; - //Beacon reciever (AWS, ATC etc.) - TrainManager.Trains[k].Cars[i].BeaconReceiver.TrackPosition = z - 0.5 * TrainManager.Trains[k].Cars[i].Length + TrainManager.Trains[k].Cars[i].BeaconReceiverPosition; - z -= TrainManager.Trains[k].Cars[i].Length; - if (i < TrainManager.Trains[k].Cars.Length - 1) { - z -= 0.5 * (TrainManager.Trains[k].Couplers[i].MinimumDistanceBetweenCars + TrainManager.Trains[k].Couplers[i].MaximumDistanceBetweenCars); - } - } - } + TrainManager.Trains[k].PlaceCars(0.0); + // configure ai / timetable if (TrainManager.Trains[k] == TrainManager.PlayerTrain) { TrainManager.Trains[k].TimetableDelta = 0.0; diff --git a/source/OpenBVE/System/Logging/BlackBox.cs b/source/OpenBVE/System/Logging/BlackBox.cs index e74289e50..059eff60f 100644 --- a/source/OpenBVE/System/Logging/BlackBox.cs +++ b/source/OpenBVE/System/Logging/BlackBox.cs @@ -86,48 +86,60 @@ internal static void SaveLogs() return; } string BlackBoxFile = OpenBveApi.Path.CombineFile(Program.FileSystem.SettingsFolder, "logs.bin"); - using (System.IO.FileStream Stream = new System.IO.FileStream(BlackBoxFile, System.IO.FileMode.Create, System.IO.FileAccess.Write)) + try { - //TODO: This code recreates the file every frame..... - //It should be possible to spin up a stream in a separate thread which then continously appends - using (System.IO.BinaryWriter Writer = new System.IO.BinaryWriter(Stream, System.Text.Encoding.UTF8)) + using (System.IO.FileStream Stream = new System.IO.FileStream(BlackBoxFile, System.IO.FileMode.Create, System.IO.FileAccess.Write)) { - byte[] Identifier = new byte[] { 111, 112, 101, 110, 66, 86, 69, 95, 76, 79, 71, 83 }; - const short Version = 1; - Writer.Write(Identifier); - Writer.Write(Version); - Writer.Write(Game.LogRouteName); - Writer.Write(Game.LogTrainName); - Writer.Write(Game.LogDateTime.ToBinary()); - Writer.Write((short)Interface.CurrentOptions.GameMode); - Writer.Write(Game.BlackBoxEntryCount); - for (int i = 0; i < Game.BlackBoxEntryCount; i++) - { - Writer.Write(Game.BlackBoxEntries[i].Time); - Writer.Write(Game.BlackBoxEntries[i].Position); - Writer.Write(Game.BlackBoxEntries[i].Speed); - Writer.Write(Game.BlackBoxEntries[i].Acceleration); - Writer.Write(Game.BlackBoxEntries[i].ReverserDriver); - Writer.Write(Game.BlackBoxEntries[i].ReverserSafety); - Writer.Write((short)Game.BlackBoxEntries[i].PowerDriver); - Writer.Write((short)Game.BlackBoxEntries[i].PowerSafety); - Writer.Write((short)Game.BlackBoxEntries[i].BrakeDriver); - Writer.Write((short)Game.BlackBoxEntries[i].BrakeSafety); - Writer.Write((short)Game.BlackBoxEntries[i].EventToken); - } - Writer.Write(Game.ScoreLogCount); - for (int i = 0; i < Game.ScoreLogCount; i++) + //TODO: This code recreates the file every frame..... + //It should be possible to spin up a stream in a separate thread which then continously appends + using (System.IO.BinaryWriter Writer = new System.IO.BinaryWriter(Stream, System.Text.Encoding.UTF8)) { - Writer.Write(Game.ScoreLogs[i].Time); - Writer.Write(Game.ScoreLogs[i].Position); - Writer.Write(Game.ScoreLogs[i].Value); - Writer.Write((short)Game.ScoreLogs[i].TextToken); + byte[] Identifier = new byte[] {111, 112, 101, 110, 66, 86, 69, 95, 76, 79, 71, 83}; + const short Version = 1; + Writer.Write(Identifier); + Writer.Write(Version); + Writer.Write(Game.LogRouteName); + Writer.Write(Game.LogTrainName); + Writer.Write(Game.LogDateTime.ToBinary()); + Writer.Write((short) Interface.CurrentOptions.GameMode); + Writer.Write(Game.BlackBoxEntryCount); + for (int i = 0; i < Game.BlackBoxEntryCount; i++) + { + Writer.Write(Game.BlackBoxEntries[i].Time); + Writer.Write(Game.BlackBoxEntries[i].Position); + Writer.Write(Game.BlackBoxEntries[i].Speed); + Writer.Write(Game.BlackBoxEntries[i].Acceleration); + Writer.Write(Game.BlackBoxEntries[i].ReverserDriver); + Writer.Write(Game.BlackBoxEntries[i].ReverserSafety); + Writer.Write((short) Game.BlackBoxEntries[i].PowerDriver); + Writer.Write((short) Game.BlackBoxEntries[i].PowerSafety); + Writer.Write((short) Game.BlackBoxEntries[i].BrakeDriver); + Writer.Write((short) Game.BlackBoxEntries[i].BrakeSafety); + Writer.Write((short) Game.BlackBoxEntries[i].EventToken); + } + + Writer.Write(Game.ScoreLogCount); + for (int i = 0; i < Game.ScoreLogCount; i++) + { + Writer.Write(Game.ScoreLogs[i].Time); + Writer.Write(Game.ScoreLogs[i].Position); + Writer.Write(Game.ScoreLogs[i].Value); + Writer.Write((short) Game.ScoreLogs[i].TextToken); + } + + Writer.Write(Game.CurrentScore.Maximum); + Identifier = new byte[] {95, 102, 105, 108, 101, 69, 78, 68}; + Writer.Write(Identifier); + Writer.Close(); } - Writer.Write(Game.CurrentScore.Maximum); - Identifier = new byte[] { 95, 102, 105, 108, 101, 69, 78, 68 }; - Writer.Write(Identifier); - Writer.Close(); - } Stream.Close(); + + Stream.Close(); + } + } + catch + { + Interface.CurrentOptions.BlackBox = false; + Interface.AddMessage(MessageType.Error, false, "An unexpected error occurred whilst attempting to write to the black box log- Black box has been disabled."); } } diff --git a/source/OpenBVE/System/Options.cs b/source/OpenBVE/System/Options.cs index 4dd702222..f6b330697 100644 --- a/source/OpenBVE/System/Options.cs +++ b/source/OpenBVE/System/Options.cs @@ -138,7 +138,7 @@ internal class Options /// The list of recently used trains internal string[] RecentlyUsedTrains; /// The maximum number of recently used routes/ trains to display - internal int RecentlyUsedLimit; + internal readonly int RecentlyUsedLimit; /// The list of recently used route character encodings internal TextEncoding.EncodingValue[] RouteEncodings; /// The list of recently used train character encodings @@ -697,6 +697,7 @@ internal static void LoadOptions() { #pragma warning disable CS0219 //Used to check that the parsed integer is a valid codepage + // ReSharper disable once UnusedVariable Encoding e = Encoding.GetEncoding(a); #pragma warning restore CS0219 } @@ -720,6 +721,7 @@ internal static void LoadOptions() { #pragma warning disable CS0219 //Used to check that the parsed integer is a valid codepage + // ReSharper disable once UnusedVariable Encoding e = Encoding.GetEncoding(a); #pragma warning restore CS0219 } diff --git a/source/OpenBVE/System/Plugins/PluginManager.cs b/source/OpenBVE/System/Plugins/PluginManager.cs index 79d8b8cfb..4205ea5f6 100644 --- a/source/OpenBVE/System/Plugins/PluginManager.cs +++ b/source/OpenBVE/System/Plugins/PluginManager.cs @@ -95,11 +95,11 @@ internal void UpdatePlugin() { } //End of additions double speed = this.Train.Cars[this.Train.DriverCar].Specs.CurrentPerceivedSpeed; - double bcPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.BrakeCylinderCurrentPressure; - double mrPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.MainReservoirCurrentPressure; - double erPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.EqualizingReservoirCurrentPressure; - double bpPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.BrakePipeCurrentPressure; - double sapPressure = this.Train.Cars[this.Train.DriverCar].Specs.AirBrake.StraightAirPipeCurrentPressure; + double bcPressure = this.Train.Cars[this.Train.DriverCar].CarBrake.brakeCylinder.CurrentPressure; + double mrPressure = this.Train.Cars[this.Train.DriverCar].CarBrake.mainReservoir.CurrentPressure; + double erPressure = this.Train.Cars[this.Train.DriverCar].CarBrake.equalizingReservoir.CurrentPressure; + double bpPressure = this.Train.Cars[this.Train.DriverCar].CarBrake.brakePipe.CurrentPressure; + double sapPressure = this.Train.Cars[this.Train.DriverCar].CarBrake.straightAirPipe.CurrentPressure; VehicleState vehicle = new VehicleState(location, new Speed(speed), bcPressure, mrPressure, erPressure, bpPressure, sapPressure, CurrentRadius, CurrentCant, CurrentPitch); /* * Prepare the preceding vehicle state. @@ -162,8 +162,8 @@ private Handles GetHandles() { int reverser = (int)this.Train.Handles.Reverser.Driver; int powerNotch = this.Train.Handles.Power.Driver; int brakeNotch; - if (this.Train.Cars[this.Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { - brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? 3 : this.Train.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Service ? 2 : this.Train.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Lap ? 1 : 0; + if (this.Train.Handles.Brake is TrainManager.AirBrakeHandle) { + brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? 3 : this.Train.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Service ? 2 : this.Train.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap ? 1 : 0; } else { if (this.Train.Handles.HasHoldBrake) { brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? this.Train.Handles.Brake.MaximumNotch + 2 : this.Train.Handles.Brake.Driver > 0 ? this.Train.Handles.Brake.Driver + 1 : this.Train.Handles.HoldBrake.Driver ? 1 : 0; @@ -171,8 +171,9 @@ private Handles GetHandles() { brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? this.Train.Handles.Brake.MaximumNotch + 1 : this.Train.Handles.Brake.Driver; } } + int locoBrakeNotch = this.Train.Handles.LocoBrake.Driver; bool constSpeed = this.Train.Specs.CurrentConstSpeed; - return new Handles(reverser, powerNotch, brakeNotch, constSpeed); + return new Handles(reverser, powerNotch, brakeNotch, locoBrakeNotch, constSpeed); } /// Sets the driver handles or the virtual handles. /// The handles. @@ -191,7 +192,7 @@ private void SetHandles(Handles handles, bool virtualHandles) { if (virtualHandles) { this.Train.Handles.Reverser.Actual = (TrainManager.ReverserPosition)handles.Reverser; } else { - TrainManager.ApplyReverser(this.Train, handles.Reverser, false); + this.Train.ApplyReverser(handles.Reverser, false); } } else { if (virtualHandles) { @@ -221,35 +222,35 @@ private void SetHandles(Handles handles, bool virtualHandles) { this.Train.Handles.EmergencyBrake.Safety = false; this.Train.Handles.HoldBrake.Actual = false; } - if (this.Train.Cars[this.Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (this.Train.Handles.Brake is TrainManager.AirBrakeHandle) { if (handles.BrakeNotch == 0) { if (virtualHandles) { - this.Train.Handles.AirBrake.Handle.Safety = TrainManager.AirBrakeHandleState.Release; + this.Train.Handles.Brake.Safety = (int)TrainManager.AirBrakeHandleState.Release; } else { - TrainManager.UnapplyEmergencyBrake(this.Train); - TrainManager.ApplyAirBrakeHandle(this.Train, TrainManager.AirBrakeHandleState.Release); + this.Train.UnapplyEmergencyBrake(); + this.Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); } } else if (handles.BrakeNotch == 1) { if (virtualHandles) { - this.Train.Handles.AirBrake.Handle.Safety = TrainManager.AirBrakeHandleState.Lap; + this.Train.Handles.Brake.Safety = (int)TrainManager.AirBrakeHandleState.Lap; } else { - TrainManager.UnapplyEmergencyBrake(this.Train); - TrainManager.ApplyAirBrakeHandle(this.Train, TrainManager.AirBrakeHandleState.Lap); + this.Train.UnapplyEmergencyBrake(); + this.Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Lap); } } else if (handles.BrakeNotch == 2) { if (virtualHandles) { - this.Train.Handles.AirBrake.Handle.Safety = TrainManager.AirBrakeHandleState.Service; + this.Train.Handles.Brake.Safety = (int)TrainManager.AirBrakeHandleState.Service; } else { - TrainManager.UnapplyEmergencyBrake(this.Train); - TrainManager.ApplyAirBrakeHandle(this.Train, TrainManager.AirBrakeHandleState.Release); + this.Train.UnapplyEmergencyBrake(); + this.Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Release); } } else if (handles.BrakeNotch == 3) { if (virtualHandles) { - this.Train.Handles.AirBrake.Handle.Safety = TrainManager.AirBrakeHandleState.Service; + this.Train.Handles.Brake.Safety = (int)TrainManager.AirBrakeHandleState.Service; this.Train.Handles.EmergencyBrake.Safety = true; } else { - TrainManager.ApplyAirBrakeHandle(this.Train, TrainManager.AirBrakeHandleState.Service); - TrainManager.ApplyEmergencyBrake(this.Train); + this.Train.ApplyAirBrakeHandle(TrainManager.AirBrakeHandleState.Service); + this.Train.ApplyEmergencyBrake(); } } else { this.PluginValid = false; @@ -261,16 +262,16 @@ private void SetHandles(Handles handles, bool virtualHandles) { this.Train.Handles.EmergencyBrake.Safety = true; this.Train.Handles.Brake.Safety = this.Train.Handles.Brake.MaximumNotch; } else { - TrainManager.ApplyHoldBrake(this.Train, false); + this.Train.ApplyHoldBrake(false); Train.ApplyNotch(0, true, this.Train.Handles.Brake.MaximumNotch, false); - TrainManager.ApplyEmergencyBrake(this.Train); + this.Train.ApplyEmergencyBrake(); } } else if (handles.BrakeNotch >= 2 & handles.BrakeNotch <= this.Train.Handles.Brake.MaximumNotch + 1) { if (virtualHandles) { this.Train.Handles.Brake.Safety = handles.BrakeNotch - 1; } else { - TrainManager.UnapplyEmergencyBrake(this.Train); - TrainManager.ApplyHoldBrake(this.Train, false); + this.Train.UnapplyEmergencyBrake(); + this.Train.ApplyHoldBrake(false); Train.ApplyNotch(0, true, handles.BrakeNotch - 1, false); } } else if (handles.BrakeNotch == 1) { @@ -278,17 +279,17 @@ private void SetHandles(Handles handles, bool virtualHandles) { this.Train.Handles.Brake.Safety = 0; this.Train.Handles.HoldBrake.Actual = true; } else { - TrainManager.UnapplyEmergencyBrake(this.Train); + this.Train.UnapplyEmergencyBrake(); Train.ApplyNotch(0, true, 0, false); - TrainManager.ApplyHoldBrake(this.Train, true); + this.Train.ApplyHoldBrake(true); } } else if (handles.BrakeNotch == 0) { if (virtualHandles) { this.Train.Handles.Brake.Safety = 0; } else { - TrainManager.UnapplyEmergencyBrake(this.Train); + this.Train.UnapplyEmergencyBrake(); Train.ApplyNotch(0, true, 0, false); - TrainManager.ApplyHoldBrake(this.Train, false); + this.Train.ApplyHoldBrake(false); } } else { if (virtualHandles) { @@ -302,14 +303,14 @@ private void SetHandles(Handles handles, bool virtualHandles) { this.Train.Handles.EmergencyBrake.Safety = true; this.Train.Handles.Brake.Safety = this.Train.Handles.Brake.MaximumNotch; } else { - TrainManager.ApplyHoldBrake(this.Train, false); - TrainManager.ApplyEmergencyBrake(this.Train); + this.Train.ApplyHoldBrake(false); + this.Train.ApplyEmergencyBrake(); } } else if (handles.BrakeNotch >= 0 & handles.BrakeNotch <= this.Train.Handles.Brake.MaximumNotch | this.Train.Handles.Brake.DelayedChanges.Length == 0) { if (virtualHandles) { this.Train.Handles.Brake.Safety = handles.BrakeNotch; } else { - TrainManager.UnapplyEmergencyBrake(this.Train); + this.Train.UnapplyEmergencyBrake(); Train.ApplyNotch(0, true, handles.BrakeNotch, false); } } else { @@ -356,11 +357,11 @@ internal void UpdatePower() { /// Called to update the brake notch. This invokes a call to SetBrake only if a change actually occured. internal void UpdateBrake() { int brakeNotch; - if (this.Train.Cars[this.Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) { + if (this.Train.Handles.Brake is TrainManager.AirBrakeHandle) { if (this.Train.Handles.HasHoldBrake) { - brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? 4 : this.Train.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Service ? 3 : this.Train.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Lap ? 2 : this.Train.Handles.HoldBrake.Driver ? 1 : 0; + brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? 4 : this.Train.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Service ? 3 : this.Train.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap ? 2 : this.Train.Handles.HoldBrake.Driver ? 1 : 0; } else { - brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? 3 : this.Train.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Service ? 2 : this.Train.Handles.AirBrake.Handle.Driver == TrainManager.AirBrakeHandleState.Lap ? 1 : 0; + brakeNotch = this.Train.Handles.EmergencyBrake.Driver ? 3 : this.Train.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Service ? 2 : this.Train.Handles.Brake.Driver == (int)TrainManager.AirBrakeHandleState.Lap ? 1 : 0; } } else { if (this.Train.Handles.HasHoldBrake) { @@ -489,9 +490,25 @@ internal static bool LoadCustomPlugin(TrainManager.Train train, string trainFold } string file = OpenBveApi.Path.CombineFile(trainFolder, lines[0]); string title = System.IO.Path.GetFileName(file); - if (!System.IO.File.Exists(file)) { - Interface.AddMessage(Interface.MessageType.Error, true, "The train plugin " + title + " could not be found in " + config); - return false; + if (!System.IO.File.Exists(file)) + { + if(lines[0].EndsWith(".dll") && encoding.Equals(System.Text.Encoding.Unicode)) + { + // Our filename ends with .dll so probably is not mangled Unicode + Interface.AddMessage(Interface.MessageType.Error, true, "The train plugin " + title + " could not be found in " + config); + return false; + } + // Try again with ASCII encoding + lines = System.IO.File.ReadAllLines(config, System.Text.Encoding.GetEncoding(1252)); + file = OpenBveApi.Path.CombineFile(trainFolder, lines[0]); + title = System.IO.Path.GetFileName(file); + if (!System.IO.File.Exists(file)) + { + // Nope, still not found + Interface.AddMessage(Interface.MessageType.Error, true, "The train plugin " + title + " could not be found in " + config); + return false; + } + } Program.AppendToLogFile("Loading train plugin: " + file); bool success = LoadPlugin(train, file, trainFolder); @@ -510,13 +527,12 @@ internal static bool LoadCustomPlugin(TrainManager.Train train, string trainFold /// The train to attach the plugin to. /// The train folder. /// Whether the plugin was loaded successfully. - internal static bool LoadDefaultPlugin(TrainManager.Train train, string trainFolder) { + internal static void LoadDefaultPlugin(TrainManager.Train train, string trainFolder) { string file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Plugins"), "OpenBveAts.dll"); bool success = LoadPlugin(train, file, trainFolder); if (success) { train.Plugin.IsDefault = true; } - return success; } /// Loads the specified plugin for the specified train. @@ -539,7 +555,7 @@ private static bool LoadPlugin(TrainManager.Train train, string pluginFile, stri /* * Prepare initialization data for the plugin. * */ - BrakeTypes brakeType = (BrakeTypes)train.Cars[train.DriverCar].Specs.BrakeType; + BrakeTypes brakeType = (BrakeTypes)train.Cars[train.DriverCar].CarBrake.brakeType; int brakeNotches; int powerNotches; bool hasHoldBrake; @@ -552,8 +568,10 @@ private static bool LoadPlugin(TrainManager.Train train, string pluginFile, stri powerNotches = train.Handles.Power.MaximumNotch; hasHoldBrake = train.Handles.HasHoldBrake; } + + bool hasLocoBrake = train.Handles.HasLocoBrake; int cars = train.Cars.Length; - VehicleSpecs specs = new VehicleSpecs(powerNotches, brakeType, brakeNotches, hasHoldBrake, cars); + VehicleSpecs specs = new VehicleSpecs(powerNotches, brakeType, brakeNotches, hasHoldBrake, hasLocoBrake, cars); InitializationModes mode = (InitializationModes)Game.TrainStart; /* * Check if the plugin is a .NET plugin. diff --git a/source/OpenBVE/System/Program.cs b/source/OpenBVE/System/Program.cs index 2bd01918e..48c56a298 100644 --- a/source/OpenBVE/System/Program.cs +++ b/source/OpenBVE/System/Program.cs @@ -4,7 +4,6 @@ using System.IO; using System.Reflection; using System.Runtime.InteropServices; -using System.Threading; using System.Windows.Forms; using OpenTK; @@ -55,17 +54,15 @@ internal static partial class Program { /// The command-line arguments. [STAThread] private static void Main(string[] args) { - -#if !DEBUG // Add handler for UI thread exceptions - Application.ThreadException += new ThreadExceptionEventHandler(CrashHandler.UIThreadException); + Application.ThreadException += (CrashHandler.UIThreadException); // Force all WinForms errors to go through handler Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); // This handler is for catching non-UI thread exceptions - AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CrashHandler.CurrentDomain_UnhandledException); -#endif + AppDomain.CurrentDomain.UnhandledException += (CrashHandler.CurrentDomain_UnhandledException); + //Determine the current CPU architecture- //ARM will generally only support OpenGL-ES diff --git a/source/OpenBVE/System/Scripting.cs b/source/OpenBVE/System/Scripting.cs index e4479c5b7..e71fd6c3c 100644 --- a/source/OpenBVE/System/Scripting.cs +++ b/source/OpenBVE/System/Scripting.cs @@ -1,5 +1,6 @@ using System; using OpenBveApi.Math; +// ReSharper disable UnusedMember.Global namespace OpenBve { @@ -247,7 +248,7 @@ public static double mainReservoir(TrainManager.Train Train, int CarIndex) { return 0.0; } - return Train.Cars[CarIndex].Specs.AirBrake.MainReservoirCurrentPressure; + return Train.Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure; } /// Returns the brake pipe pressure of the selected car of the selected train @@ -261,7 +262,7 @@ public static double brakePipe(TrainManager.Train Train, int CarIndex) { return 0.0; } - return Train.Cars[CarIndex].Specs.AirBrake.BrakePipeCurrentPressure; + return Train.Cars[CarIndex].CarBrake.brakePipe.CurrentPressure; } /// Returns the brake cylinder pressure of the selected car of the selected train @@ -275,7 +276,7 @@ public static double brakeCylinder(TrainManager.Train Train, int CarIndex) { return 0.0; } - return Train.Cars[CarIndex].Specs.AirBrake.BrakeCylinderCurrentPressure; + return Train.Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure; } /// Returns the brake pipe pressure of the selected car of the selected train @@ -289,7 +290,7 @@ public static double straightAirPipe(TrainManager.Train Train, int CarIndex) { return 0.0; } - return Train.Cars[CarIndex].Specs.AirBrake.StraightAirPipeCurrentPressure; + return Train.Cars[CarIndex].CarBrake.straightAirPipe.CurrentPressure; } /// Returns the doors state of the selected train @@ -547,13 +548,13 @@ public static int brakeNotches(TrainManager.Train Train) public static int brakeNotchLinear(TrainManager.Train Train) { if (Train == null) return 0; - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { if (Train.Handles.EmergencyBrake.Driver) { return 3; } - return (int) Train.Handles.AirBrake.Handle.Driver; + return (int) Train.Handles.Brake.Driver; } if (Train.Handles.HasHoldBrake) { @@ -580,7 +581,7 @@ public static int brakeNotchLinear(TrainManager.Train Train) public static int brakeNotchesLinear(TrainManager.Train Train) { if (Train == null) return 0; - if (Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake) + if (Train.Handles.Brake is TrainManager.AirBrakeHandle) { return 3; } @@ -606,7 +607,7 @@ public static bool emergencyBrake(TrainManager.Train Train) public static bool hasAirBrake(TrainManager.Train Train) { if (Train == null) return false; - return Train.Cars[Train.DriverCar].Specs.BrakeType == TrainManager.CarBrakeType.AutomaticAirBrake; + return Train.Handles.Brake is TrainManager.AirBrakeHandle; } /// Whether the hold brake is currently active for the selected train diff --git a/source/OpenBVE/UserInterface/formImage.cs b/source/OpenBVE/UserInterface/formImage.cs index 6270be80f..fbb049de7 100644 --- a/source/OpenBVE/UserInterface/formImage.cs +++ b/source/OpenBVE/UserInterface/formImage.cs @@ -4,7 +4,7 @@ namespace OpenBve { internal partial class formImage : Form { - internal formImage() { + private formImage() { InitializeComponent(); } @@ -16,7 +16,7 @@ internal static void ShowImageDialog(Image Image) { } // members - internal Image CurrentImage = null; + private Image CurrentImage = null; // resize private void formImage_Resize(object sender, EventArgs e) { diff --git a/source/OpenBVE/UserInterface/formMain.Designer.cs b/source/OpenBVE/UserInterface/formMain.Designer.cs index ae2ee819d..45f369cef 100644 --- a/source/OpenBVE/UserInterface/formMain.Designer.cs +++ b/source/OpenBVE/UserInterface/formMain.Designer.cs @@ -91,67 +91,13 @@ private void InitializeComponent() { this.panelOptions = new System.Windows.Forms.Panel(); this.buttonOptionsPrevious = new System.Windows.Forms.Button(); this.buttonOptionsNext = new System.Windows.Forms.Button(); - this.panelOptionsPage2 = new System.Windows.Forms.Panel(); - this.groupBoxKioskMode = new System.Windows.Forms.GroupBox(); - this.labelKioskTimeout = new System.Windows.Forms.Label(); - this.numericUpDownKioskTimeout = new System.Windows.Forms.NumericUpDown(); - this.checkBoxEnableKiosk = new System.Windows.Forms.CheckBox(); - this.groupBoxAdvancedOptions = new System.Windows.Forms.GroupBox(); - this.checkBoxHacks = new System.Windows.Forms.CheckBox(); - this.checkBoxTransparencyFix = new System.Windows.Forms.CheckBox(); - this.checkBoxUnloadTextures = new System.Windows.Forms.CheckBox(); - this.labelNumberFive = new System.Windows.Forms.Label(); - this.labelNumberZero = new System.Windows.Forms.Label(); - this.labelTimeAcceleration = new System.Windows.Forms.Label(); - this.trackBarTimeAccelerationFactor = new System.Windows.Forms.TrackBar(); - this.checkBoxDisableDisplayLists = new System.Windows.Forms.CheckBox(); - this.checkBoxLoadInAdvance = new System.Windows.Forms.CheckBox(); - this.groupBoxPackageOptions = new System.Windows.Forms.GroupBox(); - this.comboBoxCompressionFormat = new System.Windows.Forms.ComboBox(); - this.labelPackageCompression = new System.Windows.Forms.Label(); - this.buttonOtherDirectory = new System.Windows.Forms.Button(); - this.labelOtherInstallDirectory = new System.Windows.Forms.Label(); - this.textBoxOtherDirectory = new System.Windows.Forms.TextBox(); - this.buttonTrainInstallationDirectory = new System.Windows.Forms.Button(); - this.labelTrainInstallDirectory = new System.Windows.Forms.Label(); - this.textBoxTrainDirectory = new System.Windows.Forms.TextBox(); - this.buttonSetRouteDirectory = new System.Windows.Forms.Button(); - this.labelRouteInstallDirectory = new System.Windows.Forms.Label(); - this.textBoxRouteDirectory = new System.Windows.Forms.TextBox(); - this.panelOptionsRight = new System.Windows.Forms.Panel(); - this.groupBoxRailDriver = new System.Windows.Forms.GroupBox(); - this.labelRailDriverCalibration = new System.Windows.Forms.Label(); - this.buttonRailDriverCalibration = new System.Windows.Forms.Button(); - this.comboBoxRailDriverUnits = new System.Windows.Forms.ComboBox(); - this.labelRailDriverSpeedUnits = new System.Windows.Forms.Label(); - this.groupboxDistance = new System.Windows.Forms.GroupBox(); - this.comboboxMotionBlur = new System.Windows.Forms.ComboBox(); - this.labelMotionBlur = new System.Windows.Forms.Label(); - this.labelDistanceUnit = new System.Windows.Forms.Label(); - this.updownDistance = new System.Windows.Forms.NumericUpDown(); - this.labelDistance = new System.Windows.Forms.Label(); - this.groupboxControls = new System.Windows.Forms.GroupBox(); - this.checkBoxEBAxis = new System.Windows.Forms.CheckBox(); - this.trackbarJoystickAxisThreshold = new System.Windows.Forms.TrackBar(); - this.checkboxJoysticksUsed = new System.Windows.Forms.CheckBox(); - this.labelJoystickAxisThreshold = new System.Windows.Forms.Label(); - this.groupboxVerbosity = new System.Windows.Forms.GroupBox(); - this.checkboxErrorMessages = new System.Windows.Forms.CheckBox(); - this.checkboxWarningMessages = new System.Windows.Forms.CheckBox(); - this.groupboxSimulation = new System.Windows.Forms.GroupBox(); - this.checkBoxLoadingSway = new System.Windows.Forms.CheckBox(); - this.checkboxBlackBox = new System.Windows.Forms.CheckBox(); - this.checkboxDerailments = new System.Windows.Forms.CheckBox(); - this.checkboxCollisions = new System.Windows.Forms.CheckBox(); - this.checkboxToppling = new System.Windows.Forms.CheckBox(); - this.groupboxSound = new System.Windows.Forms.GroupBox(); - this.updownSoundNumber = new System.Windows.Forms.NumericUpDown(); - this.labelSoundNumber = new System.Windows.Forms.Label(); this.panelOptionsLeft = new System.Windows.Forms.Panel(); - this.groupBoxOther = new System.Windows.Forms.GroupBox(); - this.comboBoxTimeTableDisplayMode = new System.Windows.Forms.ComboBox(); - this.labelTimeTableDisplayMode = new System.Windows.Forms.Label(); this.groupboxDisplayMode = new System.Windows.Forms.GroupBox(); + this.labelHUDLarge = new System.Windows.Forms.Label(); + this.labelHUDNormal = new System.Windows.Forms.Label(); + this.labelHUDSmall = new System.Windows.Forms.Label(); + this.trackBarHUDSize = new System.Windows.Forms.TrackBar(); + this.labelHUDScale = new System.Windows.Forms.Label(); this.comboboxVSync = new System.Windows.Forms.ComboBox(); this.labelVSync = new System.Windows.Forms.Label(); this.radiobuttonFullscreen = new System.Windows.Forms.RadioButton(); @@ -179,7 +125,66 @@ private void InitializeComponent() { this.comboboxInterpolation = new System.Windows.Forms.ComboBox(); this.labelInterpolation = new System.Windows.Forms.Label(); this.trackbarTransparency = new System.Windows.Forms.TrackBar(); + this.panelOptionsRight = new System.Windows.Forms.Panel(); + this.groupBoxOther = new System.Windows.Forms.GroupBox(); + this.comboBoxTimeTableDisplayMode = new System.Windows.Forms.ComboBox(); + this.labelTimeTableDisplayMode = new System.Windows.Forms.Label(); + this.groupBoxRailDriver = new System.Windows.Forms.GroupBox(); + this.labelRailDriverCalibration = new System.Windows.Forms.Label(); + this.buttonRailDriverCalibration = new System.Windows.Forms.Button(); + this.comboBoxRailDriverUnits = new System.Windows.Forms.ComboBox(); + this.labelRailDriverSpeedUnits = new System.Windows.Forms.Label(); + this.groupboxDistance = new System.Windows.Forms.GroupBox(); + this.comboboxMotionBlur = new System.Windows.Forms.ComboBox(); + this.labelMotionBlur = new System.Windows.Forms.Label(); + this.labelDistanceUnit = new System.Windows.Forms.Label(); + this.updownDistance = new System.Windows.Forms.NumericUpDown(); + this.labelDistance = new System.Windows.Forms.Label(); + this.groupboxControls = new System.Windows.Forms.GroupBox(); + this.checkBoxEBAxis = new System.Windows.Forms.CheckBox(); + this.trackbarJoystickAxisThreshold = new System.Windows.Forms.TrackBar(); + this.checkboxJoysticksUsed = new System.Windows.Forms.CheckBox(); + this.labelJoystickAxisThreshold = new System.Windows.Forms.Label(); + this.groupboxVerbosity = new System.Windows.Forms.GroupBox(); + this.checkboxErrorMessages = new System.Windows.Forms.CheckBox(); + this.checkboxWarningMessages = new System.Windows.Forms.CheckBox(); + this.groupboxSimulation = new System.Windows.Forms.GroupBox(); + this.checkBoxLoadingSway = new System.Windows.Forms.CheckBox(); + this.checkboxBlackBox = new System.Windows.Forms.CheckBox(); + this.checkboxDerailments = new System.Windows.Forms.CheckBox(); + this.checkboxCollisions = new System.Windows.Forms.CheckBox(); + this.checkboxToppling = new System.Windows.Forms.CheckBox(); + this.groupboxSound = new System.Windows.Forms.GroupBox(); + this.updownSoundNumber = new System.Windows.Forms.NumericUpDown(); + this.labelSoundNumber = new System.Windows.Forms.Label(); this.pictureboxLanguage = new System.Windows.Forms.PictureBox(); + this.panelOptionsPage2 = new System.Windows.Forms.Panel(); + this.groupBoxKioskMode = new System.Windows.Forms.GroupBox(); + this.labelKioskTimeout = new System.Windows.Forms.Label(); + this.numericUpDownKioskTimeout = new System.Windows.Forms.NumericUpDown(); + this.checkBoxEnableKiosk = new System.Windows.Forms.CheckBox(); + this.groupBoxAdvancedOptions = new System.Windows.Forms.GroupBox(); + this.checkBoxHacks = new System.Windows.Forms.CheckBox(); + this.checkBoxTransparencyFix = new System.Windows.Forms.CheckBox(); + this.checkBoxUnloadTextures = new System.Windows.Forms.CheckBox(); + this.labelNumberFive = new System.Windows.Forms.Label(); + this.labelNumberZero = new System.Windows.Forms.Label(); + this.labelTimeAcceleration = new System.Windows.Forms.Label(); + this.trackBarTimeAccelerationFactor = new System.Windows.Forms.TrackBar(); + this.checkBoxDisableDisplayLists = new System.Windows.Forms.CheckBox(); + this.checkBoxLoadInAdvance = new System.Windows.Forms.CheckBox(); + this.groupBoxPackageOptions = new System.Windows.Forms.GroupBox(); + this.comboBoxCompressionFormat = new System.Windows.Forms.ComboBox(); + this.labelPackageCompression = new System.Windows.Forms.Label(); + this.buttonOtherDirectory = new System.Windows.Forms.Button(); + this.labelOtherInstallDirectory = new System.Windows.Forms.Label(); + this.textBoxOtherDirectory = new System.Windows.Forms.TextBox(); + this.buttonTrainInstallationDirectory = new System.Windows.Forms.Button(); + this.labelTrainInstallDirectory = new System.Windows.Forms.Label(); + this.textBoxTrainDirectory = new System.Windows.Forms.TextBox(); + this.buttonSetRouteDirectory = new System.Windows.Forms.Button(); + this.labelRouteInstallDirectory = new System.Windows.Forms.Label(); + this.textBoxRouteDirectory = new System.Windows.Forms.TextBox(); this.comboboxLanguages = new System.Windows.Forms.ComboBox(); this.labelOptionsTitleSeparator = new System.Windows.Forms.Label(); this.labelOptionsTitle = new System.Windows.Forms.Label(); @@ -448,25 +453,9 @@ private void InitializeComponent() { this.tabpageRouteSettings.SuspendLayout(); this.panelRouteEncoding.SuspendLayout(); this.panelOptions.SuspendLayout(); - this.panelOptionsPage2.SuspendLayout(); - this.groupBoxKioskMode.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDownKioskTimeout)).BeginInit(); - this.groupBoxAdvancedOptions.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarTimeAccelerationFactor)).BeginInit(); - this.groupBoxPackageOptions.SuspendLayout(); - this.panelOptionsRight.SuspendLayout(); - this.groupBoxRailDriver.SuspendLayout(); - this.groupboxDistance.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.updownDistance)).BeginInit(); - this.groupboxControls.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackbarJoystickAxisThreshold)).BeginInit(); - this.groupboxVerbosity.SuspendLayout(); - this.groupboxSimulation.SuspendLayout(); - this.groupboxSound.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.updownSoundNumber)).BeginInit(); this.panelOptionsLeft.SuspendLayout(); - this.groupBoxOther.SuspendLayout(); this.groupboxDisplayMode.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarHUDSize)).BeginInit(); this.groupboxWindow.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.updownWindowHeight)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.updownWindowWidth)).BeginInit(); @@ -477,7 +466,24 @@ private void InitializeComponent() { ((System.ComponentModel.ISupportInitialize)(this.updownAntiAliasing)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.updownAnisotropic)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.trackbarTransparency)).BeginInit(); + this.panelOptionsRight.SuspendLayout(); + this.groupBoxOther.SuspendLayout(); + this.groupBoxRailDriver.SuspendLayout(); + this.groupboxDistance.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.updownDistance)).BeginInit(); + this.groupboxControls.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackbarJoystickAxisThreshold)).BeginInit(); + this.groupboxVerbosity.SuspendLayout(); + this.groupboxSimulation.SuspendLayout(); + this.groupboxSound.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.updownSoundNumber)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureboxLanguage)).BeginInit(); + this.panelOptionsPage2.SuspendLayout(); + this.groupBoxKioskMode.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownKioskTimeout)).BeginInit(); + this.groupBoxAdvancedOptions.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarTimeAccelerationFactor)).BeginInit(); + this.groupBoxPackageOptions.SuspendLayout(); this.panelPanels.SuspendLayout(); this.panelReview.SuspendLayout(); this.groupboxReviewDateTime.SuspendLayout(); @@ -1356,10 +1362,10 @@ private void InitializeComponent() { this.panelOptions.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(243)))), ((int)(((byte)(255)))), ((int)(((byte)(243))))); this.panelOptions.Controls.Add(this.buttonOptionsPrevious); this.panelOptions.Controls.Add(this.buttonOptionsNext); - this.panelOptions.Controls.Add(this.panelOptionsPage2); - this.panelOptions.Controls.Add(this.panelOptionsRight); this.panelOptions.Controls.Add(this.panelOptionsLeft); + this.panelOptions.Controls.Add(this.panelOptionsRight); this.panelOptions.Controls.Add(this.pictureboxLanguage); + this.panelOptions.Controls.Add(this.panelOptionsPage2); this.panelOptions.Controls.Add(this.comboboxLanguages); this.panelOptions.Controls.Add(this.labelOptionsTitleSeparator); this.panelOptions.Controls.Add(this.labelOptionsTitle); @@ -1391,311 +1397,468 @@ private void InitializeComponent() { this.buttonOptionsNext.UseVisualStyleBackColor = true; this.buttonOptionsNext.Click += new System.EventHandler(this.buttonOptionsPrevious_Click); // - // panelOptionsPage2 + // panelOptionsLeft // - this.panelOptionsPage2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.panelOptionsPage2.Controls.Add(this.groupBoxKioskMode); - this.panelOptionsPage2.Controls.Add(this.groupBoxAdvancedOptions); - this.panelOptionsPage2.Controls.Add(this.groupBoxPackageOptions); - this.panelOptionsPage2.Location = new System.Drawing.Point(8, 72); - this.panelOptionsPage2.Name = "panelOptionsPage2"; - this.panelOptionsPage2.Size = new System.Drawing.Size(643, 528); - this.panelOptionsPage2.TabIndex = 20; + this.panelOptionsLeft.Controls.Add(this.groupboxDisplayMode); + this.panelOptionsLeft.Controls.Add(this.groupboxWindow); + this.panelOptionsLeft.Controls.Add(this.groupboxFullscreen); + this.panelOptionsLeft.Controls.Add(this.groupboxInterpolation); + this.panelOptionsLeft.Location = new System.Drawing.Point(8, 72); + this.panelOptionsLeft.Name = "panelOptionsLeft"; + this.panelOptionsLeft.Size = new System.Drawing.Size(316, 576); + this.panelOptionsLeft.TabIndex = 16; // - // groupBoxKioskMode + // groupboxDisplayMode // - this.groupBoxKioskMode.Controls.Add(this.labelKioskTimeout); - this.groupBoxKioskMode.Controls.Add(this.numericUpDownKioskTimeout); - this.groupBoxKioskMode.Controls.Add(this.checkBoxEnableKiosk); - this.groupBoxKioskMode.Location = new System.Drawing.Point(334, 164); - this.groupBoxKioskMode.Name = "groupBoxKioskMode"; - this.groupBoxKioskMode.Size = new System.Drawing.Size(305, 88); - this.groupBoxKioskMode.TabIndex = 22; - this.groupBoxKioskMode.TabStop = false; - this.groupBoxKioskMode.Text = "Kiosk Mode"; + this.groupboxDisplayMode.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupboxDisplayMode.Controls.Add(this.labelHUDLarge); + this.groupboxDisplayMode.Controls.Add(this.labelHUDNormal); + this.groupboxDisplayMode.Controls.Add(this.labelHUDSmall); + this.groupboxDisplayMode.Controls.Add(this.trackBarHUDSize); + this.groupboxDisplayMode.Controls.Add(this.labelHUDScale); + this.groupboxDisplayMode.Controls.Add(this.comboboxVSync); + this.groupboxDisplayMode.Controls.Add(this.labelVSync); + this.groupboxDisplayMode.Controls.Add(this.radiobuttonFullscreen); + this.groupboxDisplayMode.Controls.Add(this.radiobuttonWindow); + this.groupboxDisplayMode.ForeColor = System.Drawing.Color.Black; + this.groupboxDisplayMode.Location = new System.Drawing.Point(0, 0); + this.groupboxDisplayMode.Name = "groupboxDisplayMode"; + this.groupboxDisplayMode.Size = new System.Drawing.Size(316, 149); + this.groupboxDisplayMode.TabIndex = 4; + this.groupboxDisplayMode.TabStop = false; + this.groupboxDisplayMode.Text = "Display mode"; // - // labelKioskTimeout + // labelHUDLarge // - this.labelKioskTimeout.AutoSize = true; - this.labelKioskTimeout.Location = new System.Drawing.Point(8, 43); - this.labelKioskTimeout.Name = "labelKioskTimeout"; - this.labelKioskTimeout.Size = new System.Drawing.Size(91, 13); - this.labelKioskTimeout.TabIndex = 2; - this.labelKioskTimeout.Text = "Control timeout (s)"; + this.labelHUDLarge.AutoSize = true; + this.labelHUDLarge.Location = new System.Drawing.Point(267, 125); + this.labelHUDLarge.Name = "labelHUDLarge"; + this.labelHUDLarge.Size = new System.Drawing.Size(34, 13); + this.labelHUDLarge.TabIndex = 12; + this.labelHUDLarge.Text = "Large"; // - // numericUpDownKioskTimeout + // labelHUDNormal // - this.numericUpDownKioskTimeout.DecimalPlaces = 2; - this.numericUpDownKioskTimeout.Location = new System.Drawing.Point(166, 41); - this.numericUpDownKioskTimeout.Maximum = new decimal(new int[] { - 10000, - 0, - 0, - 0}); - this.numericUpDownKioskTimeout.Name = "numericUpDownKioskTimeout"; - this.numericUpDownKioskTimeout.Size = new System.Drawing.Size(131, 20); - this.numericUpDownKioskTimeout.TabIndex = 1; + this.labelHUDNormal.AutoSize = true; + this.labelHUDNormal.Location = new System.Drawing.Point(174, 125); + this.labelHUDNormal.Name = "labelHUDNormal"; + this.labelHUDNormal.Size = new System.Drawing.Size(40, 13); + this.labelHUDNormal.TabIndex = 11; + this.labelHUDNormal.Text = "Normal"; // - // checkBoxEnableKiosk + // labelHUDSmall // - this.checkBoxEnableKiosk.AutoSize = true; - this.checkBoxEnableKiosk.Location = new System.Drawing.Point(9, 20); - this.checkBoxEnableKiosk.Name = "checkBoxEnableKiosk"; - this.checkBoxEnableKiosk.Size = new System.Drawing.Size(118, 17); - this.checkBoxEnableKiosk.TabIndex = 0; - this.checkBoxEnableKiosk.Text = "Enable Kiosk Mode"; - this.checkBoxEnableKiosk.UseVisualStyleBackColor = true; + this.labelHUDSmall.AutoSize = true; + this.labelHUDSmall.Location = new System.Drawing.Point(84, 125); + this.labelHUDSmall.Name = "labelHUDSmall"; + this.labelHUDSmall.Size = new System.Drawing.Size(32, 13); + this.labelHUDSmall.TabIndex = 10; + this.labelHUDSmall.Text = "Small"; // - // groupBoxAdvancedOptions + // trackBarHUDSize // - this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxHacks); - this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxTransparencyFix); - this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxUnloadTextures); - this.groupBoxAdvancedOptions.Controls.Add(this.labelNumberFive); - this.groupBoxAdvancedOptions.Controls.Add(this.labelNumberZero); - this.groupBoxAdvancedOptions.Controls.Add(this.labelTimeAcceleration); - this.groupBoxAdvancedOptions.Controls.Add(this.trackBarTimeAccelerationFactor); - this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxDisableDisplayLists); - this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxLoadInAdvance); - this.groupBoxAdvancedOptions.Location = new System.Drawing.Point(6, 160); - this.groupBoxAdvancedOptions.Name = "groupBoxAdvancedOptions"; - this.groupBoxAdvancedOptions.Size = new System.Drawing.Size(316, 208); - this.groupBoxAdvancedOptions.TabIndex = 21; - this.groupBoxAdvancedOptions.TabStop = false; - this.groupBoxAdvancedOptions.Text = "Advanced Options"; + this.trackBarHUDSize.LargeChange = 1; + this.trackBarHUDSize.Location = new System.Drawing.Point(88, 100); + this.trackBarHUDSize.Maximum = 2; + this.trackBarHUDSize.Name = "trackBarHUDSize"; + this.trackBarHUDSize.Size = new System.Drawing.Size(220, 45); + this.trackBarHUDSize.TabIndex = 9; + this.trackBarHUDSize.Value = 1; // - // checkBoxHacks + // labelHUDScale // - this.checkBoxHacks.AutoSize = true; - this.checkBoxHacks.Location = new System.Drawing.Point(8, 100); - this.checkBoxHacks.Name = "checkBoxHacks"; - this.checkBoxHacks.Size = new System.Drawing.Size(203, 17); - this.checkBoxHacks.TabIndex = 15; - this.checkBoxHacks.Text = "Enable hacks for buggy older content"; - this.checkBoxHacks.UseVisualStyleBackColor = true; + this.labelHUDScale.AutoSize = true; + this.labelHUDScale.Location = new System.Drawing.Point(8, 106); + this.labelHUDScale.Name = "labelHUDScale"; + this.labelHUDScale.Size = new System.Drawing.Size(54, 13); + this.labelHUDScale.TabIndex = 8; + this.labelHUDScale.Text = "HUD Size"; // - // checkBoxTransparencyFix + // comboboxVSync // - this.checkBoxTransparencyFix.AutoSize = true; - this.checkBoxTransparencyFix.Location = new System.Drawing.Point(8, 81); - this.checkBoxTransparencyFix.Name = "checkBoxTransparencyFix"; - this.checkBoxTransparencyFix.Size = new System.Drawing.Size(259, 17); - this.checkBoxTransparencyFix.TabIndex = 14; - this.checkBoxTransparencyFix.Text = "Attempt to fix transparency issues in older content"; - this.checkBoxTransparencyFix.UseVisualStyleBackColor = true; + this.comboboxVSync.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.comboboxVSync.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboboxVSync.FormattingEnabled = true; + this.comboboxVSync.Location = new System.Drawing.Point(156, 72); + this.comboboxVSync.Name = "comboboxVSync"; + this.comboboxVSync.Size = new System.Drawing.Size(152, 21); + this.comboboxVSync.TabIndex = 7; // - // checkBoxUnloadTextures + // labelVSync // - this.checkBoxUnloadTextures.AutoSize = true; - this.checkBoxUnloadTextures.Location = new System.Drawing.Point(8, 62); - this.checkBoxUnloadTextures.Name = "checkBoxUnloadTextures"; - this.checkBoxUnloadTextures.Size = new System.Drawing.Size(138, 17); - this.checkBoxUnloadTextures.TabIndex = 13; - this.checkBoxUnloadTextures.Text = "Unload unused textures"; - this.checkBoxUnloadTextures.UseVisualStyleBackColor = true; - this.checkBoxUnloadTextures.CheckedChanged += new System.EventHandler(this.checkBoxUnloadTextures_CheckedChanged); + this.labelVSync.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelVSync.AutoEllipsis = true; + this.labelVSync.Location = new System.Drawing.Point(8, 72); + this.labelVSync.Name = "labelVSync"; + this.labelVSync.Size = new System.Drawing.Size(148, 16); + this.labelVSync.TabIndex = 2; + this.labelVSync.Text = "Vertical syncronization:"; + this.labelVSync.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // labelNumberFive + // radiobuttonFullscreen // - this.labelNumberFive.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.labelNumberFive.AutoSize = true; - this.labelNumberFive.Location = new System.Drawing.Point(267, 163); - this.labelNumberFive.Name = "labelNumberFive"; - this.labelNumberFive.Size = new System.Drawing.Size(13, 13); - this.labelNumberFive.TabIndex = 12; - this.labelNumberFive.Text = "5"; + this.radiobuttonFullscreen.AutoSize = true; + this.radiobuttonFullscreen.Location = new System.Drawing.Point(8, 48); + this.radiobuttonFullscreen.Name = "radiobuttonFullscreen"; + this.radiobuttonFullscreen.Size = new System.Drawing.Size(102, 17); + this.radiobuttonFullscreen.TabIndex = 1; + this.radiobuttonFullscreen.TabStop = true; + this.radiobuttonFullscreen.Text = "Fullscreen mode"; + this.radiobuttonFullscreen.UseVisualStyleBackColor = true; // - // labelNumberZero + // radiobuttonWindow // - this.labelNumberZero.AutoSize = true; - this.labelNumberZero.Location = new System.Drawing.Point(186, 163); - this.labelNumberZero.Name = "labelNumberZero"; - this.labelNumberZero.Size = new System.Drawing.Size(13, 13); - this.labelNumberZero.TabIndex = 11; - this.labelNumberZero.Text = "0"; + this.radiobuttonWindow.AutoSize = true; + this.radiobuttonWindow.Checked = true; + this.radiobuttonWindow.Location = new System.Drawing.Point(8, 24); + this.radiobuttonWindow.Name = "radiobuttonWindow"; + this.radiobuttonWindow.Size = new System.Drawing.Size(93, 17); + this.radiobuttonWindow.TabIndex = 0; + this.radiobuttonWindow.TabStop = true; + this.radiobuttonWindow.Text = "Window mode"; + this.radiobuttonWindow.UseVisualStyleBackColor = true; // - // labelTimeAcceleration + // groupboxWindow // - this.labelTimeAcceleration.Location = new System.Drawing.Point(-1, 132); - this.labelTimeAcceleration.Name = "labelTimeAcceleration"; - this.labelTimeAcceleration.Size = new System.Drawing.Size(179, 22); - this.labelTimeAcceleration.TabIndex = 10; - this.labelTimeAcceleration.Text = "Accelerated Time Factor:"; - this.labelTimeAcceleration.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + this.groupboxWindow.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupboxWindow.Controls.Add(this.updownWindowHeight); + this.groupboxWindow.Controls.Add(this.labelWindowHeight); + this.groupboxWindow.Controls.Add(this.updownWindowWidth); + this.groupboxWindow.Controls.Add(this.labelWindowWidth); + this.groupboxWindow.ForeColor = System.Drawing.Color.Black; + this.groupboxWindow.Location = new System.Drawing.Point(0, 155); + this.groupboxWindow.Name = "groupboxWindow"; + this.groupboxWindow.Size = new System.Drawing.Size(316, 80); + this.groupboxWindow.TabIndex = 5; + this.groupboxWindow.TabStop = false; + this.groupboxWindow.Text = "Window mode"; // - // trackBarTimeAccelerationFactor + // updownWindowHeight // - this.trackBarTimeAccelerationFactor.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.updownWindowHeight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.updownWindowHeight.Location = new System.Drawing.Point(156, 48); + this.updownWindowHeight.Maximum = new decimal(new int[] { + 1048575, + 0, + 0, + 0}); + this.updownWindowHeight.Minimum = new decimal(new int[] { + 16, + 0, + 0, + 0}); + this.updownWindowHeight.Name = "updownWindowHeight"; + this.updownWindowHeight.Size = new System.Drawing.Size(152, 20); + this.updownWindowHeight.TabIndex = 3; + this.updownWindowHeight.Value = new decimal(new int[] { + 600, + 0, + 0, + 0}); + // + // labelWindowHeight + // + this.labelWindowHeight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.trackBarTimeAccelerationFactor.LargeChange = 1; - this.trackBarTimeAccelerationFactor.Location = new System.Drawing.Point(179, 122); - this.trackBarTimeAccelerationFactor.Maximum = 5; - this.trackBarTimeAccelerationFactor.Name = "trackBarTimeAccelerationFactor"; - this.trackBarTimeAccelerationFactor.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.trackBarTimeAccelerationFactor.Size = new System.Drawing.Size(108, 45); - this.trackBarTimeAccelerationFactor.TabIndex = 3; - this.trackBarTimeAccelerationFactor.TickStyle = System.Windows.Forms.TickStyle.Both; + this.labelWindowHeight.AutoEllipsis = true; + this.labelWindowHeight.Location = new System.Drawing.Point(8, 50); + this.labelWindowHeight.Name = "labelWindowHeight"; + this.labelWindowHeight.Size = new System.Drawing.Size(148, 16); + this.labelWindowHeight.TabIndex = 2; + this.labelWindowHeight.Text = "Height:"; + this.labelWindowHeight.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // checkBoxDisableDisplayLists + // updownWindowWidth // - this.checkBoxDisableDisplayLists.AutoSize = true; - this.checkBoxDisableDisplayLists.Location = new System.Drawing.Point(8, 43); - this.checkBoxDisableDisplayLists.Name = "checkBoxDisableDisplayLists"; - this.checkBoxDisableDisplayLists.Size = new System.Drawing.Size(159, 17); - this.checkBoxDisableDisplayLists.TabIndex = 2; - this.checkBoxDisableDisplayLists.Text = "Disable OpenGL display lists"; - this.checkBoxDisableDisplayLists.UseVisualStyleBackColor = true; + this.updownWindowWidth.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.updownWindowWidth.Location = new System.Drawing.Point(156, 24); + this.updownWindowWidth.Maximum = new decimal(new int[] { + 1048575, + 0, + 0, + 0}); + this.updownWindowWidth.Minimum = new decimal(new int[] { + 16, + 0, + 0, + 0}); + this.updownWindowWidth.Name = "updownWindowWidth"; + this.updownWindowWidth.Size = new System.Drawing.Size(152, 20); + this.updownWindowWidth.TabIndex = 1; + this.updownWindowWidth.Value = new decimal(new int[] { + 960, + 0, + 0, + 0}); // - // checkBoxLoadInAdvance + // labelWindowWidth // - this.checkBoxLoadInAdvance.AutoSize = true; - this.checkBoxLoadInAdvance.Location = new System.Drawing.Point(8, 24); - this.checkBoxLoadInAdvance.Name = "checkBoxLoadInAdvance"; - this.checkBoxLoadInAdvance.Size = new System.Drawing.Size(106, 17); - this.checkBoxLoadInAdvance.TabIndex = 1; - this.checkBoxLoadInAdvance.Text = "Load in advance"; - this.checkBoxLoadInAdvance.UseVisualStyleBackColor = true; - this.checkBoxLoadInAdvance.CheckedChanged += new System.EventHandler(this.checkBoxLoadInAdvance_CheckedChanged); + this.labelWindowWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelWindowWidth.AutoEllipsis = true; + this.labelWindowWidth.Location = new System.Drawing.Point(8, 26); + this.labelWindowWidth.Name = "labelWindowWidth"; + this.labelWindowWidth.Size = new System.Drawing.Size(148, 16); + this.labelWindowWidth.TabIndex = 0; + this.labelWindowWidth.Text = "Width:"; + this.labelWindowWidth.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // groupBoxPackageOptions + // groupboxFullscreen // - this.groupBoxPackageOptions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.groupboxFullscreen.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.groupBoxPackageOptions.Controls.Add(this.comboBoxCompressionFormat); - this.groupBoxPackageOptions.Controls.Add(this.labelPackageCompression); - this.groupBoxPackageOptions.Controls.Add(this.buttonOtherDirectory); - this.groupBoxPackageOptions.Controls.Add(this.labelOtherInstallDirectory); - this.groupBoxPackageOptions.Controls.Add(this.textBoxOtherDirectory); - this.groupBoxPackageOptions.Controls.Add(this.buttonTrainInstallationDirectory); - this.groupBoxPackageOptions.Controls.Add(this.labelTrainInstallDirectory); - this.groupBoxPackageOptions.Controls.Add(this.textBoxTrainDirectory); - this.groupBoxPackageOptions.Controls.Add(this.buttonSetRouteDirectory); - this.groupBoxPackageOptions.Controls.Add(this.labelRouteInstallDirectory); - this.groupBoxPackageOptions.Controls.Add(this.textBoxRouteDirectory); - this.groupBoxPackageOptions.ForeColor = System.Drawing.Color.Black; - this.groupBoxPackageOptions.Location = new System.Drawing.Point(0, 0); - this.groupBoxPackageOptions.Name = "groupBoxPackageOptions"; - this.groupBoxPackageOptions.Size = new System.Drawing.Size(640, 154); - this.groupBoxPackageOptions.TabIndex = 19; - this.groupBoxPackageOptions.TabStop = false; - this.groupBoxPackageOptions.Text = "Package Management"; + this.groupboxFullscreen.Controls.Add(this.comboboxFullscreenBits); + this.groupboxFullscreen.Controls.Add(this.labelFullscreenBits); + this.groupboxFullscreen.Controls.Add(this.updownFullscreenHeight); + this.groupboxFullscreen.Controls.Add(this.labelFullscreenHeight); + this.groupboxFullscreen.Controls.Add(this.updownFullscreenWidth); + this.groupboxFullscreen.Controls.Add(this.labelFullscreenWidth); + this.groupboxFullscreen.ForeColor = System.Drawing.Color.Black; + this.groupboxFullscreen.Location = new System.Drawing.Point(0, 245); + this.groupboxFullscreen.Name = "groupboxFullscreen"; + this.groupboxFullscreen.Size = new System.Drawing.Size(316, 104); + this.groupboxFullscreen.TabIndex = 6; + this.groupboxFullscreen.TabStop = false; + this.groupboxFullscreen.Text = "Fullscreen mode"; // - // comboBoxCompressionFormat + // comboboxFullscreenBits // - this.comboBoxCompressionFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxCompressionFormat.Items.AddRange(new object[] { - "LZMA ZIP ( .zip )", - "GZip ( .tgz )", - "BZip2 ( .bz2 )"}); - this.comboBoxCompressionFormat.Location = new System.Drawing.Point(200, 117); - this.comboBoxCompressionFormat.Name = "comboBoxCompressionFormat"; - this.comboBoxCompressionFormat.Size = new System.Drawing.Size(188, 21); - this.comboBoxCompressionFormat.TabIndex = 10; - this.comboBoxCompressionFormat.SelectedIndexChanged += new System.EventHandler(this.comboBoxCompressionFormat_SelectedIndexChanged); + this.comboboxFullscreenBits.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.comboboxFullscreenBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboboxFullscreenBits.FormattingEnabled = true; + this.comboboxFullscreenBits.Location = new System.Drawing.Point(156, 72); + this.comboboxFullscreenBits.Name = "comboboxFullscreenBits"; + this.comboboxFullscreenBits.Size = new System.Drawing.Size(152, 21); + this.comboboxFullscreenBits.TabIndex = 5; // - // labelPackageCompression + // labelFullscreenBits // - this.labelPackageCompression.AutoSize = true; - this.labelPackageCompression.Location = new System.Drawing.Point(6, 121); - this.labelPackageCompression.Name = "labelPackageCompression"; - this.labelPackageCompression.Size = new System.Drawing.Size(147, 13); - this.labelPackageCompression.TabIndex = 9; - this.labelPackageCompression.Text = "Package compression format:"; + this.labelFullscreenBits.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelFullscreenBits.AutoEllipsis = true; + this.labelFullscreenBits.Location = new System.Drawing.Point(8, 74); + this.labelFullscreenBits.Name = "labelFullscreenBits"; + this.labelFullscreenBits.Size = new System.Drawing.Size(148, 16); + this.labelFullscreenBits.TabIndex = 4; + this.labelFullscreenBits.Text = "Bits per pixel:"; + this.labelFullscreenBits.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // buttonOtherDirectory + // updownFullscreenHeight // - this.buttonOtherDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonOtherDirectory.Location = new System.Drawing.Point(560, 82); - this.buttonOtherDirectory.Name = "buttonOtherDirectory"; - this.buttonOtherDirectory.Size = new System.Drawing.Size(75, 23); - this.buttonOtherDirectory.TabIndex = 8; - this.buttonOtherDirectory.Text = "Choose..."; - this.buttonOtherDirectory.UseVisualStyleBackColor = true; - this.buttonOtherDirectory.Click += new System.EventHandler(this.buttonOtherDirectory_Click); + this.updownFullscreenHeight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.updownFullscreenHeight.Location = new System.Drawing.Point(156, 48); + this.updownFullscreenHeight.Maximum = new decimal(new int[] { + 1048575, + 0, + 0, + 0}); + this.updownFullscreenHeight.Minimum = new decimal(new int[] { + 16, + 0, + 0, + 0}); + this.updownFullscreenHeight.Name = "updownFullscreenHeight"; + this.updownFullscreenHeight.Size = new System.Drawing.Size(152, 20); + this.updownFullscreenHeight.TabIndex = 3; + this.updownFullscreenHeight.Value = new decimal(new int[] { + 768, + 0, + 0, + 0}); // - // labelOtherInstallDirectory + // labelFullscreenHeight // - this.labelOtherInstallDirectory.AutoSize = true; - this.labelOtherInstallDirectory.Location = new System.Drawing.Point(6, 85); - this.labelOtherInstallDirectory.Name = "labelOtherInstallDirectory"; - this.labelOtherInstallDirectory.Size = new System.Drawing.Size(158, 13); - this.labelOtherInstallDirectory.TabIndex = 7; - this.labelOtherInstallDirectory.Text = "Other items installation directory:"; + this.labelFullscreenHeight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelFullscreenHeight.AutoEllipsis = true; + this.labelFullscreenHeight.Location = new System.Drawing.Point(8, 50); + this.labelFullscreenHeight.Name = "labelFullscreenHeight"; + this.labelFullscreenHeight.Size = new System.Drawing.Size(148, 16); + this.labelFullscreenHeight.TabIndex = 2; + this.labelFullscreenHeight.Text = "Height:"; + this.labelFullscreenHeight.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // textBoxOtherDirectory + // updownFullscreenWidth // - this.textBoxOtherDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.updownFullscreenWidth.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.updownFullscreenWidth.Location = new System.Drawing.Point(156, 24); + this.updownFullscreenWidth.Maximum = new decimal(new int[] { + 1048575, + 0, + 0, + 0}); + this.updownFullscreenWidth.Minimum = new decimal(new int[] { + 16, + 0, + 0, + 0}); + this.updownFullscreenWidth.Name = "updownFullscreenWidth"; + this.updownFullscreenWidth.Size = new System.Drawing.Size(152, 20); + this.updownFullscreenWidth.TabIndex = 1; + this.updownFullscreenWidth.Value = new decimal(new int[] { + 1024, + 0, + 0, + 0}); + // + // labelFullscreenWidth + // + this.labelFullscreenWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxOtherDirectory.Location = new System.Drawing.Point(200, 84); - this.textBoxOtherDirectory.Name = "textBoxOtherDirectory"; - this.textBoxOtherDirectory.ReadOnly = true; - this.textBoxOtherDirectory.Size = new System.Drawing.Size(353, 20); - this.textBoxOtherDirectory.TabIndex = 6; + this.labelFullscreenWidth.AutoEllipsis = true; + this.labelFullscreenWidth.Location = new System.Drawing.Point(8, 26); + this.labelFullscreenWidth.Name = "labelFullscreenWidth"; + this.labelFullscreenWidth.Size = new System.Drawing.Size(148, 16); + this.labelFullscreenWidth.TabIndex = 0; + this.labelFullscreenWidth.Text = "Width:"; + this.labelFullscreenWidth.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // buttonTrainInstallationDirectory + // groupboxInterpolation // - this.buttonTrainInstallationDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonTrainInstallationDirectory.Location = new System.Drawing.Point(560, 49); - this.buttonTrainInstallationDirectory.Name = "buttonTrainInstallationDirectory"; - this.buttonTrainInstallationDirectory.Size = new System.Drawing.Size(75, 23); - this.buttonTrainInstallationDirectory.TabIndex = 5; - this.buttonTrainInstallationDirectory.Text = "Choose..."; - this.buttonTrainInstallationDirectory.UseVisualStyleBackColor = true; - this.buttonTrainInstallationDirectory.Click += new System.EventHandler(this.buttonTrainInstallationDirectory_Click); + this.groupboxInterpolation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupboxInterpolation.Controls.Add(this.updownAntiAliasing); + this.groupboxInterpolation.Controls.Add(this.labelAntiAliasing); + this.groupboxInterpolation.Controls.Add(this.labelTransparencyQuality); + this.groupboxInterpolation.Controls.Add(this.labelTransparencyPerformance); + this.groupboxInterpolation.Controls.Add(this.labelTransparency); + this.groupboxInterpolation.Controls.Add(this.updownAnisotropic); + this.groupboxInterpolation.Controls.Add(this.labelAnisotropic); + this.groupboxInterpolation.Controls.Add(this.comboboxInterpolation); + this.groupboxInterpolation.Controls.Add(this.labelInterpolation); + this.groupboxInterpolation.Controls.Add(this.trackbarTransparency); + this.groupboxInterpolation.ForeColor = System.Drawing.Color.Black; + this.groupboxInterpolation.Location = new System.Drawing.Point(0, 357); + this.groupboxInterpolation.Name = "groupboxInterpolation"; + this.groupboxInterpolation.Size = new System.Drawing.Size(316, 160); + this.groupboxInterpolation.TabIndex = 7; + this.groupboxInterpolation.TabStop = false; + this.groupboxInterpolation.Text = "Interpolation"; // - // labelTrainInstallDirectory + // updownAntiAliasing // - this.labelTrainInstallDirectory.AutoSize = true; - this.labelTrainInstallDirectory.Location = new System.Drawing.Point(6, 52); - this.labelTrainInstallDirectory.Name = "labelTrainInstallDirectory"; - this.labelTrainInstallDirectory.Size = new System.Drawing.Size(129, 13); - this.labelTrainInstallDirectory.TabIndex = 4; - this.labelTrainInstallDirectory.Text = "Train installation directory:"; + this.updownAntiAliasing.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.updownAntiAliasing.Location = new System.Drawing.Point(156, 64); + this.updownAntiAliasing.Maximum = new decimal(new int[] { + 16, + 0, + 0, + 0}); + this.updownAntiAliasing.Name = "updownAntiAliasing"; + this.updownAntiAliasing.Size = new System.Drawing.Size(152, 20); + this.updownAntiAliasing.TabIndex = 5; // - // textBoxTrainDirectory + // labelAntiAliasing // - this.textBoxTrainDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.labelAntiAliasing.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxTrainDirectory.Location = new System.Drawing.Point(200, 51); - this.textBoxTrainDirectory.Name = "textBoxTrainDirectory"; - this.textBoxTrainDirectory.ReadOnly = true; - this.textBoxTrainDirectory.Size = new System.Drawing.Size(353, 20); - this.textBoxTrainDirectory.TabIndex = 3; + this.labelAntiAliasing.AutoEllipsis = true; + this.labelAntiAliasing.Location = new System.Drawing.Point(8, 66); + this.labelAntiAliasing.Name = "labelAntiAliasing"; + this.labelAntiAliasing.Size = new System.Drawing.Size(148, 16); + this.labelAntiAliasing.TabIndex = 4; + this.labelAntiAliasing.Text = "Level of anti-aliasing:"; + this.labelAntiAliasing.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // buttonSetRouteDirectory + // labelTransparencyQuality // - this.buttonSetRouteDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonSetRouteDirectory.Location = new System.Drawing.Point(560, 18); - this.buttonSetRouteDirectory.Name = "buttonSetRouteDirectory"; - this.buttonSetRouteDirectory.Size = new System.Drawing.Size(75, 23); - this.buttonSetRouteDirectory.TabIndex = 2; - this.buttonSetRouteDirectory.Text = "Choose..."; - this.buttonSetRouteDirectory.UseVisualStyleBackColor = true; - this.buttonSetRouteDirectory.Click += new System.EventHandler(this.buttonSetRouteDirectory_Click); + this.labelTransparencyQuality.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.labelTransparencyQuality.AutoEllipsis = true; + this.labelTransparencyQuality.Location = new System.Drawing.Point(230, 136); + this.labelTransparencyQuality.Name = "labelTransparencyQuality"; + this.labelTransparencyQuality.Size = new System.Drawing.Size(76, 16); + this.labelTransparencyQuality.TabIndex = 9; + this.labelTransparencyQuality.Text = "Quality"; + this.labelTransparencyQuality.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // labelRouteInstallDirectory + // labelTransparencyPerformance + // + this.labelTransparencyPerformance.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.labelTransparencyPerformance.AutoEllipsis = true; + this.labelTransparencyPerformance.Location = new System.Drawing.Point(156, 136); + this.labelTransparencyPerformance.Name = "labelTransparencyPerformance"; + this.labelTransparencyPerformance.Size = new System.Drawing.Size(76, 16); + this.labelTransparencyPerformance.TabIndex = 8; + this.labelTransparencyPerformance.Text = "Performance"; + // + // labelTransparency + // + this.labelTransparency.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelTransparency.AutoEllipsis = true; + this.labelTransparency.Location = new System.Drawing.Point(8, 100); + this.labelTransparency.Name = "labelTransparency"; + this.labelTransparency.Size = new System.Drawing.Size(148, 16); + this.labelTransparency.TabIndex = 6; + this.labelTransparency.Text = "Transparency:"; + this.labelTransparency.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // updownAnisotropic + // + this.updownAnisotropic.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.updownAnisotropic.Enabled = false; + this.updownAnisotropic.Location = new System.Drawing.Point(156, 40); + this.updownAnisotropic.Maximum = new decimal(new int[] { + 16, + 0, + 0, + 0}); + this.updownAnisotropic.Name = "updownAnisotropic"; + this.updownAnisotropic.Size = new System.Drawing.Size(152, 20); + this.updownAnisotropic.TabIndex = 3; + // + // labelAnisotropic + // + this.labelAnisotropic.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelAnisotropic.AutoEllipsis = true; + this.labelAnisotropic.Enabled = false; + this.labelAnisotropic.Location = new System.Drawing.Point(8, 42); + this.labelAnisotropic.Name = "labelAnisotropic"; + this.labelAnisotropic.Size = new System.Drawing.Size(148, 16); + this.labelAnisotropic.TabIndex = 2; + this.labelAnisotropic.Text = "Level of anisotropic filtering:"; + this.labelAnisotropic.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // comboboxInterpolation // - this.labelRouteInstallDirectory.AutoSize = true; - this.labelRouteInstallDirectory.Location = new System.Drawing.Point(6, 21); - this.labelRouteInstallDirectory.Name = "labelRouteInstallDirectory"; - this.labelRouteInstallDirectory.Size = new System.Drawing.Size(134, 13); - this.labelRouteInstallDirectory.TabIndex = 1; - this.labelRouteInstallDirectory.Text = "Route installation directory:"; + this.comboboxInterpolation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.comboboxInterpolation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboboxInterpolation.FormattingEnabled = true; + this.comboboxInterpolation.Location = new System.Drawing.Point(156, 16); + this.comboboxInterpolation.Name = "comboboxInterpolation"; + this.comboboxInterpolation.Size = new System.Drawing.Size(152, 21); + this.comboboxInterpolation.TabIndex = 1; + this.comboboxInterpolation.SelectedIndexChanged += new System.EventHandler(this.comboboxInterpolation_SelectedIndexChanged); // - // textBoxRouteDirectory + // labelInterpolation // - this.textBoxRouteDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.labelInterpolation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxRouteDirectory.Location = new System.Drawing.Point(200, 20); - this.textBoxRouteDirectory.Name = "textBoxRouteDirectory"; - this.textBoxRouteDirectory.ReadOnly = true; - this.textBoxRouteDirectory.Size = new System.Drawing.Size(353, 20); - this.textBoxRouteDirectory.TabIndex = 0; + this.labelInterpolation.AutoEllipsis = true; + this.labelInterpolation.Location = new System.Drawing.Point(8, 18); + this.labelInterpolation.Name = "labelInterpolation"; + this.labelInterpolation.Size = new System.Drawing.Size(148, 16); + this.labelInterpolation.TabIndex = 0; + this.labelInterpolation.Text = "Mode:"; + this.labelInterpolation.TextAlign = System.Drawing.ContentAlignment.TopRight; + // + // trackbarTransparency + // + this.trackbarTransparency.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.trackbarTransparency.Location = new System.Drawing.Point(156, 88); + this.trackbarTransparency.Maximum = 2; + this.trackbarTransparency.Name = "trackbarTransparency"; + this.trackbarTransparency.Size = new System.Drawing.Size(152, 45); + this.trackbarTransparency.TabIndex = 7; + this.trackbarTransparency.TickStyle = System.Windows.Forms.TickStyle.Both; // // panelOptionsRight // + this.panelOptionsRight.Controls.Add(this.groupBoxOther); this.panelOptionsRight.Controls.Add(this.groupBoxRailDriver); this.panelOptionsRight.Controls.Add(this.groupboxDistance); this.panelOptionsRight.Controls.Add(this.groupboxControls); @@ -1707,6 +1870,43 @@ private void InitializeComponent() { this.panelOptionsRight.Size = new System.Drawing.Size(316, 579); this.panelOptionsRight.TabIndex = 17; // + // groupBoxOther + // + this.groupBoxOther.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBoxOther.Controls.Add(this.comboBoxTimeTableDisplayMode); + this.groupBoxOther.Controls.Add(this.labelTimeTableDisplayMode); + this.groupBoxOther.ForeColor = System.Drawing.Color.Black; + this.groupBoxOther.Location = new System.Drawing.Point(3, 468); + this.groupBoxOther.Name = "groupBoxOther"; + this.groupBoxOther.Size = new System.Drawing.Size(316, 48); + this.groupBoxOther.TabIndex = 19; + this.groupBoxOther.TabStop = false; + this.groupBoxOther.Text = "Other"; + // + // comboBoxTimeTableDisplayMode + // + this.comboBoxTimeTableDisplayMode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.comboBoxTimeTableDisplayMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxTimeTableDisplayMode.FormattingEnabled = true; + this.comboBoxTimeTableDisplayMode.Location = new System.Drawing.Point(156, 16); + this.comboBoxTimeTableDisplayMode.Name = "comboBoxTimeTableDisplayMode"; + this.comboBoxTimeTableDisplayMode.Size = new System.Drawing.Size(152, 21); + this.comboBoxTimeTableDisplayMode.TabIndex = 1; + this.comboBoxTimeTableDisplayMode.SelectedIndexChanged += new System.EventHandler(this.comboBoxTimeTableDisplayMode_SelectedIndexChanged); + // + // labelTimeTableDisplayMode + // + this.labelTimeTableDisplayMode.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelTimeTableDisplayMode.AutoEllipsis = true; + this.labelTimeTableDisplayMode.Location = new System.Drawing.Point(3, 17); + this.labelTimeTableDisplayMode.Name = "labelTimeTableDisplayMode"; + this.labelTimeTableDisplayMode.Size = new System.Drawing.Size(153, 16); + this.labelTimeTableDisplayMode.TabIndex = 0; + this.labelTimeTableDisplayMode.Text = "Timetable Display Mode:"; + this.labelTimeTableDisplayMode.TextAlign = System.Drawing.ContentAlignment.MiddleRight; + // // groupBoxRailDriver // this.groupBoxRailDriver.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) @@ -2063,460 +2263,317 @@ private void InitializeComponent() { this.labelSoundNumber.Text = "Number of allowed sounds:"; this.labelSoundNumber.TextAlign = System.Drawing.ContentAlignment.TopRight; // - // panelOptionsLeft - // - this.panelOptionsLeft.Controls.Add(this.groupBoxOther); - this.panelOptionsLeft.Controls.Add(this.groupboxDisplayMode); - this.panelOptionsLeft.Controls.Add(this.groupboxWindow); - this.panelOptionsLeft.Controls.Add(this.groupboxFullscreen); - this.panelOptionsLeft.Controls.Add(this.groupboxInterpolation); - this.panelOptionsLeft.Location = new System.Drawing.Point(8, 72); - this.panelOptionsLeft.Name = "panelOptionsLeft"; - this.panelOptionsLeft.Size = new System.Drawing.Size(316, 576); - this.panelOptionsLeft.TabIndex = 16; - // - // groupBoxOther - // - this.groupBoxOther.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.groupBoxOther.Controls.Add(this.comboBoxTimeTableDisplayMode); - this.groupBoxOther.Controls.Add(this.labelTimeTableDisplayMode); - this.groupBoxOther.ForeColor = System.Drawing.Color.Black; - this.groupBoxOther.Location = new System.Drawing.Point(0, 478); - this.groupBoxOther.Name = "groupBoxOther"; - this.groupBoxOther.Size = new System.Drawing.Size(316, 48); - this.groupBoxOther.TabIndex = 19; - this.groupBoxOther.TabStop = false; - this.groupBoxOther.Text = "Other"; - // - // comboBoxTimeTableDisplayMode - // - this.comboBoxTimeTableDisplayMode.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.comboBoxTimeTableDisplayMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxTimeTableDisplayMode.FormattingEnabled = true; - this.comboBoxTimeTableDisplayMode.Location = new System.Drawing.Point(156, 16); - this.comboBoxTimeTableDisplayMode.Name = "comboBoxTimeTableDisplayMode"; - this.comboBoxTimeTableDisplayMode.Size = new System.Drawing.Size(152, 21); - this.comboBoxTimeTableDisplayMode.TabIndex = 1; - this.comboBoxTimeTableDisplayMode.SelectedIndexChanged += new System.EventHandler(this.comboBoxTimeTableDisplayMode_SelectedIndexChanged); - // - // labelTimeTableDisplayMode - // - this.labelTimeTableDisplayMode.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelTimeTableDisplayMode.AutoEllipsis = true; - this.labelTimeTableDisplayMode.Location = new System.Drawing.Point(3, 17); - this.labelTimeTableDisplayMode.Name = "labelTimeTableDisplayMode"; - this.labelTimeTableDisplayMode.Size = new System.Drawing.Size(153, 16); - this.labelTimeTableDisplayMode.TabIndex = 0; - this.labelTimeTableDisplayMode.Text = "Timetable Display Mode:"; - this.labelTimeTableDisplayMode.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // - // groupboxDisplayMode - // - this.groupboxDisplayMode.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.groupboxDisplayMode.Controls.Add(this.comboboxVSync); - this.groupboxDisplayMode.Controls.Add(this.labelVSync); - this.groupboxDisplayMode.Controls.Add(this.radiobuttonFullscreen); - this.groupboxDisplayMode.Controls.Add(this.radiobuttonWindow); - this.groupboxDisplayMode.ForeColor = System.Drawing.Color.Black; - this.groupboxDisplayMode.Location = new System.Drawing.Point(0, 0); - this.groupboxDisplayMode.Name = "groupboxDisplayMode"; - this.groupboxDisplayMode.Size = new System.Drawing.Size(316, 104); - this.groupboxDisplayMode.TabIndex = 4; - this.groupboxDisplayMode.TabStop = false; - this.groupboxDisplayMode.Text = "Display mode"; - // - // comboboxVSync - // - this.comboboxVSync.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.comboboxVSync.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboboxVSync.FormattingEnabled = true; - this.comboboxVSync.Location = new System.Drawing.Point(156, 72); - this.comboboxVSync.Name = "comboboxVSync"; - this.comboboxVSync.Size = new System.Drawing.Size(152, 21); - this.comboboxVSync.TabIndex = 7; - // - // labelVSync - // - this.labelVSync.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelVSync.AutoEllipsis = true; - this.labelVSync.Location = new System.Drawing.Point(8, 72); - this.labelVSync.Name = "labelVSync"; - this.labelVSync.Size = new System.Drawing.Size(148, 16); - this.labelVSync.TabIndex = 2; - this.labelVSync.Text = "Vertical syncronization:"; - this.labelVSync.TextAlign = System.Drawing.ContentAlignment.TopRight; - // - // radiobuttonFullscreen - // - this.radiobuttonFullscreen.AutoSize = true; - this.radiobuttonFullscreen.Location = new System.Drawing.Point(8, 48); - this.radiobuttonFullscreen.Name = "radiobuttonFullscreen"; - this.radiobuttonFullscreen.Size = new System.Drawing.Size(102, 17); - this.radiobuttonFullscreen.TabIndex = 1; - this.radiobuttonFullscreen.TabStop = true; - this.radiobuttonFullscreen.Text = "Fullscreen mode"; - this.radiobuttonFullscreen.UseVisualStyleBackColor = true; - // - // radiobuttonWindow + // pictureboxLanguage // - this.radiobuttonWindow.AutoSize = true; - this.radiobuttonWindow.Checked = true; - this.radiobuttonWindow.Location = new System.Drawing.Point(8, 24); - this.radiobuttonWindow.Name = "radiobuttonWindow"; - this.radiobuttonWindow.Size = new System.Drawing.Size(93, 17); - this.radiobuttonWindow.TabIndex = 0; - this.radiobuttonWindow.TabStop = true; - this.radiobuttonWindow.Text = "Window mode"; - this.radiobuttonWindow.UseVisualStyleBackColor = true; + this.pictureboxLanguage.Location = new System.Drawing.Point(8, 40); + this.pictureboxLanguage.Name = "pictureboxLanguage"; + this.pictureboxLanguage.Size = new System.Drawing.Size(32, 20); + this.pictureboxLanguage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.pictureboxLanguage.TabIndex = 15; + this.pictureboxLanguage.TabStop = false; // - // groupboxWindow + // panelOptionsPage2 // - this.groupboxWindow.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.panelOptionsPage2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.groupboxWindow.Controls.Add(this.updownWindowHeight); - this.groupboxWindow.Controls.Add(this.labelWindowHeight); - this.groupboxWindow.Controls.Add(this.updownWindowWidth); - this.groupboxWindow.Controls.Add(this.labelWindowWidth); - this.groupboxWindow.ForeColor = System.Drawing.Color.Black; - this.groupboxWindow.Location = new System.Drawing.Point(0, 112); - this.groupboxWindow.Name = "groupboxWindow"; - this.groupboxWindow.Size = new System.Drawing.Size(316, 80); - this.groupboxWindow.TabIndex = 5; - this.groupboxWindow.TabStop = false; - this.groupboxWindow.Text = "Window mode"; + this.panelOptionsPage2.Controls.Add(this.groupBoxKioskMode); + this.panelOptionsPage2.Controls.Add(this.groupBoxAdvancedOptions); + this.panelOptionsPage2.Controls.Add(this.groupBoxPackageOptions); + this.panelOptionsPage2.Location = new System.Drawing.Point(0, 72); + this.panelOptionsPage2.Name = "panelOptionsPage2"; + this.panelOptionsPage2.Size = new System.Drawing.Size(643, 528); + this.panelOptionsPage2.TabIndex = 20; // - // updownWindowHeight + // groupBoxKioskMode // - this.updownWindowHeight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.updownWindowHeight.Location = new System.Drawing.Point(156, 48); - this.updownWindowHeight.Maximum = new decimal(new int[] { - 1048575, - 0, - 0, - 0}); - this.updownWindowHeight.Minimum = new decimal(new int[] { - 16, - 0, - 0, - 0}); - this.updownWindowHeight.Name = "updownWindowHeight"; - this.updownWindowHeight.Size = new System.Drawing.Size(152, 20); - this.updownWindowHeight.TabIndex = 3; - this.updownWindowHeight.Value = new decimal(new int[] { - 600, - 0, - 0, - 0}); + this.groupBoxKioskMode.Controls.Add(this.labelKioskTimeout); + this.groupBoxKioskMode.Controls.Add(this.numericUpDownKioskTimeout); + this.groupBoxKioskMode.Controls.Add(this.checkBoxEnableKiosk); + this.groupBoxKioskMode.Location = new System.Drawing.Point(334, 164); + this.groupBoxKioskMode.Name = "groupBoxKioskMode"; + this.groupBoxKioskMode.Size = new System.Drawing.Size(305, 88); + this.groupBoxKioskMode.TabIndex = 22; + this.groupBoxKioskMode.TabStop = false; + this.groupBoxKioskMode.Text = "Kiosk Mode"; // - // labelWindowHeight + // labelKioskTimeout // - this.labelWindowHeight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelWindowHeight.AutoEllipsis = true; - this.labelWindowHeight.Location = new System.Drawing.Point(8, 50); - this.labelWindowHeight.Name = "labelWindowHeight"; - this.labelWindowHeight.Size = new System.Drawing.Size(148, 16); - this.labelWindowHeight.TabIndex = 2; - this.labelWindowHeight.Text = "Height:"; - this.labelWindowHeight.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.labelKioskTimeout.AutoSize = true; + this.labelKioskTimeout.Location = new System.Drawing.Point(8, 43); + this.labelKioskTimeout.Name = "labelKioskTimeout"; + this.labelKioskTimeout.Size = new System.Drawing.Size(91, 13); + this.labelKioskTimeout.TabIndex = 2; + this.labelKioskTimeout.Text = "Control timeout (s)"; // - // updownWindowWidth + // numericUpDownKioskTimeout // - this.updownWindowWidth.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.updownWindowWidth.Location = new System.Drawing.Point(156, 24); - this.updownWindowWidth.Maximum = new decimal(new int[] { - 1048575, - 0, - 0, - 0}); - this.updownWindowWidth.Minimum = new decimal(new int[] { - 16, - 0, - 0, - 0}); - this.updownWindowWidth.Name = "updownWindowWidth"; - this.updownWindowWidth.Size = new System.Drawing.Size(152, 20); - this.updownWindowWidth.TabIndex = 1; - this.updownWindowWidth.Value = new decimal(new int[] { - 960, + this.numericUpDownKioskTimeout.DecimalPlaces = 2; + this.numericUpDownKioskTimeout.Location = new System.Drawing.Point(166, 41); + this.numericUpDownKioskTimeout.Maximum = new decimal(new int[] { + 10000, 0, 0, 0}); + this.numericUpDownKioskTimeout.Name = "numericUpDownKioskTimeout"; + this.numericUpDownKioskTimeout.Size = new System.Drawing.Size(131, 20); + this.numericUpDownKioskTimeout.TabIndex = 1; // - // labelWindowWidth + // checkBoxEnableKiosk // - this.labelWindowWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelWindowWidth.AutoEllipsis = true; - this.labelWindowWidth.Location = new System.Drawing.Point(8, 26); - this.labelWindowWidth.Name = "labelWindowWidth"; - this.labelWindowWidth.Size = new System.Drawing.Size(148, 16); - this.labelWindowWidth.TabIndex = 0; - this.labelWindowWidth.Text = "Width:"; - this.labelWindowWidth.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.checkBoxEnableKiosk.AutoSize = true; + this.checkBoxEnableKiosk.Location = new System.Drawing.Point(9, 20); + this.checkBoxEnableKiosk.Name = "checkBoxEnableKiosk"; + this.checkBoxEnableKiosk.Size = new System.Drawing.Size(118, 17); + this.checkBoxEnableKiosk.TabIndex = 0; + this.checkBoxEnableKiosk.Text = "Enable Kiosk Mode"; + this.checkBoxEnableKiosk.UseVisualStyleBackColor = true; // - // groupboxFullscreen + // groupBoxAdvancedOptions // - this.groupboxFullscreen.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.groupboxFullscreen.Controls.Add(this.comboboxFullscreenBits); - this.groupboxFullscreen.Controls.Add(this.labelFullscreenBits); - this.groupboxFullscreen.Controls.Add(this.updownFullscreenHeight); - this.groupboxFullscreen.Controls.Add(this.labelFullscreenHeight); - this.groupboxFullscreen.Controls.Add(this.updownFullscreenWidth); - this.groupboxFullscreen.Controls.Add(this.labelFullscreenWidth); - this.groupboxFullscreen.ForeColor = System.Drawing.Color.Black; - this.groupboxFullscreen.Location = new System.Drawing.Point(0, 200); - this.groupboxFullscreen.Name = "groupboxFullscreen"; - this.groupboxFullscreen.Size = new System.Drawing.Size(316, 104); - this.groupboxFullscreen.TabIndex = 6; - this.groupboxFullscreen.TabStop = false; - this.groupboxFullscreen.Text = "Fullscreen mode"; + this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxHacks); + this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxTransparencyFix); + this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxUnloadTextures); + this.groupBoxAdvancedOptions.Controls.Add(this.labelNumberFive); + this.groupBoxAdvancedOptions.Controls.Add(this.labelNumberZero); + this.groupBoxAdvancedOptions.Controls.Add(this.labelTimeAcceleration); + this.groupBoxAdvancedOptions.Controls.Add(this.trackBarTimeAccelerationFactor); + this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxDisableDisplayLists); + this.groupBoxAdvancedOptions.Controls.Add(this.checkBoxLoadInAdvance); + this.groupBoxAdvancedOptions.Location = new System.Drawing.Point(6, 160); + this.groupBoxAdvancedOptions.Name = "groupBoxAdvancedOptions"; + this.groupBoxAdvancedOptions.Size = new System.Drawing.Size(316, 208); + this.groupBoxAdvancedOptions.TabIndex = 21; + this.groupBoxAdvancedOptions.TabStop = false; + this.groupBoxAdvancedOptions.Text = "Advanced Options"; // - // comboboxFullscreenBits + // checkBoxHacks // - this.comboboxFullscreenBits.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.comboboxFullscreenBits.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboboxFullscreenBits.FormattingEnabled = true; - this.comboboxFullscreenBits.Location = new System.Drawing.Point(156, 72); - this.comboboxFullscreenBits.Name = "comboboxFullscreenBits"; - this.comboboxFullscreenBits.Size = new System.Drawing.Size(152, 21); - this.comboboxFullscreenBits.TabIndex = 5; + this.checkBoxHacks.AutoSize = true; + this.checkBoxHacks.Location = new System.Drawing.Point(8, 100); + this.checkBoxHacks.Name = "checkBoxHacks"; + this.checkBoxHacks.Size = new System.Drawing.Size(203, 17); + this.checkBoxHacks.TabIndex = 15; + this.checkBoxHacks.Text = "Enable hacks for buggy older content"; + this.checkBoxHacks.UseVisualStyleBackColor = true; // - // labelFullscreenBits + // checkBoxTransparencyFix // - this.labelFullscreenBits.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelFullscreenBits.AutoEllipsis = true; - this.labelFullscreenBits.Location = new System.Drawing.Point(8, 74); - this.labelFullscreenBits.Name = "labelFullscreenBits"; - this.labelFullscreenBits.Size = new System.Drawing.Size(148, 16); - this.labelFullscreenBits.TabIndex = 4; - this.labelFullscreenBits.Text = "Bits per pixel:"; - this.labelFullscreenBits.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.checkBoxTransparencyFix.AutoSize = true; + this.checkBoxTransparencyFix.Location = new System.Drawing.Point(8, 81); + this.checkBoxTransparencyFix.Name = "checkBoxTransparencyFix"; + this.checkBoxTransparencyFix.Size = new System.Drawing.Size(259, 17); + this.checkBoxTransparencyFix.TabIndex = 14; + this.checkBoxTransparencyFix.Text = "Attempt to fix transparency issues in older content"; + this.checkBoxTransparencyFix.UseVisualStyleBackColor = true; // - // updownFullscreenHeight + // checkBoxUnloadTextures // - this.updownFullscreenHeight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.updownFullscreenHeight.Location = new System.Drawing.Point(156, 48); - this.updownFullscreenHeight.Maximum = new decimal(new int[] { - 1048575, - 0, - 0, - 0}); - this.updownFullscreenHeight.Minimum = new decimal(new int[] { - 16, - 0, - 0, - 0}); - this.updownFullscreenHeight.Name = "updownFullscreenHeight"; - this.updownFullscreenHeight.Size = new System.Drawing.Size(152, 20); - this.updownFullscreenHeight.TabIndex = 3; - this.updownFullscreenHeight.Value = new decimal(new int[] { - 768, - 0, - 0, - 0}); + this.checkBoxUnloadTextures.AutoSize = true; + this.checkBoxUnloadTextures.Location = new System.Drawing.Point(8, 62); + this.checkBoxUnloadTextures.Name = "checkBoxUnloadTextures"; + this.checkBoxUnloadTextures.Size = new System.Drawing.Size(138, 17); + this.checkBoxUnloadTextures.TabIndex = 13; + this.checkBoxUnloadTextures.Text = "Unload unused textures"; + this.checkBoxUnloadTextures.UseVisualStyleBackColor = true; + this.checkBoxUnloadTextures.CheckedChanged += new System.EventHandler(this.checkBoxUnloadTextures_CheckedChanged); // - // labelFullscreenHeight + // labelNumberFive // - this.labelFullscreenHeight.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelFullscreenHeight.AutoEllipsis = true; - this.labelFullscreenHeight.Location = new System.Drawing.Point(8, 50); - this.labelFullscreenHeight.Name = "labelFullscreenHeight"; - this.labelFullscreenHeight.Size = new System.Drawing.Size(148, 16); - this.labelFullscreenHeight.TabIndex = 2; - this.labelFullscreenHeight.Text = "Height:"; - this.labelFullscreenHeight.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.labelNumberFive.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.labelNumberFive.AutoSize = true; + this.labelNumberFive.Location = new System.Drawing.Point(267, 163); + this.labelNumberFive.Name = "labelNumberFive"; + this.labelNumberFive.Size = new System.Drawing.Size(13, 13); + this.labelNumberFive.TabIndex = 12; + this.labelNumberFive.Text = "5"; // - // updownFullscreenWidth + // labelNumberZero // - this.updownFullscreenWidth.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.updownFullscreenWidth.Location = new System.Drawing.Point(156, 24); - this.updownFullscreenWidth.Maximum = new decimal(new int[] { - 1048575, - 0, - 0, - 0}); - this.updownFullscreenWidth.Minimum = new decimal(new int[] { - 16, - 0, - 0, - 0}); - this.updownFullscreenWidth.Name = "updownFullscreenWidth"; - this.updownFullscreenWidth.Size = new System.Drawing.Size(152, 20); - this.updownFullscreenWidth.TabIndex = 1; - this.updownFullscreenWidth.Value = new decimal(new int[] { - 1024, - 0, - 0, - 0}); + this.labelNumberZero.AutoSize = true; + this.labelNumberZero.Location = new System.Drawing.Point(186, 163); + this.labelNumberZero.Name = "labelNumberZero"; + this.labelNumberZero.Size = new System.Drawing.Size(13, 13); + this.labelNumberZero.TabIndex = 11; + this.labelNumberZero.Text = "0"; // - // labelFullscreenWidth + // labelTimeAcceleration // - this.labelFullscreenWidth.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelFullscreenWidth.AutoEllipsis = true; - this.labelFullscreenWidth.Location = new System.Drawing.Point(8, 26); - this.labelFullscreenWidth.Name = "labelFullscreenWidth"; - this.labelFullscreenWidth.Size = new System.Drawing.Size(148, 16); - this.labelFullscreenWidth.TabIndex = 0; - this.labelFullscreenWidth.Text = "Width:"; - this.labelFullscreenWidth.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.labelTimeAcceleration.Location = new System.Drawing.Point(-1, 132); + this.labelTimeAcceleration.Name = "labelTimeAcceleration"; + this.labelTimeAcceleration.Size = new System.Drawing.Size(179, 22); + this.labelTimeAcceleration.TabIndex = 10; + this.labelTimeAcceleration.Text = "Accelerated Time Factor:"; + this.labelTimeAcceleration.TextAlign = System.Drawing.ContentAlignment.MiddleRight; // - // groupboxInterpolation + // trackBarTimeAccelerationFactor // - this.groupboxInterpolation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.trackBarTimeAccelerationFactor.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.groupboxInterpolation.Controls.Add(this.updownAntiAliasing); - this.groupboxInterpolation.Controls.Add(this.labelAntiAliasing); - this.groupboxInterpolation.Controls.Add(this.labelTransparencyQuality); - this.groupboxInterpolation.Controls.Add(this.labelTransparencyPerformance); - this.groupboxInterpolation.Controls.Add(this.labelTransparency); - this.groupboxInterpolation.Controls.Add(this.updownAnisotropic); - this.groupboxInterpolation.Controls.Add(this.labelAnisotropic); - this.groupboxInterpolation.Controls.Add(this.comboboxInterpolation); - this.groupboxInterpolation.Controls.Add(this.labelInterpolation); - this.groupboxInterpolation.Controls.Add(this.trackbarTransparency); - this.groupboxInterpolation.ForeColor = System.Drawing.Color.Black; - this.groupboxInterpolation.Location = new System.Drawing.Point(0, 312); - this.groupboxInterpolation.Name = "groupboxInterpolation"; - this.groupboxInterpolation.Size = new System.Drawing.Size(316, 160); - this.groupboxInterpolation.TabIndex = 7; - this.groupboxInterpolation.TabStop = false; - this.groupboxInterpolation.Text = "Interpolation"; + this.trackBarTimeAccelerationFactor.LargeChange = 1; + this.trackBarTimeAccelerationFactor.Location = new System.Drawing.Point(179, 122); + this.trackBarTimeAccelerationFactor.Maximum = 5; + this.trackBarTimeAccelerationFactor.Name = "trackBarTimeAccelerationFactor"; + this.trackBarTimeAccelerationFactor.RightToLeft = System.Windows.Forms.RightToLeft.No; + this.trackBarTimeAccelerationFactor.Size = new System.Drawing.Size(108, 45); + this.trackBarTimeAccelerationFactor.TabIndex = 3; + this.trackBarTimeAccelerationFactor.TickStyle = System.Windows.Forms.TickStyle.Both; // - // updownAntiAliasing + // checkBoxDisableDisplayLists // - this.updownAntiAliasing.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.updownAntiAliasing.Location = new System.Drawing.Point(156, 64); - this.updownAntiAliasing.Maximum = new decimal(new int[] { - 16, - 0, - 0, - 0}); - this.updownAntiAliasing.Name = "updownAntiAliasing"; - this.updownAntiAliasing.Size = new System.Drawing.Size(152, 20); - this.updownAntiAliasing.TabIndex = 5; + this.checkBoxDisableDisplayLists.AutoSize = true; + this.checkBoxDisableDisplayLists.Location = new System.Drawing.Point(8, 43); + this.checkBoxDisableDisplayLists.Name = "checkBoxDisableDisplayLists"; + this.checkBoxDisableDisplayLists.Size = new System.Drawing.Size(159, 17); + this.checkBoxDisableDisplayLists.TabIndex = 2; + this.checkBoxDisableDisplayLists.Text = "Disable OpenGL display lists"; + this.checkBoxDisableDisplayLists.UseVisualStyleBackColor = true; + // + // checkBoxLoadInAdvance + // + this.checkBoxLoadInAdvance.AutoSize = true; + this.checkBoxLoadInAdvance.Location = new System.Drawing.Point(8, 24); + this.checkBoxLoadInAdvance.Name = "checkBoxLoadInAdvance"; + this.checkBoxLoadInAdvance.Size = new System.Drawing.Size(106, 17); + this.checkBoxLoadInAdvance.TabIndex = 1; + this.checkBoxLoadInAdvance.Text = "Load in advance"; + this.checkBoxLoadInAdvance.UseVisualStyleBackColor = true; + this.checkBoxLoadInAdvance.CheckedChanged += new System.EventHandler(this.checkBoxLoadInAdvance_CheckedChanged); // - // labelAntiAliasing + // groupBoxPackageOptions // - this.labelAntiAliasing.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.groupBoxPackageOptions.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.labelAntiAliasing.AutoEllipsis = true; - this.labelAntiAliasing.Location = new System.Drawing.Point(8, 66); - this.labelAntiAliasing.Name = "labelAntiAliasing"; - this.labelAntiAliasing.Size = new System.Drawing.Size(148, 16); - this.labelAntiAliasing.TabIndex = 4; - this.labelAntiAliasing.Text = "Level of anti-aliasing:"; - this.labelAntiAliasing.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.groupBoxPackageOptions.Controls.Add(this.comboBoxCompressionFormat); + this.groupBoxPackageOptions.Controls.Add(this.labelPackageCompression); + this.groupBoxPackageOptions.Controls.Add(this.buttonOtherDirectory); + this.groupBoxPackageOptions.Controls.Add(this.labelOtherInstallDirectory); + this.groupBoxPackageOptions.Controls.Add(this.textBoxOtherDirectory); + this.groupBoxPackageOptions.Controls.Add(this.buttonTrainInstallationDirectory); + this.groupBoxPackageOptions.Controls.Add(this.labelTrainInstallDirectory); + this.groupBoxPackageOptions.Controls.Add(this.textBoxTrainDirectory); + this.groupBoxPackageOptions.Controls.Add(this.buttonSetRouteDirectory); + this.groupBoxPackageOptions.Controls.Add(this.labelRouteInstallDirectory); + this.groupBoxPackageOptions.Controls.Add(this.textBoxRouteDirectory); + this.groupBoxPackageOptions.ForeColor = System.Drawing.Color.Black; + this.groupBoxPackageOptions.Location = new System.Drawing.Point(0, 0); + this.groupBoxPackageOptions.Name = "groupBoxPackageOptions"; + this.groupBoxPackageOptions.Size = new System.Drawing.Size(640, 154); + this.groupBoxPackageOptions.TabIndex = 19; + this.groupBoxPackageOptions.TabStop = false; + this.groupBoxPackageOptions.Text = "Package Management"; // - // labelTransparencyQuality + // comboBoxCompressionFormat // - this.labelTransparencyQuality.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.labelTransparencyQuality.AutoEllipsis = true; - this.labelTransparencyQuality.Location = new System.Drawing.Point(230, 136); - this.labelTransparencyQuality.Name = "labelTransparencyQuality"; - this.labelTransparencyQuality.Size = new System.Drawing.Size(76, 16); - this.labelTransparencyQuality.TabIndex = 9; - this.labelTransparencyQuality.Text = "Quality"; - this.labelTransparencyQuality.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.comboBoxCompressionFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxCompressionFormat.Items.AddRange(new object[] { + "LZMA ZIP ( .zip )", + "GZip ( .tgz )", + "BZip2 ( .bz2 )"}); + this.comboBoxCompressionFormat.Location = new System.Drawing.Point(200, 117); + this.comboBoxCompressionFormat.Name = "comboBoxCompressionFormat"; + this.comboBoxCompressionFormat.Size = new System.Drawing.Size(188, 21); + this.comboBoxCompressionFormat.TabIndex = 10; + this.comboBoxCompressionFormat.SelectedIndexChanged += new System.EventHandler(this.comboBoxCompressionFormat_SelectedIndexChanged); // - // labelTransparencyPerformance + // labelPackageCompression // - this.labelTransparencyPerformance.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.labelTransparencyPerformance.AutoEllipsis = true; - this.labelTransparencyPerformance.Location = new System.Drawing.Point(156, 136); - this.labelTransparencyPerformance.Name = "labelTransparencyPerformance"; - this.labelTransparencyPerformance.Size = new System.Drawing.Size(76, 16); - this.labelTransparencyPerformance.TabIndex = 8; - this.labelTransparencyPerformance.Text = "Performance"; + this.labelPackageCompression.AutoSize = true; + this.labelPackageCompression.Location = new System.Drawing.Point(6, 121); + this.labelPackageCompression.Name = "labelPackageCompression"; + this.labelPackageCompression.Size = new System.Drawing.Size(147, 13); + this.labelPackageCompression.TabIndex = 9; + this.labelPackageCompression.Text = "Package compression format:"; // - // labelTransparency + // buttonOtherDirectory // - this.labelTransparency.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.labelTransparency.AutoEllipsis = true; - this.labelTransparency.Location = new System.Drawing.Point(8, 100); - this.labelTransparency.Name = "labelTransparency"; - this.labelTransparency.Size = new System.Drawing.Size(148, 16); - this.labelTransparency.TabIndex = 6; - this.labelTransparency.Text = "Transparency:"; - this.labelTransparency.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.buttonOtherDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonOtherDirectory.Location = new System.Drawing.Point(560, 82); + this.buttonOtherDirectory.Name = "buttonOtherDirectory"; + this.buttonOtherDirectory.Size = new System.Drawing.Size(75, 23); + this.buttonOtherDirectory.TabIndex = 8; + this.buttonOtherDirectory.Text = "Choose..."; + this.buttonOtherDirectory.UseVisualStyleBackColor = true; + this.buttonOtherDirectory.Click += new System.EventHandler(this.buttonOtherDirectory_Click); // - // updownAnisotropic + // labelOtherInstallDirectory // - this.updownAnisotropic.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.updownAnisotropic.Enabled = false; - this.updownAnisotropic.Location = new System.Drawing.Point(156, 40); - this.updownAnisotropic.Maximum = new decimal(new int[] { - 16, - 0, - 0, - 0}); - this.updownAnisotropic.Name = "updownAnisotropic"; - this.updownAnisotropic.Size = new System.Drawing.Size(152, 20); - this.updownAnisotropic.TabIndex = 3; + this.labelOtherInstallDirectory.AutoSize = true; + this.labelOtherInstallDirectory.Location = new System.Drawing.Point(6, 85); + this.labelOtherInstallDirectory.Name = "labelOtherInstallDirectory"; + this.labelOtherInstallDirectory.Size = new System.Drawing.Size(158, 13); + this.labelOtherInstallDirectory.TabIndex = 7; + this.labelOtherInstallDirectory.Text = "Other items installation directory:"; // - // labelAnisotropic + // textBoxOtherDirectory // - this.labelAnisotropic.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.textBoxOtherDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.labelAnisotropic.AutoEllipsis = true; - this.labelAnisotropic.Enabled = false; - this.labelAnisotropic.Location = new System.Drawing.Point(8, 42); - this.labelAnisotropic.Name = "labelAnisotropic"; - this.labelAnisotropic.Size = new System.Drawing.Size(148, 16); - this.labelAnisotropic.TabIndex = 2; - this.labelAnisotropic.Text = "Level of anisotropic filtering:"; - this.labelAnisotropic.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.textBoxOtherDirectory.Location = new System.Drawing.Point(200, 84); + this.textBoxOtherDirectory.Name = "textBoxOtherDirectory"; + this.textBoxOtherDirectory.ReadOnly = true; + this.textBoxOtherDirectory.Size = new System.Drawing.Size(353, 20); + this.textBoxOtherDirectory.TabIndex = 6; // - // comboboxInterpolation + // buttonTrainInstallationDirectory // - this.comboboxInterpolation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.comboboxInterpolation.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboboxInterpolation.FormattingEnabled = true; - this.comboboxInterpolation.Location = new System.Drawing.Point(156, 16); - this.comboboxInterpolation.Name = "comboboxInterpolation"; - this.comboboxInterpolation.Size = new System.Drawing.Size(152, 21); - this.comboboxInterpolation.TabIndex = 1; - this.comboboxInterpolation.SelectedIndexChanged += new System.EventHandler(this.comboboxInterpolation_SelectedIndexChanged); + this.buttonTrainInstallationDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonTrainInstallationDirectory.Location = new System.Drawing.Point(560, 49); + this.buttonTrainInstallationDirectory.Name = "buttonTrainInstallationDirectory"; + this.buttonTrainInstallationDirectory.Size = new System.Drawing.Size(75, 23); + this.buttonTrainInstallationDirectory.TabIndex = 5; + this.buttonTrainInstallationDirectory.Text = "Choose..."; + this.buttonTrainInstallationDirectory.UseVisualStyleBackColor = true; + this.buttonTrainInstallationDirectory.Click += new System.EventHandler(this.buttonTrainInstallationDirectory_Click); // - // labelInterpolation + // labelTrainInstallDirectory // - this.labelInterpolation.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.labelTrainInstallDirectory.AutoSize = true; + this.labelTrainInstallDirectory.Location = new System.Drawing.Point(6, 52); + this.labelTrainInstallDirectory.Name = "labelTrainInstallDirectory"; + this.labelTrainInstallDirectory.Size = new System.Drawing.Size(129, 13); + this.labelTrainInstallDirectory.TabIndex = 4; + this.labelTrainInstallDirectory.Text = "Train installation directory:"; + // + // textBoxTrainDirectory + // + this.textBoxTrainDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.labelInterpolation.AutoEllipsis = true; - this.labelInterpolation.Location = new System.Drawing.Point(8, 18); - this.labelInterpolation.Name = "labelInterpolation"; - this.labelInterpolation.Size = new System.Drawing.Size(148, 16); - this.labelInterpolation.TabIndex = 0; - this.labelInterpolation.Text = "Mode:"; - this.labelInterpolation.TextAlign = System.Drawing.ContentAlignment.TopRight; + this.textBoxTrainDirectory.Location = new System.Drawing.Point(200, 51); + this.textBoxTrainDirectory.Name = "textBoxTrainDirectory"; + this.textBoxTrainDirectory.ReadOnly = true; + this.textBoxTrainDirectory.Size = new System.Drawing.Size(353, 20); + this.textBoxTrainDirectory.TabIndex = 3; // - // trackbarTransparency + // buttonSetRouteDirectory // - this.trackbarTransparency.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.trackbarTransparency.Location = new System.Drawing.Point(156, 88); - this.trackbarTransparency.Maximum = 2; - this.trackbarTransparency.Name = "trackbarTransparency"; - this.trackbarTransparency.Size = new System.Drawing.Size(152, 45); - this.trackbarTransparency.TabIndex = 7; - this.trackbarTransparency.TickStyle = System.Windows.Forms.TickStyle.Both; + this.buttonSetRouteDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.buttonSetRouteDirectory.Location = new System.Drawing.Point(560, 18); + this.buttonSetRouteDirectory.Name = "buttonSetRouteDirectory"; + this.buttonSetRouteDirectory.Size = new System.Drawing.Size(75, 23); + this.buttonSetRouteDirectory.TabIndex = 2; + this.buttonSetRouteDirectory.Text = "Choose..."; + this.buttonSetRouteDirectory.UseVisualStyleBackColor = true; + this.buttonSetRouteDirectory.Click += new System.EventHandler(this.buttonSetRouteDirectory_Click); // - // pictureboxLanguage + // labelRouteInstallDirectory // - this.pictureboxLanguage.Location = new System.Drawing.Point(8, 40); - this.pictureboxLanguage.Name = "pictureboxLanguage"; - this.pictureboxLanguage.Size = new System.Drawing.Size(32, 20); - this.pictureboxLanguage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; - this.pictureboxLanguage.TabIndex = 15; - this.pictureboxLanguage.TabStop = false; + this.labelRouteInstallDirectory.AutoSize = true; + this.labelRouteInstallDirectory.Location = new System.Drawing.Point(6, 21); + this.labelRouteInstallDirectory.Name = "labelRouteInstallDirectory"; + this.labelRouteInstallDirectory.Size = new System.Drawing.Size(134, 13); + this.labelRouteInstallDirectory.TabIndex = 1; + this.labelRouteInstallDirectory.Text = "Route installation directory:"; + // + // textBoxRouteDirectory + // + this.textBoxRouteDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBoxRouteDirectory.Location = new System.Drawing.Point(200, 20); + this.textBoxRouteDirectory.Name = "textBoxRouteDirectory"; + this.textBoxRouteDirectory.ReadOnly = true; + this.textBoxRouteDirectory.Size = new System.Drawing.Size(353, 20); + this.textBoxRouteDirectory.TabIndex = 0; // // comboboxLanguages // @@ -5379,33 +5436,10 @@ private void InitializeComponent() { this.panelRouteEncoding.ResumeLayout(false); this.panelOptions.ResumeLayout(false); this.panelOptions.PerformLayout(); - this.panelOptionsPage2.ResumeLayout(false); - this.groupBoxKioskMode.ResumeLayout(false); - this.groupBoxKioskMode.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.numericUpDownKioskTimeout)).EndInit(); - this.groupBoxAdvancedOptions.ResumeLayout(false); - this.groupBoxAdvancedOptions.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackBarTimeAccelerationFactor)).EndInit(); - this.groupBoxPackageOptions.ResumeLayout(false); - this.groupBoxPackageOptions.PerformLayout(); - this.panelOptionsRight.ResumeLayout(false); - this.groupBoxRailDriver.ResumeLayout(false); - this.groupBoxRailDriver.PerformLayout(); - this.groupboxDistance.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.updownDistance)).EndInit(); - this.groupboxControls.ResumeLayout(false); - this.groupboxControls.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.trackbarJoystickAxisThreshold)).EndInit(); - this.groupboxVerbosity.ResumeLayout(false); - this.groupboxVerbosity.PerformLayout(); - this.groupboxSimulation.ResumeLayout(false); - this.groupboxSimulation.PerformLayout(); - this.groupboxSound.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.updownSoundNumber)).EndInit(); this.panelOptionsLeft.ResumeLayout(false); - this.groupBoxOther.ResumeLayout(false); this.groupboxDisplayMode.ResumeLayout(false); this.groupboxDisplayMode.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarHUDSize)).EndInit(); this.groupboxWindow.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.updownWindowHeight)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.updownWindowWidth)).EndInit(); @@ -5417,7 +5451,31 @@ private void InitializeComponent() { ((System.ComponentModel.ISupportInitialize)(this.updownAntiAliasing)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.updownAnisotropic)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.trackbarTransparency)).EndInit(); + this.panelOptionsRight.ResumeLayout(false); + this.groupBoxOther.ResumeLayout(false); + this.groupBoxRailDriver.ResumeLayout(false); + this.groupBoxRailDriver.PerformLayout(); + this.groupboxDistance.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.updownDistance)).EndInit(); + this.groupboxControls.ResumeLayout(false); + this.groupboxControls.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackbarJoystickAxisThreshold)).EndInit(); + this.groupboxVerbosity.ResumeLayout(false); + this.groupboxVerbosity.PerformLayout(); + this.groupboxSimulation.ResumeLayout(false); + this.groupboxSimulation.PerformLayout(); + this.groupboxSound.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.updownSoundNumber)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureboxLanguage)).EndInit(); + this.panelOptionsPage2.ResumeLayout(false); + this.groupBoxKioskMode.ResumeLayout(false); + this.groupBoxKioskMode.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numericUpDownKioskTimeout)).EndInit(); + this.groupBoxAdvancedOptions.ResumeLayout(false); + this.groupBoxAdvancedOptions.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackBarTimeAccelerationFactor)).EndInit(); + this.groupBoxPackageOptions.ResumeLayout(false); + this.groupBoxPackageOptions.PerformLayout(); this.panelPanels.ResumeLayout(false); this.panelPanels.PerformLayout(); this.panelReview.ResumeLayout(false); @@ -5883,5 +5941,10 @@ private void InitializeComponent() { private System.Windows.Forms.NumericUpDown numericUpDownKioskTimeout; private System.Windows.Forms.CheckBox checkBoxEnableKiosk; private System.Windows.Forms.Label labelKioskTimeout; + private System.Windows.Forms.Label labelHUDLarge; + private System.Windows.Forms.Label labelHUDNormal; + private System.Windows.Forms.Label labelHUDSmall; + private System.Windows.Forms.TrackBar trackBarHUDSize; + private System.Windows.Forms.Label labelHUDScale; } } diff --git a/source/OpenBVE/UserInterface/formMain.Packages.cs b/source/OpenBVE/UserInterface/formMain.Packages.cs index 049654e6c..0ba8cdfe5 100644 --- a/source/OpenBVE/UserInterface/formMain.Packages.cs +++ b/source/OpenBVE/UserInterface/formMain.Packages.cs @@ -816,6 +816,7 @@ private void buttonCreatePackage_Click(object sender, EventArgs e) //Mono doesn't support System.Security.AccessControl, so this doesn't work.... Directory.GetAccessControl(directory); } + // ReSharper disable once UnusedVariable using (FileStream fs = File.OpenWrite(currentPackage.FileName)) { //Just attempt to open the file with to write as a test diff --git a/source/OpenBVE/UserInterface/formMain.cs b/source/OpenBVE/UserInterface/formMain.cs index 435f2c227..8e69e75a1 100644 --- a/source/OpenBVE/UserInterface/formMain.cs +++ b/source/OpenBVE/UserInterface/formMain.cs @@ -343,6 +343,21 @@ private void formMain_Load(object sender, EventArgs e) comboboxVSync.Items.Add(""); comboboxVSync.Items.Add(""); comboboxVSync.SelectedIndex = Interface.CurrentOptions.VerticalSynchronization ? 1 : 0; + switch (Interface.CurrentOptions.UserInterfaceFolder) + { + case "Slim": + trackBarHUDSize.Value = 0; + break; + case "Default": + trackBarHUDSize.Value = 1; + break; + case "Large": + trackBarHUDSize.Value = 2; + break; + default: + trackBarHUDSize.Value = 1; + break; + } updownWindowWidth.Value = (decimal)Interface.CurrentOptions.WindowWidth; updownWindowHeight.Value = (decimal)Interface.CurrentOptions.WindowHeight; updownFullscreenWidth.Value = (decimal)Interface.CurrentOptions.FullscreenWidth; @@ -502,6 +517,10 @@ private void ApplyLanguage() labelVSync.Text = Interface.GetInterfaceString("options_display_vsync"); comboboxVSync.Items[0] = Interface.GetInterfaceString("options_display_vsync_off"); comboboxVSync.Items[1] = Interface.GetInterfaceString("options_display_vsync_on"); + labelHUDScale.Text = Interface.GetInterfaceString("options_hud_size"); + labelHUDSmall.Text = Interface.GetInterfaceString("options_hud_size_small"); + labelHUDNormal.Text = Interface.GetInterfaceString("options_hud_size_normal"); + labelHUDLarge.Text = Interface.GetInterfaceString("options_hud_size_large"); //Windowed Mode groupboxWindow.Text = Interface.GetInterfaceString("options_display_window"); labelWindowWidth.Text = Interface.GetInterfaceString("options_display_window_width"); @@ -589,6 +608,13 @@ private void ApplyLanguage() groupBoxKioskMode.Text = Interface.GetInterfaceString("options_kiosk_mode"); checkBoxEnableKiosk.Text = Interface.GetInterfaceString("options_kiosk_mode_enable"); labelKioskTimeout.Text = Interface.GetInterfaceString("options_kiosk_mode_timer"); + labelRailDriverSpeedUnits.Text = Interface.GetInterfaceString("raildriver_speedunits"); + comboBoxRailDriverUnits.Items[0] = Interface.GetInterfaceString("raildriver_milesperhour"); + comboBoxRailDriverUnits.Items[1] = Interface.GetInterfaceString("raildriver_kilometersperhour"); + labelRailDriverCalibration.Text = Interface.GetInterfaceString("raildriver_setcalibration"); + buttonRailDriverCalibration.Text = Interface.GetInterfaceString("raildriver_launch"); + checkBoxTransparencyFix.Text = Interface.GetInterfaceString("options_transparencyfix"); + checkBoxHacks.Text = Interface.GetInterfaceString("options_hacks_enable"); /* * Localisation for strings in the game start pane */ @@ -858,8 +884,17 @@ private void ApplyLanguage() //Uninstall result panel // *** All labels set at runtime *** - //HACK - panelOptionsPage2.Hide(); + //HACK- WHY IS THIS NEEDED??? + if (panelOptionsPage2.Visible) + { + panelOptionsPage2.Hide(); + panelOptionsPage2.Show(); + } + else + { + panelOptionsPage2.Hide(); + } + } @@ -901,6 +936,20 @@ private void formMain_FormClosing(object sender, FormClosingEventArgs e) Interface.CurrentOptions.TrainFolder = textboxTrainFolder.Text; Interface.CurrentOptions.MainMenuWidth = this.WindowState == FormWindowState.Maximized ? -1 : this.Size.Width; Interface.CurrentOptions.MainMenuHeight = this.WindowState == FormWindowState.Maximized ? -1 : this.Size.Height; + Interface.CurrentOptions.KioskMode = checkBoxEnableKiosk.Checked; + Interface.CurrentOptions.KioskModeTimer = (double)numericUpDownKioskTimeout.Value; + switch (trackBarHUDSize.Value) + { + case 0: + Interface.CurrentOptions.UserInterfaceFolder = "Slim"; + break; + case 1: + Interface.CurrentOptions.UserInterfaceFolder = "Default"; + break; + case 2: + Interface.CurrentOptions.UserInterfaceFolder = "Large"; + break; + } if (Result.Start) { // recently used routes diff --git a/source/OpenBVE/UserInterface/formRaildriverCalibration.cs b/source/OpenBVE/UserInterface/formRaildriverCalibration.cs index f0cdf8bbe..c312e9320 100644 --- a/source/OpenBVE/UserInterface/formRaildriverCalibration.cs +++ b/source/OpenBVE/UserInterface/formRaildriverCalibration.cs @@ -14,6 +14,7 @@ public formRaildriverCalibration() main = (Bitmap)Image.FromFile(OpenBveApi.Path.CombineFile(Program.FileSystem.DataFolder, "Menu\\raildriver.png")); pictureBox1.Image = main; buttonCalibrationPrevious.Enabled = false; + labelCalibrationText.Text = Interface.GetInterfaceString("raildriver_calibration_start"); if (JoystickManager.devices.Length == 0) { MessageBox.Show(Interface.GetInterfaceString("raildriver_notdetected"), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); diff --git a/source/OpenBveApi/Archives.cs b/source/OpenBveApi/Archives.cs deleted file mode 100644 index ff06748b7..000000000 --- a/source/OpenBveApi/Archives.cs +++ /dev/null @@ -1,37 +0,0 @@ -#pragma warning disable 0659, 0661 - -namespace OpenBveApi.Archives { - - /* ---------------------------------------- - * TODO: This part of the API is unstable. - * Modifications can be made at will. - * ---------------------------------------- */ - - // --- interfaces --- - - /// Represents the interface for loading archives. Plugins must implement this interface if they wish to expose archives. - public abstract class ArchiveInterface { - - /// Called when the plugin is loaded. - /// The host that loaded the plugin. - public virtual void Load(Hosts.HostInterface host) { } - - /// Called when the plugin is unloaded. - public virtual void Unload() { } - - /// Checks whether the plugin can load the specified element. - /// The path to the file or folder that contains the archive. - /// The path to the element. - /// Whether the plugin can load the specified element. - public abstract bool CanLoadElement(string path, string element); - - /// Loads an item from the specified archive. - /// The path to the file or folder that contains the archive. - /// The path to the element. - /// Receives the element data. - /// Whether loading the element was successful. - public abstract bool LoadElement(string path, string element, out byte[] data); - - } - -} \ No newline at end of file diff --git a/source/OpenBveApi/OpenBveApi.csproj b/source/OpenBveApi/OpenBveApi.csproj index ac6ec21c3..3b5b46fb3 100644 --- a/source/OpenBveApi/OpenBveApi.csproj +++ b/source/OpenBveApi/OpenBveApi.csproj @@ -63,7 +63,6 @@ - @@ -85,6 +84,7 @@ Textures.cs + diff --git a/source/OpenBveApi/Properties/AssemblyInfo.cs b/source/OpenBveApi/Properties/AssemblyInfo.cs index 1be490528..0edc7f37f 100644 --- a/source/OpenBveApi/Properties/AssemblyInfo.cs +++ b/source/OpenBveApi/Properties/AssemblyInfo.cs @@ -8,4 +8,4 @@ [assembly: ComVisible(false)] [assembly: CLSCompliant(true)] -[assembly: AssemblyVersion("1.5.4.0")] +[assembly: AssemblyVersion("1.5.5.0")] diff --git a/source/OpenBveApi/Runtime.cs b/source/OpenBveApi/Runtime.cs index 5c73ad3a5..e075e73b7 100644 --- a/source/OpenBveApi/Runtime.cs +++ b/source/OpenBveApi/Runtime.cs @@ -236,6 +236,8 @@ public class VehicleSpecs { private readonly BrakeTypes MyBrakeType; /// Whether the train has a hold brake. private readonly bool MyHasHoldBrake; + /// Whether the train has a hold brake. + private readonly bool MyHasLocoBrake; /// The number of brake notches the train has, including the hold brake, but excluding the emergency brake. private readonly int MyBrakeNotches; /// The number of cars the train has. @@ -265,6 +267,13 @@ public bool HasHoldBrake { return this.MyHasHoldBrake; } } + + /// Gets whether the train has a hold brake. + public bool HasLocoBrake { + get { + return this.MyHasLocoBrake; + } + } /// Gets the index of the brake notch that corresponds to B1 or LAP. /// For trains without a hold brake, this returns 1. For trains with a hold brake, this returns 2. public int AtsNotch { @@ -300,6 +309,23 @@ public VehicleSpecs(int powerNotches, BrakeTypes brakeType, int brakeNotches, bo this.MyBrakeType = brakeType; this.MyBrakeNotches = brakeNotches; this.MyHasHoldBrake = hasHoldBrake; + this.MyHasLocoBrake = false; + this.MyCars = cars; + } + + /// Creates a new instance of this class. + /// The number of power notches the train has. + /// The type of brake the train uses. + /// The number of brake notches the train has, including the hold brake, but excluding the emergency brake. + /// Whether the train has a hold brake. + /// Whether the train has a loco brake. + /// The number of cars the train has. + public VehicleSpecs(int powerNotches, BrakeTypes brakeType, int brakeNotches, bool hasHoldBrake, bool hasLocoBrake, int cars) { + this.MyPowerNotches = powerNotches; + this.MyBrakeType = brakeType; + this.MyBrakeNotches = brakeNotches; + this.MyHasHoldBrake = hasHoldBrake; + this.MyHasLocoBrake = hasLocoBrake; this.MyCars = cars; } } @@ -565,6 +591,8 @@ public class Handles { private int MyPowerNotch; /// The brake notch. private int MyBrakeNotch; + /// The loco brake notch. + private int MyLocoBrakeNotch; /// Whether the const speed system is enabled. private bool MyConstSpeed; // --- properties --- @@ -595,6 +623,15 @@ public int BrakeNotch { this.MyBrakeNotch = value; } } + /// Gets or sets the brake notch. + public int LocoBrakeNotch { + get { + return this.MyLocoBrakeNotch; + } + set { + this.MyLocoBrakeNotch = value; + } + } /// Gets or sets whether the const speed system is enabled. public bool ConstSpeed { get { @@ -616,6 +653,19 @@ public Handles(int reverser, int powerNotch, int brakeNotch, bool constSpeed) { this.MyBrakeNotch = brakeNotch; this.MyConstSpeed = constSpeed; } + /// Creates a new instance of this class. + /// The current reverser position. + /// The current power notch. + /// The current brake notch. + /// /// The current loco brake notch. + /// Whether the const speed system is enabled. + public Handles(int reverser, int powerNotch, int brakeNotch, int locoBrakeNotch, bool constSpeed) { + this.MyReverser = reverser; + this.MyPowerNotch = powerNotch; + this.MyBrakeNotch = brakeNotch; + this.MyLocoBrakeNotch = locoBrakeNotch; + this.MyConstSpeed = constSpeed; + } } /// Represents data given to the plugin in the Elapse call. diff --git a/source/OpenBveApi/Transformations.cs b/source/OpenBveApi/Transformations.cs new file mode 100644 index 000000000..04e6aba22 --- /dev/null +++ b/source/OpenBveApi/Transformations.cs @@ -0,0 +1,94 @@ +using OpenBveApi.Math; + +namespace OpenBveApi.World +{ + /// Describes a world transformation consisting of three vectors + public struct Transformation + { + /// The X Vector + public Vector3 X; + /// The Y Vector + public Vector3 Y; + /// The Z Vector + public Vector3 Z; + + /// Creates a new transformation, based upon yaw pitch and roll values + /// The yaw to apply + /// The pitch to apply + /// The roll to apply + public Transformation(double Yaw, double Pitch, double Roll) + { + if (Yaw == 0.0 & Pitch == 0.0 & Roll == 0.0) + { + this.X = new Vector3(1.0, 0.0, 0.0); + this.Y = new Vector3(0.0, 1.0, 0.0); + this.Z = new Vector3(0.0, 0.0, 1.0); + } + else if (Pitch == 0.0 & Roll == 0.0) + { + double cosYaw = System.Math.Cos(Yaw); + double sinYaw = System.Math.Sin(Yaw); + this.X = new Vector3(cosYaw, 0.0, -sinYaw); + this.Y = new Vector3(0.0, 1.0, 0.0); + this.Z = new Vector3(sinYaw, 0.0, cosYaw); + } + else + { + X = new Vector3(1.0, 0.0, 0.0); + Y = new Vector3(0.0, 1.0, 0.0); + Z = new Vector3(0.0, 0.0, 1.0); + double cosYaw = System.Math.Cos(Yaw); + double sinYaw = System.Math.Sin(Yaw); + double cosPitch = System.Math.Cos(-Pitch); + double sinPitch = System.Math.Sin(-Pitch); + double cosRoll = System.Math.Cos(-Roll); + double sinRoll = System.Math.Sin(-Roll); + X.Rotate(Y, cosYaw, sinYaw); + Z.Rotate(Y, cosYaw, sinYaw); + Y.Rotate(X, cosPitch, sinPitch); + Z.Rotate(X, cosPitch, sinPitch); + X.Rotate(Z, cosRoll, sinRoll); + Y.Rotate(Z, cosRoll, sinRoll); + } + } + + /// Creates a new transformation, based upon an initial transformation, plus secondary yaw pitch and roll values + /// The initial transformation + /// The yaw to apply + /// The pitch to apply + /// The roll to apply + public Transformation(Transformation Transformation, double Yaw, double Pitch, double Roll) + { + X = new Vector3(Transformation.X.X, Transformation.X.Y, Transformation.X.Z); + Y = new Vector3(Transformation.Y.X, Transformation.Y.Y, Transformation.Y.Z); + Z = new Vector3(Transformation.Z.X, Transformation.Z.Y, Transformation.Z.Z); + double cosYaw = System.Math.Cos(Yaw); + double sinYaw = System.Math.Sin(Yaw); + double cosPitch = System.Math.Cos(-Pitch); + double sinPitch = System.Math.Sin(-Pitch); + double cosRoll = System.Math.Cos(Roll); + double sinRoll = System.Math.Sin(Roll); + X.Rotate(Y, cosYaw, sinYaw); + Z.Rotate(Y, cosYaw, sinYaw); + Y.Rotate(X, cosPitch, sinPitch); + Z.Rotate(X, cosPitch, sinPitch); + X.Rotate(Z, cosRoll, sinRoll); + Y.Rotate(Z, cosRoll, sinRoll); + } + + /// Creates a new transformation, based upon a base transformation and an auxiliary transformation + /// The base transformation + /// The auxiliary transformation + public Transformation(Transformation BaseTransformation, Transformation AuxTransformation) + { + X = new Vector3(BaseTransformation.X.X, BaseTransformation.X.Y, BaseTransformation.X.Z); + Y = new Vector3(BaseTransformation.Y.X, BaseTransformation.Y.Y, BaseTransformation.Y.Z); + Z = new Vector3(BaseTransformation.Z.X, BaseTransformation.Z.Y, BaseTransformation.Z.Z); + X.Rotate(AuxTransformation.Z, AuxTransformation.Y, AuxTransformation.X); + Y.Rotate(AuxTransformation.Z, AuxTransformation.Y, AuxTransformation.X); + Z.Rotate(AuxTransformation.Z, AuxTransformation.Y, AuxTransformation.X); + } + + } + +} diff --git a/source/OpenBveApi/Vector2.cs b/source/OpenBveApi/Vector2.cs index a9df09462..8b130aada 100644 --- a/source/OpenBveApi/Vector2.cs +++ b/source/OpenBveApi/Vector2.cs @@ -22,6 +22,14 @@ public Vector2(double x, double y) { this.X = x; this.Y = y; } + + /// Creates a clone of a vector + /// The vector to clone + public Vector2(Vector2 v) + { + this.X = v.X; + this.Y = v.Y; + } // --- arithmetic operators --- @@ -371,4 +379,4 @@ public override string ToString() } } -} \ No newline at end of file +} diff --git a/source/OpenBveApi/Vector3.cs b/source/OpenBveApi/Vector3.cs index 877b5b1be..7866256b5 100644 --- a/source/OpenBveApi/Vector3.cs +++ b/source/OpenBveApi/Vector3.cs @@ -28,6 +28,14 @@ public Vector3(double x, double y, double z) { this.Z = z; } + /// Creates a clone of a vector + /// The vector to clone + public Vector3(Vector3 v) { + this.X = v.X; + this.Y = v.Y; + this.Z = v.Z; + } + /// Interpolates between two Vector3 values using a simple Cosine algorithm /// The first vector /// The second vector @@ -285,7 +293,18 @@ public void Rotate(Vector3 direction, double cosineOfAngle, double sineOfAngle) double z = (cosineOfAngle + cosineComplement * direction.Z * direction.Z) * this.Z + (cosineComplement * direction.X * direction.Z - sineOfAngle * direction.Y) * this.X + (cosineComplement * direction.Y * direction.Z + sineOfAngle * direction.X) * this.Y; this = new Vector3(x, y, z); } - + + /// Rotates the vector based upon three other vectors + /// The first vector + /// The second vector + /// The third vector + public void Rotate(Vector3 firstVector, Vector3 secondVector, Vector3 thirdVector) { + var x = thirdVector.X * this.X + secondVector.X * this.Y + firstVector.X * this.Z; + var y = thirdVector.Y * this.X + secondVector.Y * this.Y + firstVector.Y * this.Z; + var z = thirdVector.Z * this.X + secondVector.Z * this.Y + firstVector.Z * this.Z; + this = new Vector3(x, y, z); + } + /// Rotates the vector from the default orientation into a specified orientation. /// The orientation. /// The default orientation is X = {1, 0, 0), Y = {0, 1, 0} and Z = {0, 0, 1}. @@ -516,4 +535,4 @@ public override string ToString() return toString; } } -} \ No newline at end of file +} diff --git a/source/Plugins/Formats.Msts/Plugin.cs b/source/Plugins/Formats.Msts/Plugin.cs index f29bca578..57d5b5b68 100644 --- a/source/Plugins/Formats.Msts/Plugin.cs +++ b/source/Plugins/Formats.Msts/Plugin.cs @@ -480,10 +480,10 @@ public override uint ReadUInt32() } string s = getNextValue(); - int val; - if (int.TryParse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out val)) + uint val; + if (uint.TryParse(s, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out val)) { - return (ushort) val; + return val; } throw new Exception("Unable to parse " + s + " to a valid integer in block " + Token); diff --git a/source/Plugins/Formats.Msts/Tokens.cs b/source/Plugins/Formats.Msts/Tokens.cs index c04cb0ef1..fefda446b 100644 --- a/source/Plugins/Formats.Msts/Tokens.cs +++ b/source/Plugins/Formats.Msts/Tokens.cs @@ -1,4 +1,5 @@ -namespace OpenBve.Formats.MsTs +// ReSharper disable UnusedMember.Global +namespace OpenBve.Formats.MsTs { /// The tokens from the Kuju compressed binary format public enum KujuTokenID : uint diff --git a/source/Plugins/OpenBveAts/Train.cs b/source/Plugins/OpenBveAts/Train.cs index 817a70a09..d57409867 100644 --- a/source/Plugins/OpenBveAts/Train.cs +++ b/source/Plugins/OpenBveAts/Train.cs @@ -20,6 +20,8 @@ internal class ReadOnlyHandles { private int MyPowerNotch; /// The brake notch. private int MyBrakeNotch; + /// The loco brake notch. + private int MyLocoBrakeNotch; /// Whether the const speed system is enabled. private bool MyConstSpeed; // --- properties --- @@ -41,6 +43,12 @@ internal int BrakeNotch { return this.MyBrakeNotch; } } + /// Gets or sets the brake notch. + internal int LocoBrakeNotch { + get { + return this.MyLocoBrakeNotch; + } + } /// Gets or sets whether the const speed system is enabled. internal bool ConstSpeed { get { @@ -55,6 +63,7 @@ internal ReadOnlyHandles(Handles handles) { this.MyPowerNotch = handles.PowerNotch; this.MyBrakeNotch = handles.BrakeNotch; this.MyConstSpeed = handles.ConstSpeed; + this.MyLocoBrakeNotch = handles.LocoBrakeNotch; } } @@ -120,9 +129,9 @@ internal ReadOnlyHandles(Handles handles) { /// The delegate to play sounds. internal Train(int[] panel, PlaySoundDelegate playSound) { this.PluginInitializing = false; - this.Specs = new VehicleSpecs(0, BrakeTypes.ElectromagneticStraightAirBrake, 0, false, 0); + this.Specs = new VehicleSpecs(0, BrakeTypes.ElectromagneticStraightAirBrake, 0, false, false, 0); this.State = new VehicleState(0.0, new Speed(0.0), 0.0, 0.0, 0.0, 0.0, 0.0,0.0,0.0,0.0); - this.Handles = new ReadOnlyHandles(new Handles(0, 0, 0, false)); + this.Handles = new ReadOnlyHandles(new Handles(0, 0, 0, 0, false)); this.Doors = DoorStates.None; this.Panel = panel; this.Sounds = new Sounds(playSound); diff --git a/source/Plugins/Sound.Flac/Plugin.cs b/source/Plugins/Sound.Flac/Plugin.cs index b3dfd8ece..7f60abf00 100644 --- a/source/Plugins/Sound.Flac/Plugin.cs +++ b/source/Plugins/Sound.Flac/Plugin.cs @@ -4,13 +4,6 @@ namespace Plugin { public class Plugin : SoundInterface { - - // --- members --- - - /// The host that loaded the plugin. - // private HostInterface CurrentHost = null; - - // --- functions --- /// Called when the plugin is loaded. diff --git a/source/Plugins/Sound.MP3/Plugin.Parser.cs b/source/Plugins/Sound.MP3/Plugin.Parser.cs index 1add6ac33..94fc240ef 100644 --- a/source/Plugins/Sound.MP3/Plugin.Parser.cs +++ b/source/Plugins/Sound.MP3/Plugin.Parser.cs @@ -1,5 +1,4 @@ -using System; -using OpenBveApi.Sounds; +using OpenBveApi.Sounds; using NAudio.Wave; namespace Plugin { diff --git a/source/Plugins/Sound.RiffWave/Plugin.cs b/source/Plugins/Sound.RiffWave/Plugin.cs index 123f4c529..aa4f65bf1 100644 --- a/source/Plugins/Sound.RiffWave/Plugin.cs +++ b/source/Plugins/Sound.RiffWave/Plugin.cs @@ -4,13 +4,6 @@ namespace Plugin { public partial class Plugin : SoundInterface { - - // --- members --- - - /// The host that loaded the plugin. - // private HostInterface CurrentHost = null; - - // --- functions --- /// Called when the plugin is loaded. diff --git a/source/Plugins/Texture.Ace/Plugin.cs b/source/Plugins/Texture.Ace/Plugin.cs index 3b770861b..c39ef84d9 100644 --- a/source/Plugins/Texture.Ace/Plugin.cs +++ b/source/Plugins/Texture.Ace/Plugin.cs @@ -5,13 +5,6 @@ namespace Plugin { /// Implements the texture interface. public partial class Plugin : TextureInterface { - - // --- members --- - - /// The host that loaded the plugin. - // private HostInterface CurrentHost = null; - - // --- functions --- /// Called when the plugin is loaded. diff --git a/source/Plugins/Texture.Dds/Plugin.cs b/source/Plugins/Texture.Dds/Plugin.cs index d8ce8f735..eaf66e91a 100644 --- a/source/Plugins/Texture.Dds/Plugin.cs +++ b/source/Plugins/Texture.Dds/Plugin.cs @@ -1,18 +1,10 @@ using System.IO; -using Microsoft.Win32.SafeHandles; using OpenBveApi.Hosts; using OpenBveApi.Textures; namespace Plugin { /// Implements the texture interface. - public partial class Plugin : TextureInterface { - - // --- members --- - - /// The host that loaded the plugin. - // private HostInterface CurrentHost = null; - - + public class Plugin : TextureInterface { // --- functions --- /// Called when the plugin is loaded. diff --git a/source/RouteViewer/Audio/Sounds.cs b/source/RouteViewer/Audio/Sounds.cs index 5484c7d10..57740ef1e 100644 --- a/source/RouteViewer/Audio/Sounds.cs +++ b/source/RouteViewer/Audio/Sounds.cs @@ -42,7 +42,7 @@ internal enum SoundModels private static int SourceCount = 0; /// The gain threshold. Sounds with gains below this value are not played. - internal const double GainThreshold = 0.0001; + private const double GainThreshold = 0.0001; /// Whether all sounds are mute. internal static bool GlobalMute = false; @@ -184,15 +184,15 @@ internal static SoundBuffer RegisterBuffer(OpenBveApi.Sounds.Sound data, double /// Loads the specified sound buffer. /// The sound buffer. /// Whether loading the buffer was successful. - internal static bool LoadBuffer(SoundBuffer buffer) + internal static void LoadBuffer(SoundBuffer buffer) { if (buffer.Loaded) { - return true; + return; } if (buffer.Ignore) { - return false; + return; } OpenBveApi.Sounds.Sound sound; if (buffer.Origin.GetSound(out sound)) @@ -205,11 +205,10 @@ internal static bool LoadBuffer(SoundBuffer buffer) AL.BufferData(buffer.OpenAlBufferName, format, bytes, bytes.Length, sound.SampleRate); buffer.Duration = sound.Duration; buffer.Loaded = true; - return true; + return; } } buffer.Ignore = true; - return false; } /// Loads all sound buffers immediately. diff --git a/source/RouteViewer/FunctionScripts.cs b/source/RouteViewer/FunctionScripts.cs index 9b49e4cf4..c3cc15458 100644 --- a/source/RouteViewer/FunctionScripts.cs +++ b/source/RouteViewer/FunctionScripts.cs @@ -18,7 +18,7 @@ internal enum Instructions { TrainCars, TrainDestination, TrainSpeed, TrainSpeedometer, TrainAcceleration, TrainAccelerationMotor, TrainSpeedOfCar, TrainSpeedometerOfCar, TrainAccelerationOfCar, TrainAccelerationMotorOfCar, - TrainDistance, TrainDistanceToCar, TrainTrackDistance, TrainTrackDistanceToCar, CurveRadius, FrontAxleCurveRadius, RearAxleCurveRadius, CurveCant, Odometer, OdometerOfCar, + TrainDistance, TrainDistanceToCar, TrainTrackDistance, TrainTrackDistanceToCar, CurveRadius, FrontAxleCurveRadius, RearAxleCurveRadius, CurveCant, Pitch, Odometer, OdometerOfCar, Doors, DoorsIndex, LeftDoors, LeftDoorsIndex, RightDoors, RightDoorsIndex, LeftDoorsTarget, LeftDoorsTargetIndex, RightDoorsTarget, RightDoorsTargetIndex, @@ -513,6 +513,25 @@ private static void ExecuteFunctionScript(FunctionScript Function, TrainManager. } } break; + case Instructions.Pitch: + if (Train == null) + { + Function.Stack[s - 1] = 0.0; + } + else + { + int j = (int)Math.Round(Function.Stack[s - 1]); + if (j < 0) j += Train.Cars.Length; + if (j >= 0 & j < Train.Cars.Length) + { + Function.Stack[s - 1] = Train.Cars[j].FrontAxle.Follower.Pitch; + } + else + { + Function.Stack[s - 1] = 0.0; + } + } + break; case Instructions.Odometer: Function.Stack[s] = 0.0; s++; @@ -1359,6 +1378,10 @@ private static string GetPostfixNotationFromFunctionNotation(string Expression) if (Expression.EndsWith("]")) { throw new System.IO.InvalidDataException("Unexpected closing bracket encountered in " + Expression); } else { + // ReSharper disable once NotAccessedVariable + /* + * If this is a simple number, we can short-circuit the rest of this function + */ double value; if (double.TryParse(Expression, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out value)) { return Expression; @@ -1607,6 +1630,7 @@ private static string GetPostfixNotationFromFunctionNotation(string Expression) case "frontaxlecurveradius": case "rearaxlecurveradius": case "curvecant": + case "pitch": case "odometer": case "speed": case "speedometer": @@ -2470,6 +2494,11 @@ internal static FunctionScript GetFunctionScriptFromPostfixNotation(string Expre if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); Result.Instructions[n] = Instructions.CurveCant; n++; break; + case "pitchindex": + if (s < 1) throw new System.InvalidOperationException(Arguments[i] + " requires at least 1 argument on the stack in function script " + Expression); + if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); + Result.Instructions[n] = Instructions.Pitch; + n++; break; case "odometer": if (n >= Result.Instructions.Length) Array.Resize(ref Result.Instructions, Result.Instructions.Length << 1); Result.Instructions[n] = Instructions.Odometer; diff --git a/source/RouteViewer/ObjectManager.cs b/source/RouteViewer/ObjectManager.cs index cfd0f5a57..979d715e0 100644 --- a/source/RouteViewer/ObjectManager.cs +++ b/source/RouteViewer/ObjectManager.cs @@ -1,6 +1,7 @@ using System; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { internal static class ObjectManager { @@ -547,13 +548,13 @@ internal static void UpdateAnimatedObject(ref AnimatedObject Object, bool IsPart for (int k = 0; k < Object.States[s].Object.Mesh.Vertices.Length; k++) { // rotate if (rotateX) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateXDirection.X, Object.RotateXDirection.Y, Object.RotateXDirection.Z, cosX, sinX); + ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(Object.RotateXDirection, cosX, sinX); } if (rotateY) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateYDirection.X, Object.RotateYDirection.Y, Object.RotateYDirection.Z, cosY, sinY); + ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(Object.RotateYDirection, cosY, sinY); } if (rotateZ) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.X, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Y, ref ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Z, Object.RotateZDirection.X, Object.RotateZDirection.Y, Object.RotateZDirection.Z, cosZ, sinZ); + ObjectManager.Objects[i].Mesh.Vertices[k].Coordinates.Rotate(Object.RotateZDirection, cosZ, sinZ); } // translate if (Overlay & World.CameraRestriction != World.CameraRestrictionMode.NotAvailable) { @@ -585,13 +586,13 @@ internal static void UpdateAnimatedObject(ref AnimatedObject Object, bool IsPart for (int h = 0; h < Object.States[s].Object.Mesh.Faces[k].Vertices.Length; h++) { if (!Vector3.IsZero(Object.States[s].Object.Mesh.Faces[k].Vertices[h].Normal)) { if (rotateX) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateXDirection.X, Object.RotateXDirection.Y, Object.RotateXDirection.Z, cosX, sinX); + ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(Object.RotateXDirection, cosX, sinX); } if (rotateY) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateYDirection.X, Object.RotateYDirection.Y, Object.RotateYDirection.Z, cosY, sinY); + ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(Object.RotateYDirection, cosY, sinY); } if (rotateZ) { - World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Object.RotateZDirection.X, Object.RotateZDirection.Y, Object.RotateZDirection.Z, cosZ, sinZ); + ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Rotate(Object.RotateZDirection, cosZ, sinZ); } World.Rotate(ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.X, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Y, ref ObjectManager.Objects[i].Mesh.Faces[k].Vertices[h].Normal.Z, Direction.X, Direction.Y, Direction.Z, Up.X, Up.Y, Up.Z, Side.X, Side.Y, Side.Z); } @@ -679,7 +680,7 @@ internal class AnimatedWorldObject { } internal static AnimatedWorldObject[] AnimatedWorldObjects = new AnimatedWorldObject[4]; internal static int AnimatedWorldObjectsUsed = 0; - internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { + internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { bool[] free = new bool[Prototypes.Length]; bool anyfree = false; for (int i = 0; i < Prototypes.Length; i++) { @@ -691,7 +692,7 @@ internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vec if (Prototypes[i].States.Length != 0) { if (free[i]) { Vector3 p = Position; - World.Transformation t = new OpenBve.World.Transformation(BaseTransformation, AuxTransformation); + Transformation t = new Transformation(BaseTransformation, AuxTransformation); Vector3 s = t.X; Vector3 u = t.Y; Vector3 d = t.Z; @@ -713,12 +714,12 @@ internal static void CreateAnimatedWorldObjects(AnimatedObject[] Prototypes, Vec } } } - internal static int CreateAnimatedWorldObject(AnimatedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { + internal static int CreateAnimatedWorldObject(AnimatedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, double TrackPosition, double Brightness) { int a = AnimatedWorldObjectsUsed; if (a >= AnimatedWorldObjects.Length) { Array.Resize(ref AnimatedWorldObjects, AnimatedWorldObjects.Length << 1); } - World.Transformation FinalTransformation = new World.Transformation(AuxTransformation, BaseTransformation); + Transformation FinalTransformation = new Transformation(AuxTransformation, BaseTransformation); AnimatedWorldObjects[a] = new AnimatedWorldObject(); AnimatedWorldObjects[a].Position = Position; AnimatedWorldObjects[a].Direction = FinalTransformation.Z; @@ -1400,10 +1401,10 @@ internal static void JoinObjects(ref StaticObject Base, StaticObject Add) { } // create object - internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { + internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { CreateObject(Prototype, Position, BaseTransformation, AuxTransformation, -1, AccurateObjectDisposal, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0, false); } - internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { + internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, int SectionIndex, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { if (Prototype is StaticObject) { StaticObject s = (StaticObject)Prototype; CreateStaticObject(s, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, Brightness, DuplicateMaterials); @@ -1414,10 +1415,10 @@ internal static void CreateObject(UnifiedObject Prototype, Vector3 Position, Wor } // create static object - internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { + internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition) { return CreateStaticObject(Prototype, Position, BaseTransformation, AuxTransformation, AccurateObjectDisposal, 0.0, StartingDistance, EndingDistance, BlockLength, TrackPosition, 1.0, false); } - internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { + internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { int a = ObjectsUsed; if (a >= Objects.Length) { Array.Resize(ref Objects, Objects.Length << 1); @@ -1445,7 +1446,7 @@ internal static int CreateStaticObject(StaticObject Prototype, Vector3 Position, ObjectsUsed++; return a; } - internal static void ApplyStaticObjectData(ref StaticObject Object, StaticObject Prototype, Vector3 Position, World.Transformation BaseTransformation, World.Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { + internal static void ApplyStaticObjectData(ref StaticObject Object, StaticObject Prototype, Vector3 Position, Transformation BaseTransformation, Transformation AuxTransformation, bool AccurateObjectDisposal, double AccurateObjectDisposalZOffset, double StartingDistance, double EndingDistance, double BlockLength, double TrackPosition, double Brightness, bool DuplicateMaterials) { Object = new StaticObject(); Object.StartingDistance = float.MaxValue; Object.EndingDistance = float.MinValue; diff --git a/source/RouteViewer/Parsers/CsvB3dObjectParser.cs b/source/RouteViewer/Parsers/CsvB3dObjectParser.cs index 6c1c36286..8231e3f7e 100644 --- a/source/RouteViewer/Parsers/CsvB3dObjectParser.cs +++ b/source/RouteViewer/Parsers/CsvB3dObjectParser.cs @@ -496,9 +496,9 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te y *= t; z *= t; a *= 0.0174532925199433; - ApplyRotation(Builder, x, y, z, a); + ApplyRotation(Builder, new Vector3(x,y,z), a); if (cmd == "rotateall") { - ApplyRotation(Object, x, y, z, a); + ApplyRotation(Object, new Vector3(x,y,z), a); } } } break; @@ -1212,27 +1212,27 @@ internal static void ApplyScale(ObjectManager.StaticObject Object, double x, dou } // apply rotation - private static void ApplyRotation(MeshBuilder Builder, double x, double y, double z, double a) { - double cosa = Math.Cos(a); - double sina = Math.Sin(a); + private static void ApplyRotation(MeshBuilder Builder, Vector3 Rotation, double Angle) { + double cosa = Math.Cos(Angle); + double sina = Math.Sin(Angle); for (int i = 0; i < Builder.Vertices.Length; i++) { - World.Rotate(ref Builder.Vertices[i].Coordinates.X, ref Builder.Vertices[i].Coordinates.Y, ref Builder.Vertices[i].Coordinates.Z, x, y, z, cosa, sina); + Builder.Vertices[i].Coordinates.Rotate(Rotation, cosa, sina); } for (int i = 0; i < Builder.Faces.Length; i++) { for (int j = 0; j < Builder.Faces[i].Vertices.Length; j++) { - World.Rotate(ref Builder.Faces[i].Vertices[j].Normal.X, ref Builder.Faces[i].Vertices[j].Normal.Y, ref Builder.Faces[i].Vertices[j].Normal.Z, x, y, z, cosa, sina); + Builder.Faces[i].Vertices[j].Normal.Rotate(Rotation, cosa, sina); } } } - private static void ApplyRotation(ObjectManager.StaticObject Object, double x, double y, double z, double a) { - double cosa = Math.Cos(a); - double sina = Math.Sin(a); + private static void ApplyRotation(ObjectManager.StaticObject Object, Vector3 Rotation, double Angle) { + double cosa = Math.Cos(Angle); + double sina = Math.Sin(Angle); for (int j = 0; j < Object.Mesh.Vertices.Length; j++) { - World.Rotate(ref Object.Mesh.Vertices[j].Coordinates.X, ref Object.Mesh.Vertices[j].Coordinates.Y, ref Object.Mesh.Vertices[j].Coordinates.Z, x, y, z, cosa, sina); + Object.Mesh.Vertices[j].Coordinates.Rotate(Rotation, cosa, sina); } for (int j = 0; j < Object.Mesh.Faces.Length; j++) { for (int k = 0; k < Object.Mesh.Faces[j].Vertices.Length; k++) { - World.Rotate(ref Object.Mesh.Faces[j].Vertices[k].Normal.X, ref Object.Mesh.Faces[j].Vertices[k].Normal.Y, ref Object.Mesh.Faces[j].Vertices[k].Normal.Z, x, y, z, cosa, sina); + Object.Mesh.Faces[j].Vertices[k].Normal.Rotate(Rotation, cosa, sina); } } } diff --git a/source/RouteViewer/Parsers/CsvRwRouteParser.cs b/source/RouteViewer/Parsers/CsvRwRouteParser.cs index a7450fd0e..60919ea32 100644 --- a/source/RouteViewer/Parsers/CsvRwRouteParser.cs +++ b/source/RouteViewer/Parsers/CsvRwRouteParser.cs @@ -4,6 +4,7 @@ using OpenBveApi; using OpenBveApi.Math; using OpenBveApi.Colors; +using OpenBveApi.World; namespace OpenBve { internal class CsvRwRouteParser { @@ -160,6 +161,20 @@ private struct Transponder { internal double Pitch; internal double Roll; } + private struct DestinationEvent + { + internal double TrackPosition; + internal int Type; + internal bool TriggerOnce; + internal int BeaconStructureIndex; + internal int NextDestination; + internal int PreviousDestination; + internal double X; + internal double Y; + internal double Yaw; + internal double Pitch; + internal double Roll; + } private struct PointOfInterest { internal double TrackPosition; internal int RailIndex; @@ -197,6 +212,7 @@ private class Block { internal Stop[] Stop; internal Sound[] Sound; internal Transponder[] Transponder; + internal DestinationEvent[] DestinationChanges; internal PointOfInterest[] PointsOfInterest; internal TrackManager.TrackElement CurrentTrackState; internal double Pitch; @@ -310,6 +326,7 @@ internal static void ParseRoute(string FileName, bool IsRW, System.Text.Encoding Data.Blocks[0].Section = new Section[] { }; Data.Blocks[0].Sound = new Sound[] { }; Data.Blocks[0].Transponder = new Transponder[] { }; + Data.Blocks[0].DestinationChanges = new DestinationEvent[] { }; Data.Blocks[0].PointsOfInterest = new PointOfInterest[] { }; Data.Markers = new Marker[] { }; string PoleFolder = OpenBveApi.Path.CombineDirectory(CompatibilityFolder, "Poles"); @@ -1969,28 +1986,6 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } else if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } - // Code was always unreachable because this is routeviewer // - // else if (Program.CurrentProgramType == Program.ProgramType.OpenBve) { - // if (Path.ContainsInvalidChars(Arguments[0])) { - // Interface.AddMessage(Interface.MessageType.Error, false, "FileName " + Arguments[0] + " contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); - // } else { - // while (CommandIndex1 >= Data.TimetableDaytime.Length) { - // int n = Data.TimetableDaytime.Length; - // Array.Resize(ref Data.TimetableDaytime, n << 1); - // for (int i = n; i < Data.TimetableDaytime.Length; i++) { - // Data.TimetableDaytime[i] = -1; - // } - // } - // string f = OpenBveApi.Path.CombineFile(TrainPath, Arguments[0]); - // if (!System.IO.File.Exists(f)) { - // f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); - // } - // if (System.IO.File.Exists(f)) { - // Data.TimetableDaytime[CommandIndex1] = TextureManager.RegisterTexture(f, TextureManager.TextureWrapMode.ClampToEdge, TextureManager.TextureWrapMode.ClampToEdge, true); - // TextureManager.UseTexture(Data.TimetableDaytime[CommandIndex1], TextureManager.UseMode.Normal); - // } - // } - // } } } break; case "train.timetable.night": @@ -2001,31 +1996,17 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En } else if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } - // Code was always unreachable because this is routeviewer // - // else if (Program.CurrentProgramType == Program.ProgramType.OpenBve) { - // if (Path.ContainsInvalidChars(Arguments[0])) { - // Interface.AddMessage(Interface.MessageType.Error, false, "FileName " + Arguments[0] + " contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); - // } else { - // while (CommandIndex1 >= Data.TimetableNighttime.Length) { - // int n = Data.TimetableNighttime.Length; - // Array.Resize(ref Data.TimetableNighttime, n << 1); - // for (int i = n; i < Data.TimetableNighttime.Length; i++) { - // Data.TimetableNighttime[i] = -1; - // } - // } - // string f = OpenBveApi.Path.CombineFile(TrainPath, Arguments[0]); - // if (!System.IO.File.Exists(f)) { - // f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); - // } - // if (System.IO.File.Exists(f)) { - // Data.TimetableNighttime[CommandIndex1] = TextureManager.RegisterTexture(f, TextureManager.TextureWrapMode.ClampToEdge, TextureManager.TextureWrapMode.ClampToEdge, false); - // TextureManager.UseTexture(Data.TimetableNighttime[CommandIndex1], TextureManager.UseMode.Normal); - // } - // } - // } } } break; - // structure + case "train.destination": + if (!PreviewOnly) + { + if (Arguments.Length < 1) + { + Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + } + } + break; case "structure.rail": { if (!PreviewOnly) { @@ -2595,17 +2576,17 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En bool notFound = false; while (true) { - f = Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), System.IO.Path.GetFileName(FileName) + ".x"); + f = Path.CombineFile(System.IO.Path.GetDirectoryName(f), System.IO.Path.GetFileName(f) + ".x"); if (System.IO.File.Exists(f)) { break; } - f = Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), System.IO.Path.GetFileName(FileName) + ".csv"); + f = Path.CombineFile(System.IO.Path.GetDirectoryName(f), System.IO.Path.GetFileName(f) + ".csv"); if (System.IO.File.Exists(f)) { break; } - f = Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), System.IO.Path.GetFileName(FileName) + ".b3d"); + f = Path.CombineFile(System.IO.Path.GetDirectoryName(f), System.IO.Path.GetFileName(f) + ".b3d"); if (System.IO.File.Exists(f)) { break; @@ -2618,7 +2599,6 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En { break; } - break; } Bve4SignalData Signal = new Bve4SignalData(); Signal.BaseObject = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); @@ -3555,6 +3535,102 @@ private static void ParseRouteForData(string FileName, bool IsRW, System.Text.En Data.Blocks[BlockIndex].Signal[n].ShowPost = x != 0.0 & y < 0.0; } } break; + case "track.destination": + { + if (!PreviewOnly) + { + int type = 0; + if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[0], out type)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "Type is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + type = 0; + } + if (type < -1 || type > 1) + { + Interface.AddMessage(Interface.MessageType.Error, false, "Type is expected to be in the range of -1 to 1 in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + } + else + { + int structure = 0, nextDestination = 0, previousDestination = 0, triggerOnce = 0; + if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[1], out structure)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "BeaconStructureIndex is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + structure = 0; + } + if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[2], out nextDestination)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "NextDestination is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + nextDestination = 0; + } + if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[3], out previousDestination)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "PreviousDestination is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + previousDestination = 0; + } + if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[4], out triggerOnce)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "TriggerOnce is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + previousDestination = 0; + } + if (structure < -1) + { + Interface.AddMessage(Interface.MessageType.Error, false, "BeaconStructureIndex is expected to be non-negative or -1 in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + structure = -1; + } + else if (structure >= 0 && !Data.Structure.Beacon.ContainsKey(structure)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "BeaconStructureIndex " + structure + " references an object not loaded in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + structure = -1; + } + if (triggerOnce < 0 || triggerOnce > 1) + { + Interface.AddMessage(Interface.MessageType.Error, false, "TriggerOnce is expected to be in the range of 0 to 1 in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + triggerOnce = 0; + } + double x = 0.0, y = 0.0; + double yaw = 0.0, pitch = 0.0, roll = 0.0; + if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[5], UnitOfLength, out x)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + x = 0.0; + } + if (Arguments.Length >= 7 && Arguments[6].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[6], UnitOfLength, out y)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + y = 0.0; + } + if (Arguments.Length >= 8 && Arguments[7].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[7], out yaw)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + yaw = 0.0; + } + if (Arguments.Length >= 9 && Arguments[8].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[8], out pitch)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + pitch = 0.0; + } + if (Arguments.Length >= 10 && Arguments[9].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[9], out roll)) + { + Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.Destination at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); + roll = 0.0; + } + int n = Data.Blocks[BlockIndex].DestinationChanges.Length; + Array.Resize(ref Data.Blocks[BlockIndex].DestinationChanges, n + 1); + Data.Blocks[BlockIndex].DestinationChanges[n].TrackPosition = Data.TrackPosition; + Data.Blocks[BlockIndex].DestinationChanges[n].Type = type; + Data.Blocks[BlockIndex].DestinationChanges[n].TriggerOnce = triggerOnce != 0; + Data.Blocks[BlockIndex].DestinationChanges[n].PreviousDestination = previousDestination; + Data.Blocks[BlockIndex].DestinationChanges[n].BeaconStructureIndex = structure; + Data.Blocks[BlockIndex].DestinationChanges[n].NextDestination = nextDestination; + Data.Blocks[BlockIndex].DestinationChanges[n].X = x; + Data.Blocks[BlockIndex].DestinationChanges[n].Y = y; + Data.Blocks[BlockIndex].DestinationChanges[n].Yaw = yaw * 0.0174532925199433; + Data.Blocks[BlockIndex].DestinationChanges[n].Pitch = pitch * 0.0174532925199433; + Data.Blocks[BlockIndex].DestinationChanges[n].Roll = roll * 0.0174532925199433; + } + } + } + break; case "track.beacon": { if (!PreviewOnly) { @@ -4918,6 +4994,7 @@ private static void CreateMissingBlocks(ref RouteData Data, ref int BlocksUsed, Data.Blocks[i].Section = new Section[] { }; Data.Blocks[i].Sound = new Sound[] { }; Data.Blocks[i].Transponder = new Transponder[] { }; + Data.Blocks[i].DestinationChanges = new DestinationEvent[] { }; Data.Blocks[i].RailFreeObj = new FreeObj[][] { }; Data.Blocks[i].GroundFreeObj = new FreeObj[] { }; Data.Blocks[i].PointsOfInterest = new PointOfInterest[] { }; @@ -5463,11 +5540,19 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin double ag = -Math.Atan(Data.Blocks[i].Turn); double cosag = Math.Cos(ag); double sinag = Math.Sin(ag); - World.Rotate(ref Direction, cosag, sinag); + Direction.Rotate(cosag, sinag); World.RotatePlane(ref TrackManager.CurrentTrack.Elements[n].WorldDirection, cosag, sinag); World.RotatePlane(ref TrackManager.CurrentTrack.Elements[n].WorldSide, cosag, sinag); TrackManager.CurrentTrack.Elements[n].WorldUp = Vector3.Cross(TrackManager.CurrentTrack.Elements[n].WorldDirection, TrackManager.CurrentTrack.Elements[n].WorldSide); } + if (Data.Blocks[i].Pitch != 0.0) + { + TrackManager.CurrentTrack.Elements[n].Pitch = Data.Blocks[i].Pitch; + } + else + { + TrackManager.CurrentTrack.Elements[n].Pitch = 0.0; + } // curves double a = 0.0; double c = Data.BlockInterval; @@ -5481,14 +5566,14 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin double b = s / Math.Abs(r); c = Math.Sqrt(2.0 * r * r * (1.0 - Math.Cos(b))); a = 0.5 * (double)Math.Sign(r) * b; - World.Rotate(ref Direction, Math.Cos(-a), Math.Sin(-a)); + Direction.Rotate(Math.Cos(-a), Math.Sin(-a)); } else if (WorldTrackElement.CurveRadius != 0.0) { double d = Data.BlockInterval; double r = WorldTrackElement.CurveRadius; double b = d / Math.Abs(r); c = Math.Sqrt(2.0 * r * r * (1.0 - Math.Cos(b))); a = 0.5 * (double)Math.Sign(r) * b; - World.Rotate(ref Direction, Math.Cos(-a), Math.Sin(-a)); + Direction.Rotate(Math.Cos(-a), Math.Sin(-a)); } else if (Data.Blocks[i].Pitch != 0.0) { double p = Data.Blocks[i].Pitch; double d = Data.BlockInterval; @@ -5497,9 +5582,9 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin } double TrackYaw = Math.Atan2(Direction.X, Direction.Y); double TrackPitch = Math.Atan(Data.Blocks[i].Pitch); - World.Transformation GroundTransformation = new World.Transformation(TrackYaw, 0.0, 0.0); - World.Transformation TrackTransformation = new World.Transformation(TrackYaw, TrackPitch, 0.0); - World.Transformation NullTransformation = new World.Transformation(0.0, 0.0, 0.0); + Transformation GroundTransformation = new Transformation(TrackYaw, 0.0, 0.0); + Transformation TrackTransformation = new Transformation(TrackYaw, TrackPitch, 0.0); + Transformation NullTransformation = new Transformation(0.0, 0.0, 0.0); // ground if (!PreviewOnly) { int cb = (int)Math.Floor((double)i + 0.001); @@ -5518,7 +5603,7 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin double dy = Data.Blocks[i].GroundFreeObj[j].Y; Vector3 wpos = Position + new Vector3(Direction.X * d + Direction.Y * dx, dy - Data.Blocks[i].Height, Direction.Y * d - Direction.X * dx); double tpos = Data.Blocks[i].GroundFreeObj[j].TrackPosition; - ObjectManager.CreateObject(Data.Structure.FreeObjects[sttype], wpos, GroundTransformation, new World.Transformation(Data.Blocks[i].GroundFreeObj[j].Yaw, Data.Blocks[i].GroundFreeObj[j].Pitch, Data.Blocks[i].GroundFreeObj[j].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); + ObjectManager.CreateObject(Data.Structure.FreeObjects[sttype], wpos, GroundTransformation, new Transformation(Data.Blocks[i].GroundFreeObj[j].Yaw, Data.Blocks[i].GroundFreeObj[j].Pitch, Data.Blocks[i].GroundFreeObj[j].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); } } // rail-aligned objects @@ -5527,14 +5612,14 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin if (j > 0 && !Data.Blocks[i].Rail[j].RailStart) continue; // rail Vector3 pos; - World.Transformation RailTransformation; + Transformation RailTransformation; double planar, updown; if (j == 0) { // rail 0 pos = Position; planar = 0.0; updown = 0.0; - RailTransformation = new World.Transformation(TrackTransformation, planar, updown, 0.0); + RailTransformation = new Transformation(TrackTransformation, planar, updown, 0.0); pos = Position; } else { // rails 1-infinity @@ -5551,13 +5636,13 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin Position2.Y += h; Position2.Z += Direction.Y * c; if (a != 0.0) { - World.Rotate(ref Direction2, Math.Cos(-a), Math.Sin(-a)); + Direction2.Rotate(Math.Cos(-a), Math.Sin(-a)); } if (Data.Blocks[i + 1].Turn != 0.0) { double ag = -Math.Atan(Data.Blocks[i + 1].Turn); double cosag = Math.Cos(ag); double sinag = Math.Sin(ag); - World.Rotate(ref Direction2, cosag, sinag); + Direction2.Rotate(cosag, sinag); } double a2 = 0.0; // double c2 = Data.BlockInterval; @@ -5571,14 +5656,14 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin double b2 = s2 / Math.Abs(r2); // c2 = Math.Sqrt(2.0 * r2 * r2 * (1.0 - Math.Cos(b2))); a2 = 0.5 * (double)Math.Sign(r2) * b2; - World.Rotate(ref Direction2, Math.Cos(-a2), Math.Sin(-a2)); + Direction2.Rotate(Math.Cos(-a2), Math.Sin(-a2)); } else if (Data.Blocks[i + 1].CurrentTrackState.CurveRadius != 0.0) { double d2 = Data.BlockInterval; double r2 = Data.Blocks[i + 1].CurrentTrackState.CurveRadius; double b2 = d2 / Math.Abs(r2); // c2 = Math.Sqrt(2.0 * r2 * r2 * (1.0 - Math.Cos(b2))); a2 = 0.5 * (double)Math.Sign(r2) * b2; - World.Rotate(ref Direction2, Math.Cos(-a2), Math.Sin(-a2)); + Direction2.Rotate(Math.Cos(-a2), Math.Sin(-a2)); } else if (Data.Blocks[i + 1].Pitch != 0.0) { // double p2 = Data.Blocks[i + 1].Pitch; // double d2 = Data.BlockInterval; @@ -5587,8 +5672,8 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin } // double TrackYaw2 = Math.Atan2(Direction2.X, Direction2.Y); // double TrackPitch2 = Math.Atan(Data.Blocks[i + 1].Pitch); - // World.Transformation GroundTransformation2 = new World.Transformation(TrackYaw2, 0.0, 0.0); - // World.Transformation TrackTransformation2 = new World.Transformation(TrackYaw2, TrackPitch2, 0.0); + // Transformation GroundTransformation2 = new Transformation(TrackYaw2, 0.0, 0.0); + // Transformation TrackTransformation2 = new Transformation(TrackYaw2, TrackPitch2, 0.0); double x2 = Data.Blocks[i + 1].Rail[j].RailEndX; double y2 = Data.Blocks[i + 1].Rail[j].RailEndY; Vector3 offset2 = new Vector3(Direction2.Y * x2, y2, -Direction2.X * x2); @@ -5610,7 +5695,7 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin planar = 0.0; dh = 0.0; updown = 0.0; - RailTransformation = new World.Transformation(TrackTransformation, 0.0, 0.0, 0.0); + RailTransformation = new Transformation(TrackTransformation, 0.0, 0.0, 0.0); } } if (Data.Structure.RailObjects.ContainsKey(Data.Blocks[i].RailType[j])) { @@ -5922,7 +6007,7 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin wpos.Y += dx * RailTransformation.X.Y + dy * RailTransformation.Y.Y + dz * RailTransformation.Z.Y; wpos.Z += dx * RailTransformation.X.Z + dy * RailTransformation.Y.Z + dz * RailTransformation.Z.Z; double tpos = Data.Blocks[i].RailFreeObj[j][k].TrackPosition; - ObjectManager.CreateObject(Data.Structure.FreeObjects[sttype], wpos, RailTransformation, new World.Transformation(Data.Blocks[i].RailFreeObj[j][k].Yaw, Data.Blocks[i].RailFreeObj[j][k].Pitch, Data.Blocks[i].RailFreeObj[j][k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); + ObjectManager.CreateObject(Data.Structure.FreeObjects[sttype], wpos, RailTransformation, new Transformation(Data.Blocks[i].RailFreeObj[j][k].Yaw, Data.Blocks[i].RailFreeObj[j][k].Pitch, Data.Blocks[i].RailFreeObj[j][k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); } } // transponder objects @@ -5954,12 +6039,33 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin double tpos = Data.Blocks[i].Transponder[k].TrackPosition; if (Data.Blocks[i].Transponder[k].ShowDefaultObject) { double b = 0.25 + 0.75 * GetBrightness(ref Data, tpos); - ObjectManager.CreateObject(obj, wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Transponder[k].Yaw, Data.Blocks[i].Transponder[k].Pitch, Data.Blocks[i].Transponder[k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); + ObjectManager.CreateObject(obj, wpos, RailTransformation, new Transformation(Data.Blocks[i].Transponder[k].Yaw, Data.Blocks[i].Transponder[k].Pitch, Data.Blocks[i].Transponder[k].Roll), -1, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, b, false); } else { - ObjectManager.CreateObject(obj, wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Transponder[k].Yaw, Data.Blocks[i].Transponder[k].Pitch, Data.Blocks[i].Transponder[k].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); + ObjectManager.CreateObject(obj, wpos, RailTransformation, new Transformation(Data.Blocks[i].Transponder[k].Yaw, Data.Blocks[i].Transponder[k].Pitch, Data.Blocks[i].Transponder[k].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); } } } + for (int k = 0; k < Data.Blocks[i].DestinationChanges.Length; k++) + { + ObjectManager.UnifiedObject obj = null; + int b = Data.Blocks[i].DestinationChanges[k].BeaconStructureIndex; + if (b >= 0 & Data.Structure.Beacon.ContainsKey(b)) + { + obj = Data.Structure.Beacon[b]; + } + if (obj != null) + { + double dx = Data.Blocks[i].DestinationChanges[k].X; + double dy = Data.Blocks[i].DestinationChanges[k].Y; + double dz = Data.Blocks[i].DestinationChanges[k].TrackPosition - StartingDistance; + Vector3 wpos = pos; + wpos.X += dx * RailTransformation.X.X + dy * RailTransformation.Y.X + dz * RailTransformation.Z.X; + wpos.Y += dx * RailTransformation.X.Y + dy * RailTransformation.Y.Y + dz * RailTransformation.Z.Y; + wpos.Z += dx * RailTransformation.X.Z + dy * RailTransformation.Y.Z + dz * RailTransformation.Z.Z; + double tpos = Data.Blocks[i].DestinationChanges[k].TrackPosition; + ObjectManager.CreateObject(obj, wpos, RailTransformation, new Transformation(Data.Blocks[i].DestinationChanges[k].Yaw, Data.Blocks[i].DestinationChanges[k].Pitch, Data.Blocks[i].DestinationChanges[k].Roll), Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos); + } + } } // sections/signals/transponders if (j == 0) { @@ -5995,7 +6101,7 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin double tpos = Data.Blocks[i].Signal[k].TrackPosition; if (sd is AnimatedObjectSignalData) { AnimatedObjectSignalData aosd = (AnimatedObjectSignalData)sd; - ObjectManager.CreateObject(aosd.Objects, wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); + ObjectManager.CreateObject(aosd.Objects, wpos, RailTransformation, new Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); } else if (sd is CompatibilitySignalData) { CompatibilitySignalData csd = (CompatibilitySignalData)sd; if (csd.Numbers.Length != 0) { @@ -6017,7 +6123,7 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin } aoc.Objects[0].StateFunction = FunctionScripts.GetFunctionScriptFromPostfixNotation(expr); aoc.Objects[0].RefreshRate = 1.0 + 0.01 * Game.Generator.NextDouble(); - ObjectManager.CreateObject(aoc, wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, brightness, false); + ObjectManager.CreateObject(aoc, wpos, RailTransformation, new Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, brightness, false); } } else if (sd is Bve4SignalData) { Bve4SignalData b4sd = (Bve4SignalData)sd; @@ -6064,7 +6170,7 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin } aoc.Objects[0].StateFunction = FunctionScripts.GetFunctionScriptFromPostfixNotation(expr); aoc.Objects[0].RefreshRate = 1.0 + 0.01 * Game.Generator.NextDouble(); - ObjectManager.CreateObject(aoc, wpos, RailTransformation, new World.Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); + ObjectManager.CreateObject(aoc, wpos, RailTransformation, new Transformation(Data.Blocks[i].Signal[k].Yaw, Data.Blocks[i].Signal[k].Pitch, Data.Blocks[i].Signal[k].Roll), Data.Blocks[i].Signal[k].Section, Data.AccurateObjectDisposal, StartingDistance, EndingDistance, Data.BlockInterval, tpos, 1.0, false); } } } @@ -6211,7 +6317,7 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin Position.Y += h; Position.Z += Direction.Y * c; if (a != 0.0) { - World.Rotate(ref Direction, Math.Cos(-a), Math.Sin(-a)); + Direction.Rotate(Math.Cos(-a), Math.Sin(-a)); } } // orphaned transponders @@ -6229,6 +6335,16 @@ private static void ApplyRouteData(string FileName, System.Text.Encoding Encodin Data.Blocks[i].Transponder[j].Type = TrackManager.TransponderType.None; } } + // Destination Change Events + for (int j = 0; j < Data.Blocks[i].DestinationChanges.Length; j++) + { + int n = i - Data.FirstUsedBlock; + int m = TrackManager.CurrentTrack.Elements[n].Events.Length; + Array.Resize(ref TrackManager.CurrentTrack.Elements[n].Events, m + 1); + double d = Data.Blocks[i].DestinationChanges[j].TrackPosition - TrackManager.CurrentTrack.Elements[n].StartingTrackPosition; + //Destination events not supported in Route Viewer..... + //TrackManager.CurrentTrack.Elements[n].Events[m] = new TrackManager.DestinationEvent(d, Data.Blocks[i].DestinationChanges[j].Type, Data.Blocks[i].DestinationChanges[j].NextDestination, Data.Blocks[i].DestinationChanges[j].PreviousDestination, Data.Blocks[i].DestinationChanges[j].TriggerOnce); + } } } // insert station end events diff --git a/source/RouteViewer/Parsers/WavefrontObjParser.cs b/source/RouteViewer/Parsers/WavefrontObjParser.cs index a6bc14aee..7f1a86e86 100644 --- a/source/RouteViewer/Parsers/WavefrontObjParser.cs +++ b/source/RouteViewer/Parsers/WavefrontObjParser.cs @@ -137,8 +137,6 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te { Interface.AddMessage(Interface.MessageType.Warning, false, "Invalid X co-ordinate in Texture Co-Ordinates at Line " + i); } - //Wavefront obj texture co-ords Y axis appear inverted v.s. BVE standard - coords.Y = -coords.Y; tempCoords.Add(coords); break; case "vn": @@ -218,6 +216,10 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te currentCoord++; currentCoord += idx; } + else + { + currentCoord = idx; + } if (currentCoord > tempCoords.Count) { Interface.AddMessage(Interface.MessageType.Warning, false, "Texture Co-ordinate index " + currentCoord + " was greater than the available number of texture co-ordinates in Face " + f + " at Line " + i); @@ -252,6 +254,10 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te currentNormal++; currentNormal += idx; } + else + { + currentNormal = idx; + } if (currentNormal > tempNormals.Count) { Interface.AddMessage(Interface.MessageType.Warning, false, "Vertex Normal index " + currentNormal + " was greater than the available number of normals in Face " + f + " at Line " + i); diff --git a/source/RouteViewer/Parsers/XObjectParser.cs b/source/RouteViewer/Parsers/XObjectParser.cs index 215ada7b4..93462d016 100644 --- a/source/RouteViewer/Parsers/XObjectParser.cs +++ b/source/RouteViewer/Parsers/XObjectParser.cs @@ -39,7 +39,7 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te return LoadTextualX(FileName, System.IO.File.ReadAllText(FileName), Encoding, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); } else if (Data[8] == 98 & Data[9] == 105 & Data[10] == 110 & Data[11] == 32) { // binary flavor - return LoadBinaryX(FileName, Data, 16, Encoding, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); + return LoadBinaryX(FileName, Data, 16, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); } else if (Data[8] == 116 & Data[9] == 122 & Data[10] == 105 & Data[11] == 112) { // compressed textual flavor #if !DEBUG @@ -60,7 +60,7 @@ internal static ObjectManager.StaticObject ReadObject(string FileName, System.Te try { #endif byte[] Uncompressed = Decompress(Data); - return LoadBinaryX(FileName, Uncompressed, 0, Encoding, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); + return LoadBinaryX(FileName, Uncompressed, 0, FloatingPointSize, LoadMode, ForceTextureRepeatX, ForceTextureRepeatY); #if !DEBUG } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Error, false, "An unexpected error occured (" + ex.Message + ") while attempting to decompress the binary X object file encountered in " + FileName); @@ -838,7 +838,7 @@ private static bool ReadTextualTemplate(string FileName, string Content, ref int // ================================ // load binary x - private static ObjectManager.StaticObject LoadBinaryX(string FileName, byte[] Data, int StartingPosition, System.Text.Encoding Encoding, int FloatingPointSize, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { + private static ObjectManager.StaticObject LoadBinaryX(string FileName, byte[] Data, int StartingPosition, int FloatingPointSize, ObjectManager.ObjectLoadMode LoadMode, bool ForceTextureRepeatX, bool ForceTextureRepeatY) { // parse file AlternateStructure = false; LoadedMaterials = new Structure[] {}; diff --git a/source/RouteViewer/TrackManagerR.cs b/source/RouteViewer/TrackManagerR.cs index 56d479957..912196c5b 100644 --- a/source/RouteViewer/TrackManagerR.cs +++ b/source/RouteViewer/TrackManagerR.cs @@ -285,6 +285,7 @@ internal override void Trigger(int Direction, EventTriggerType TriggerType, Trai // track element internal struct TrackElement { internal double StartingTrackPosition; + internal double Pitch; internal double CurveRadius; internal double CurveCant; internal double CurveCantTangent; @@ -297,6 +298,7 @@ internal struct TrackElement { internal GeneralEvent[] Events; internal TrackElement(double StartingTrackPosition) { this.StartingTrackPosition = StartingTrackPosition; + this.Pitch = 0.0; this.CurveRadius = 0.0; this.CurveCant = 0.0; this.CurveCantTangent = 0.0; @@ -326,6 +328,7 @@ internal struct TrackFollower { internal Vector3 WorldSide; internal double CurveRadius; internal double CurveCant; + internal double Pitch; internal double CantDueToInaccuracy; internal double AdhesionMultiplier; internal EventTriggerType TriggerType; @@ -452,6 +455,7 @@ internal static void UpdateTrackFollower(ref TrackFollower Follower, double NewT } } Follower.AdhesionMultiplier = CurrentTrack.Elements[i].AdhesionMultiplier; + Follower.Pitch = CurrentTrack.Elements[i].Pitch * 1000; // inaccuracy if (AddTrackInaccurary) { double x, y, c; diff --git a/source/RouteViewer/WorldR.cs b/source/RouteViewer/WorldR.cs index 1418b300f..2941fbce8 100644 --- a/source/RouteViewer/WorldR.cs +++ b/source/RouteViewer/WorldR.cs @@ -9,6 +9,7 @@ using OpenBveApi.Colors; using OpenBveApi.Math; using OpenBveApi.Objects; +using OpenBveApi.World; namespace OpenBve { public static class World { @@ -426,79 +427,6 @@ internal static void Cross(double ax, double ay, double az, double bx, double by cz = ax * by - ay * bx; } - // transformation - internal struct Transformation { - internal Vector3 X; - internal Vector3 Y; - internal Vector3 Z; - internal Transformation(double Yaw, double Pitch, double Roll) { - if (Yaw == 0.0 & Pitch == 0.0 & Roll == 0.0) { - this.X = new Vector3(1.0, 0.0, 0.0); - this.Y = new Vector3(0.0, 1.0, 0.0); - this.Z = new Vector3(0.0, 0.0, 1.0); - } else if (Pitch == 0.0 & Roll == 0.0) { - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - this.X = new Vector3(cosYaw, 0.0, -sinYaw); - this.Y = new Vector3(0.0, 1.0, 0.0); - this.Z = new Vector3(sinYaw, 0.0, cosYaw); - } else { - double sx = 1.0, sy = 0.0, sz = 0.0; - double ux = 0.0, uy = 1.0, uz = 0.0; - double dx = 0.0, dy = 0.0, dz = 1.0; - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - double cosPitch = Math.Cos(-Pitch); - double sinPitch = Math.Sin(-Pitch); - double cosRoll = Math.Cos(-Roll); - double sinRoll = Math.Sin(-Roll); - Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosRoll, sinRoll); - Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosRoll, sinRoll); - this.X = new Vector3(sx, sy, sz); - this.Y = new Vector3(ux, uy, uz); - this.Z = new Vector3(dx, dy, dz); - } - } - internal Transformation(Transformation Transformation, double Yaw, double Pitch, double Roll) { - double sx = Transformation.X.X, sy = Transformation.X.Y, sz = Transformation.X.Z; - double ux = Transformation.Y.X, uy = Transformation.Y.Y, uz = Transformation.Y.Z; - double dx = Transformation.Z.X, dy = Transformation.Z.Y, dz = Transformation.Z.Z; - double cosYaw = Math.Cos(Yaw); - double sinYaw = Math.Sin(Yaw); - double cosPitch = Math.Cos(-Pitch); - double sinPitch = Math.Sin(-Pitch); - double cosRoll = Math.Cos(Roll); - double sinRoll = Math.Sin(Roll); - Rotate(ref sx, ref sy, ref sz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref dx, ref dy, ref dz, ux, uy, uz, cosYaw, sinYaw); - Rotate(ref ux, ref uy, ref uz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref dx, ref dy, ref dz, sx, sy, sz, cosPitch, sinPitch); - Rotate(ref sx, ref sy, ref sz, dx, dy, dz, cosRoll, sinRoll); - Rotate(ref ux, ref uy, ref uz, dx, dy, dz, cosRoll, sinRoll); - this.X = new Vector3(sx, sy, sz); - this.Y = new Vector3(ux, uy, uz); - this.Z = new Vector3(dx, dy, dz); - } - internal Transformation(Transformation BaseTransformation, Transformation AuxTransformation) { - Vector3 x = BaseTransformation.X; - Vector3 y = BaseTransformation.Y; - Vector3 z = BaseTransformation.Z; - Vector3 s = AuxTransformation.X; - Vector3 u = AuxTransformation.Y; - Vector3 d = AuxTransformation.Z; - Rotate(ref x.X, ref x.Y, ref x.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - Rotate(ref y.X, ref y.Y, ref y.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - Rotate(ref z.X, ref z.Y, ref z.Z, d.X, d.Y, d.Z, u.X, u.Y, u.Z, s.X, s.Y, s.Z); - this.X = x; - this.Y = y; - this.Z = z; - } - } - // rotate internal static void Rotate(ref double px, ref double py, ref double pz, double dx, double dy, double dz, double cosa, double sina) { double t = 1.0 / Math.Sqrt(dx * dx + dy * dy + dz * dz); @@ -518,19 +446,7 @@ internal static void Rotate(ref float px, ref float py, ref float pz, double dx, double z = (cosa + oc * dz * dz) * (double)pz + (oc * dx * dz - sina * dy) * (double)px + (oc * dy * dz + sina * dx) * (double)py; px = (float)x; py = (float)y; pz = (float)z; } - internal static void Rotate(ref Vector2 Vector, double cosa, double sina) { - double u = Vector.X * cosa - Vector.Y * sina; - double v = Vector.X * sina + Vector.Y * cosa; - Vector.X = u; - Vector.Y = v; - } - internal static void Rotate(ref float px, ref float py, ref float pz, double dx, double dy, double dz, double ux, double uy, double uz, double sx, double sy, double sz) { - double x, y, z; - x = sx * (double)px + ux * (double)py + dx * (double)pz; - y = sy * (double)px + uy * (double)py + dy * (double)pz; - z = sz * (double)px + uz * (double)py + dz * (double)pz; - px = (float)x; py = (float)y; pz = (float)z; - } + internal static void Rotate(ref double px, ref double py, ref double pz, double dx, double dy, double dz, double ux, double uy, double uz, double sx, double sy, double sz) { double x, y, z; x = sx * px + ux * py + dx * pz; @@ -538,13 +454,7 @@ internal static void Rotate(ref double px, ref double py, ref double pz, double z = sz * px + uz * py + dz * pz; px = x; py = y; pz = z; } - internal static void Rotate(ref float px, ref float py, ref float pz, Transformation t) { - double x, y, z; - x = t.X.X * (double)px + t.Y.X * (double)py + t.Z.X * (double)pz; - y = t.X.Y * (double)px + t.Y.Y * (double)py + t.Z.Y * (double)pz; - z = t.X.Z * (double)px + t.Y.Z * (double)py + t.Z.Z * (double)pz; - px = (float)x; py = (float)y; pz = (float)z; - } + internal static void Rotate(ref double px, ref double py, ref double pz, Transformation t) { double x, y, z; x = t.X.X * px + t.Y.X * py + t.Z.X * pz; @@ -559,33 +469,6 @@ internal static void RotatePlane(ref Vector3 Vector, double cosa, double sina) { Vector.Z = v; } - internal static void RotateUpDown(ref Vector3 Vector, Vector2 Direction, double cosa, double sina) { - double dx = Direction.X, dy = Direction.Y; - double x = Vector.X, y = Vector.Y, z = Vector.Z; - double u = dy * x - dx * z; - double v = dx * x + dy * z; - Vector.X = dy * u + dx * v * cosa - dx * y * sina; - Vector.Y = y * cosa + v * sina; - Vector.Z = -dx * u + dy * v * cosa - dy * y * sina; - } - internal static void RotateUpDown(ref Vector3 Vector, double dx, double dy, double cosa, double sina) { - double x = Vector.X, y = Vector.Y, z = Vector.Z; - double u = dy * x - dx * z; - double v = dx * x + dy * z; - Vector.X = dy * u + dx * v * cosa - dx * y * sina; - Vector.Y = y * cosa + v * sina; - Vector.Z = -dx * u + dy * v * cosa - dy * y * sina; - } - - internal static void RotateUpDown(ref double px, ref double py, ref double pz, double dx, double dz, double cosa, double sina) { - double x = px, y = py, z = pz; - double u = dz * x - dx * z; - double v = dx * x + dz * z; - px = dz * u + dx * v * cosa - dx * y * sina; - py = y * cosa + v * sina; - pz = -dx * u + dz * v * cosa - dz * y * sina; - } - // normalize internal static void Normalize(ref double x, ref double y) { double t = x * x + y * y; diff --git a/source/TrainEditor/TrainDat.cs b/source/TrainEditor/TrainDat.cs index c4a8f2563..a46e25c1d 100644 --- a/source/TrainEditor/TrainDat.cs +++ b/source/TrainEditor/TrainDat.cs @@ -92,16 +92,23 @@ internal enum BrakeTypes { ElectricCommandBrake = 1, AutomaticAirBrake = 2 } + internal enum LocoBrakeTypes { + NotFitted = 0, + NotchedAirBrake = 1, + AutomaticAirBrake = 2 + } internal enum BrakeControlSystems { None = 0, ClosingElectromagneticValve = 1, DelayIncludingSystem = 2 } internal BrakeTypes BrakeType; + internal LocoBrakeTypes LocoBrakeType; internal BrakeControlSystems BrakeControlSystem; internal double BrakeControlSpeed; internal Brake() { this.BrakeType = BrakeTypes.ElectromagneticStraightAirBrake; + this.LocoBrakeType = LocoBrakeTypes.NotFitted; this.BrakeControlSystem = BrakeControlSystems.None; this.BrakeControlSpeed = 0.0; } @@ -357,7 +364,7 @@ internal static Train Load(string FileName) { { string tt = s.Substring(7, s.Length - 7); int v; - if (int.TryParse(tt, out v)) + if (int.TryParse(tt, System.Globalization.NumberStyles.Float, Culture, out v)) { if (v > currentVersion) { @@ -477,22 +484,22 @@ internal static Train Load(string FileName) { switch (n) { case 0: - t.Delay.DelayPowerUp = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + t.Delay.DelayPowerUp = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); break; case 1: - t.Delay.DelayPowerDown = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + t.Delay.DelayPowerDown = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); break; case 2: - t.Delay.DelayBrakeUp = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + t.Delay.DelayBrakeUp = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); break; case 3: - t.Delay.DelayBrakeDown = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + t.Delay.DelayBrakeDown = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); break; case 4: - t.Delay.DelayLocoBrakeUp = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + t.Delay.DelayLocoBrakeUp = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); break; case 5: - t.Delay.DelayLocoBrakeDown = Lines[i].Split(',').Select(Convert.ToDouble).ToArray(); + t.Delay.DelayLocoBrakeDown = Lines[i].Split(',').Select(x => Double.Parse(x, Culture)).ToArray(); break; } } @@ -537,6 +544,9 @@ internal static Train Load(string FileName) { case 2: if (a >= 0.0) t.Brake.BrakeControlSpeed = a; break; + case 3: + if (a <= 0 && a > 3) t.Brake.LocoBrakeType = (Brake.LocoBrakeTypes) b; + break; } } i++; n++; } i--; break; @@ -580,7 +590,7 @@ internal static Train Load(string FileName) { if (b >= 0) t.Handle.PowerNotchReduceSteps = b; break; case 4: - if (a <= 0 && a > 4) t.Handle.HandleBehaviour = (Handle.EbHandleBehaviour) b; + if (a >= 0 && a < 4) t.Handle.HandleBehaviour = (Handle.EbHandleBehaviour) b; break; case 5: if (b > 0) t.Handle.LocoBrakeNotches = b; @@ -836,6 +846,7 @@ internal static void Save(string FileName, Train t) { b.AppendLine(((int)t.Brake.BrakeType).ToString(Culture).PadRight(n, ' ') + "; BrakeType"); b.AppendLine(((int)t.Brake.BrakeControlSystem).ToString(Culture).PadRight(n, ' ') + "; BrakeControlSystem"); b.AppendLine(t.Brake.BrakeControlSpeed.ToString(Culture).PadRight(n, ' ') + "; BrakeControlSpeed"); + b.AppendLine(((int)t.Brake.LocoBrakeType).ToString(Culture).PadRight(n, ' ') + "; LocoBrakeType (1.5.3.4+)"); b.AppendLine("#PRESSURE"); b.AppendLine(t.Pressure.BrakeCylinderServiceMaximumPressure.ToString(Culture).PadRight(n, ' ') + "; BrakeCylinderServiceMaximumPressure"); b.AppendLine(t.Pressure.BrakeCylinderEmergencyMaximumPressure.ToString(Culture).PadRight(n, ' ') + "; BrakeCylinderEmergencyMaximumPressure"); diff --git a/source/TrainEditor/formEditor.Designer.cs b/source/TrainEditor/formEditor.Designer.cs index 0fb17b787..e6d288bb5 100644 --- a/source/TrainEditor/formEditor.Designer.cs +++ b/source/TrainEditor/formEditor.Designer.cs @@ -98,9 +98,6 @@ private void InitializeComponent() { this.textboxDeceleration = new System.Windows.Forms.TextBox(); this.labelDeceleration = new System.Windows.Forms.Label(); this.tabpagePropertiesTwo = new System.Windows.Forms.TabPage(); - this.groupBoxOther = new System.Windows.Forms.GroupBox(); - this.comboBoxHandleBehaviour = new System.Windows.Forms.ComboBox(); - this.label1 = new System.Windows.Forms.Label(); this.groupboxCar = new System.Windows.Forms.GroupBox(); this.labelCenterOfGravityHeightUnit = new System.Windows.Forms.Label(); this.textboxCenterOfGravityHeight = new System.Windows.Forms.TextBox(); @@ -219,6 +216,23 @@ private void InitializeComponent() { this.splitMotorB = new System.Windows.Forms.SplitContainer(); this.pictureboxMotorB1 = new System.Windows.Forms.PictureBox(); this.pictureboxMotorB2 = new System.Windows.Forms.PictureBox(); + this.tabPageExtended = new System.Windows.Forms.TabPage(); + this.groupBoxMisc = new System.Windows.Forms.GroupBox(); + this.comboBoxEBHandleBehaviour = new System.Windows.Forms.ComboBox(); + this.labelEBHandleBehaviour = new System.Windows.Forms.Label(); + this.groupBoxLocoBrake = new System.Windows.Forms.GroupBox(); + this.comboBoxLocoBrakeSystemType = new System.Windows.Forms.ComboBox(); + this.labelLocoBrakeSystemType = new System.Windows.Forms.Label(); + this.comboBoxLocoBrakeType = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.buttonLocoBrakeDelayDown = new System.Windows.Forms.Button(); + this.labelLocoBrakeDelayDown = new System.Windows.Forms.Label(); + this.buttonLocoBrakeDelayUp = new System.Windows.Forms.Button(); + this.labelLocoBrakeDelayUp = new System.Windows.Forms.Label(); + this.numericUpDownLocoBrakeNotches = new System.Windows.Forms.NumericUpDown(); + this.labelLocoBrakeNotches = new System.Windows.Forms.Label(); + this.labelMinVersion = new System.Windows.Forms.Label(); + this.labelExtendedNote = new System.Windows.Forms.Label(); this.panelPane = new System.Windows.Forms.Panel(); this.labelLineHorizontal = new System.Windows.Forms.Label(); this.buttonClose = new System.Windows.Forms.Button(); @@ -228,21 +242,6 @@ private void InitializeComponent() { this.buttonNew = new System.Windows.Forms.Button(); this.pictureboxLogo = new System.Windows.Forms.PictureBox(); this.labelLineVertical = new System.Windows.Forms.Label(); - this.tabPageExtended = new System.Windows.Forms.TabPage(); - this.labelExtendedNote = new System.Windows.Forms.Label(); - this.labelMinVersion = new System.Windows.Forms.Label(); - this.groupBoxLocoBrake = new System.Windows.Forms.GroupBox(); - this.labelLocoBrakeNotches = new System.Windows.Forms.Label(); - this.numericUpDownLocoBrakeNotches = new System.Windows.Forms.NumericUpDown(); - this.labelLocoBrakeDelayUp = new System.Windows.Forms.Label(); - this.buttonLocoBrakeDelayUp = new System.Windows.Forms.Button(); - this.buttonLocoBrakeDelayDown = new System.Windows.Forms.Button(); - this.labelLocoBrakeDelayDown = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.comboBoxLocoBrakeType = new System.Windows.Forms.ComboBox(); - this.groupBoxMisc = new System.Windows.Forms.GroupBox(); - this.labelEBHandleBehaviour = new System.Windows.Forms.Label(); - this.comboBoxEBHandleBehaviour = new System.Windows.Forms.ComboBox(); this.tabcontrolTabs.SuspendLayout(); this.tabpagePropertiesOne.SuspendLayout(); this.groupboxPressure.SuspendLayout(); @@ -254,7 +253,6 @@ private void InitializeComponent() { this.groupboxBrake.SuspendLayout(); this.groupboxPerformance.SuspendLayout(); this.tabpagePropertiesTwo.SuspendLayout(); - this.groupBoxOther.SuspendLayout(); this.groupboxCar.SuspendLayout(); this.groupboxCab.SuspendLayout(); this.groupboxDevice.SuspendLayout(); @@ -281,12 +279,12 @@ private void InitializeComponent() { this.splitMotorB.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.pictureboxMotorB1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureboxMotorB2)).BeginInit(); - this.panelPane.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.pictureboxLogo)).BeginInit(); this.tabPageExtended.SuspendLayout(); + this.groupBoxMisc.SuspendLayout(); this.groupBoxLocoBrake.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDownLocoBrakeNotches)).BeginInit(); - this.groupBoxMisc.SuspendLayout(); + this.panelPane.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureboxLogo)).BeginInit(); this.SuspendLayout(); // // tabcontrolTabs @@ -1091,7 +1089,6 @@ private void InitializeComponent() { // // tabpagePropertiesTwo // - this.tabpagePropertiesTwo.Controls.Add(this.groupBoxOther); this.tabpagePropertiesTwo.Controls.Add(this.groupboxCar); this.tabpagePropertiesTwo.Controls.Add(this.groupboxCab); this.tabpagePropertiesTwo.Controls.Add(this.groupboxDevice); @@ -1103,38 +1100,6 @@ private void InitializeComponent() { this.tabpagePropertiesTwo.Text = "Properties (2)"; this.tabpagePropertiesTwo.UseVisualStyleBackColor = true; // - // groupBoxOther - // - this.groupBoxOther.Controls.Add(this.comboBoxHandleBehaviour); - this.groupBoxOther.Controls.Add(this.label1); - this.groupBoxOther.Location = new System.Drawing.Point(296, 257); - this.groupBoxOther.Name = "groupBoxOther"; - this.groupBoxOther.Size = new System.Drawing.Size(347, 166); - this.groupBoxOther.TabIndex = 3; - this.groupBoxOther.TabStop = false; - this.groupBoxOther.Text = "Other"; - // - // comboBoxHandleBehaviour - // - this.comboBoxHandleBehaviour.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.comboBoxHandleBehaviour.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxHandleBehaviour.FormattingEnabled = true; - this.comboBoxHandleBehaviour.Location = new System.Drawing.Point(168, 19); - this.comboBoxHandleBehaviour.Name = "comboBoxHandleBehaviour"; - this.comboBoxHandleBehaviour.Size = new System.Drawing.Size(160, 21); - this.comboBoxHandleBehaviour.TabIndex = 13; - // - // label1 - // - this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.label1.Location = new System.Drawing.Point(8, 19); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(160, 16); - this.label1.TabIndex = 12; - this.label1.Text = "EbHandlesBehaviour:"; - this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - // // groupboxCar // this.groupboxCar.Controls.Add(this.labelCenterOfGravityHeightUnit); @@ -2478,6 +2443,196 @@ private void InitializeComponent() { this.pictureboxMotorB2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PictureboxMotorB2MouseDown); this.pictureboxMotorB2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureboxMotorB2MouseMove); this.pictureboxMotorB2.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PictureboxMotorB2MouseUp); + // + // tabPageExtended + // + this.tabPageExtended.Controls.Add(this.groupBoxMisc); + this.tabPageExtended.Controls.Add(this.groupBoxLocoBrake); + this.tabPageExtended.Controls.Add(this.labelMinVersion); + this.tabPageExtended.Controls.Add(this.labelExtendedNote); + this.tabPageExtended.Location = new System.Drawing.Point(4, 22); + this.tabPageExtended.Name = "tabPageExtended"; + this.tabPageExtended.Padding = new System.Windows.Forms.Padding(3); + this.tabPageExtended.Size = new System.Drawing.Size(640, 438); + this.tabPageExtended.TabIndex = 4; + this.tabPageExtended.Text = "Extended Features"; + this.tabPageExtended.UseVisualStyleBackColor = true; + // + // groupBoxMisc + // + this.groupBoxMisc.Controls.Add(this.comboBoxEBHandleBehaviour); + this.groupBoxMisc.Controls.Add(this.labelEBHandleBehaviour); + this.groupBoxMisc.Location = new System.Drawing.Point(295, 58); + this.groupBoxMisc.Name = "groupBoxMisc"; + this.groupBoxMisc.Size = new System.Drawing.Size(339, 131); + this.groupBoxMisc.TabIndex = 3; + this.groupBoxMisc.TabStop = false; + this.groupBoxMisc.Text = "Miscellaneous Features"; + // + // comboBoxEBHandleBehaviour + // + this.comboBoxEBHandleBehaviour.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxEBHandleBehaviour.FormattingEnabled = true; + this.comboBoxEBHandleBehaviour.Location = new System.Drawing.Point(139, 17); + this.comboBoxEBHandleBehaviour.Name = "comboBoxEBHandleBehaviour"; + this.comboBoxEBHandleBehaviour.Size = new System.Drawing.Size(194, 21); + this.comboBoxEBHandleBehaviour.TabIndex = 8; + this.comboBoxEBHandleBehaviour.SelectedIndexChanged += new System.EventHandler(this.comboBoxEBHandleBehaviour_SelectedIndexChanged); + // + // labelEBHandleBehaviour + // + this.labelEBHandleBehaviour.AutoSize = true; + this.labelEBHandleBehaviour.Location = new System.Drawing.Point(7, 20); + this.labelEBHandleBehaviour.Name = "labelEBHandleBehaviour"; + this.labelEBHandleBehaviour.Size = new System.Drawing.Size(126, 13); + this.labelEBHandleBehaviour.TabIndex = 0; + this.labelEBHandleBehaviour.Text = "Handle behaviour on EB:"; + // + // groupBoxLocoBrake + // + this.groupBoxLocoBrake.Controls.Add(this.comboBoxLocoBrakeSystemType); + this.groupBoxLocoBrake.Controls.Add(this.labelLocoBrakeSystemType); + this.groupBoxLocoBrake.Controls.Add(this.comboBoxLocoBrakeType); + this.groupBoxLocoBrake.Controls.Add(this.label2); + this.groupBoxLocoBrake.Controls.Add(this.buttonLocoBrakeDelayDown); + this.groupBoxLocoBrake.Controls.Add(this.labelLocoBrakeDelayDown); + this.groupBoxLocoBrake.Controls.Add(this.buttonLocoBrakeDelayUp); + this.groupBoxLocoBrake.Controls.Add(this.labelLocoBrakeDelayUp); + this.groupBoxLocoBrake.Controls.Add(this.numericUpDownLocoBrakeNotches); + this.groupBoxLocoBrake.Controls.Add(this.labelLocoBrakeNotches); + this.groupBoxLocoBrake.Location = new System.Drawing.Point(8, 55); + this.groupBoxLocoBrake.Name = "groupBoxLocoBrake"; + this.groupBoxLocoBrake.Size = new System.Drawing.Size(280, 190); + this.groupBoxLocoBrake.TabIndex = 2; + this.groupBoxLocoBrake.TabStop = false; + this.groupBoxLocoBrake.Text = "Locomotive Brake"; + // + // comboBoxLocoBrakeSystemType + // + this.comboBoxLocoBrakeSystemType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.comboBoxLocoBrakeSystemType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxLocoBrakeSystemType.FormattingEnabled = true; + this.comboBoxLocoBrakeSystemType.Location = new System.Drawing.Point(6, 32); + this.comboBoxLocoBrakeSystemType.Name = "comboBoxLocoBrakeSystemType"; + this.comboBoxLocoBrakeSystemType.Size = new System.Drawing.Size(268, 21); + this.comboBoxLocoBrakeSystemType.TabIndex = 9; + this.comboBoxLocoBrakeSystemType.SelectedIndexChanged += new System.EventHandler(this.comboBoxLocoBrakeSystemType_SelectedIndexChanged); + // + // labelLocoBrakeSystemType + // + this.labelLocoBrakeSystemType.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.labelLocoBrakeSystemType.Location = new System.Drawing.Point(6, 16); + this.labelLocoBrakeSystemType.Name = "labelLocoBrakeSystemType"; + this.labelLocoBrakeSystemType.Size = new System.Drawing.Size(268, 16); + this.labelLocoBrakeSystemType.TabIndex = 8; + this.labelLocoBrakeSystemType.Text = "BrakeType:"; + this.labelLocoBrakeSystemType.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // comboBoxLocoBrakeType + // + this.comboBoxLocoBrakeType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBoxLocoBrakeType.FormattingEnabled = true; + this.comboBoxLocoBrakeType.Items.AddRange(new object[] { + "Combined", + "Independant", + "Blocking"}); + this.comboBoxLocoBrakeType.Location = new System.Drawing.Point(156, 148); + this.comboBoxLocoBrakeType.Name = "comboBoxLocoBrakeType"; + this.comboBoxLocoBrakeType.Size = new System.Drawing.Size(118, 21); + this.comboBoxLocoBrakeType.TabIndex = 7; + this.comboBoxLocoBrakeType.SelectedIndexChanged += new System.EventHandler(this.comboBoxLocoBrakeType_SelectedIndexChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(6, 151); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(34, 13); + this.label2.TabIndex = 6; + this.label2.Text = "Type:"; + // + // buttonLocoBrakeDelayDown + // + this.buttonLocoBrakeDelayDown.Location = new System.Drawing.Point(156, 117); + this.buttonLocoBrakeDelayDown.Name = "buttonLocoBrakeDelayDown"; + this.buttonLocoBrakeDelayDown.Size = new System.Drawing.Size(118, 25); + this.buttonLocoBrakeDelayDown.TabIndex = 5; + this.buttonLocoBrakeDelayDown.Text = "Set"; + this.buttonLocoBrakeDelayDown.UseVisualStyleBackColor = true; + this.buttonLocoBrakeDelayDown.Click += new System.EventHandler(this.buttonLocoBrakeDelayDown_Click); + // + // labelLocoBrakeDelayDown + // + this.labelLocoBrakeDelayDown.AutoSize = true; + this.labelLocoBrakeDelayDown.Location = new System.Drawing.Point(6, 125); + this.labelLocoBrakeDelayDown.Name = "labelLocoBrakeDelayDown"; + this.labelLocoBrakeDelayDown.Size = new System.Drawing.Size(65, 13); + this.labelLocoBrakeDelayDown.TabIndex = 4; + this.labelLocoBrakeDelayDown.Text = "DelayDown:"; + // + // buttonLocoBrakeDelayUp + // + this.buttonLocoBrakeDelayUp.Location = new System.Drawing.Point(156, 91); + this.buttonLocoBrakeDelayUp.Name = "buttonLocoBrakeDelayUp"; + this.buttonLocoBrakeDelayUp.Size = new System.Drawing.Size(118, 25); + this.buttonLocoBrakeDelayUp.TabIndex = 3; + this.buttonLocoBrakeDelayUp.Text = "Set"; + this.buttonLocoBrakeDelayUp.UseVisualStyleBackColor = true; + this.buttonLocoBrakeDelayUp.Click += new System.EventHandler(this.buttonLocoBrakeDelayUp_Click); + // + // labelLocoBrakeDelayUp + // + this.labelLocoBrakeDelayUp.AutoSize = true; + this.labelLocoBrakeDelayUp.Location = new System.Drawing.Point(6, 98); + this.labelLocoBrakeDelayUp.Name = "labelLocoBrakeDelayUp"; + this.labelLocoBrakeDelayUp.Size = new System.Drawing.Size(51, 13); + this.labelLocoBrakeDelayUp.TabIndex = 2; + this.labelLocoBrakeDelayUp.Text = "DelayUp:"; + // + // numericUpDownLocoBrakeNotches + // + this.numericUpDownLocoBrakeNotches.Location = new System.Drawing.Point(156, 65); + this.numericUpDownLocoBrakeNotches.Maximum = new decimal(new int[] { + 20, + 0, + 0, + 0}); + this.numericUpDownLocoBrakeNotches.Name = "numericUpDownLocoBrakeNotches"; + this.numericUpDownLocoBrakeNotches.Size = new System.Drawing.Size(118, 20); + this.numericUpDownLocoBrakeNotches.TabIndex = 1; + // + // labelLocoBrakeNotches + // + this.labelLocoBrakeNotches.AutoSize = true; + this.labelLocoBrakeNotches.Location = new System.Drawing.Point(6, 67); + this.labelLocoBrakeNotches.Name = "labelLocoBrakeNotches"; + this.labelLocoBrakeNotches.Size = new System.Drawing.Size(50, 13); + this.labelLocoBrakeNotches.TabIndex = 0; + this.labelLocoBrakeNotches.Text = "Notches:"; + // + // labelMinVersion + // + this.labelMinVersion.AutoSize = true; + this.labelMinVersion.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelMinVersion.Location = new System.Drawing.Point(6, 35); + this.labelMinVersion.Name = "labelMinVersion"; + this.labelMinVersion.Size = new System.Drawing.Size(52, 16); + this.labelMinVersion.TabIndex = 1; + this.labelMinVersion.Text = "v1.5.3.4"; + // + // labelExtendedNote + // + this.labelExtendedNote.AutoSize = true; + this.labelExtendedNote.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.labelExtendedNote.Location = new System.Drawing.Point(6, 3); + this.labelExtendedNote.MaximumSize = new System.Drawing.Size(640, 0); + this.labelExtendedNote.Name = "labelExtendedNote"; + this.labelExtendedNote.Size = new System.Drawing.Size(607, 32); + this.labelExtendedNote.TabIndex = 0; + this.labelExtendedNote.Text = "Please note: Features found on this page may require the following minimum versio" + + "n of openBVE:"; // // panelPane // @@ -2584,176 +2739,6 @@ private void InitializeComponent() { this.labelLineVertical.Size = new System.Drawing.Size(2, 480); this.labelLineVertical.TabIndex = 13; // - // tabPageExtended - // - this.tabPageExtended.Controls.Add(this.groupBoxMisc); - this.tabPageExtended.Controls.Add(this.groupBoxLocoBrake); - this.tabPageExtended.Controls.Add(this.labelMinVersion); - this.tabPageExtended.Controls.Add(this.labelExtendedNote); - this.tabPageExtended.Location = new System.Drawing.Point(4, 22); - this.tabPageExtended.Name = "tabPageExtended"; - this.tabPageExtended.Padding = new System.Windows.Forms.Padding(3); - this.tabPageExtended.Size = new System.Drawing.Size(640, 438); - this.tabPageExtended.TabIndex = 4; - this.tabPageExtended.Text = "Extended Features"; - this.tabPageExtended.UseVisualStyleBackColor = true; - // - // labelExtendedNote - // - this.labelExtendedNote.AutoSize = true; - this.labelExtendedNote.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelExtendedNote.Location = new System.Drawing.Point(6, 3); - this.labelExtendedNote.MaximumSize = new System.Drawing.Size(640, 0); - this.labelExtendedNote.Name = "labelExtendedNote"; - this.labelExtendedNote.Size = new System.Drawing.Size(607, 32); - this.labelExtendedNote.TabIndex = 0; - this.labelExtendedNote.Text = "Please note: Features found on this page may require the following minimum versio" + - "n of openBVE:"; - // - // labelMinVersion - // - this.labelMinVersion.AutoSize = true; - this.labelMinVersion.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.labelMinVersion.Location = new System.Drawing.Point(6, 35); - this.labelMinVersion.Name = "labelMinVersion"; - this.labelMinVersion.Size = new System.Drawing.Size(52, 16); - this.labelMinVersion.TabIndex = 1; - this.labelMinVersion.Text = "v1.5.3.4"; - // - // groupBoxLocoBrake - // - this.groupBoxLocoBrake.Controls.Add(this.comboBoxLocoBrakeType); - this.groupBoxLocoBrake.Controls.Add(this.label2); - this.groupBoxLocoBrake.Controls.Add(this.buttonLocoBrakeDelayDown); - this.groupBoxLocoBrake.Controls.Add(this.labelLocoBrakeDelayDown); - this.groupBoxLocoBrake.Controls.Add(this.buttonLocoBrakeDelayUp); - this.groupBoxLocoBrake.Controls.Add(this.labelLocoBrakeDelayUp); - this.groupBoxLocoBrake.Controls.Add(this.numericUpDownLocoBrakeNotches); - this.groupBoxLocoBrake.Controls.Add(this.labelLocoBrakeNotches); - this.groupBoxLocoBrake.Location = new System.Drawing.Point(8, 55); - this.groupBoxLocoBrake.Name = "groupBoxLocoBrake"; - this.groupBoxLocoBrake.Size = new System.Drawing.Size(280, 134); - this.groupBoxLocoBrake.TabIndex = 2; - this.groupBoxLocoBrake.TabStop = false; - this.groupBoxLocoBrake.Text = "Locomotive Brake"; - // - // labelLocoBrakeNotches - // - this.labelLocoBrakeNotches.AutoSize = true; - this.labelLocoBrakeNotches.Location = new System.Drawing.Point(6, 15); - this.labelLocoBrakeNotches.Name = "labelLocoBrakeNotches"; - this.labelLocoBrakeNotches.Size = new System.Drawing.Size(50, 13); - this.labelLocoBrakeNotches.TabIndex = 0; - this.labelLocoBrakeNotches.Text = "Notches:"; - // - // numericUpDownLocoBrakeNotches - // - this.numericUpDownLocoBrakeNotches.Location = new System.Drawing.Point(156, 13); - this.numericUpDownLocoBrakeNotches.Maximum = new decimal(new int[] { - 20, - 0, - 0, - 0}); - this.numericUpDownLocoBrakeNotches.Name = "numericUpDownLocoBrakeNotches"; - this.numericUpDownLocoBrakeNotches.Size = new System.Drawing.Size(118, 20); - this.numericUpDownLocoBrakeNotches.TabIndex = 1; - // - // labelLocoBrakeDelayUp - // - this.labelLocoBrakeDelayUp.AutoSize = true; - this.labelLocoBrakeDelayUp.Location = new System.Drawing.Point(6, 46); - this.labelLocoBrakeDelayUp.Name = "labelLocoBrakeDelayUp"; - this.labelLocoBrakeDelayUp.Size = new System.Drawing.Size(51, 13); - this.labelLocoBrakeDelayUp.TabIndex = 2; - this.labelLocoBrakeDelayUp.Text = "DelayUp:"; - // - // buttonLocoBrakeDelayUp - // - this.buttonLocoBrakeDelayUp.Location = new System.Drawing.Point(156, 41); - this.buttonLocoBrakeDelayUp.Name = "buttonLocoBrakeDelayUp"; - this.buttonLocoBrakeDelayUp.Size = new System.Drawing.Size(118, 23); - this.buttonLocoBrakeDelayUp.TabIndex = 3; - this.buttonLocoBrakeDelayUp.Text = "Set"; - this.buttonLocoBrakeDelayUp.UseVisualStyleBackColor = true; - this.buttonLocoBrakeDelayUp.Click += new System.EventHandler(this.buttonLocoBrakeDelayUp_Click); - // - // buttonLocoBrakeDelayDown - // - this.buttonLocoBrakeDelayDown.Location = new System.Drawing.Point(156, 67); - this.buttonLocoBrakeDelayDown.Name = "buttonLocoBrakeDelayDown"; - this.buttonLocoBrakeDelayDown.Size = new System.Drawing.Size(118, 23); - this.buttonLocoBrakeDelayDown.TabIndex = 5; - this.buttonLocoBrakeDelayDown.Text = "Set"; - this.buttonLocoBrakeDelayDown.UseVisualStyleBackColor = true; - this.buttonLocoBrakeDelayDown.Click += new System.EventHandler(this.buttonLocoBrakeDelayDown_Click); - // - // labelLocoBrakeDelayDown - // - this.labelLocoBrakeDelayDown.AutoSize = true; - this.labelLocoBrakeDelayDown.Location = new System.Drawing.Point(6, 73); - this.labelLocoBrakeDelayDown.Name = "labelLocoBrakeDelayDown"; - this.labelLocoBrakeDelayDown.Size = new System.Drawing.Size(65, 13); - this.labelLocoBrakeDelayDown.TabIndex = 4; - this.labelLocoBrakeDelayDown.Text = "DelayDown:"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(6, 99); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(34, 13); - this.label2.TabIndex = 6; - this.label2.Text = "Type:"; - // - // comboBoxLocoBrakeType - // - this.comboBoxLocoBrakeType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxLocoBrakeType.FormattingEnabled = true; - this.comboBoxLocoBrakeType.Items.AddRange(new object[] { - "Combined", - "Independant", - "Blocking"}); - this.comboBoxLocoBrakeType.Location = new System.Drawing.Point(156, 96); - this.comboBoxLocoBrakeType.Name = "comboBoxLocoBrakeType"; - this.comboBoxLocoBrakeType.Size = new System.Drawing.Size(118, 21); - this.comboBoxLocoBrakeType.TabIndex = 7; - this.comboBoxLocoBrakeType.SelectedIndexChanged += new System.EventHandler(this.comboBoxLocoBrakeType_SelectedIndexChanged); - // - // groupBoxMisc - // - this.groupBoxMisc.Controls.Add(this.comboBoxEBHandleBehaviour); - this.groupBoxMisc.Controls.Add(this.labelEBHandleBehaviour); - this.groupBoxMisc.Location = new System.Drawing.Point(295, 58); - this.groupBoxMisc.Name = "groupBoxMisc"; - this.groupBoxMisc.Size = new System.Drawing.Size(339, 131); - this.groupBoxMisc.TabIndex = 3; - this.groupBoxMisc.TabStop = false; - this.groupBoxMisc.Text = "Miscellaneous Features"; - // - // labelEBHandleBehaviour - // - this.labelEBHandleBehaviour.AutoSize = true; - this.labelEBHandleBehaviour.Location = new System.Drawing.Point(7, 20); - this.labelEBHandleBehaviour.Name = "labelEBHandleBehaviour"; - this.labelEBHandleBehaviour.Size = new System.Drawing.Size(126, 13); - this.labelEBHandleBehaviour.TabIndex = 0; - this.labelEBHandleBehaviour.Text = "Handle behaviour on EB:"; - // - // comboBoxEBHandleBehaviour - // - this.comboBoxEBHandleBehaviour.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxEBHandleBehaviour.FormattingEnabled = true; - this.comboBoxEBHandleBehaviour.Items.AddRange(new object[] { - "No Action", - "Power to Neutral", - "Reverser to Neutral", - "Power and Reverser to Neutral"}); - this.comboBoxEBHandleBehaviour.Location = new System.Drawing.Point(139, 17); - this.comboBoxEBHandleBehaviour.Name = "comboBoxEBHandleBehaviour"; - this.comboBoxEBHandleBehaviour.Size = new System.Drawing.Size(194, 21); - this.comboBoxEBHandleBehaviour.TabIndex = 8; - this.comboBoxEBHandleBehaviour.SelectedIndexChanged += new System.EventHandler(this.comboBoxEBHandleBehaviour_SelectedIndexChanged); - // // formEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -2785,7 +2770,6 @@ private void InitializeComponent() { this.groupboxPerformance.ResumeLayout(false); this.groupboxPerformance.PerformLayout(); this.tabpagePropertiesTwo.ResumeLayout(false); - this.groupBoxOther.ResumeLayout(false); this.groupboxCar.ResumeLayout(false); this.groupboxCar.PerformLayout(); this.groupboxCab.ResumeLayout(false); @@ -2819,15 +2803,15 @@ private void InitializeComponent() { this.splitMotorB.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.pictureboxMotorB1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.pictureboxMotorB2)).EndInit(); - this.panelPane.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.pictureboxLogo)).EndInit(); this.tabPageExtended.ResumeLayout(false); this.tabPageExtended.PerformLayout(); + this.groupBoxMisc.ResumeLayout(false); + this.groupBoxMisc.PerformLayout(); this.groupBoxLocoBrake.ResumeLayout(false); this.groupBoxLocoBrake.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.numericUpDownLocoBrakeNotches)).EndInit(); - this.groupBoxMisc.ResumeLayout(false); - this.groupBoxMisc.PerformLayout(); + this.panelPane.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)(this.pictureboxLogo)).EndInit(); this.ResumeLayout(false); } @@ -3029,9 +3013,6 @@ private void InitializeComponent() { private System.Windows.Forms.Label labelUnexposedFrontalAreaUnit; private System.Windows.Forms.TextBox textboxUnexposedFrontalArea; private System.Windows.Forms.Label labelUnexposedFrontalArea; - private System.Windows.Forms.GroupBox groupBoxOther; - private System.Windows.Forms.ComboBox comboBoxHandleBehaviour; - private System.Windows.Forms.Label label1; private System.Windows.Forms.Button buttonSetDelayPowerUp; private System.Windows.Forms.Button buttonSetDelayBrakeDown; private System.Windows.Forms.Button buttonSetDelayBrakeUp; @@ -3053,6 +3034,8 @@ private void InitializeComponent() { private System.Windows.Forms.GroupBox groupBoxMisc; private System.Windows.Forms.ComboBox comboBoxEBHandleBehaviour; private System.Windows.Forms.Label labelEBHandleBehaviour; + private System.Windows.Forms.ComboBox comboBoxLocoBrakeSystemType; + private System.Windows.Forms.Label labelLocoBrakeSystemType; } } diff --git a/source/TrainEditor/formEditor.cs b/source/TrainEditor/formEditor.cs index b830f797f..cb51d56be 100644 --- a/source/TrainEditor/formEditor.cs +++ b/source/TrainEditor/formEditor.cs @@ -52,10 +52,13 @@ private void FormEditorLoad(object sender, EventArgs e) { comboboxDoorCloseMode.Items.Add("Automatic"); comboboxDoorCloseMode.Items.Add("Manual"); comboboxSoundIndex.Items.Add("None"); - comboBoxHandleBehaviour.Items.Add("No Action"); - comboBoxHandleBehaviour.Items.Add("Return Power to neutral"); - comboBoxHandleBehaviour.Items.Add("Return Reverser to neutral"); - comboBoxHandleBehaviour.Items.Add("Return Power & Reverser to neutral"); + comboBoxEBHandleBehaviour.Items.Add("No Action"); + comboBoxEBHandleBehaviour.Items.Add("Return Power to neutral"); + comboBoxEBHandleBehaviour.Items.Add("Return Reverser to neutral"); + comboBoxEBHandleBehaviour.Items.Add("Return Power & Reverser to neutral"); + comboBoxLocoBrakeSystemType.Items.Add("Not fitted"); + comboBoxLocoBrakeSystemType.Items.Add("Notched air brake"); + comboBoxLocoBrakeSystemType.Items.Add("Air brake with partial release"); comboBoxLocoBrakeType.SelectedIndex = 0; CultureInfo culture = CultureInfo.InvariantCulture; for (int i = 0; i < 16; i++) { @@ -152,6 +155,8 @@ private void LoadControlContent() { comboboxPassAlarm.SelectedIndex = (int)Train.Device.PassAlarm; comboboxDoorOpenMode.SelectedIndex = (int)Train.Device.DoorOpenMode; comboboxDoorCloseMode.SelectedIndex = (int)Train.Device.DoorCloseMode; + comboBoxEBHandleBehaviour.SelectedIndex = (int)Train.Handle.HandleBehaviour; + comboBoxLocoBrakeSystemType.SelectedIndex = (int) Train.Brake.LocoBrakeType; } // save control content @@ -190,7 +195,7 @@ private bool SaveControlContent() { numericUpDownBrakeNotches.Focus(); return false; } - Train.Handle.HandleBehaviour = (TrainDat.Handle.EbHandleBehaviour) comboBoxHandleBehaviour.SelectedIndex; + Train.Handle.HandleBehaviour = (TrainDat.Handle.EbHandleBehaviour) comboBoxEBHandleBehaviour.SelectedIndex; if (!SaveControlContent(textboxPowerNotchReduceSteps, "PowerNotchReduceSteps", tabpagePropertiesOne, NumberRange.NonNegative, out Train.Handle.PowerNotchReduceSteps)) return false; // cab if (!SaveControlContent(textboxX, "X", tabpagePropertiesTwo, NumberRange.Any, out Train.Cab.X)) return false; @@ -1421,7 +1426,7 @@ private void setDelay(ref double[] delayValues, string delayType) TextBox t = new TextBox { Location = new Point(20, currentPosition), - Text = delayValues[index].ToString() + Text = delayValues[index].ToString(CultureInfo.InvariantCulture) }; formDelay.Controls.Add(t); Label l = new Label @@ -1515,5 +1520,31 @@ private void comboBoxLocoBrakeType_SelectedIndexChanged(object sender, EventArgs { Train.Handle.LocoBrake = (TrainDat.Handle.LocoBrakeType)comboBoxLocoBrakeType.SelectedIndex; } + + private void comboBoxLocoBrakeSystemType_SelectedIndexChanged(object sender, EventArgs e) + { + Train.Brake.LocoBrakeType = (TrainDat.Brake.LocoBrakeTypes)comboBoxLocoBrakeSystemType.SelectedIndex; + if (Train.Brake.LocoBrakeType == TrainDat.Brake.LocoBrakeTypes.NotFitted) + { + numericUpDownLocoBrakeNotches.Enabled = false; + buttonLocoBrakeDelayUp.Enabled = false; + buttonLocoBrakeDelayDown.Enabled = false; + comboBoxLocoBrakeType.Enabled = false; + } + else + { + if (Train.Brake.LocoBrakeType != TrainDat.Brake.LocoBrakeTypes.AutomaticAirBrake) + { + numericUpDownLocoBrakeNotches.Enabled = true; + } + else + { + numericUpDownLocoBrakeNotches.Enabled = false; + } + buttonLocoBrakeDelayUp.Enabled = true; + buttonLocoBrakeDelayDown.Enabled = true; + comboBoxLocoBrakeType.Enabled = true; + } + } } }