"Reversed Trains" Option#19305
Conversation
There was a problem hiding this comment.
It's a lot of code changes for inverting the vehicle->bank_rotation... I think you could create a function inside the vehicle class to get the transformed bank rotation if it is inverted and use it. You could remove all the uint8_t imageBankRotation variables in the function parameters I believe.
I figured there was a less nasty solution but couldn't think of it at the time - this is definitely a better way to do it. |
frutiemax
left a comment
There was a problem hiding this comment.
I've tested it with the corkscrew coaster and I like it. You should implement this with all the roller coasters with continuous mode enabled and get it merged as is before adding new features.
Regarding which coaster types to add the new modes to, my initial thought was to add it to types that Traditional, sit-down style coasters work well with this. I could add it to the classic variants of the rides I've already added. In terms of access without cheats, I think adding it to all coaster types would make it a bit bloated. Additionally, there are a few types it doesn't work well for: One coaster that could benefit from the new modes is the Multidim, as flipping the trains would open up more design space for it. |
|
It's also pretty common for Six Flags parks to run their batman B&M roller coasters in reversed mode. |
ZehMatt
left a comment
There was a problem hiding this comment.
I think this can be all a bit simplified by passing the mode and not storing a new field, having that field per vehicle would make sense if only some vehicles are reversed but if I get this right its always all or none.
I implemented it this way with reversing individual cars in mind, I'm just not sure how that would be designed/implemented yet. Could be a toggle somewhere in the ride settings to flip either the last car in the train, or any cars of the player's choosing. Depending on the design of the cars it could cause visual weirdness with the positions of the wheel bogies (since most coaster cars are trailered, rather than having four wheel bogies). Because of that, the additional flexibility might be something that is better left to cheats or plugins. As I mentioned before, this implementation also makes it possible to simplify the ride types that currently support flipping cars, and allow other train types to use turntables/etc. I've added this for testing to the log flume turntable, and it seems to work well (at least for single-car trains). If only the whole-ride-reversing modes are wanted, though, the implementation can certainly be changed. |
I would prefer to do things in gradual steps, the lines you touched revealed that it can be a bit cleaned up in general, you can add the new field to the vehicle when its actually possible to individually set their rotation. The reverse field is a bit too specific to store as its driven by the operating mode at the moment. |
|
It seems like this PR could easily change from using a unique operating mode to having a tickbox in vehicle selection, which the tickbox could be enabled with the TrackedRide RTD flag (assuming it isn't also present for tower rides). This means more flexibility and less code bloat since you don't have to copy all the Continuous Circuit/Continuous Circuit Block Section code, and it can be applied to rides of other operating modes like Reverse Incline Lift Hill, Powered Launch, Powered Launch Block Section, etc. Otherwise this is a pretty solid implementation. |
|
This is all good feedback - It seems there's some different opinions on how best to support this feature, so maybe it'd be worth sending this PR back to draft to let more discussion take place (I maybe jumped the gun a bit with this PR)
|
|
Something to consider doing is changing the peep target locations when the ride vehicle is loading/unloading. It appears the peeps will walk to (when loading) or spawn from (when unloading) the regular positions instead of the reverse positions. |
|
You need to rebase this PR as I did some cleaning around that code. Right now the question is rather should be this be an operating mode or not, I think that an operating mode fits this case the best but I can see how people might have the idea to individually reverse only certain vehicles, in both cases quite a bit logic requires to be changed. I'm not opposed of the new operating mode but some comments should be addressed, the reversed field is not needed when it can be derived from the operating mode. I think having it per vehicle basis makes things a bit more complicated code wise and probably has some issues with certain modes. |
For what it's worth, my opinion is that per-vehicle flipping is great for advanced players (has applications in creating custom rides, for instance) but might be too crazy or overwhelming for your average player. I think splitting it up between plugin support for full flexibility, and operating modes for "official" support, could be a good compromise. I've been developing the feature based on that framework so far, but I'm open to different ideas. Maybe it'd be helpful to get a few more opinions to try and reach a consensus. |
|
To clear up any confusion, since there might be some, I am not advocating for allowing users to flip individual vehicles around using the ride window. That granular functionality should be limited to plugins whose purpose is to manipulate individual vehicles. |
|
I think the implementation is reasonable now, tagging @Broxzier and @duncanspumpkin to see what they think, I think this is a great addition overall I just were not too happy about the code. |
| } | ||
|
|
||
| // Returns the opposite of the bank angle for reversed cars, normal bank angle otherwise | ||
| static uint8_t GetBankRotationForDrawing(const Vehicle* vehicle) |
There was a problem hiding this comment.
Generally this is seen as a paint function. The drawing functions are the ones that operate on the output of the paint graph. Just call it GetPaintBankRotation. I eventually want to rename bank rotation to roll as it makes things easier to understand (and is much shorter than bank rotation) amusingly that would then end up making this a GetPaintRoll

