diff --git a/projects/openrct2.vcxproj b/projects/openrct2.vcxproj
index 505725ffa4..fef57276cd 100644
--- a/projects/openrct2.vcxproj
+++ b/projects/openrct2.vcxproj
@@ -33,6 +33,8 @@
+
+
@@ -72,6 +74,8 @@
+
+
@@ -195,4 +199,4 @@
-
\ No newline at end of file
+
diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index e71a9b1250..f6568613c3 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -78,6 +78,12 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
Header Files
@@ -194,6 +200,12 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
Source Files
@@ -308,4 +320,4 @@
Resource Files
-
\ No newline at end of file
+
diff --git a/src/config.c b/src/config.c
index aa164ce818..f1f62e5cb7 100644
--- a/src/config.c
+++ b/src/config.c
@@ -615,4 +615,3 @@ static void config_error(char *msg){
}
-
diff --git a/src/finance.c b/src/finance.c
index ad0626a52f..cceea4ee5d 100644
--- a/src/finance.c
+++ b/src/finance.c
@@ -126,7 +126,7 @@ void finance_pay_ride_upkeep()
if (ride->type == RIDE_TYPE_NULL)
continue;
- if (!(ride->var_1D0 & 0x1000)) {
+ if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_EVER_BEEN_OPENED)) {
ride->build_date = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16);
ride->var_196 = 25855; // durability?
@@ -191,4 +191,4 @@ void sub_69E869()
value += RCT2_GLOBAL(RCT2_ADDRESS_MAXIMUM_LOAN, money32);
value = ror32(value, 3);
RCT2_GLOBAL(0x013587C4, sint32) = value;
-}
\ No newline at end of file
+}
diff --git a/src/news_item.c b/src/news_item.c
index 5cc8083781..85eab71a89 100644
--- a/src/news_item.c
+++ b/src/news_item.c
@@ -206,8 +206,7 @@ void news_item_get_subject_location(int type, int subject, int *x, int *y, int *
// Find which ride peep is on
ride = &(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_LIST, rct_ride)[peep->current_ride]);
- // Check if there are trains on the track (first bit of var_1D0)
- if (!(ride->var_1D0 & 1)) {
+ if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) {
*x = SPRITE_LOCATION_NULL;
break;
}
diff --git a/src/ride.h b/src/ride.h
index ba6814d20f..6d1c7ab6d7 100644
--- a/src/ride.h
+++ b/src/ride.h
@@ -29,6 +29,8 @@
*/
typedef struct {
uint8 type; // 0x000
+ // pointer to static info. for example, wild mouse type is 0x36, subtype is
+ // 0x4c.
uint8 subtype; // 0x001
uint16 pad_002;
uint8 mode; // 0x004
@@ -46,11 +48,24 @@ typedef struct {
uint16 exits[4]; // 0x072
uint8 pad_07A[0x0C];
uint16 train_car_map[1]; // 0x086 Points to the first car in the train
- uint8 pad_088[0x68];
- sint16 var_0F0;
- sint16 var_0F2;
- sint16 var_0F4;
- uint8 pad_0F6[0x2E];
+ uint8 pad_088[0x3F];
+
+ // Not sure if these should be uint or sint.
+ uint8 var_0C7;
+ uint8 var_0C8;
+ uint8 var_0C9;
+
+ uint8 pad_0CA[0x1B];
+
+ sint32 var_0E4;
+ sint32 var_0E8;
+ sint32 var_0EC;
+ sint32 var_0F0;
+ uint8 pad_0F4[0x20];
+ uint8 var_114;
+ // Track length? Number of track segments?
+ uint8 var_115;
+ uint8 pad_116[0x0F];
sint16 var_124;
sint16 var_126;
sint16 var_128;
@@ -78,15 +93,22 @@ typedef struct {
sint16 upkeep_cost; // 0x182
uint8 pad_184[0x12];
uint16 var_196;
- uint8 pad_198;
+ // used in computing excitement, nausea, etc
+ uint8 var_198;
uint8 var_199;
uint8 pad_19A[0x1A];
money32 profit; // 0x1B4
uint8 queue_time[4]; // 0x1B8
- uint8 pad_1BC[0x12];
+ uint8 pad_1BC[0x11];
+ uint8 var_1CD;
uint16 guests_favourite; // 0x1CE
- uint32 var_1D0;
- uint8 pad_1D4[0x2C];
+ uint32 lifecycle_flags;
+ uint8 pad_1D4[0x20];
+ // Example value for wild mouse ride is d5 (before it's been constructed)
+ // I tried searching the IDA file for "1F4" but couldn't find places where
+ // this is written to.
+ uint16 var_1F4;
+ uint8 pad_1F6[0x0a];
uint16 queue_length[4]; // 0x200
uint8 pad_208[0x58];
} rct_ride;
@@ -106,6 +128,27 @@ enum {
RIDE_CLASS_KIOSK_OR_FACILITY
};
+// Constants used by the lifecycle_flags property at 0x1D0
+enum {
+ RIDE_LIFECYCLE_ON_TRACK = 1,
+ RIDE_LIFECYCLE_TESTED = 1 << 1,
+ RIDE_LIFECYCLE_TEST_IN_PROGRESS = 1 << 2,
+ RIDE_LIFECYCLE_NO_RAW_STATS = 1 << 3,
+ RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING = 1 << 4,
+ RIDE_LIFECYCLE_ON_RIDE_PHOTO = 1 << 5,
+
+ RIDE_LIFECYCLE_BROKEN_DOWN = 1 << 7,
+
+ RIDE_LIFECYCLE_CRASHED = 1 << 10,
+
+ RIDE_LIFECYCLE_EVER_BEEN_OPENED = 1 << 12,
+ RIDE_LIFECYCLE_MUSIC = 1 << 13,
+ RIDE_LIFECYCLE_INDESTRUCTIBLE = 1 << 14,
+ RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK = 1 << 15,
+
+ RIDE_LIFECYCLE_CABLE_LIFT = 1 << 17
+};
+
enum {
RIDE_TYPE_NULL = 255,
RIDE_TYPE_SPIRAL_ROLLER_COASTER = 0,
@@ -230,7 +273,7 @@ enum {
RIDE_MODE_3D_FILM_MOUSE_TAILS,
RIDE_MODE_SPACE_RINGS,
RIDE_MODE_BEGINNERS,
- RIDE_MODE_LIM_POWERED_LAUNCH,
+ RIDE_MODE_LIM_POWERED_LAUNCH, // 0x17
RIDE_MODE_FILM_THRILL_RIDERS,
RIDE_MODE_3D_FILM_STORM_CHASERS,
RIDE_MODE_3D_FILM_SPACE_RAIDERS,
@@ -242,7 +285,7 @@ enum {
RIDE_MODE_CROOKED_HOUSE,
RIDE_MODE_FREEFALL_DROP,
RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED,
- RIDE_MODE_POWERED_LAUNCH2, // RCT2 style?
+ RIDE_MODE_POWERED_LAUNCH2, // 0x23. RCT2 style?
RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED
};
diff --git a/src/ride_data.c b/src/ride_data.c
new file mode 100644
index 0000000000..aefda2a666
--- /dev/null
+++ b/src/ride_data.c
@@ -0,0 +1,585 @@
+/*
+ * Whether a particular ride has a running track or not. Will probably end up
+ * being used in various places in the game.
+ *
+ * Data source is 0x0097E3AC
+ *
+ * Generating function is here
+ * https://gist.github.com/kevinburke/eaeb1d8149a6eef0dcc1
+ */
+
+#include
+#include "rct2.h"
+#include "ride_data.h"
+
+const bool hasRunningTrack[0x60] = {
+ true, // 0 Spiral Roller coaster
+ true, // 1 Stand Up Coaster
+ true, // 2 Suspended Swinging
+ true, // 3 Inverted
+ true, // 4 Steel Mini Coaster
+ true, // 5 Mini Railroad
+ true, // 6 Monorail
+ true, // 7 Mini Suspended Coaster
+ false, // 8 Bumper Boats
+ true, // 9 Wooden Wild Mine/Mouse
+ true, // a Steeplechase/Motorbike/Soap Box Derby
+ true, // b Car Ride
+ true, // c Launched Freefall
+ true, // d Bobsleigh Coaster
+ true, // e Observation Tower
+ true, // f Looping Roller Coaster
+ true, // 10 Dinghy Slide
+ true, // 11 Mine Train Coaster
+ true, // 12 Chairlift
+ true, // 13 Corkscrew Roller Coaster
+ false, // 14 Maze
+ false, // 15 Spiral Slide
+ true, // 16 Go Karts
+ true, // 17 Log Flume
+ true, // 18 River Rapids
+ false, // 19 Bumper Cars
+ false, // 1a Pirate Ship
+ false, // 1b Swinging Inverter Ship
+ false, // 1c Food Stall
+ false, // 1d (none)
+ false, // 1e Drink Stall
+ false, // 1f (none)
+ false, // 20 Shop (all types)
+ false, // 21 Merry Go Round
+ false, // 22 Balloon Stall (maybe)
+ false, // 23 Information Kiosk
+ false, // 24 Bathroom
+ false, // 25 Ferris Wheel
+ false, // 26 Motion Simulator
+ false, // 27 3D Cinema
+ false, // 28 Gravitron
+ false, // 29 Space Rings
+ true, // 2a Reverse Freefall Coaster
+ true, // 2b Elevator
+ true, // 2c Vertical Drop Roller Coaster
+ false, // 2d ATM
+ false, // 2e Twist
+ false, // 2f Haunted House
+ false, // 30 First Aid
+ false, // 31 Circus Show
+ true, // 32 Ghost Train
+ true, // 33 Twister Roller Coaster
+ true, // 34 Wooden Roller Coaster
+ true, // 35 Side-Friction Roller Coaster
+ true, // 36 Wild Mouse
+ true, // 37 Multi Dimension Coaster
+ true, // 38 (none)
+ true, // 39 Flying Roller Coaster
+ true, // 3a (none)
+ true, // 3b Virginia Reel
+ true, // 3c Splash Boats
+ true, // 3d Mini Helicopters
+ true, // 3e Lay-down Roller Coaster
+ true, // 3f Suspended Monorail
+ true, // 40 (none)
+ true, // 41 Reverser Roller Coaster
+ true, // 42 Heartline Twister Roller Coaster
+ true, // 43 Mini Golf
+ true, // 44 Giga Coaster
+ true, // 45 Roto-Drop
+ false, // 46 Flying Saucers
+ false, // 47 Crooked House
+ true, // 48 Monorail Cycles
+ true, // 49 Compact Inverted Coaster
+ true, // 4a Water Coaster
+ true, // 4b Air Powered Vertical Coaster
+ true, // 4c Inverted Hairpin Coaster
+ false, // 4d Magic Carpet
+ false, // 4e Submarine Ride
+ true, // 4f River Rafts
+ false, // 50 (none)
+ false, // 51 Enterprise
+ false, // 52 (none)
+ false, // 53 (none)
+ false, // 54 (none)
+ true, // 55 (none)
+ true, // 56 Inverted Impulse Coaster
+ true, // 57 Mini Roller Coaster
+ true, // 58 Mine Ride
+ true, // 59 LIM Launched Roller Coaster
+};
+
+/**
+ * Data about ride running costs. This is widely adjusted by the upkeep
+ * function, so values that don't make much sense here (a roller coaster having
+ * cheaper upkeep than a car ride) are fixed later on.
+ *
+ * data generation script: https://gist.github.com/kevinburke/6bcf4a8fcc95faad7bac
+ */
+const uint8 initialUpkeepCosts[0x60] = {
+ 41, // 00 Spiral Roller coaster
+ 40, // 01 Stand Up Coaster
+ 40, // 02 Suspended Swinging
+ 40, // 03 Inverted
+ 40, // 04 Steel Mini Coaster
+ 60, // 05 Mini Railroad
+ 65, // 06 Monorail
+ 40, // 07 Mini Suspended Coaster
+ 50, // 08 Bumper Boats
+ 40, // 09 Wooden Wild Mine/Mouse
+ 40, // 0a Steeplechase/Motorbike/Soap Box Derby
+ 70, // 0b Car Ride
+ 50, // 0c Launched Freefall
+ 40, // 0d Bobsleigh Coaster
+ 50, // 0e Observation Tower
+ 40, // 0f Looping Roller Coaster
+ 40, // 10 Dinghy Slide
+ 40, // 11 Mine Train Coaster
+ 60, // 12 Chairlift
+ 40, // 13 Corkscrew Roller Coaster
+ 50, // 14 Maze
+ 50, // 15 Spiral Slide
+ 50, // 16 Go Karts
+ 80, // 17 Log Flume
+ 82, // 18 River Rapids
+ 50, // 19 Bumper Cars
+ 50, // 1a Pirate Ship
+ 50, // 1b Swinging Inverter Ship
+ 50, // 1c Food Stall
+ 50, // 1d (none)
+ 50, // 1e Drink Stall
+ 50, // 1f (none)
+ 50, // 20 Shop (all types)
+ 50, // 21 Merry Go Round
+ 50, // 22 Balloon Stall (maybe)
+ 50, // 23 Information Kiosk
+ 50, // 24 Bathroom
+ 50, // 25 Ferris Wheel
+ 50, // 26 Motion Simulator
+ 50, // 27 3D Cinema
+ 50, // 28 Gravitron
+ 50, // 29 Space Rings
+ 80, // 2a Reverse Freefall Coaster
+ 50, // 2b Elevator
+ 44, // 2c Vertical Drop Roller Coaster
+ 40, // 2d ATM
+ 50, // 2e Twist
+ 50, // 2f Haunted House
+ 45, // 30 First Aid
+ 50, // 31 Circus Show
+ 80, // 32 Ghost Train
+ 43, // 33 Twister Roller Coaster
+ 40, // 34 Wooden Roller Coaster
+ 39, // 35 Side-Friction Roller Coaster
+ 40, // 36 Wild Mouse
+ 75, // 37 Multi Dimension Coaster
+ 75, // 38 (none)
+ 49, // 39 Flying Roller Coaster
+ 49, // 3a (none)
+ 39, // 3b Virginia Reel
+ 70, // 3c Splash Boats
+ 70, // 3d Mini Helicopters
+ 49, // 3e Lay-down Roller Coaster
+ 70, // 3f Suspended Monorail
+ 49, // 40 (none)
+ 39, // 41 Reverser Roller Coaster
+ 47, // 42 Heartline Twister Roller Coaster
+ 30, // 43 Mini Golf
+ 10, // 44 Giga Coaster
+ 50, // 45 Roto-Drop
+ 90, // 46 Flying Saucers
+ 30, // 47 Crooked House
+ 47, // 48 Monorail Cycles
+ 40, // 49 Compact Inverted Coaster
+ 60, // 4a Water Coaster
+ 90, // 4b Air Powered Vertical Coaster
+ 40, // 4c Inverted Hairpin Coaster
+ 50, // 4d Magic Carpet
+ 50, // 4e Submarine Ride
+ 50, // 4f River Rafts
+ 50, // 50 (none)
+ 50, // 51 Enterprise
+ 50, // 52 (none)
+ 50, // 53 (none)
+ 50, // 54 (none)
+ 40, // 55 (none)
+ 180, // 56 Inverted Impulse Coaster
+ 35, // 57 Mini Roller Coaster
+ 50, // 58 Mine Ride
+ 42, // 59 LIM Launched Roller Coaster
+};
+
+const uint8 costPerTrackPiece[0x60] = {
+ 80, // 00 Spiral Roller coaster
+ 80, // 01 Stand Up Coaster
+ 80, // 02 Suspended Swinging
+ 80, // 03 Inverted
+ 80, // 04 Steel Mini Coaster
+ 0, // 05 Mini Railroad
+ 0, // 06 Monorail
+ 80, // 07 Mini Suspended Coaster
+ 0, // 08 Bumper Boats
+ 80, // 09 Wooden Wild Mine/Mouse
+ 80, // 0a Steeplechase/Motorbike/Soap Box Derby
+ 0, // 0b Car Ride
+ 0, // 0c Launched Freefall
+ 80, // 0d Bobsleigh Coaster
+ 0, // 0e Observation Tower
+ 80, // 0f Looping Roller Coaster
+ 80, // 10 Dinghy Slide
+ 80, // 11 Mine Train Coaster
+ 0, // 12 Chairlift
+ 80, // 13 Corkscrew Roller Coaster
+ 0, // 14 Maze
+ 0, // 15 Spiral Slide
+ 0, // 16 Go Karts
+ 0, // 17 Log Flume
+ 0, // 18 River Rapids
+ 0, // 19 Bumper Cars
+ 0, // 1a Pirate Ship
+ 0, // 1b Swinging Inverter Ship
+ 0, // 1c Food Stall
+ 0, // 1d (none)
+ 0, // 1e Drink Stall
+ 0, // 1f (none)
+ 0, // 20 Shop (all types)
+ 0, // 21 Merry Go Round
+ 0, // 22 Balloon Stall (maybe)
+ 0, // 23 Information Kiosk
+ 0, // 24 Bathroom
+ 0, // 25 Ferris Wheel
+ 0, // 26 Motion Simulator
+ 0, // 27 3D Cinema
+ 0, // 28 Gravitron
+ 0, // 29 Space Rings
+ 0, // 2a Reverse Freefall Coaster
+ 0, // 2b Elevator
+ 80, // 2c Vertical Drop Roller Coaster
+ 0, // 2d ATM
+ 0, // 2e Twist
+ 0, // 2f Haunted House
+ 0, // 30 First Aid
+ 0, // 31 Circus Show
+ 0, // 32 Ghost Train
+ 80, // 33 Twister Roller Coaster
+ 80, // 34 Wooden Roller Coaster
+ 80, // 35 Side-Friction Roller Coaster
+ 80, // 36 Wild Mouse
+ 90, // 37 Multi Dimension Coaster
+ 90, // 38 (none)
+ 90, // 39 Flying Roller Coaster
+ 90, // 3a (none)
+ 80, // 3b Virginia Reel
+ 0, // 3c Splash Boats
+ 0, // 3d Mini Helicopters
+ 90, // 3e Lay-down Roller Coaster
+ 0, // 3f Suspended Monorail
+ 90, // 40 (none)
+ 80, // 41 Reverser Roller Coaster
+ 80, // 42 Heartline Twister Roller Coaster
+ 80, // 43 Mini Golf
+ 80, // 44 Giga Coaster
+ 0, // 45 Roto-Drop
+ 0, // 46 Flying Saucers
+ 0, // 47 Crooked House
+ 0, // 48 Monorail Cycles
+ 80, // 49 Compact Inverted Coaster
+ 80, // 4a Water Coaster
+ 0, // 4b Air Powered Vertical Coaster
+ 80, // 4c Inverted Hairpin Coaster
+ 0, // 4d Magic Carpet
+ 0, // 4e Submarine Ride
+ 0, // 4f River Rafts
+ 0, // 50 (none)
+ 0, // 51 Enterprise
+ 0, // 52 (none)
+ 0, // 53 (none)
+ 0, // 54 (none)
+ 80, // 55 (none)
+ 80, // 56 Inverted Impulse Coaster
+ 80, // 57 Mini Roller Coaster
+ 80, // 58 Mine Ride
+ 80, // 59 LIM Launched Roller Coaster
+};
+
+/**
+ * Data initially at 0x0097E3B4
+ */
+const uint8 rideUnknownData1[0x60] = {
+ 10, // 00 Spiral Roller coaster
+ 10, // 01 Stand Up Coaster
+ 20, // 02 Suspended Swinging
+ 13, // 03 Inverted
+ 8, // 04 Steel Mini Coaster
+ 10, // 05 Mini Railroad
+ 10, // 06 Monorail
+ 10, // 07 Mini Suspended Coaster
+ 4, // 08 Bumper Boats
+ 9, // 09 Wooden Wild Mine/Mouse
+ 10, // 0a Steeplechase/Motorbike/Soap Box Derby
+ 8, // 0b Car Ride
+ 10, // 0c Launched Freefall
+ 10, // 0d Bobsleigh Coaster
+ 10, // 0e Observation Tower
+ 10, // 0f Looping Roller Coaster
+ 4, // 10 Dinghy Slide
+ 10, // 11 Mine Train Coaster
+ 4, // 12 Chairlift
+ 11, // 13 Corkscrew Roller Coaster
+ 0, // 14 Maze
+ 0, // 15 Spiral Slide
+ 8, // 16 Go Karts
+ 9, // 17 Log Flume
+ 10, // 18 River Rapids
+ 5, // 19 Bumper Cars
+ 0, // 1a Pirate Ship
+ 0, // 1b Swinging Inverter Ship
+ 0, // 1c Food Stall
+ 0, // 1d (none)
+ 0, // 1e Drink Stall
+ 0, // 1f (none)
+ 0, // 20 Shop (all types)
+ 0, // 21 Merry Go Round
+ 0, // 22 Balloon Stall (maybe)
+ 0, // 23 Information Kiosk
+ 0, // 24 Bathroom
+ 0, // 25 Ferris Wheel
+ 0, // 26 Motion Simulator
+ 0, // 27 3D Cinema
+ 0, // 28 Gravitron
+ 0, // 29 Space Rings
+ 0, // 2a Reverse Freefall Coaster
+ 10, // 2b Elevator
+ 11, // 2c Vertical Drop Roller Coaster
+ 0, // 2d ATM
+ 0, // 2e Twist
+ 0, // 2f Haunted House
+ 0, // 30 First Aid
+ 0, // 31 Circus Show
+ 8, // 32 Ghost Train
+ 11, // 33 Twister Roller Coaster
+ 10, // 34 Wooden Roller Coaster
+ 10, // 35 Side-Friction Roller Coaster
+ 9, // 36 Wild Mouse
+ 11, // 37 Multi Dimension Coaster
+ 11, // 38 (none)
+ 11, // 39 Flying Roller Coaster
+ 11, // 3a (none)
+ 10, // 3b Virginia Reel
+ 9, // 3c Splash Boats
+ 8, // 3d Mini Helicopters
+ 11, // 3e Lay-down Roller Coaster
+ 10, // 3f Suspended Monorail
+ 11, // 40 (none)
+ 10, // 41 Reverser Roller Coaster
+ 11, // 42 Heartline Twister Roller Coaster
+ 11, // 43 Mini Golf
+ 12, // 44 Giga Coaster
+ 10, // 45 Roto-Drop
+ 5, // 46 Flying Saucers
+ 0, // 47 Crooked House
+ 8, // 48 Monorail Cycles
+ 13, // 49 Compact Inverted Coaster
+ 8, // 4a Water Coaster
+ 0, // 4b Air Powered Vertical Coaster
+ 9, // 4c Inverted Hairpin Coaster
+ 0, // 4d Magic Carpet
+ 4, // 4e Submarine Ride
+ 9, // 4f River Rafts
+ 0, // 50 (none)
+ 0, // 51 Enterprise
+ 0, // 52 (none)
+ 0, // 53 (none)
+ 0, // 54 (none)
+ 11, // 55 (none)
+ 11, // 56 Inverted Impulse Coaster
+ 8, // 57 Mini Roller Coaster
+ 10, // 58 Mine Ride
+ 9, // 59 LIM Launched Roller Coaster
+};
+
+/**
+ * Data at 0x0097E3B6, originally set to either be 3 or 0 and replaced here by
+ * a boolean table. This may be exactly the same as hasRunningTrack above.
+ */
+const bool rideUnknownData2[0x60] = {
+ true, // 00 Spiral Roller coaster
+ true, // 01 Stand Up Coaster
+ true, // 02 Suspended Swinging
+ true, // 03 Inverted
+ true, // 04 Steel Mini Coaster
+ true, // 05 Mini Railroad
+ true, // 06 Monorail
+ true, // 07 Mini Suspended Coaster
+ false, // 08 Bumper Boats
+ true, // 09 Wooden Wild Mine/Mouse
+ true, // 0a Steeplechase/Motorbike/Soap Box Derby
+ true, // 0b Car Ride
+ false, // 0c Launched Freefall
+ true, // 0d Bobsleigh Coaster
+ false, // 0e Observation Tower
+ true, // 0f Looping Roller Coaster
+ true, // 10 Dinghy Slide
+ true, // 11 Mine Train Coaster
+ true, // 12 Chairlift
+ true, // 13 Corkscrew Roller Coaster
+ false, // 14 Maze
+ false, // 15 Spiral Slide
+ false, // 16 Go Karts
+ false, // 17 Log Flume
+ false, // 18 River Rapids
+ false, // 19 Bumper Cars
+ false, // 1a Pirate Ship
+ false, // 1b Swinging Inverter Ship
+ false, // 1c Food Stall
+ false, // 1d (none)
+ false, // 1e Drink Stall
+ false, // 1f (none)
+ false, // 20 Shop (all types)
+ false, // 21 Merry Go Round
+ false, // 22 Balloon Stall (maybe)
+ false, // 23 Information Kiosk
+ false, // 24 Bathroom
+ false, // 25 Ferris Wheel
+ false, // 26 Motion Simulator
+ false, // 27 3D Cinema
+ false, // 28 Gravitron
+ false, // 29 Space Rings
+ false, // 2a Reverse Freefall Coaster
+ false, // 2b Elevator
+ true, // 2c Vertical Drop Roller Coaster
+ false, // 2d ATM
+ false, // 2e Twist
+ false, // 2f Haunted House
+ false, // 30 First Aid
+ false, // 31 Circus Show
+ true, // 32 Ghost Train
+ true, // 33 Twister Roller Coaster
+ true, // 34 Wooden Roller Coaster
+ true, // 35 Side-Friction Roller Coaster
+ true, // 36 Wild Mouse
+ true, // 37 Multi Dimension Coaster
+ true, // 38 (none)
+ true, // 39 Flying Roller Coaster
+ true, // 3a (none)
+ true, // 3b Virginia Reel
+ false, // 3c Splash Boats
+ true, // 3d Mini Helicopters
+ true, // 3e Lay-down Roller Coaster
+ true, // 3f Suspended Monorail
+ true, // 40 (none)
+ true, // 41 Reverser Roller Coaster
+ true, // 42 Heartline Twister Roller Coaster
+ true, // 43 Mini Golf
+ true, // 44 Giga Coaster
+ false, // 45 Roto-Drop
+ false, // 46 Flying Saucers
+ false, // 47 Crooked House
+ true, // 48 Monorail Cycles
+ true, // 49 Compact Inverted Coaster
+ true, // 4a Water Coaster
+ false, // 4b Air Powered Vertical Coaster
+ true, // 4c Inverted Hairpin Coaster
+ false, // 4d Magic Carpet
+ false, // 4e Submarine Ride
+ false, // 4f River Rafts
+ false, // 50 (none)
+ false, // 51 Enterprise
+ false, // 52 (none)
+ false, // 53 (none)
+ false, // 54 (none)
+ true, // 55 (none)
+ true, // 56 Inverted Impulse Coaster
+ true, // 57 Mini Roller Coaster
+ true, // 58 Mine Ride
+ true, // 59 LIM Launched Roller Coaster
+};
+
+const uint8 rideUnknownData3[0x60] = {
+ 10, // 00 Spiral Roller coaster
+ 10, // 01 Stand Up Coaster
+ 10, // 02 Suspended Swinging
+ 10, // 03 Inverted
+ 5, // 04 Steel Mini Coaster
+ 5, // 05 Mini Railroad
+ 10, // 06 Monorail
+ 10, // 07 Mini Suspended Coaster
+ 0, // 08 Bumper Boats
+ 10, // 09 Wooden Wild Mine/Mouse
+ 10, // 0a Steeplechase/Motorbike/Soap Box Derby
+ 5, // 0b Car Ride
+ 0, // 0c Launched Freefall
+ 10, // 0d Bobsleigh Coaster
+ 0, // 0e Observation Tower
+ 10, // 0f Looping Roller Coaster
+ 10, // 10 Dinghy Slide
+ 10, // 11 Mine Train Coaster
+ 10, // 12 Chairlift
+ 10, // 13 Corkscrew Roller Coaster
+ 0, // 14 Maze
+ 0, // 15 Spiral Slide
+ 0, // 16 Go Karts
+ 10, // 17 Log Flume
+ 10, // 18 River Rapids
+ 0, // 19 Bumper Cars
+ 0, // 1a Pirate Ship
+ 0, // 1b Swinging Inverter Ship
+ 0, // 1c Food Stall
+ 0, // 1d (none)
+ 0, // 1e Drink Stall
+ 0, // 1f (none)
+ 0, // 20 Shop (all types)
+ 0, // 21 Merry Go Round
+ 0, // 22 Balloon Stall (maybe)
+ 0, // 23 Information Kiosk
+ 0, // 24 Bathroom
+ 0, // 25 Ferris Wheel
+ 0, // 26 Motion Simulator
+ 0, // 27 3D Cinema
+ 0, // 28 Gravitron
+ 0, // 29 Space Rings
+ 10, // 2a Reverse Freefall Coaster
+ 0, // 2b Elevator
+ 10, // 2c Vertical Drop Roller Coaster
+ 0, // 2d ATM
+ 0, // 2e Twist
+ 0, // 2f Haunted House
+ 0, // 30 First Aid
+ 0, // 31 Circus Show
+ 5, // 32 Ghost Train
+ 10, // 33 Twister Roller Coaster
+ 10, // 34 Wooden Roller Coaster
+ 10, // 35 Side-Friction Roller Coaster
+ 10, // 36 Wild Mouse
+ 15, // 37 Multi Dimension Coaster
+ 15, // 38 (none)
+ 15, // 39 Flying Roller Coaster
+ 15, // 3a (none)
+ 10, // 3b Virginia Reel
+ 10, // 3c Splash Boats
+ 5, // 3d Mini Helicopters
+ 15, // 3e Lay-down Roller Coaster
+ 10, // 3f Suspended Monorail
+ 15, // 40 (none)
+ 10, // 41 Reverser Roller Coaster
+ 10, // 42 Heartline Twister Roller Coaster
+ 10, // 43 Mini Golf
+ 40, // 44 Giga Coaster
+ 0, // 45 Roto-Drop
+ 0, // 46 Flying Saucers
+ 0, // 47 Crooked House
+ 5, // 48 Monorail Cycles
+ 10, // 49 Compact Inverted Coaster
+ 10, // 4a Water Coaster
+ 10, // 4b Air Powered Vertical Coaster
+ 10, // 4c Inverted Hairpin Coaster
+ 0, // 4d Magic Carpet
+ 0, // 4e Submarine Ride
+ 10, // 4f River Rafts
+ 0, // 50 (none)
+ 0, // 51 Enterprise
+ 0, // 52 (none)
+ 0, // 53 (none)
+ 0, // 54 (none)
+ 10, // 55 (none)
+ 10, // 56 Inverted Impulse Coaster
+ 10, // 57 Mini Roller Coaster
+ 10, // 58 Mine Ride
+ 10, // 59 LIM Launched Roller Coaster
+};
\ No newline at end of file
diff --git a/src/ride_data.h b/src/ride_data.h
new file mode 100644
index 0000000000..d107ad6aac
--- /dev/null
+++ b/src/ride_data.h
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Kevin Burke
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _RIDE_DATA_H_
+#define _RIDE_DATA_H_
+
+#include
+#include "rct2.h"
+
+extern const bool hasRunningTrack[0x60];
+extern const uint8 initialUpkeepCosts[0x60];
+extern const uint8 costPerTrackPiece[0x60];
+
+extern const uint8 rideUnknownData1[0x60];
+extern const bool rideUnknownData2[0x60];
+extern const uint8 rideUnknownData3[0x60];
+
+#endif
\ No newline at end of file
diff --git a/src/ride_ratings.c b/src/ride_ratings.c
new file mode 100644
index 0000000000..915c78a3e2
--- /dev/null
+++ b/src/ride_ratings.c
@@ -0,0 +1,260 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Ted John
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#include "addresses.h"
+#include "ride.h"
+#include "ride_data.h"
+#include "ride_ratings.h"
+
+/**
+ * rct2: 0x0065C4D4
+ *
+ * Compute excitement, intensity, etc. for a crooked house ride.
+ */
+void crooked_house_excitement(rct_ride *ride)
+{
+ // Set lifecycle bits
+ ride->lifecycle_flags |= RIDE_LIFECYCLE_TESTED;
+ ride->lifecycle_flags |= RIDE_LIFECYCLE_NO_RAW_STATS;
+ ride->var_198 = 5;
+ sub_655FD6(ride);
+
+ ride_rating excitement = RIDE_RATING(2,15);
+ ride_rating intensity = RIDE_RATING(0,62);
+ ride_rating nausea = RIDE_RATING(0,34);
+
+ // NB this should get marked out by the compiler, if it's smart.
+ excitement = apply_intensity_penalty(excitement, intensity);
+ rating_tuple tup = per_ride_rating_adjustments(ride, excitement, intensity, nausea);
+ excitement = tup.excitement;
+ intensity = tup.intensity;
+ nausea = tup.nausea;
+
+ ride->excitement = excitement;
+ ride->intensity = intensity;
+ ride->nausea = nausea;
+
+ ride->upkeep_cost = compute_upkeep(ride);
+ // Upkeep flag? or a dirtiness flag
+ ride->var_14D |= 2;
+
+ // clear all bits except lowest 5
+ ride->var_114 &= 0x1f;
+ // set 6th,7th,8th bits
+ ride->var_114 |= 0xE0;
+}
+
+/**
+ * rct2: sub_65E621
+ *
+ * I think this function computes ride upkeep? Though it is weird that the
+ *
+ * inputs
+ * - edi: ride ptr
+ */
+uint16 compute_upkeep(rct_ride *ride)
+{
+ // data stored at 0x0057E3A8, incrementing 18 bytes at a time
+ uint16 upkeep = initialUpkeepCosts[ride->type];
+
+ uint16 trackCost = costPerTrackPiece[ride->type];
+ uint8 dl = ride->var_115;
+
+ dl = dl >> 6;
+ dl = dl & 3;
+ upkeep += trackCost * dl;
+
+ uint32 cuml = ride->var_0E4;
+ cuml += ride->var_0E8;
+ cuml += ride->var_0EC;
+ cuml += ride->var_0F0;
+ cuml = cuml >> 0x10;
+
+ // The data originally here was 20's and 0's. The 20's all represented
+ // rides that had tracks. The 0's were fixed rides like crooked house or
+ // bumper cars.
+ // Data source is 0x0097E3AC
+ if (hasRunningTrack[ride->type]) {
+ cuml = cuml * 20;
+ }
+ cuml = cuml >> 0x0A;
+ upkeep += (uint16)cuml;
+
+ if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO) {
+ // The original code read from a table starting at 0x0097E3AE and
+ // incrementing by 0x12 bytes between values. However, all of these
+ // values were 40. I have replaced the table lookup with the constant
+ // 40 in this case.
+ upkeep += 40;
+ }
+
+ // Originally this data was at 0x0097E3B0 and incrementing in 18 byte
+ // offsets. The value here for every ride is 80, except for the reverser,
+ // which is 10
+ uint16 eax;
+ if (ride->type == RIDE_TYPE_REVERSER_ROLLER_COASTER) {
+ eax = 10;
+ } else {
+ eax = 80;
+ }
+
+ // not sure what this value is; it's only written to in one place, where
+ // it's incremented.
+ sint16 dx = RCT2_GLOBAL(0x0138B5CC, sint16);
+ upkeep += eax * dx;
+
+ dx = RCT2_GLOBAL(0x0138B5CA, sint16);
+ // Originally there was a lookup into a table at 0x0097E3B0 and
+ // incrementing in 18 byte offsets. The value here for every ride was 20,
+ // so it's been replaced here by the constant.
+ upkeep += 20 * dx;
+
+ // these seem to be adhoc adjustments to a ride's upkeep/cost, times
+ // various variables set on the ride itself.
+
+ // https://gist.github.com/kevinburke/e19b803cd2769d96c540
+ upkeep += rideUnknownData1[ride->type] * ride->var_0C8;
+
+ // either set to 3 or 0, extra boosts for some rides including mini golf
+ if (rideUnknownData2[ride->type]) {
+ upkeep += 3 * ride->var_0C9;
+ }
+
+ // slight upkeep boosts for some rides - 5 for mini railroad, 10 for log
+ // flume/rapids, 10 for roller coaster, 28 for giga coaster
+ upkeep += rideUnknownData3[ride->type] * ride->var_0C7;
+
+ if (ride->mode == RIDE_MODE_REVERSE_INCLINED_SHUTTLE) {
+ upkeep += 30;
+ } else if (ride->mode == RIDE_MODE_POWERED_LAUNCH) {
+ upkeep += 160;
+ } else if (ride->mode == RIDE_MODE_LIM_POWERED_LAUNCH) {
+ upkeep += 320;
+ } else if (ride->mode == RIDE_MODE_POWERED_LAUNCH2 ||
+ ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED) {
+ upkeep += 220;
+ }
+
+ // multiply by 5/8
+ upkeep = upkeep * 10;
+ upkeep = upkeep >> 4;
+ return upkeep;
+}
+
+/**
+ * rct2: 0x0065E7FB
+ *
+ * inputs
+ * - bx: excitement
+ * - cx: intensity
+ * - bp: nausea
+ * - edi: ride ptr
+ */
+rating_tuple per_ride_rating_adjustments(rct_ride *ride, ride_rating excitement,
+ ride_rating intensity, ride_rating nausea)
+{
+ // NB: The table here is allocated dynamically. Reading the exe will tell
+ // you nothing
+ uint32 subtype_p = RCT2_GLOBAL(0x009ACFA4 + ride->subtype * 4, uint32);
+
+ // example value here: 12 (?)
+ sint16 ctr = RCT2_GLOBAL(subtype_p + 0x1b2, sint16);
+ excitement = excitement + ((excitement * ctr) >> 7);
+
+ ctr = RCT2_GLOBAL(subtype_p + 0x1b3, sint16);
+ intensity = intensity + ((intensity * ctr) >> 7);
+
+ ctr = RCT2_GLOBAL(subtype_p + 0x1b4, sint16);
+ nausea = nausea + ((nausea * ctr) >> 7);
+
+ // As far as I can tell, this flag detects whether the ride is a roller
+ // coaster, or a log flume or rapids. Everything else it's not set.
+ // more detail: https://gist.github.com/kevinburke/d951e74e678b235eef3e
+ uint16 ridetype_var = RCT2_GLOBAL(0x0097D4F2 + ride->type * 8, uint16);
+ if (ridetype_var & 0x80) {
+ uint16 ax = ride->var_1F4;
+ if (RCT2_GLOBAL(subtype_p + 8, uint32) & 0x800) {
+ // 65e86e
+ ax = ax - 96;
+ if (ax >= 0) {
+ ax = ax >> 3;
+ excitement = excitement - ax;
+ ax = ax >> 1;
+ nausea = nausea - ax;
+ }
+ } else {
+ ax = ax >> 3;
+ excitement = excitement + ax;
+ ax = ax >> 1;
+ nausea += ax;
+ }
+ }
+ rating_tuple tup = { excitement, intensity, nausea };
+ return tup;
+}
+
+/**
+ * rct2: 0x0065E7A3
+ *
+ * inputs from x86
+ * - bx: excitement
+ * - cx: intensity
+ * - bp: nausea
+ *
+ * returns: the excitement level, with intensity penalties applied
+ */
+ride_rating apply_intensity_penalty(ride_rating excitement, ride_rating intensity)
+{
+ // intensity penalty
+ if (intensity >= 1000) {
+ excitement = excitement - (excitement >> 2);
+ }
+ if (intensity >= 1100) {
+ excitement = excitement - (excitement >> 2);
+ }
+ if (intensity >= 1200) {
+ excitement = excitement - (excitement >> 2);
+ }
+ if (intensity >= 1320) {
+ excitement = excitement - (excitement >> 2);
+ }
+ if (intensity >= 1450) {
+ excitement = excitement - (excitement >> 2);
+ }
+ return excitement;
+}
+
+/**
+ * rct2: 0x00655FD6
+ *
+ * Take ride property 1CD, make some modifications, store the modified value in
+ * property 198.
+ */
+void sub_655FD6(rct_ride *ride)
+{
+ uint8 al = ride->var_1CD;
+ // No idea what this address is; maybe like compensation of some kind? The
+ // maximum possible value?
+ // List of ride names/values is here:
+ // https://gist.github.com/kevinburke/5eebcda14d94e6ee99c0
+ al -= RCT2_ADDRESS(0x0097D7C9, uint8)[4 * ride->type];
+ al = al << 1;
+ ride->var_198 += al;
+}
diff --git a/src/ride_ratings.h b/src/ride_ratings.h
new file mode 100644
index 0000000000..28ad8bc451
--- /dev/null
+++ b/src/ride_ratings.h
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2014 Kevin Burke
+ * OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
+ *
+ * This file is part of OpenRCT2.
+ *
+ * OpenRCT2 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *****************************************************************************/
+
+#ifndef _RIDE_RATINGS_H_
+#define _RIDE_RATINGS_H_
+
+#include "rct2.h"
+
+typedef fixed16_2dp ride_rating;
+
+#define RIDE_RATING(whole, fraction) FIXED_2DP(whole, fraction)
+
+// Used for return values, for functions that modify all three.
+typedef struct {
+ ride_rating excitement;
+ ride_rating intensity;
+ ride_rating nausea;
+} rating_tuple;
+
+void crooked_house_excitement(rct_ride *ride);
+void sub_655FD6(rct_ride *ride);
+ride_rating apply_intensity_penalty(ride_rating excitement, ride_rating intensity);
+rating_tuple per_ride_rating_adjustments(rct_ride *ride, ride_rating excitement,
+ ride_rating intensity, ride_rating nausea);
+uint16 compute_upkeep(rct_ride *ride);
+
+#endif
\ No newline at end of file