Changes look nice and concise and simple. I don't have much to add. |
That's certainly doable, though I do have some concerns:
I definitely agree that having to touch a bunch of ride mode conditions isn't the best. My impression while I was writing the code was that the RideMode type could stand a rework - perhaps to a parameterized enum or struct. Obviously that's outside the scope of this PR though. |
More or less what I thought also. And you are also correct that the PR should not extend beyond the current scope, as I suggested before its best de-hardcode such things so in the future either plugins or some form of meta data can extend/change the functionality of the game, the long term goal should be to rewrite the code in a way that we no longer have to change/add code for the sake of changing/adding things, this also allows people with very little to no coding experience to extend/modify the game in a way they see fit. |
There was a problem hiding this comment.
Not sure if the discussion about the per-vehicle reversed flag is still going or settled, but I'd love to have it for plugins and would love to use it in the RideVehicleEditor, and I'm sure many others would love it too. 😃 Rest of the plugin implementation is a LGTM!
I don't know how the OpenRCT2 team feels but I don't think twice about bumping save file format. If a feature needs a modification to the save file format, then so be it. RTD flags: there's no issue with using another ride type flag because we have BitSet which RTDs already use for available track elements but nobody has gotten around to upgrading the ride flags field to use it. Ride flags: the lifecycle_flags field has 22 of 32 flags used, so there's no issues there.
I don't see how it would add complexity compared to modifying all the ContinuousCircuit/ContinuousCircuitBlockBrakeReferences in ride and vehicle code. With the number of those changes, LOC might not even go up up with this approach. There's already RideSetSettingAction which can handle setting the reverse property.
As a separate button, it will integrate with the "disable vehicle limits" cheat, and as a ride type flag it is equally trivial to add to a different ride type.
I think the solution is then add it to enough rides that the pattern is clear. If all roller coasters had this tickbox, it would be relatively obvious that roller coasters can have reversed vehicles. I could see limiting the number of rides with the operating mode but when it's separated from operating mode I don't see why it would be arbitrarily limited to a few roller coasters. I realize this is your first OpenRCT2 PR so if I come off too strong, I apologize. Vehicle update code is something I feel strongly about. I am willing to help implement what I've outlined above if you want it. |
|
Not coming off too strong at all, this is all good info (and I do this stuff for a living, I'm used to it). I want this to be the best it can possibly be. Regarding the flags, the lifecycle flags didn't initially seem to me like the right place for that sort of setting, and I didn't want to just add it haphazardly. I now notice that the flag for music is there, so it makes enough sense for a cosmetic setting like this. I totally get the concerns with the hardcoded conditions. It seems to me like this feature revealed an issue with the RideModes implementation, and I think it could be addressed with some improvements to the RideMode model in a separate PR. I have some ideas as to how to do that, so if that's desirable I could potentially tackle it (if you want to talk about that more we can take it to a separate discussion thread). If those issues are resolved I personally think an operating mode would be the simplest (and easiest to understand for players) implementation for this. This PR could either wait for that redesign, or temporarily make the code smell a little worse, or go with the tickbox design instead. I'll give the tickbox a try to see how it plays. In an earlier comment I mentioned limiting this feature to a few coasters for visual & realism reasons. Of course, with cheats it's usable on any, but for the "proper" experience I think having it be kept special makes sense. There's also a few rides that it would cause graphical oddities with, such as all the ones with swinging sprites (Not sure if I can do something about that). Thanks for all your help and patience! |
|
Newest commit uses the tickbox implementation. Now that I see it in action I like it a bit more. Let me know how you folks feel about it. A couple notes:
|
Ride trains are either "powered" or "unpowered" and that status is determined by the factory template of the first car in the train. The steam locomotive is flagged as powered, and the cars are flagged as unpowered. EDIT: For the tickbox cheat, disable vehicle limits might be more appropriate - it already affects stuff on the vehicle selection page. |
f34d8ee to
707c136
Compare
- Feature: [#18713] Block brakes have speed control and brakes slower than adjacent block brakes copy block brake speed when block brake open. - Feature: [#19276] Add Powered Lifthill to Giga Coaster. - Feature: [#19305] Add new Reversed Trains ride setting to run trains backwards, granting a bonus to ride ratings. - Feature: [#19305] [Plugin] Add “Car.isReversed” to allow individual ride vehicles to run backwards. - Feature: [#19446] Add new color options to color dropdown. - Feature: [#19547] Add large sloped turns to hybrid coaster and single rail coaster. - Feature: [#19930] Add plugin APIs for research. - Feature: [OpenMusic#25] Added Prehistoric ride music style. - Feature: [OpenMusic#26] Fairground Organ style 2 with new recordings from Herman's 35er Voigt (Previously known as Bressingham Voigt). - Feature: [OpenMusic#28] Add Ragtime style 2 ride music. - Improved: [#17739] Raise water and land height limits to 254 units/182m/600ft. - Improved: [#18490] Reduce guests walking through trains on level crossing next to station. - Improved: [#18996] When marketing campaigns are disabled, disable the Marketing tab in the Finances window. - Improved: [#19764] Miscellaneous scenery tab now grouped next to the all-scenery tab. - Improved: [#19830] “Highlight path issues” will now hide wall elements. - Improved: [#19905] Add prompt before resetting shortcut keys. - Improved: [#19952] Add colour preset to Spiral Slide using the new colour options. - Improved: [#19953] Add keyboard shortcut to Keyboard Shortcuts window. - Improved: [#20055] Performance improvement for the software renderer. - Change: [OpenSFX#17] Update Hybrid RC lifthill loop. - Fix: [#12598] Number of holes is not set correctly when saving track designs. - Fix: [#13130] Android always defaulting to UK locale for language, currency and temperature. - Fix: [#13397] Ride simulation causes strange station behaviour and makes the ride unusable in some cases. - Fix: [#16791] Rotodrop top piece replicates when walls are placed around it and clearance checks are disabled (original bug). - Fix: [#18583] Land dropdown is incorrect if there are surface entry index holes. - Fix: [#18895] Responding mechanic blocked at level crossing. - Fix: [#19231] Crash due to null pointer to previously deleted banner in tile copy/paste functionality. - Fix: [#19296] Crash due to a race condition for parallel object loading. - Fix: [#19733] Favorite ride of X guests integer overflow. - Fix: [#19756] Crash with title sequences containing no commands. - Fix: [#19767] No message when path is not connected to ride exit and is therefore unreachable for mechanics. - Fix: [#19800] Crash when displaying station stats with more than 62 stations. - Fix: [#19801] The in-game load/save window cannot be resized anymore. - Fix: [#19854] Looping Coaster trains clipping through steep quarter turns down. - Fix: [#19858] Issue drawing simulate flag icon on alternate colour palettes. - Fix: [#19901] Random shop colours never assigning last colour. - Fix: [#19911] Guests stuck at certain railway crossings. - Fix: [#19924] Destructible cheat does not allow partial ride modification. - Fix: [#19950] Mine train block brake supports drawn incorrectly. - Fix: [#19955] Mine Train Roller Coaster has incorrect supports on the sloped left small turn (original bug). - Fix: [#19987] [Plugin] ‘SetCheatAction’ has wrong ID in plugin API. - Fix: [#20016] The group box for small scenery details in the Tile Inspector window has unused empty space. - Fix: [#20018] Shops not calculating up-keep cost. - Fix: [#20033] Asset packs cannot reference game data. - Fix: [#20104] [Plugin] Some network APIs use player index and group index. - Fix: [#20099] Some scrollbar is glitched or have incorrect size when open window for the first time - Fix: [#20134] Grass length being updated for tiles in the void, causing unneccesary drawing operations.
Release v0.4.5 - Feature: [OpenRCT2#18713] Block brakes have speed control and brakes slower than adjacent block brakes copy block brake speed when block brake open. - Feature: [OpenRCT2#19276] Add Powered Lifthill to Giga Coaster. - Feature: [OpenRCT2#19305] Add new Reversed Trains ride setting to run trains backwards, granting a bonus to ride ratings. - Feature: [OpenRCT2#19305] [Plugin] Add “Car.isReversed” to allow individual ride vehicles to run backwards. - Feature: [OpenRCT2#19446] Add new color options to color dropdown. - Feature: [OpenRCT2#19547] Add large sloped turns to hybrid coaster and single rail coaster. - Feature: [OpenRCT2#19930] Add plugin APIs for research. - Feature: [OpenMusic#25] Added Prehistoric ride music style. - Feature: [OpenMusic#26] Fairground Organ style 2 with new recordings from Herman's 35er Voigt (Previously known as Bressingham Voigt). - Feature: [OpenMusic#28] Add Ragtime style 2 ride music. - Improved: [OpenRCT2#17739] Raise water and land height limits to 254 units/182m/600ft. - Improved: [OpenRCT2#18490] Reduce guests walking through trains on level crossing next to station. - Improved: [OpenRCT2#18996] When marketing campaigns are disabled, disable the Marketing tab in the Finances window. - Improved: [OpenRCT2#19764] Miscellaneous scenery tab now grouped next to the all-scenery tab. - Improved: [OpenRCT2#19830] “Highlight path issues” will now hide wall elements. - Improved: [OpenRCT2#19905] Add prompt before resetting shortcut keys. - Improved: [OpenRCT2#19952] Add colour preset to Spiral Slide using the new colour options. - Improved: [OpenRCT2#19953] Add keyboard shortcut to Keyboard Shortcuts window. - Improved: [OpenRCT2#20055] Performance improvement for the software renderer. - Change: [OpenSFX#17] Update Hybrid RC lifthill loop. - Fix: [OpenRCT2#12598] Number of holes is not set correctly when saving track designs. - Fix: [OpenRCT2#13130] Android always defaulting to UK locale for language, currency and temperature. - Fix: [OpenRCT2#13397] Ride simulation causes strange station behaviour and makes the ride unusable in some cases. - Fix: [OpenRCT2#16791] Rotodrop top piece replicates when walls are placed around it and clearance checks are disabled (original bug). - Fix: [OpenRCT2#18583] Land dropdown is incorrect if there are surface entry index holes. - Fix: [OpenRCT2#18895] Responding mechanic blocked at level crossing. - Fix: [OpenRCT2#19231] Crash due to null pointer to previously deleted banner in tile copy/paste functionality. - Fix: [OpenRCT2#19296] Crash due to a race condition for parallel object loading. - Fix: [OpenRCT2#19733] Favorite ride of X guests integer overflow. - Fix: [OpenRCT2#19756] Crash with title sequences containing no commands. - Fix: [OpenRCT2#19767] No message when path is not connected to ride exit and is therefore unreachable for mechanics. - Fix: [OpenRCT2#19800] Crash when displaying station stats with more than 62 stations. - Fix: [OpenRCT2#19801] The in-game load/save window cannot be resized anymore. - Fix: [OpenRCT2#19854] Looping Coaster trains clipping through steep quarter turns down. - Fix: [OpenRCT2#19858] Issue drawing simulate flag icon on alternate colour palettes. - Fix: [OpenRCT2#19901] Random shop colours never assigning last colour. - Fix: [OpenRCT2#19911] Guests stuck at certain railway crossings. - Fix: [OpenRCT2#19924] Destructible cheat does not allow partial ride modification. - Fix: [OpenRCT2#19950] Mine train block brake supports drawn incorrectly. - Fix: [OpenRCT2#19955] Mine Train Roller Coaster has incorrect supports on the sloped left small turn (original bug). - Fix: [OpenRCT2#19987] [Plugin] ‘SetCheatAction’ has wrong ID in plugin API. - Fix: [OpenRCT2#20016] The group box for small scenery details in the Tile Inspector window has unused empty space. - Fix: [OpenRCT2#20018] Shops not calculating up-keep cost. - Fix: [OpenRCT2#20033] Asset packs cannot reference game data. - Fix: [OpenRCT2#20104] [Plugin] Some network APIs use player index and group index. - Fix: [OpenRCT2#20099] Some scrollbar is glitched or have incorrect size when open window for the first time - Fix: [OpenRCT2#20134] Grass length being updated for tiles in the void, causing unneccesary drawing operations.

This PR adds a new option in the ride vehicles tab, which enables the user to reverse the facing direction of the ride vehicles. By default, this is enabled for a number of select coaster types. With the "Disable vehicle limits" cheat, the user is able to apply this option to any tracked ride.
When using this option, the ride vehicles will spawn in reverse order in the station/block. Reversed vehicles display the proper backwards sprites for all track pieces (except on the Spiral Lift Hill, as it's the only pitch angle without a corresponding reverse pitch).
Internally, a new flag is added to vehicles, allowing individual cars to be reversed. This is not exposed in UI, but can be accessed via plugin API.
Per-vehicle paint schemes are functional. The backwards vehicles are compatible with block sections and boosters.
Potential follow-ups: