Merge pull request #2605 from OpenRCT2/vehicle-update

Vehicle Update
This commit is contained in:
Duncan 2016-01-10 17:13:02 +00:00
commit 8997f2aa6a
28 changed files with 9175 additions and 484 deletions

View File

@ -15,6 +15,7 @@
D43532601C34730200BA219B /* libpng.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D435325E1C3472E500BA219B /* libpng.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
D46105CE1C38828D00DB1EE3 /* scenario_sources.c in Sources */ = {isa = PBXBuildFile; fileRef = D46105CD1C38828D00DB1EE3 /* scenario_sources.c */; };
D4ABAB061C2F812B0080CAD9 /* news_options.c in Sources */ = {isa = PBXBuildFile; fileRef = D4ABAB051C2F812B0080CAD9 /* news_options.c */; };
D4B85B5B1C41C7F3005C568A /* cable_lift.c in Sources */ = {isa = PBXBuildFile; fileRef = D4B85B591C41C7F3005C568A /* cable_lift.c */; };
D4B8C2A81C41EADF00B006AC /* argparse.c in Sources */ = {isa = PBXBuildFile; fileRef = D4B8C2A61C41EADF00B006AC /* argparse.c */; };
D4D4DF141C34697B0048BE43 /* image_io.c in Sources */ = {isa = PBXBuildFile; fileRef = D4D4DF121C34697B0048BE43 /* image_io.c */; };
D4EC47DF1C26342F0024B507 /* addresses.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC46D61C26342F0024B507 /* addresses.c */; };
@ -221,6 +222,8 @@
D4895D321C23EFDD000CD788 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = distribution/osx/Info.plist; sourceTree = SOURCE_ROOT; };
D497D0781C20FD52002BF46A /* OpenRCT2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenRCT2.app; sourceTree = BUILT_PRODUCTS_DIR; };
D4ABAB051C2F812B0080CAD9 /* news_options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = news_options.c; sourceTree = "<group>"; };
D4B85B591C41C7F3005C568A /* cable_lift.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cable_lift.c; sourceTree = "<group>"; };
D4B85B5A1C41C7F3005C568A /* cable_lift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cable_lift.h; sourceTree = "<group>"; };
D4B8C2A61C41EADF00B006AC /* argparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = argparse.c; sourceTree = "<group>"; };
D4B8C2A71C41EADF00B006AC /* argparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = argparse.h; sourceTree = "<group>"; };
D4D4DF121C34697B0048BE43 /* image_io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = image_io.c; path = src/image_io.c; sourceTree = "<group>"; };
@ -856,6 +859,8 @@
D4EC475C1C26342F0024B507 /* ride */ = {
isa = PBXGroup;
children = (
D4B85B591C41C7F3005C568A /* cable_lift.c */,
D4B85B5A1C41C7F3005C568A /* cable_lift.h */,
D4EC475D1C26342F0024B507 /* ride.c */,
D4EC475E1C26342F0024B507 /* ride.h */,
D4EC475F1C26342F0024B507 /* ride_data.c */,
@ -1425,6 +1430,7 @@
D4EC48111C26342F0024B507 /* network.cpp in Sources */,
D4EC47FF1C26342F0024B507 /* widget.c in Sources */,
D4EC48691C26342F0024B507 /* title_options.c in Sources */,
D4B85B5B1C41C7F3005C568A /* cable_lift.c in Sources */,
D4EC48471C26342F0024B507 /* map_tooltip.c in Sources */,
D4EC483F1C26342F0024B507 /* guest.c in Sources */,
D4EC487A1C26342F0024B507 /* map_helpers.c in Sources */,

View File

@ -85,6 +85,7 @@
<ClCompile Include="src\platform\windows.c" />
<ClCompile Include="src\rct1.c" />
<ClCompile Include="src\rct2.c" />
<ClCompile Include="src\ride\cable_lift.c" />
<ClCompile Include="src\ride\ride.c" />
<ClCompile Include="src\ride\ride_data.c" />
<ClCompile Include="src\ride\ride_ratings.c" />
@ -247,6 +248,7 @@
<ClInclude Include="src\platform\platform.h" />
<ClInclude Include="src\rct1.h" />
<ClInclude Include="src\rct2.h" />
<ClInclude Include="src\ride\cable_lift.h" />
<ClInclude Include="src\ride\ride.h" />
<ClInclude Include="src\ride\ride_data.h" />
<ClInclude Include="src\ride\ride_ratings.h" />
@ -370,4 +372,4 @@
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
</Project>

View File

@ -543,8 +543,11 @@
<ClCompile Include="src\addresses.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="src\ride\cable_lift.c">
<Filter>Source\Ride</Filter>
</ClCompile>
<ClCompile Include="src\drawing\supports.c">
<Filter>Source</Filter>
<Filter>Source\Drawing</Filter>
</ClCompile>
<ClCompile Include="src\windows\news_options.c">
<Filter>Source\Windows</Filter>
@ -830,6 +833,12 @@
<ClInclude Include="src\interface\colour.h">
<Filter>Source\Interface</Filter>
</ClInclude>
<ClInclude Include="src\ride\cable_lift.h">
<Filter>Source\Ride</Filter>
</ClInclude>
<ClInclude Include="src\core\Util.hpp">
<Filter>Source\Core</Filter>
</ClInclude>
<ClInclude Include="src\drawing\supports.h">
<Filter>Source\Drawing</Filter>
</ClInclude>
@ -852,4 +861,4 @@
<Filter>Source\argparse</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>

View File

@ -806,6 +806,7 @@ void* Mixer_Play_Effect(size_t id, int loop, int volume, float pan, double rate,
return 0;
}
if (id >= Util::CountOf(gMixer.css1sources)) {
log_error("Tried to play an invalid sound id. %i", id);
return 0;
}
gMixer.Lock();

View File

@ -87,7 +87,7 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in
data[i++] = 0x89; //mov eax, esp
data[i++] = 0xE0;
data[i++] = 0x83; //sub eax, (0xC + numargs*4) & 0xF
data[i++] = 0xE8;
data[i++] = 0xE8;
data[i++] = (0xC + numrargs * 4) & 0xF;
data[i++] = 0x83; //and eax, 0xC
data[i++] = 0xE0;
@ -95,7 +95,7 @@ void hookfunc(int address, int newaddress, int stacksize, int registerargs[], in
data[i++] = 0xA3; //mov [0x9ABDA8], eax
data[i++] = 0xA8;
data[i++] = 0xBD;
data[i++] = 0x9A;
data[i++] = 0x9A;
data[i++] = 0x00;
data[i++] = 0x58; //pop eax
data[i++] = 0x2B; //sub esp, [0x9ABDA8]

View File

@ -501,14 +501,14 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT) {
int al = 1;
if (vehicleEntry->var_14 & 2) {
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SWINGING) {
al = 13;
if ((vehicleEntry->var_14 & 0x820) != 0x820) {
if ((vehicleEntry->flags_b & (VEHICLE_ENTRY_FLAG_B_5 | VEHICLE_ENTRY_FLAG_B_11)) != (VEHICLE_ENTRY_FLAG_B_5 | VEHICLE_ENTRY_FLAG_B_11)) {
al = 7;
if (!(vehicleEntry->var_14 & 0x20)) {
if (!(vehicleEntry->var_14 & 0x800)) {
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_5)) {
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_11)) {
al = 5;
if (vehicleEntry->var_14 & 0x200) {
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_9) {
al = 3;
}
}
@ -519,18 +519,18 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
// 0x6DE90B
al = 0x20;
if (!(vehicleEntry->var_12 & 0x4000)) {
if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_14)) {
al = 1;
if (vehicleEntry->var_14 & 0x80) {
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_7) {
if (vehicleEntry->var_11 != 6) {
al = 2;
if (!(vehicleEntry->var_12 & 0x80)) {
if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_7)) {
al = 4;
}
}
}
}
if (vehicleEntry->var_12 & 0x1000) {
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_12) {
al = vehicleEntry->special_frames;
}
vehicleEntry->var_02 = al;
@ -543,7 +543,7 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
if (vehicleEntry->car_visual != VEHICLE_VISUAL_RIVER_RAPIDS) {
int b = vehicleEntry->var_16 * 32;
if (vehicleEntry->var_12 & 0x800) b /= 2;
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_11) b /= 2;
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_15) b /= 8;
image_index += b;
@ -552,7 +552,7 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) {
vehicleEntry->var_20 = image_index;
b = vehicleEntry->var_16 * 72;
if (vehicleEntry->var_12 & 0x4000)
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_14)
b = vehicleEntry->var_16 * 16;
image_index += b;
@ -564,12 +564,14 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
b = vehicleEntry->var_16 * 80;
image_index += b;
}
// Verticle
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) {
vehicleEntry->var_28 = image_index;
b = vehicleEntry->var_16 * 116;
image_index += b;
}
// Unknown
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) {
vehicleEntry->var_2C = image_index;
@ -596,12 +598,14 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
b = vehicleEntry->var_16 * 128;
image_index += b;
}
// Unknown
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) {
vehicleEntry->var_3C = image_index;
b = vehicleEntry->var_16 * 16;
image_index += b;
}
// Unknown
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) {
vehicleEntry->var_40 = image_index;
@ -626,6 +630,7 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
b = vehicleEntry->var_16 * 80;
image_index += b;
}
// Unknown
if (vehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION) {
vehicleEntry->var_1C = image_index;
@ -649,9 +654,9 @@ static bool object_type_ride_load(void *objectEntry, uint32 entryIndex)
cur_vehicle_images_offset = image_index + vehicleEntry->no_seating_rows * vehicleEntry->no_vehicle_images;
// 0x6DEB0D
if (!(vehicleEntry->var_12 & 0x400)) {
if (!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_10)) {
int num_images = cur_vehicle_images_offset - vehicleEntry->base_image_id;
if (vehicleEntry->var_12 & 0x2000) {
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_13) {
num_images *= 2;
}
@ -734,7 +739,7 @@ static void object_type_ride_unload(void *objectEntry)
rideVehicleEntry->no_vehicle_images = 0;
rideVehicleEntry->var_16 = 0;
if (!(rideVehicleEntry->var_12 & 0x400)) {
if (!(rideVehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_10)) {
rideVehicleEntry->sprite_width = 0;
rideVehicleEntry->sprite_height_negative = 0;
rideVehicleEntry->sprite_height_positive = 0;

View File

@ -37,6 +37,7 @@
#include "../world/footpath.h"
#include "../management/marketing.h"
#include "../game.h"
#include "../ride/track.h"
#include "peep.h"
#include "staff.h"
@ -1657,8 +1658,8 @@ static void peep_go_to_ride_entrance(rct_peep* peep, rct_ride* ride){
uint8 shift_multiplier = 21;
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
if (ride_type->vehicles[ride_type->default_vehicle].var_12 & (1 << 3) ||
ride_type->vehicles[ride_type->default_vehicle].var_14 & 0x5000){
if (ride_type->vehicles[ride_type->default_vehicle].flags_a & VEHICLE_ENTRY_FLAG_A_3 ||
ride_type->vehicles[ride_type->default_vehicle].flags_b & (VEHICLE_ENTRY_FLAG_B_12 | VEHICLE_ENTRY_FLAG_B_14)){
shift_multiplier = 32;
}
@ -1736,7 +1737,7 @@ static void peep_update_ride_sub_state_0(rct_peep* peep){
}
}
else{
chosen_train = ride->var_066[peep->current_ride_station];
chosen_train = ride->train_at_station[peep->current_ride_station];
}
if (chosen_train == 0xFF){
return;
@ -1862,8 +1863,8 @@ void peep_update_ride_sub_state_1(rct_peep* peep){
{
uint8 vehicle = ride_entry->default_vehicle;
if (ride_entry->vehicles[vehicle].var_12 & (1 << 3) ||
ride_entry->vehicles[vehicle].var_14 & ((1 << 14) | (1<<12)))
if (ride_entry->vehicles[vehicle].flags_a & VEHICLE_ENTRY_FLAG_A_3 ||
ride_entry->vehicles[vehicle].flags_b & (VEHICLE_ENTRY_FLAG_B_12 | VEHICLE_ENTRY_FLAG_B_14))
RCT2_GLOBAL(0xF1AECA, uint16) = 0x1C;
else
RCT2_GLOBAL(0xF1AECA, uint16) = 0x10;
@ -1964,7 +1965,7 @@ void peep_update_ride_sub_state_1(rct_peep* peep){
ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype);
rct_ride_type_vehicle* vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type];
if (vehicle_type->var_14 & (1 << 10)){
if (vehicle_type->flags_b & VEHICLE_ENTRY_FLAG_B_10){
sint16 x, y, z;
x = ride->entrances[peep->current_ride_station] & 0xFF;
y = ride->entrances[peep->current_ride_station] >> 8;
@ -2021,7 +2022,7 @@ void peep_update_ride_sub_state_1(rct_peep* peep){
return;
}
if (vehicle_type->var_14 & (1 << 15)){
if (vehicle_type->flags_b & VEHICLE_ENTRY_FLAG_B_15){
peep->destination_x = vehicle->x;
peep->destination_y = vehicle->y;
peep->destination_tolerence = 15;
@ -2074,8 +2075,8 @@ static void peep_go_to_ride_exit(rct_peep* peep, rct_ride* ride, sint16 x, sint1
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->default_vehicle];
if (vehicle_entry->var_12 & (1 << 3) ||
vehicle_entry->var_14 & 0x5000){
if (vehicle_entry->flags_a & VEHICLE_ENTRY_FLAG_A_3 ||
vehicle_entry->flags_b & (VEHICLE_ENTRY_FLAG_B_12 | VEHICLE_ENTRY_FLAG_B_14)){
shift_multiplier = 32;
}
@ -2226,7 +2227,7 @@ static void peep_update_ride_sub_state_2(rct_peep* peep){
rct_ride_type* ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype);
if (ride_entry->vehicles[0].var_12 & (1 << 3)){
if (ride_entry->vehicles[0].flags_a & VEHICLE_ENTRY_FLAG_A_3){
vehicle->var_D5 &= ~(1 << 5);
@ -2272,8 +2273,7 @@ static void peep_update_ride_sub_state_2(rct_peep* peep){
rct_vehicle *currentTrain = GET_VEHICLE(ride->vehicles[peep->current_train]);
if (ride->status == RIDE_STATUS_OPEN &&
++peep->var_AC != 0 &&
!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART)
) {
!(currentTrain->update_flags & VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART)){
return;
}
@ -2378,7 +2378,7 @@ void peep_update_ride_sub_state_7(rct_peep* peep){
rct_ride_type* ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype);
rct_ride_type_vehicle* vehicle_entry = &ride_entry->vehicles[vehicle->vehicle_type];
if (!(vehicle_entry->var_14 & (1 << 10))){
if (!(vehicle_entry->flags_b & VEHICLE_ENTRY_FLAG_B_10)){
sint16 x, y, z;
x = ride->exits[peep->current_ride_station] & 0xFF;
y = ride->exits[peep->current_ride_station] >> 8;
@ -2393,7 +2393,7 @@ void peep_update_ride_sub_state_7(rct_peep* peep){
for (; vehicle->is_child; vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride)){
uint16 trackType = vehicle->track_type >> 2;
if (trackType == 0 || trackType > 3)
if (trackType == TRACK_ELEM_FLAT || trackType > TRACK_ELEM_MIDDLE_STATION)
continue;
rct_map_element* inner_map = map_get_first_element_at(vehicle->track_x / 32, vehicle->track_y / 32);
@ -2413,12 +2413,12 @@ void peep_update_ride_sub_state_7(rct_peep* peep){
vehicle_entry = &ride_entry->vehicles[ride_entry->default_vehicle];
uint8 shift_multiplier = 12;
if (vehicle_entry->var_14 & (1 << 14)){
if (vehicle_entry->flags_b & VEHICLE_ENTRY_FLAG_B_14){
shift_multiplier = 9;
}
uint8 direction = exit_direction;
if (vehicle_entry->var_14 & ((1 << 14) | (1 << 12))){
if (vehicle_entry->flags_b & (VEHICLE_ENTRY_FLAG_B_12 | VEHICLE_ENTRY_FLAG_B_14)){
direction = ((vehicle->sprite_direction + 3) / 8) + 1;
direction &= 3;
@ -2559,7 +2559,7 @@ static void peep_update_ride_prepare_for_state_9(rct_peep* peep){
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->default_vehicle];
if (vehicle_entry->var_14 & 0x5000){
if (vehicle_entry->flags_b & (VEHICLE_ENTRY_FLAG_B_12 | VEHICLE_ENTRY_FLAG_B_14)){
shift_multiplier = 32;
}
@ -2775,7 +2775,7 @@ static void peep_update_ride_sub_state_13(rct_peep* peep){
rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype);
rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->default_vehicle];
if (vehicle_entry->var_14 & 0x5000){
if (vehicle_entry->flags_b & (VEHICLE_ENTRY_FLAG_B_12 | VEHICLE_ENTRY_FLAG_B_14)){
shift_multiplier = 32;
}

View File

@ -414,7 +414,7 @@ typedef struct {
uint16 next_y; // 0x26
uint8 next_z; // 0x28
uint8 next_var_29; // 0x29
uint8 outside_of_park; // 0x2A
uint8 outside_of_park; // 0x2A
uint8 state; // 0x2B
uint8 sub_state; // 0x2C
uint8 sprite_type; // 0x2D

View File

@ -712,7 +712,7 @@ static void rct1_fix_z()
for (int i = 0; i < 4; i++) {
ride->station_heights[i] /= 2;
}
ride->var_116 /= 2;
ride->start_drop_height /= 2;
ride->highest_drop_height = 1;
if (ride->var_11F != 255) {
ride->var_11F /= 2;

485
src/ride/cable_lift.c Normal file
View File

@ -0,0 +1,485 @@
#include "../world/sprite.h"
#include "cable_lift.h"
#include "ride.h"
#include "track.h"
static void cable_lift_update_moving_to_end_of_station(rct_vehicle *vehicle);
static void cable_lift_update_waiting_to_depart(rct_vehicle *vehicle);
static void cable_lift_update_departing(rct_vehicle *vehicle);
static void cable_lift_update_travelling(rct_vehicle *vehicle);
static void cable_lift_update_arriving(rct_vehicle *vehicle);
rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int direction, uint16 var_44, sint32 remaining_distance, bool head)
{
rct_ride *ride = GET_RIDE(rideIndex);
rct_vehicle *current = &(create_sprite(1)->vehicle);
current->sprite_identifier = SPRITE_IDENTIFIER_VEHICLE;
current->ride = rideIndex;
current->ride_subtype = 0xFF;
if (head) {
move_sprite_to_list((rct_sprite*)current, SPRITE_LINKEDLIST_OFFSET_VEHICLE);
ride->cable_lift = current->sprite_index;
}
current->is_child = head ? 0 : 1;
current->var_44 = var_44;
current->remaining_distance = remaining_distance;
current->sprite_width = 10;
current->sprite_height_negative = 10;
current->sprite_height_positive = 10;
current->friction = 100;
current->num_seats = 0;
current->speed = 20;
current->powered_acceleration = 80;
current->velocity = 0;
current->acceleration = 0;
current->var_4A = 0;
current->swinging_car_var_0 = 0;
current->var_4E = 0;
current->restraints_position = 0;
current->var_BA = 0;
current->var_B6 = 0;
current->var_B8 = 0;
current->sound1_id = 0xFF;
current->sound2_id = 0xFF;
current->var_C4 = 0;
current->var_C5 = 0;
current->var_C8 = 0;
current->var_CA = 0;
current->scream_sound_id = 0xFF;
current->var_1F = 0;
current->var_20 = 0;
for (int j = 0; j < 32; j++) {
current->peep[j] = SPRITE_INDEX_NULL;
}
current->var_CD = 0;
current->sprite_direction = direction << 3;
current->track_x = x;
current->track_y = y;
z = z * 8;
current->track_z = z;
z += RCT2_GLOBAL(0x0097D21A + (ride->type * 8), sint8);
sprite_move(16, 16, z, (rct_sprite*)current);
current->track_type = (TRACK_ELEM_CABLE_LIFT_HILL << 2) | (current->sprite_direction >> 3);
current->track_progress = 164;
current->update_flags = VEHICLE_UPDATE_FLAG_1;
current->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION;
current->sub_state = 0;
current->num_peeps = 0;
current->next_free_seat = 0;
return current;
}
void cable_lift_update(rct_vehicle *vehicle)
{
switch (vehicle->status) {
case VEHICLE_STATUS_MOVING_TO_END_OF_STATION:
cable_lift_update_moving_to_end_of_station(vehicle);
break;
case VEHICLE_STATUS_WAITING_FOR_PASSENGERS:
// Stays in this state until a train puts it into next state
break;
case VEHICLE_STATUS_WAITING_TO_DEPART:
cable_lift_update_waiting_to_depart(vehicle);
break;
case VEHICLE_STATUS_DEPARTING:
cable_lift_update_departing(vehicle);
break;
case VEHICLE_STATUS_TRAVELLING:
cable_lift_update_travelling(vehicle);
break;
case VEHICLE_STATUS_ARRIVING:
cable_lift_update_arriving(vehicle);
break;
}
}
/**
*
* rct2: 0x006DF8A4
*/
static void cable_lift_update_moving_to_end_of_station(rct_vehicle *vehicle)
{
if (vehicle->velocity >= -439800)
vehicle->acceleration = -2932;
if (vehicle->velocity < -439800) {
vehicle->velocity -= vehicle->velocity / 16;
vehicle->acceleration = 0;
}
if (!(cable_lift_update_track_motion(vehicle) & (1 << 0)))
return;
vehicle->velocity = 0;
vehicle->acceleration = 0;
vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS;
}
/**
*
* rct2: 0x006DF8F1
*/
static void cable_lift_update_waiting_to_depart(rct_vehicle *vehicle)
{
if (vehicle->velocity >= -58640)
vehicle->acceleration = -14660;
if (vehicle->velocity < -58640) {
vehicle->velocity -= vehicle->velocity / 16;
vehicle->acceleration = 0;
}
cable_lift_update_track_motion(vehicle);
// Next check to see if the second part of the cable lift
// is at the front of the passenger vehicle to simulate the
// cable being attached underneath the train.
rct_vehicle* passengerVehicle = GET_VEHICLE(vehicle->var_C0);
rct_vehicle* cableLiftSecondPart = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
sint16 dist_x = abs(passengerVehicle->x - cableLiftSecondPart->x);
sint16 dist_y = abs(passengerVehicle->y - cableLiftSecondPart->y);
if (dist_x + dist_y > 2)
return;
vehicle->velocity = 0;
vehicle->acceleration = 0;
vehicle->status = VEHICLE_STATUS_DEPARTING;
vehicle->sub_state = 0;
}
/**
*
* rct2: 0x006DF97A
*/
static void cable_lift_update_departing(rct_vehicle *vehicle)
{
vehicle->sub_state++;
if (vehicle->sub_state < 16)
return;
rct_vehicle* passengerVehicle = GET_VEHICLE(vehicle->var_C0);
vehicle->status = VEHICLE_STATUS_TRAVELLING;
passengerVehicle->status = VEHICLE_STATUS_TRAVELLING_CABLE_LIFT;
}
/**
*
* rct2: 0x006DF99C
*/
static void cable_lift_update_travelling(rct_vehicle *vehicle)
{
rct_vehicle* passengerVehicle = GET_VEHICLE(vehicle->var_C0);
vehicle->velocity = min(passengerVehicle->velocity, 439800);
vehicle->acceleration = 0;
if (passengerVehicle->update_flags & VEHICLE_UPDATE_FLAG_BROKEN_TRAIN)
return;
if (!(cable_lift_update_track_motion(vehicle) & (1 << 1)))
return;
vehicle->velocity = 0;
vehicle->acceleration = 0;
vehicle->status = VEHICLE_STATUS_ARRIVING;
vehicle->sub_state = 0;
}
/**
*
* rct2: 0x006DF9F0
*/
static void cable_lift_update_arriving(rct_vehicle *vehicle)
{
vehicle->sub_state++;
if (vehicle->sub_state >= 64)
vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION;
}
bool sub_6DF01A_loop(rct_vehicle* vehicle) {
rct_ride* ride = GET_RIDE(vehicle->ride);
rct_xyz16 *unk_F64E20 = RCT2_ADDRESS(0x00F64E20, rct_xyz16);
for (; vehicle->remaining_distance >= 13962; RCT2_GLOBAL(0x00F64E10, uint32)++) {
uint8 trackType = vehicle->track_type >> 2;
if (trackType == TRACK_ELEM_CABLE_LIFT_HILL &&
vehicle->track_progress == 160) {
RCT2_GLOBAL(0x00F64E18, uint32) |= (1 << 1);
}
uint16 trackProgress = vehicle->track_progress + 1;
const rct_vehicle_info *moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, 0);
uint16 trackTotalProgress = *((uint16*)((int)moveInfo - 2));
if (trackProgress >= trackTotalProgress) {
RCT2_GLOBAL(0x00F64E36, uint8) = gTrackDefinitions[trackType].vangle_end;
RCT2_GLOBAL(0x00F64E37, uint8) = gTrackDefinitions[trackType].bank_end;
rct_map_element* trackElement =
map_get_track_element_at_of_type_seq(
vehicle->track_x,
vehicle->track_y,
vehicle->track_z / 8,
trackType,
0);
rct_xy_element input;
rct_xy_element output;
int outputZ;
int outputDirection;
input.x = vehicle->track_x;
input.y = vehicle->track_y;
input.element = trackElement;
if (!track_block_get_next(&input, &output, &outputZ, &outputDirection))
return false;
if (gTrackDefinitions[output.element->properties.track.type].vangle_start != RCT2_GLOBAL(0x00F64E36, uint8) ||
gTrackDefinitions[output.element->properties.track.type].bank_start != RCT2_GLOBAL(0x00F64E37, uint8))
return false;
vehicle->track_x = output.x;
vehicle->track_y = output.y;
vehicle->track_z = outputZ;
vehicle->track_direction = outputDirection;
vehicle->track_type |= output.element->properties.track.type << 2;
trackProgress = 0;
}
vehicle->track_progress = trackProgress;
moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, trackProgress);
rct_xyz16 unk = {
.x = moveInfo->x,
.y = moveInfo->y,
.z = moveInfo->z
};
unk.x += vehicle->track_x;
unk.y += vehicle->track_y;
unk.z += vehicle->track_z;
uint8 bx = 0;
unk.z += RCT2_GLOBAL(0x0097D21A + (ride->type * 8), sint8);
if (unk.x != unk_F64E20->x)
bx |= (1 << 0);
if (unk.y != unk_F64E20->y)
bx |= (1 << 1);
if (unk.z != unk_F64E20->z)
bx |= (1 << 2);
vehicle->remaining_distance -= RCT2_ADDRESS(0x009A2930, sint32)[bx];
unk_F64E20->x = unk.x;
unk_F64E20->y = unk.y;
unk_F64E20->z = unk.z;
vehicle->sprite_direction = moveInfo->direction;
vehicle->var_20 = moveInfo->var_08;
vehicle->var_1F = moveInfo->var_07;
if (vehicle->remaining_distance >= 13962) {
vehicle->acceleration += RCT2_ADDRESS(0x009A2970, sint32)[vehicle->var_1F];
}
}
return true;
}
bool sub_6DF21B_loop(rct_vehicle* vehicle) {
rct_ride* ride = GET_RIDE(vehicle->ride);
rct_xyz16 *unk_F64E20 = RCT2_ADDRESS(0x00F64E20, rct_xyz16);
for (; vehicle->remaining_distance < 0; RCT2_GLOBAL(0x00F64E10, uint32)++) {
uint16 trackProgress = vehicle->track_progress - 1;
const rct_vehicle_info *moveInfo;
if ((sint16)trackProgress == -1) {
uint8 trackType = vehicle->track_type >> 2;
RCT2_GLOBAL(0x00F64E36, uint8) = gTrackDefinitions[trackType].vangle_start;
RCT2_GLOBAL(0x00F64E37, uint8) = gTrackDefinitions[trackType].bank_start;
rct_map_element* trackElement =
map_get_track_element_at_of_type_seq(
vehicle->track_x,
vehicle->track_y,
vehicle->track_z / 8,
trackType,
0);
rct_xy_element input;
input.x = vehicle->track_x;
input.y = vehicle->track_y;
input.element = trackElement;
track_begin_end output;
if (!track_block_get_previous(input.x, input.y, input.element, &output))
return false;
if (gTrackDefinitions[output.begin_element->properties.track.type].vangle_end != RCT2_GLOBAL(0x00F64E36, uint8) ||
gTrackDefinitions[output.begin_element->properties.track.type].bank_end != RCT2_GLOBAL(0x00F64E37, uint8))
return false;
vehicle->track_x = output.begin_x;
vehicle->track_y = output.begin_y;
vehicle->track_z = output.begin_z;
vehicle->track_direction = output.begin_direction;
vehicle->track_type |= output.begin_element->properties.track.type << 2;
if (output.begin_element->properties.track.type == TRACK_ELEM_END_STATION) {
RCT2_GLOBAL(0x00F64E18, uint32) = (1 << 0);
}
moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, 0);
uint16 trackTotalProgress = *((uint16*)((int)moveInfo - 2));
trackProgress = trackTotalProgress - 1;
}
vehicle->track_progress = trackProgress;
moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, trackProgress);
rct_xyz16 unk = {
.x = moveInfo->x,
.y = moveInfo->y,
.z = moveInfo->z
};
unk.x += vehicle->track_x;
unk.y += vehicle->track_y;
unk.z += vehicle->track_z;
uint8 bx = 0;
unk.z += RCT2_GLOBAL(0x0097D21A + (ride->type * 8), sint8);
if (unk.x != unk_F64E20->x)
bx |= (1 << 0);
if (unk.y != unk_F64E20->y)
bx |= (1 << 1);
if (unk.z != unk_F64E20->z)
bx |= (1 << 2);
vehicle->remaining_distance += RCT2_ADDRESS(0x009A2930, sint32)[bx];
unk_F64E20->x = unk.x;
unk_F64E20->y = unk.y;
unk_F64E20->z = unk.z;
vehicle->sprite_direction = moveInfo->direction;
vehicle->var_20 = moveInfo->var_08;
vehicle->var_1F = moveInfo->var_07;
if (vehicle->remaining_distance < 0) {
vehicle->acceleration += RCT2_ADDRESS(0x009A2970, sint32)[vehicle->var_1F];
}
}
return true;
}
/**
*
* rct2: 0x006DEF56
*/
int cable_lift_update_track_motion(rct_vehicle *cableLift)
{
rct_ride_type* rideEntry = GET_RIDE_ENTRY(cableLift->ride_subtype);
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[cableLift->vehicle_type];
rct_ride* ride = GET_RIDE(cableLift->ride);
RCT2_GLOBAL(0x00F64E2C, uint8) = 0;
RCT2_GLOBAL(0x00F64E04, rct_vehicle*) = cableLift;
RCT2_GLOBAL(0x00F64E18, uint32) = 0;
RCT2_GLOBAL(0x00F64E1C, uint32) = (uint32)-1;
cableLift->velocity += cableLift->acceleration;
RCT2_GLOBAL(0x00F64E08, sint32) = cableLift->velocity;
RCT2_GLOBAL(0x00F64E0C, sint32) = (cableLift->velocity / 1024) * 42;
rct_vehicle* frontVehicle = cableLift;
if (cableLift->velocity < 0) {
frontVehicle = vehicle_get_tail(cableLift);
}
RCT2_GLOBAL(0x00F64E00, rct_vehicle*) = frontVehicle;
for (rct_vehicle* vehicle = frontVehicle;;) {
vehicle->acceleration = RCT2_ADDRESS(0x009A2970, sint32)[vehicle->var_1F];
RCT2_GLOBAL(0x00F64E10, uint32) = 1;
vehicle->remaining_distance += RCT2_GLOBAL(0x00F64E0C, sint32);
if (vehicle->remaining_distance < 0 || vehicle->remaining_distance >= 13962) {
rct_xyz16 *unk_F64E20 = RCT2_ADDRESS(0x00F64E20, rct_xyz16);
unk_F64E20->x = vehicle->x;
unk_F64E20->y = vehicle->y;
unk_F64E20->z = vehicle->z;
invalidate_sprite_2((rct_sprite*)vehicle);
while (true) {
if (vehicle->remaining_distance < 0) {
if (sub_6DF21B_loop(vehicle) == true) {
break;
}
else {
RCT2_GLOBAL(0x00F64E18, uint32) |= (1 << 5);
RCT2_GLOBAL(0x00F64E0C, uint32) -= vehicle->remaining_distance - 13962;
vehicle->remaining_distance = 13962;
vehicle->acceleration += RCT2_ADDRESS(0x009A2970, uint32)[vehicle->var_1F];
RCT2_GLOBAL(0x00F64E10, uint32)++;
continue;
}
}
else {
if (sub_6DF01A_loop(vehicle) == true) {
break;
}
else {
RCT2_GLOBAL(0x00F64E18, uint32) |= (1 << 5);
RCT2_GLOBAL(0x00F64E0C, uint32) -= vehicle->remaining_distance + 1;
vehicle->remaining_distance = -1;
vehicle->acceleration += RCT2_ADDRESS(0x009A2970, uint32)[vehicle->var_1F];
RCT2_GLOBAL(0x00F64E10, uint32)++;
}
}
}
sprite_move(
unk_F64E20->x,
unk_F64E20->y,
unk_F64E20->z,
(rct_sprite*)vehicle);
invalidate_sprite_2((rct_sprite*)vehicle);
}
vehicle->acceleration /= RCT2_GLOBAL(0x00F64E10, uint32);
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
if (vehicle->next_vehicle_on_train == 0xFFFF)
break;
vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train);
}
else {
if (vehicle == cableLift)
break;
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
}
}
uint32 vehicleCount = 0;
uint16 frictionTotal = 0;
sint32 var2CTotal = 0;
for (uint16 spriteId = cableLift->sprite_index; spriteId != 0xFFFF;) {
rct_vehicle* vehicle = GET_VEHICLE(spriteId);
vehicleCount++;
frictionTotal += vehicle->friction;
var2CTotal += vehicle->acceleration;
spriteId = vehicle->next_vehicle_on_train;
}
sint32 ecx = (var2CTotal / vehicleCount) >> 9;
ecx -= cableLift->velocity >> 12;
sint32 edx = cableLift->velocity >> 8;
edx *= edx;
if (cableLift->velocity < 0)
edx = -edx;
edx >>= 4;
ecx -= edx / frictionTotal;
cableLift->acceleration = ecx;
return RCT2_GLOBAL(0x00F64E18, uint32);
}

11
src/ride/cable_lift.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef _CABLE_LIFT_H_
#define _CABLE_LIFT_H_
#include "../common.h"
#include "vehicle.h"
rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int direction, uint16 var_44, sint32 remaining_distance, bool head);
void cable_lift_update(rct_vehicle *vehicle);
int cable_lift_update_track_motion(rct_vehicle *cableLift);
#endif

View File

@ -45,6 +45,7 @@
#include "../world/map.h"
#include "../world/map_animation.h"
#include "../world/sprite.h"
#include "cable_lift.h"
#include "ride.h"
#include "ride_data.h"
#include "track.h"
@ -929,7 +930,7 @@ static void ride_remove_vehicles(rct_ride *ride)
}
for (i = 0; i < 4; i++)
ride->var_066[i] = 255;
ride->train_at_station[i] = 255;
}
}
@ -2693,7 +2694,12 @@ void ride_measurement_update(rct_ride_measurement *measurement)
}
uint8 trackType = (vehicle->track_type >> 2) & 0xFF;
if (trackType == 216 || trackType == 123 || trackType == 9 || trackType == 63 || trackType == 147 || trackType == 155)
if (trackType == 216 ||
trackType == TRACK_ELEM_CABLE_LIFT_HILL ||
trackType == TRACK_ELEM_25_DEG_UP_TO_FLAT ||
trackType == TRACK_ELEM_60_DEG_UP_TO_FLAT ||
trackType == TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT ||
trackType == TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT)
if (vehicle->velocity == 0)
return;
@ -4279,7 +4285,7 @@ void loc_6DDF9C(rct_ride *ride, rct_map_element *mapElement)
for (int i = 0; i < ride->num_vehicles; i++) {
train = GET_VEHICLE(ride->vehicles[i]);
if (i == 0) {
sub_6DAB4C(train, NULL);
vehicle_update_track_motion(train, NULL);
vehicle_unset_var_48_b1(train);
continue;
}
@ -4289,9 +4295,9 @@ void loc_6DDF9C(rct_ride *ride, rct_map_element *mapElement)
car = train;
while (true) {
car->velocity = 0;
car->var_2C = 0;
car->acceleration = 0;
car->var_4A = 0;
car->var_24 += 13962;
car->remaining_distance += 13962;
uint16 spriteIndex = car->next_vehicle_on_train;
if (spriteIndex == SPRITE_INDEX_NULL) {
@ -4299,7 +4305,7 @@ void loc_6DDF9C(rct_ride *ride, rct_map_element *mapElement)
}
car = GET_VEHICLE(spriteIndex);
}
} while (sub_6DAB4C(train, NULL) & 0x400);
} while (vehicle_update_track_motion(train, NULL) & 0x400);
mapElement->flags |= (1 << 5);
car = train;
@ -4480,10 +4486,10 @@ bool ride_create_cable_lift(int rideIndex, bool isApplying)
uint16 var_44 = edx & 0xFFFF;
edx = rol32(edx, 10) >> 1;
ebx -= edx;
uint32 var_24 = ebx;
sint32 remaining_distance = ebx;
ebx -= edx;
rct_vehicle *current = cable_lift_segment_create(rideIndex, x, y, z, direction, var_44, var_24, i == 0);
rct_vehicle *current = cable_lift_segment_create(rideIndex, x, y, z, direction, var_44, remaining_distance, i == 0);
current->next_vehicle_on_train = SPRITE_INDEX_NULL;
if (i == 0) {
head = current;
@ -4498,7 +4504,7 @@ bool ride_create_cable_lift(int rideIndex, bool isApplying)
tail->next_vehicle_on_ride = head->sprite_index;
ride->lifecycle_flags |= RIDE_LIFECYCLE_CABLE_LIFT;
sub_6DEF56(head);
cable_lift_update_track_motion(head);
return true;
}
@ -5373,7 +5379,7 @@ foundRideEntry:
ride->station_starts[i] = 0xFFFF;
ride->entrances[i] = 0xFFFF;
ride->exits[i] = 0xFFFF;
ride->var_066[i] = 255;
ride->train_at_station[i] = 255;
ride->queue_time[i] = 0;
}
@ -5405,7 +5411,7 @@ foundRideEntry:
RCT2_GLOBAL(0x0097CF40 + 5 + (ride->type * 8), uint8)
) / 4;
ride->lift_hill_speed = RCT2_ADDRESS(0x0097D7C9, uint8)[ride->type * 4];
ride->lift_hill_speed = RideLiftData[ride->type].minimum_speed;
ride->measurement_index = 255;
ride->excitement = (ride_rating)-1;
@ -5978,53 +5984,182 @@ bool ride_type_has_flag(int rideType, int flag)
return (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (rideType * 8), uint32) & flag) != 0;
}
/**
* The next six functions are helpers to access ride data at the offset 10E &
* 110. We believe it stores three distinct values in the following format:
/*
* The next eight functions are helpers to access ride data at the offset 10E &
* 110. Known as the turn counts. There are 3 different types (default, banked, sloped)
* and there are 4 counts as follows:
*
* unknown1: bits 9-11
* unknown2: bits 6-8
* unknown3: low 5 bits
* 1 element turns: low 5 bits
* 2 element turns: bits 6-8
* 3 element turns: bits 9-11
* 4 element or more turns: bits 12-15
*
* 4 plus elements only possible on sloped type. Falls back to 3 element
* if by some miracle you manage 4 element none sloped.
*/
int get_var_10E_unk_1(rct_ride* ride) {
return (ride->var_10E >> 8) & 0x7;
void increment_turn_count_1_element(rct_ride* ride, uint8 type){
uint16* turn_count;
switch (type){
case 0:
turn_count = &ride->turn_count_default;
break;
case 1:
turn_count = &ride->turn_count_banked;
break;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return;
}
uint16 value = (*turn_count & TURN_MASK_1_ELEMENT) + 1;
*turn_count &= ~TURN_MASK_1_ELEMENT;
if (value > TURN_MASK_1_ELEMENT)
value = TURN_MASK_1_ELEMENT;
*turn_count |= value;
}
int get_var_10E_unk_2(rct_ride* ride) {
return (ride->var_10E >> 5) & 0x7;
void increment_turn_count_2_elements(rct_ride* ride, uint8 type){
uint16* turn_count;
switch (type){
case 0:
turn_count = &ride->turn_count_default;
break;
case 1:
turn_count = &ride->turn_count_banked;
break;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return;
}
uint16 value = (*turn_count & TURN_MASK_2_ELEMENTS) + 0x20;
*turn_count &= ~TURN_MASK_2_ELEMENTS;
if (value > TURN_MASK_2_ELEMENTS)
value = TURN_MASK_2_ELEMENTS;
*turn_count |= value;
}
int get_var_10E_unk_3(rct_ride* ride) {
return ride->var_10E & 0x1F;
void increment_turn_count_3_elements(rct_ride* ride, uint8 type){
uint16* turn_count;
switch (type){
case 0:
turn_count = &ride->turn_count_default;
break;
case 1:
turn_count = &ride->turn_count_banked;
break;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return;
}
uint16 value = (*turn_count & TURN_MASK_3_ELEMENTS) + 0x100;
*turn_count &= ~TURN_MASK_3_ELEMENTS;
if (value > TURN_MASK_3_ELEMENTS)
value = TURN_MASK_3_ELEMENTS;
*turn_count |= value;
}
int get_var_110_unk_1(rct_ride* ride) {
return (ride->var_110 >> 8) & 0x7;
void increment_turn_count_4_plus_elements(rct_ride* ride, uint8 type){
uint16* turn_count;
switch (type){
case 0:
case 1:
// Just incase fallback to 3 element turn
increment_turn_count_3_elements(ride, type);
return;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return;
}
uint16 value = (*turn_count & TURN_MASK_4_PLUS_ELEMENTS) + 0x800;
*turn_count &= ~TURN_MASK_4_PLUS_ELEMENTS;
if (value > TURN_MASK_4_PLUS_ELEMENTS)
value = TURN_MASK_4_PLUS_ELEMENTS;
*turn_count |= value;
}
int get_var_110_unk_2(rct_ride* ride) {
return (ride->var_110 >> 5) & 0x7;
int get_turn_count_1_element(rct_ride* ride, uint8 type) {
uint16* turn_count;
switch (type){
case 0:
turn_count = &ride->turn_count_default;
break;
case 1:
turn_count = &ride->turn_count_banked;
break;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return 0;
}
return (*turn_count) & TURN_MASK_1_ELEMENT;
}
int get_var_110_unk_3(rct_ride* ride) {
return ride->var_110 & 0x1F;
int get_turn_count_2_elements(rct_ride* ride, uint8 type) {
uint16* turn_count;
switch (type){
case 0:
turn_count = &ride->turn_count_default;
break;
case 1:
turn_count = &ride->turn_count_banked;
break;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return 0;
}
return ((*turn_count) & TURN_MASK_2_ELEMENTS) >> 5;
}
int get_var_112_unk_1(rct_ride* ride) {
return (ride->var_112 >> 11) & 0x3F;
int get_turn_count_3_elements(rct_ride* ride, uint8 type) {
uint16* turn_count;
switch (type){
case 0:
turn_count = &ride->turn_count_default;
break;
case 1:
turn_count = &ride->turn_count_banked;
break;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return 0;
}
return ((*turn_count) & TURN_MASK_3_ELEMENTS) >> 8;
}
int get_var_112_unk_2(rct_ride* ride) {
return (ride->var_112 >> 8) & 7;
}
int get_turn_count_4_plus_elements(rct_ride* ride, uint8 type) {
uint16* turn_count;
switch (type){
case 0:
case 1:
return 0;
case 2:
turn_count = &ride->turn_count_sloped;
break;
default:
return 0;
}
int get_var_112_unk_3(rct_ride* ride) {
return (ride->var_112 >> 5) & 7;
}
int get_var_112_unk_4(rct_ride* ride) {
return ride->var_112 & 0x1F;
return ((*turn_count) & TURN_MASK_4_PLUS_ELEMENTS) >> 11;
}
bool ride_has_spinning_tunnel(rct_ride *ride) {
@ -6183,7 +6318,7 @@ void set_vehicle_type_image_max_sizes(rct_ride_type_vehicle* vehicle_type, int n
// Moved from object paint
if (vehicle_type->var_12 & 0x2000){
if (vehicle_type->flags_a & VEHICLE_ENTRY_FLAG_A_13){
bl += 16;
}
@ -6704,7 +6839,7 @@ void ride_update_max_vehicles(int rideIndex)
int totalFriction = 0;
for (int i = 0; i < numCars; i++) {
vehicleEntry = &rideEntry->vehicles[trainLayout[i]];
trainLength += vehicleEntry->var_04;
trainLength += vehicleEntry->spacing;
totalFriction += vehicleEntry->car_friction;
}
@ -6736,7 +6871,7 @@ void ride_update_max_vehicles(int rideIndex)
trainLength = 0;
for (int i = 0; i < newCarsPerTrain; i++) {
vehicleEntry = &rideEntry->vehicles[trainLayout[i]];
trainLength += vehicleEntry->var_04;
trainLength += vehicleEntry->spacing;
}
int totalLength = trainLength / 2;
@ -6762,7 +6897,7 @@ void ride_update_max_vehicles(int rideIndex)
int totalSpacing = 0;
for (int i = 0; i < newCarsPerTrain; i++) {
vehicleEntry = &rideEntry->vehicles[trainLayout[i]];
totalSpacing += vehicleEntry->var_04;
totalSpacing += vehicleEntry->spacing;
}
totalSpacing >>= 13;
@ -7294,16 +7429,12 @@ void game_command_remove_ride_entrance_or_exit(int *eax, int *ebx, int *ecx, int
*
* rct2: 0x006B752C
*/
void ride_crash(int rideIndex, int vehicleIndex)
void ride_crash(uint8 rideIndex, uint8 vehicleIndex)
{
rct_ride *ride;
rct_vehicle *vehicle;
rct_window *w;
// TODO Remove these when hook is no longer used
rideIndex &= 0xFF;
vehicleIndex &= 0xFF;
ride = GET_RIDE(rideIndex);
vehicle = GET_VEHICLE(ride->vehicles[vehicleIndex]);

View File

@ -75,28 +75,33 @@ typedef struct {
* size: unknown
*/
typedef struct {
rct_string_id name; // 0x000
rct_string_id description; // 0x002
uint32 images_offset; // 0x004
uint32 flags; // 0x008
uint8 ride_type[3]; // 0x00C
uint8 min_cars_in_train; // 0x00F
uint8 max_cars_in_train; // 0x010
uint8 cars_per_flat_ride; // 0x011
uint8 zero_cars; // 0x012
uint8 tab_vehicle; // 0x013
uint8 default_vehicle; // 0x014
uint8 front_vehicle; // 0x015
uint8 second_vehicle; // 0x016
uint8 rear_vehicle; // 0x017
uint8 third_vehicle; // 0x018
rct_string_id name; // 0x000
rct_string_id description; // 0x002
uint32 images_offset; // 0x004
uint32 flags; // 0x008
uint8 ride_type[3]; // 0x00C
uint8 min_cars_in_train; // 0x00F
uint8 max_cars_in_train; // 0x010
uint8 cars_per_flat_ride; // 0x011
// Number of cars that can't hold passengers
uint8 zero_cars; // 0x012
// The index to the vehicle type displayed in
// the vehicle tab.
uint8 tab_vehicle; // 0x013
uint8 default_vehicle; // 0x014
// Convert from first - fourth vehicle to
// vehicle structure
uint8 front_vehicle; // 0x015
uint8 second_vehicle; // 0x016
uint8 rear_vehicle; // 0x017
uint8 third_vehicle; // 0x018
uint8 pad_019;
rct_ride_type_vehicle vehicles[4]; // 0x01A
rct_ride_type_vehicle vehicles[4]; // 0x1A
vehicle_colour_preset_list *vehicle_preset_list; // 0x1AE
sint8 excitement_multipler; // 0x1B2
sint8 intensity_multipler; // 0x1B3
sint8 nausea_multipler; // 0x1B4
uint8 max_height; // 0x1B5
sint8 excitement_multipler; // 0x1B2
sint8 intensity_multipler; // 0x1B3
sint8 nausea_multipler; // 0x1B4
uint8 max_height; // 0x1B5
union {
uint64 enabledTrackPieces; // 0x1B6
struct {
@ -138,7 +143,9 @@ typedef struct {
uint8 station_heights[4]; // 0x05A
uint8 station_length[4]; // 0x05E
uint8 station_depart[4]; // 0x062
uint8 var_066[4];
// ride->vehicle index for current train waiting for passengers
// at station
uint8 train_at_station[4]; // 0x066
uint16 entrances[4]; // 0x06A
uint16 exits[4]; // 0x072
uint16 last_peep_in_queue[4]; // 0x07A
@ -177,16 +184,24 @@ typedef struct {
// (in RCT2, display_speed = (max_speed * 9) >> 18)
sint32 max_speed; // 0x0D8
sint32 average_speed; // 0x0DC
uint8 pad_0E0[4];
uint8 current_test_segment; // 0x0E0
uint8 var_0E1;
uint8 pad_0E2[0x2];
sint32 length[4]; // 0x0E4
uint16 time[4]; // 0x0F4
fixed16_2dp max_positive_vertical_g; // 0x0FC
fixed16_2dp max_negative_vertical_g; // 0x0FE
fixed16_2dp max_lateral_g; // 0x100
uint8 pad_102[0xC];
uint16 var_10E;
uint16 var_110;
uint16 var_112;
fixed16_2dp previous_vertical_g;// 0x102
fixed16_2dp previous_lateral_g; // 0x104
uint8 pad_106[0x2];
uint32 testing_flags; // 0x108
// x y map location
uint16 var_10C;
// Next 3 variables are related (XXXX XYYY ZZZa aaaa)
uint16 turn_count_default; // 0x10E X = current turn count
uint16 turn_count_banked; // 0x110
uint16 turn_count_sloped; // 0x112 X = number turns > 3 elements
union {
uint8 inversions; // 0x114 (???X XXXX)
uint8 holes; // 0x114 (???X XXXX)
@ -194,12 +209,14 @@ typedef struct {
// It reaches the maximum value of 7 at about 50% undercover and doesn't increase beyond that.
uint8 undercover_portion; // 0x114 (XXX?-????)
};
uint8 drops; // 0x115 (??XX XXXX)
uint8 var_116;
// Y is number of powered lifts, X is drops
uint8 drops; // 0x115 (YYXX XXXX)
uint8 start_drop_height; // 0x116
uint8 highest_drop_height; // 0x117
sint32 sheltered_length; // 0x118
uint8 pad_11C[0x2];
uint8 num_sheltered_sections; // 0x11E
uint16 var_11C;
uint8 num_sheltered_sections; // 0x11E (?abY YYYY)
// z related to var_10C
uint8 var_11F;
// Customer counter in the current 960 game tick (about 30 seconds) interval
uint16 cur_num_customers; // 0x120
@ -297,7 +314,7 @@ typedef struct {
uint32 lifecycle_flags; // 0x1D0
uint8 vehicle_colours_extended[32]; // 0x1D4
uint16 total_air_time; // 0x1F4
uint8 pad_1F6;
uint8 var_1F6;
uint8 num_circuits; // 0x1F7
sint16 cable_lift_x; // 0x1F8
sint16 cable_lift_y; // 0x1FA
@ -376,9 +393,11 @@ enum {
RIDE_ENTRY_FLAG_NO_INVERSIONS = 1 << 1, // 0x2
RIDE_ENTRY_FLAG_NO_BANKED_TRACK = 1 << 2, // 0x4
RIDE_ENTRY_FLAG_3 = 1 << 3, // 0x8
RIDE_ENTRY_FLAG_4 = 1 << 4, // 0x10
RIDE_ENTRY_FLAG_5 = 1 << 5, // 0x20
RIDE_ENTRY_FLAG_6 = 1 << 6, // 0x40
RIDE_ENTRY_FLAG_ALTERNATIVE_SWING_MODE_1 = 1 << 4, // 0x10
// Twist type rotation ride
RIDE_ENTRY_FLAG_ALTERNATIVE_ROTATION_MODE_1 = 1 << 5, // 0x20
// Lifting arm rotation ride (enterprise)
RIDE_ENTRY_FLAG_ALTERNATIVE_ROTATION_MODE_2 = 1 << 6, // 0x40
RIDE_ENTRY_FLAG_7 = 1 << 7, // 0x80
RIDE_ENTRY_FLAG_8 = 1 << 8, // 0x100
RIDE_ENTRY_FLAG_9 = 1 << 9, // 0x200
@ -392,7 +411,8 @@ enum {
RIDE_ENTRY_DISABLE_FIRST_TWO_OPERATING_MODES = 1 << 17, // 0x20000
RIDE_ENTRY_FLAG_18 = 1 << 18, // 0x40000
RIDE_ENTRY_FLAG_19 = 1 << 19, // 0x80000
RIDE_ENTRY_FLAG_20 = 1 << 20, // 0x100000
// Must be set with swing mode 1 as well.
RIDE_ENTRY_FLAG_ALTERNATIVE_SWING_MODE_2 = 1 << 20, // 0x100000
RIDE_ENTRY_FLAG_21 = 1 << 21, // 0x200000
RIDE_ENTRY_FLAG_22 = 1 << 22, // 0x400000
RIDE_ENTRY_FLAG_23 = 1 << 23, // 0x800000
@ -406,6 +426,17 @@ enum {
RIDE_ENTRY_FLAG_31 = 1 << 31, // 0x80000000
};
enum{
RIDE_TESTING_SHELTERED = (1 << 0),
RIDE_TESTING_TURN_LEFT = (1 << 1),
RIDE_TESTING_TURN_RIGHT = (1 << 2),
RIDE_TESTING_TURN_BANKED = (1 << 3),
RIDE_TESTING_TURN_SLOPED = (1 << 4),
RIDE_TESTING_DROP_DOWN = (1 << 5),
RIDE_TESTING_POWERED_LIFT = (1 << 6),
RIDE_TESTING_DROP_UP = (1 << 7),
};
enum {
RIDE_TYPE_NULL = 255,
RIDE_TYPE_SPIRAL_ROLLER_COASTER = 0,
@ -518,7 +549,7 @@ enum {
RIDE_MODE_ROTATING_LIFT,
RIDE_MODE_STATION_TO_STATION,
RIDE_MODE_SINGLE_RIDE_PER_ADMISSION,
RIDE_MODE_UNLIMITED_RIDES_PER_ADMISSION,
RIDE_MODE_UNLIMITED_RIDES_PER_ADMISSION = 10,
RIDE_MODE_MAZE,
RIDE_MODE_RACE,
RIDE_MODE_BUMPERCAR,
@ -528,7 +559,7 @@ enum {
RIDE_MODE_FORWARD_ROTATION,
RIDE_MODE_BACKWARD_ROTATION,
RIDE_MODE_FILM_AVENGING_AVIATORS,
RIDE_MODE_3D_FILM_MOUSE_TAILS,
RIDE_MODE_3D_FILM_MOUSE_TAILS = 20,
RIDE_MODE_SPACE_RINGS,
RIDE_MODE_BEGINNERS,
RIDE_MODE_LIM_POWERED_LAUNCH,
@ -538,7 +569,7 @@ enum {
RIDE_MODE_INTENSE,
RIDE_MODE_BERSERK,
RIDE_MODE_HAUNTED_HOUSE,
RIDE_MODE_CIRCUS_SHOW,
RIDE_MODE_CIRCUS_SHOW = 30,
RIDE_MODE_DOWNWARD_LAUNCH,
RIDE_MODE_CROOKED_HOUSE,
RIDE_MODE_FREEFALL_DROP,
@ -813,6 +844,12 @@ enum {
#define STATION_DEPART_FLAG (1 << 7)
#define STATION_DEPART_MASK (~STATION_DEPART_FLAG)
#define CURRENT_TURN_COUNT_MASK 0xF800
#define TURN_MASK_1_ELEMENT 0x001F
#define TURN_MASK_2_ELEMENTS 0x00E0
#define TURN_MASK_3_ELEMENTS 0x0700
#define TURN_MASK_4_PLUS_ELEMENTS 0xF800
// rct2: 0x009ACFA4
extern rct_ride_type **gRideTypeList;
@ -934,6 +971,7 @@ void game_command_callback_ride_remove_track_piece(int eax, int ebx, int ecx, in
void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_set_ride_appearance(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void game_command_set_ride_price(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void ride_clear_for_construction(int rideIndex);
void set_vehicle_type_image_max_sizes(rct_ride_type_vehicle* vehicle_type, int num_images);
void invalidate_test_results(int rideIndex);
@ -941,16 +979,14 @@ void invalidate_test_results(int rideIndex);
void ride_select_next_section();
void ride_select_previous_section();
int get_var_10E_unk_1(rct_ride* ride);
int get_var_10E_unk_2(rct_ride* ride);
int get_var_10E_unk_3(rct_ride* ride);
int get_var_110_unk_1(rct_ride* ride);
int get_var_110_unk_2(rct_ride* ride);
int get_var_110_unk_3(rct_ride* ride);
int get_var_112_unk_1(rct_ride* ride);
int get_var_112_unk_2(rct_ride* ride);
int get_var_112_unk_3(rct_ride* ride);
int get_var_112_unk_4(rct_ride* ride);
void increment_turn_count_1_element(rct_ride* ride, uint8 type);
void increment_turn_count_2_elements(rct_ride* ride, uint8 type);
void increment_turn_count_3_elements(rct_ride* ride, uint8 type);
void increment_turn_count_4_plus_elements(rct_ride* ride, uint8 type);
int get_turn_count_1_element(rct_ride* ride, uint8 type);
int get_turn_count_2_elements(rct_ride* ride, uint8 type);
int get_turn_count_3_elements(rct_ride* ride, uint8 type);
int get_turn_count_4_plus_elements(rct_ride* ride, uint8 type);
uint8 ride_get_helix_sections(rct_ride *ride);
bool ride_has_spinning_tunnel(rct_ride *ride);
@ -999,7 +1035,7 @@ void game_command_place_ride_entrance_or_exit(int *eax, int *ebx, int *ecx, int
void game_command_remove_ride_entrance_or_exit(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
void sub_6CB945(int rideIndex);
void ride_crash(int rideIndex, int vehicleIndex);
void ride_crash(uint8 rideIndex, uint8 vehicleIndex);
bool ride_type_is_intamin(int rideType);
void sub_6C94D8();

View File

@ -11,6 +11,7 @@
#include "../localisation/localisation.h"
#include "ride.h"
#include "ride_data.h"
#include "../audio/audio.h"
const bool hasRunningTrack[0x60] = {
true, // 0 Spiral Roller coaster
@ -986,100 +987,6 @@ const rct_ride_entrance_definition RideEntranceDefinitions[RIDE_ENTRANCE_STYLE_C
{ 0, 0, 2, STR_ENTRANCE_NONE, 0x00000000, 0, } // RIDE_ENTRANCE_STYLE_NONE
};
// Data read from 0x0097D7C9 4 bytes at a time
const uint8 RideLiftHillAdjustments[0x60] = {
7, // Spiral Roller coaster
4, // Stand Up Coaster
4, // Suspended Swinging
5, // Inverted
4, // Steel Mini Coaster
5, // Mini Railroad
5, // Monorail
4, // Mini Suspended Coaster
5, // Boat Ride
4, // Wooden Wild Mine/Mouse
4, // Steeplechase/Motorbike/Soap Box Derby
5, // Car Ride
5, // Launched Freefall
4, // Bobsleigh Coaster
5, // Observation Tower
4, // Looping Roller Coaster
4, // Dinghy Slide
4, // Mine Train Coaster
5, // Chairlift
4, // Corkscrew Roller Coaster
5, // Maze
5, // Spiral Slide
5, // Go Karts
5, // Log Flume
5, // River Rapids
5, // Bumper Cars
5, // Pirate Ship
5, // Swinging Inverter Ship
5, // Food Stall
5, // (none)
5, // Drink Stall
5, // (none)
5, // Shop (all types)
5, // Merry Go Round
5, // Balloon Stall (maybe)
5, // Information Kiosk
5, // Bathroom
5, // Ferris Wheel
5, // Motion Simulator
5, // 3D Cinema
5, // Topspin
5, // Space Rings
5, // Reverse Freefall Coaster
5, // Elevator
4, // Vertical Drop Roller Coaster
5, // ATM
5, // Twist
5, // Haunted House
5, // First Aid
5, // Circus Show
5, // Ghost Train
5, // Twister Roller Coaster
5, // Wooden Roller Coaster
3, // Side-Friction Roller Coaster
4, // Wild Mouse
4, // Multi Dimension Coaster
4, // (none)
4, // Flying Roller Coaster
4, // (none)
3, // Virginia Reel
5, // Splash Boats
5, // Mini Helicopters
4, // Lay-down Roller Coaster
5, // Suspended Monorail
4, // (none)
3, // Reverser Roller Coaster
4, // Heartline Twister Roller Coaster
5, // Mini Golf
5, // Giga Coaster
5, // Roto-Drop
5, // Flying Saucers
5, // Crooked House
5, // Monorail Cycles
4, // Compact Inverted Coaster
4, // Water Coaster
5, // Air Powered Vertical Coaster
4, // Inverted Hairpin Coaster
5, // Magic Carpet
5, // Submarine Ride
5, // River Rafts
5, // (none)
5, // Enterprise
5, // (none)
5, // (none)
5, // (none)
4, // (none)
4, // Inverted Impulse Coaster
4, // Mini Roller Coaster
5, // Mine Ride
4 // LIM Launched Roller Coaster
};
// rct2: 0x0097D4F2
const rct_ride_data_4 RideData4[91] = {
{ RIDE_TYPE_FLAG4_ALLOW_MUSIC | RIDE_TYPE_FLAG4_PEEP_CHECK_GFORCES | RIDE_TYPE_FLAG4_HAS_ENTRANCE_EXIT | RIDE_TYPE_FLAG4_HAS_AIR_TIME | RIDE_TYPE_FLAG4_ALLOW_MULTIPLE_CIRCUITS | RIDE_TYPE_FLAG4_11 | RIDE_TYPE_FLAG4_13, MUSIC_STYLE_ROCK_STYLE_3, 0, 0, 0, 20, 20 }, // RIDE_TYPE_SPIRAL_ROLLER_COASTER
@ -1353,7 +1260,7 @@ const rct_ride_type_vehicle CableLiftVehicle = {
.rotation_frame_mask = 31,
.var_02 = 0,
.var_03 = 0,
.var_04 = 0,
.spacing = 0,
.car_friction = 0,
.tab_height = 0,
.num_seats = 0,
@ -1362,8 +1269,8 @@ const rct_ride_type_vehicle CableLiftVehicle = {
.sprite_height_negative = 0,
.sprite_height_positive = 0,
.var_11 = 0,
.var_12 = 0,
.var_14 = 0,
.flags_a = 0,
.flags_b = 0,
.var_16 = 1,
.base_image_id = 29110,
.var_1C = 0,
@ -1383,7 +1290,9 @@ const rct_ride_type_vehicle CableLiftVehicle = {
.no_seating_rows = 0,
.spinning_inertia = 0,
.spinning_friction = 255,
.pad_57 = { 0,0,0 },
.var_57 = 0,
.var_58 = 0,
.sound_range = 0,
.var_5A = 0,
.powered_acceleration = 0,
.powered_max_speed = 0,
@ -1393,3 +1302,110 @@ const rct_ride_type_vehicle CableLiftVehicle = {
.special_frames = 0,
.peep_loading_positions = NULL
};
/* rct2: 0x009A0AA0 */
const uint16 RideFilmLength[3] = {
5000, // MOUSE_TAILS
6000, // STORM_CHASERS
7000 // SPACE_RAIDERS
};
/* rct2: 0x009A0AC4 */
const uint16 RideCrookedHouseLength[1] = {
600
};
/* rct2: 0x0097D7C8, 0x0097D7C9, 0x0097D7CA */
const rct_ride_lift_data RideLiftData[] = {
{ SOUND_LIFT_3, 7, 7 }, // Spiral Roller coaster
{ SOUND_LIFT_1, 4, 6 }, // Stand Up Coaster
{ SOUND_LIFT_1, 4, 6 }, // Suspended Swinging
{ SOUND_LIFT_7, 5, 7 }, // Inverted
{ SOUND_LIFT_3, 4, 6 }, // Steel Mini Coaster
{ 255, 5, 5 }, // Mini Railroad
{ 255, 5, 5 }, // Monorail
{ SOUND_LIFT_3, 4, 5 }, // Mini Suspended Coaster
{ 255, 5, 5 }, // Boat Ride
{ SOUND_LIFT_1, 4, 5 }, // Wooden Wild Mine/Mouse
{ SOUND_LIFT_1, 4, 5 }, // Steeplechase/Motorbike/Soap Box D
{ 255, 5, 5 }, // Car Ride
{ 255, 5, 5 }, // Launched Freefall
{ SOUND_LIFT_3, 4, 5 }, // Bobsleigh Coaster
{ 255, 5, 5 }, // Observation Tower
{ SOUND_LIFT_1, 4, 6 }, // Looping Roller Coaster
{ SOUND_LIFT_3, 4, 5 }, // Dinghy Slide
{ SOUND_LIFT_4, 4, 6 }, // Mine Train Coaster
{ 255, 5, 5 }, // Chairlift
{ SOUND_LIFT_4, 4, 6 }, // Corkscrew Roller Coaster
{ 255, 5, 5 }, // Maze
{ 255, 5, 5 }, // Spiral Slide
{ 255, 5, 5 }, // Go Karts
{ 255, 5, 5 }, // Log Flume
{ 255, 5, 5 }, // River Rapids
{ 255, 5, 5 }, // Bumper Cars
{ 255, 5, 5 }, // Pirate Ship
{ 255, 5, 5 }, // Swinging Inverter Ship
{ 255, 5, 5 }, // Food Stall
{ 255, 5, 5 }, // (none)
{ 255, 5, 5 }, // Drink Stall
{ 255, 5, 5 }, // (none)
{ 255, 5, 5 }, // Shop (all types)
{ 255, 5, 5 }, // Merry Go Round
{ 255, 5, 5 }, // Balloon Stall (maybe)
{ 255, 5, 5 }, // Information Kiosk
{ 255, 5, 5 }, // Bathroom
{ 255, 5, 5 }, // Ferris Wheel
{ 255, 5, 5 }, // Motion Simulator
{ 255, 5, 5 }, // 3D Cinema
{ 255, 5, 5 }, // Topspin
{ 255, 5, 5 }, // Space Rings
{ 255, 5, 5 }, // Reverse Freefall Coaster
{ 255, 5, 5 }, // Elevator
{ SOUND_LIFT_7, 4, 5 }, // Vertical Drop Roller Coaster
{ 255, 5, 5 }, // ATM
{ 255, 5, 5 }, // Twist
{ 255, 5, 5 }, // Haunted House
{ 255, 5, 5 }, // First Aid
{ 255, 5, 5 }, // Circus Show
{ 255, 5, 5 }, // Ghost Train
{ SOUND_LIFT_7, 5, 8 }, // Twister Roller Coaster
{ SOUND_LIFT_5, 5, 7 }, // Wooden Roller Coaster
{ SOUND_LIFT_5, 3, 4 }, // Side-Friction Roller Coaster
{ SOUND_LIFT_6, 4, 6 }, // Wild Mouse
{ SOUND_LIFT_3, 4, 6 }, // Multi Dimension Coaster
{ SOUND_LIFT_3, 4, 6 }, // (none)
{ SOUND_LIFT_7, 4, 6 }, // Flying Roller Coaster
{ SOUND_LIFT_7, 4, 6 }, // (none)
{ SOUND_LIFT_1, 3, 4 }, // Virginia Reel
{ 255, 5, 5 }, // Splash Boats
{ 255, 5, 5 }, // Mini Helicopters
{ SOUND_LIFT_1, 4, 6 }, // Lay-down Roller Coaster
{ 255, 5, 5 }, // Suspended Monorail
{ SOUND_LIFT_1, 4, 6 }, // (none)
{ SOUND_LIFT_1, 3, 4 }, // Reverser Roller Coaster
{ SOUND_LIFT_1, 4, 6 }, // Heartline Twister Roller Coaster
{ 255, 5, 5 }, // Mini Golf
{ SOUND_LIFT_1, 5, 8 }, // Giga Coaster
{ 255, 5, 5 }, // Roto-Drop
{ 255, 5, 5 }, // Flying Saucers
{ 255, 5, 5 }, // Crooked House
{ 255, 5, 5 }, // Monorail Cycles
{ SOUND_LIFT_3, 4, 6 }, // Compact Inverted Coaster
{ SOUND_LIFT_1, 4, 6 }, // Water Coaster
{ 255, 5, 5 }, // Air Powered Vertical Coaster
{ SOUND_LIFT_6, 4, 6 }, // Inverted Hairpin Coaster
{ 255, 5, 5 }, // Magic Carpet
{ 255, 5, 5 }, // Submarine Ride
{ 255, 5, 5 }, // River Rafts
{ 255, 5, 5 }, // (none)
{ 255, 5, 5 }, // Enterprise
{ 255, 5, 5 }, // (none)
{ 255, 5, 5 }, // (none)
{ 255, 5, 5 }, // (none)
{ SOUND_LIFT_4, 4, 7 }, // (none)
{ SOUND_LIFT_1, 4, 7 }, // Inverted Impulse Coaster
{ SOUND_LIFT_1, 4, 6 }, // Mini Roller Coaster
{ 255, 5, 5 }, // Mine Ride
{ SOUND_LIFT_6, 4, 6 }, // (none)
{ 255, 4, 6 } // LIM Launched Roller Coaster
};

View File

@ -54,6 +54,12 @@ typedef struct {
uint8 pad[4];
} rct_ride_data_4;
typedef struct {
uint8 sound_id;
uint8 minimum_speed;
uint8 maximum_speed;
} rct_ride_lift_data;
enum {
RIDE_TYPE_FLAG4_0 = (1 << 0),
RIDE_TYPE_FLAG4_MUSIC_ON_DEFAULT = (1 << 1),
@ -88,7 +94,7 @@ extern const uint8 AllRideModesAvailable[];
extern const uint8 RideAvailableBreakdowns[];
extern const rct_ride_entrance_definition RideEntranceDefinitions[RIDE_ENTRANCE_STYLE_COUNT];
extern const uint8 RideLiftHillAdjustments[0x60];
extern const rct_ride_lift_data RideLiftData[91];
extern const rct_ride_data_4 RideData4[91];
@ -98,4 +104,7 @@ extern const uint32 ShopItemImage[SHOP_ITEM_COUNT];
extern const rct_ride_type_vehicle CableLiftVehicle;
extern const uint16 RideFilmLength[3];
extern const uint16 RideCrookedHouseLength[1];
#endif

View File

@ -843,12 +843,9 @@ static void ride_ratings_apply_intensity_penalty(rating_tuple *ratings)
*/
static void set_unreliability_factor(rct_ride *ride)
{
// The higher the number, the lower the breakdown
// possibility. Range is [3, 7]. values are here:
// https://gist.github.com/kevinburke/123977c4884ccadbec70. Consider
// inlining this per ride
uint8 lift_speed_adjustment = RideLiftHillAdjustments[ride->type];
ride->unreliability_factor += (ride->lift_hill_speed - lift_speed_adjustment) * 2;
// The bigger the difference in lift speed and minimum the higher the unreliability
uint8 lift_speed_adjustment = RideLiftData[ride->type].minimum_speed;
ride->unreliability_factor += (ride->lift_hill_speed - lift_speed_adjustment) * 2;
}
static uint32 get_proximity_score_helper_1(uint16 x, uint16 max, uint32 multiplier)
@ -930,24 +927,25 @@ static int sub_65E72D(rct_ride *ride)
return (dh << 8) | numShelteredEighths;
}
static rating_tuple get_var_10E_rating(rct_ride* ride) {
int var_10E_unk_1 = get_var_10E_unk_1(ride);
int var_10E_unk_2 = get_var_10E_unk_2(ride);
int var_10E_unk_3 = get_var_10E_unk_3(ride);
static rating_tuple get_flat_turns_rating(rct_ride* ride) {
rating_tuple rating;
int excitement = (var_10E_unk_1 * 0x28000) >> 16;
excitement += (var_10E_unk_2 * 0x30000) >> 16;
excitement += (var_10E_unk_3 * 63421) >> 16;
int no_3_plus_turns = get_turn_count_3_elements(ride, 0);
int no_2_turns = get_turn_count_2_elements(ride, 0);
int no_1_turns = get_turn_count_1_element(ride, 0);
int intensity = (var_10E_unk_1 * 81920) >> 16;
intensity += (var_10E_unk_2 * 49152) >> 16;
intensity += (var_10E_unk_3 * 21140) >> 16;
rating.excitement = (no_3_plus_turns * 0x28000) >> 16;
rating.excitement += (no_2_turns * 0x30000) >> 16;
rating.excitement += (no_1_turns * 63421) >> 16;
int nausea = (var_10E_unk_1 * 0x50000) >> 16;
nausea += (var_10E_unk_2 * 0x32000) >> 16;
nausea += (var_10E_unk_3 * 42281) >> 16;
rating.intensity = (no_3_plus_turns * 81920) >> 16;
rating.intensity += (no_2_turns * 49152) >> 16;
rating.intensity += (no_1_turns * 21140) >> 16;
rating.nausea = (no_3_plus_turns * 0x50000) >> 16;
rating.nausea += (no_2_turns * 0x32000) >> 16;
rating.nausea += (no_1_turns * 42281) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
@ -955,24 +953,25 @@ static rating_tuple get_var_10E_rating(rct_ride* ride) {
*
* rct2: 0x0065DF72
*/
static rating_tuple get_var_110_rating(rct_ride* ride) {
int var_110_unk_1 = get_var_110_unk_1(ride);
int var_110_unk_2 = get_var_110_unk_2(ride);
int var_110_unk_3 = get_var_110_unk_3(ride);
static rating_tuple get_banked_turns_rating(rct_ride* ride) {
rating_tuple rating;
int excitement = (var_110_unk_1 * 0x3C000) >> 16;
excitement += (var_110_unk_2 * 0x3C000) >> 16;
excitement += (var_110_unk_3 * 73992) >> 16;
int no_3_plus_turns = get_turn_count_3_elements(ride, 1);
int no_2_turns = get_turn_count_2_elements(ride, 1);
int no_1_turns = get_turn_count_1_element(ride, 1);
int intensity = (var_110_unk_1 * 0x14000) >> 16;
intensity += (var_110_unk_2 * 49152) >> 16;
intensity += (var_110_unk_3 * 21140) >> 16;
rating.excitement = (no_3_plus_turns * 0x3C000) >> 16;
rating.excitement += (no_2_turns * 0x3C000) >> 16;
rating.excitement += (no_1_turns * 73992) >> 16;
int nausea = (var_110_unk_1 * 0x50000) >> 16;
nausea += (var_110_unk_2 * 0x32000) >> 16;
nausea += (var_110_unk_3 * 48623) >> 16;
rating.intensity = (no_3_plus_turns * 0x14000) >> 16;
rating.intensity += (no_2_turns * 49152) >> 16;
rating.intensity += (no_1_turns * 21140) >> 16;
rating.nausea = (no_3_plus_turns * 0x50000) >> 16;
rating.nausea += (no_2_turns * 0x32000) >> 16;
rating.nausea += (no_1_turns * 48623) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
@ -980,30 +979,21 @@ static rating_tuple get_var_110_rating(rct_ride* ride) {
*
* rct2: 0x0065E047
*/
static rating_tuple get_var_112_rating(rct_ride *ride) {
int al;
static rating_tuple get_sloped_turns_rating(rct_ride* ride) {
rating_tuple rating;
al = get_var_112_unk_1(ride);
al = min(al, 4);
int excitement = (al * 0x78000) >> 16;
int no_4_plus_turns = get_turn_count_4_plus_elements(ride, 2);
int no_3_turns = get_turn_count_3_elements(ride, 2);
int no_2_turns = get_turn_count_2_elements(ride, 2);
int no_1_turns = get_turn_count_1_element(ride, 2);
al = get_var_112_unk_1(ride);
al = min(al, 8);
int nausea = (al * 0x78000) >> 16;
rating.excitement = (min(no_4_plus_turns, 4) * 0x78000) >> 16;
rating.excitement += (min(no_3_turns, 6) * 273066) >> 16;
rating.excitement += (min(no_2_turns, 6) * 0x3AAAA) >> 16;
rating.excitement += (min(no_1_turns, 7) * 187245) >> 16;
rating.intensity = 0;
rating.nausea = (min(no_4_plus_turns, 8) * 0x78000) >> 16;
al = get_var_112_unk_2(ride);
al = min(al, 6);
excitement += (al * 273066) >> 16;
al = get_var_112_unk_3(ride);
al = min(al, 6);
excitement += (al * 0x3AAAA) >> 16;
al = get_var_112_unk_4(ride);
al = min(al, 7);
excitement += (al * 187245) >> 16;
rating_tuple rating = { excitement, 0, nausea };
return rating;
}
@ -1012,11 +1002,12 @@ static rating_tuple get_var_112_rating(rct_ride *ride) {
* rct2: 0x0065E0F2
*/
static rating_tuple get_inversions_ratings(uint8 inversions) {
int excitement = (min(inversions, 6) * 0x1AAAAA) >> 16;
int intensity = (inversions * 0x320000) >> 16;
int nausea = (inversions * 0x15AAAA) >> 16;
rating_tuple rating;
rating.excitement = (min(inversions, 6) * 0x1AAAAA) >> 16;
rating.intensity = (inversions * 0x320000) >> 16;
rating.nausea = (inversions * 0x15AAAA) >> 16;
rating_tuple rating = { excitement, intensity, nausea };
return rating;
}
@ -1079,17 +1070,17 @@ static rating_tuple sub_65DDD1(rct_ride *ride)
intensity += special_track_element_rating.intensity;
nausea += special_track_element_rating.nausea;
rating_tuple var_10E_rating = get_var_10E_rating(ride);
rating_tuple var_10E_rating = get_flat_turns_rating(ride);
excitement += var_10E_rating.excitement;
intensity += var_10E_rating.intensity;
nausea += var_10E_rating.nausea;
rating_tuple var_110_rating = get_var_110_rating(ride);
rating_tuple var_110_rating = get_banked_turns_rating(ride);
excitement += var_110_rating.excitement;
intensity += var_110_rating.intensity;
nausea += var_110_rating.nausea;
rating_tuple var_112_rating = get_var_112_rating(ride);
rating_tuple var_112_rating = get_sloped_turns_rating(ride);
excitement += var_112_rating.excitement;
intensity += var_112_rating.intensity;
nausea += var_112_rating.nausea;

View File

@ -105,7 +105,7 @@ static void ride_update_station_bumpercar(rct_ride *ride, int stationIndex)
dh = (dx >> 8) & 0xFF;
for (i = 0; i < ride->num_vehicles; i++) {
vehicle = &(g_sprite_list[ride->vehicles[i]].vehicle);
if (vehicle->var_CE < dh || (vehicle->var_CE < dh && vehicle->var_51 > dl))
if (vehicle->var_CE < dh || (vehicle->var_CE < dh && vehicle->sub_state > dl))
continue;
// End match

View File

@ -2385,33 +2385,16 @@ int track_delete()
int track_is_connected_by_shape(rct_map_element *a, rct_map_element *b)
{
int trackType, aBank, aAngle, bBank, bAngle;
rct_ride *ride;
ride = GET_RIDE(a->properties.track.ride_index);
trackType = a->properties.track.type;
aBank = gTrackDefinitions[trackType].bank_end;
aAngle = gTrackDefinitions[trackType].vangle_end;
if (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_3) {
if (a->properties.track.colour & 4) {
if (aBank == TRACK_BANK_NONE)
aBank = TRACK_BANK_UPSIDE_DOWN;
else if (aBank == TRACK_BANK_UPSIDE_DOWN)
aBank = TRACK_BANK_NONE;
}
}
aBank = track_get_actual_bank(a, aBank);
ride = GET_RIDE(b->properties.track.ride_index);
trackType = b->properties.track.type;
bBank = gTrackDefinitions[trackType].bank_start;
bAngle = gTrackDefinitions[trackType].vangle_start;
if (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_3) {
if (b->properties.track.colour & 4) {
if (bBank == TRACK_BANK_NONE)
bBank = TRACK_BANK_UPSIDE_DOWN;
else if (bBank == TRACK_BANK_UPSIDE_DOWN)
bBank = TRACK_BANK_NONE;
}
}
bBank = track_get_actual_bank(b, bBank);
return aBank == bBank && aAngle == bAngle;
}
@ -4939,6 +4922,30 @@ bool track_element_is_lift_hill(rct_map_element *trackElement)
return trackElement->type & 0x80;
}
/**
* Checks if a track element is recognised as the beginning of a block.
* A beginning of a block can be the end of a station, the end of a lift hill,
* or a block brake.
*/
bool track_element_is_block_start(rct_map_element *trackElement)
{
switch (trackElement->properties.track.type) {
case TRACK_ELEM_END_STATION:
case TRACK_ELEM_CABLE_LIFT_HILL:
case 216:
return true;
case TRACK_ELEM_25_DEG_UP_TO_FLAT:
case TRACK_ELEM_60_DEG_UP_TO_FLAT:
case TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT:
case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT:
if (track_element_is_lift_hill(trackElement)) {
return true;
}
break;
}
return false;
}
bool track_element_is_cable_lift(rct_map_element *trackElement) {
return trackElement->properties.track.colour & TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT;
}
@ -4950,3 +4957,74 @@ void track_element_set_cable_lift(rct_map_element *trackElement) {
void track_element_clear_cable_lift(rct_map_element *trackElement) {
trackElement->properties.track.colour &= ~TRACK_ELEMENT_COLOUR_FLAG_CABLE_LIFT;
}
int track_get_actual_bank(rct_map_element *mapElement, int bank)
{
rct_ride *ride = GET_RIDE(mapElement->properties.track.ride_index);
int trackColour = mapElement->properties.track.colour;
return track_get_actual_bank_2(ride->type, trackColour, bank);
}
int track_get_actual_bank_2(int rideType, int trackColour, int bank)
{
if (RideData4[rideType].flags & RIDE_TYPE_FLAG4_3) {
if (trackColour & 4) {
if (bank == TRACK_BANK_NONE) {
bank = TRACK_BANK_UPSIDE_DOWN;
} else if (bank == TRACK_BANK_UPSIDE_DOWN) {
bank = TRACK_BANK_NONE;
}
}
}
return bank;
}
int track_get_actual_bank_3(rct_vehicle *vehicle, rct_map_element *mapElement)
{
uint8 colourThingToXor = (vehicle->update_flags >> 9) & 0xFF;
int trackType = mapElement->properties.track.type;
int rideType = GET_RIDE(mapElement->properties.track.ride_index)->type;
int trackColour = mapElement->properties.track.colour ^ colourThingToXor;
int bankStart = gTrackDefinitions[trackType].bank_start;
return track_get_actual_bank_2(rideType, trackColour, bankStart);
}
bool track_element_is_station(rct_map_element *trackElement)
{
switch (trackElement->properties.track.type) {
case TRACK_ELEM_END_STATION:
case TRACK_ELEM_BEGIN_STATION:
case TRACK_ELEM_MIDDLE_STATION:
return true;
default:
return false;
}
}
bool track_element_is_covered(int trackElementType)
{
switch (trackElementType) {
case TRACK_ELEM_FLAT_COVERED:
case TRACK_ELEM_25_DEG_UP_COVERED:
case TRACK_ELEM_60_DEG_UP_COVERED:
case TRACK_ELEM_FLAT_TO_25_DEG_UP_COVERED:
case TRACK_ELEM_25_DEG_UP_TO_60_DEG_UP_COVERED:
case TRACK_ELEM_60_DEG_UP_TO_25_DEG_UP_COVERED:
case TRACK_ELEM_25_DEG_UP_TO_FLAT_COVERED:
case TRACK_ELEM_25_DEG_DOWN_COVERED:
case TRACK_ELEM_60_DEG_DOWN_COVERED:
case TRACK_ELEM_FLAT_TO_25_DEG_DOWN_COVERED:
case TRACK_ELEM_25_DEG_DOWN_TO_60_DEG_DOWN_COVERED:
case TRACK_ELEM_60_DEG_DOWN_TO_25_DEG_DOWN_COVERED:
case TRACK_ELEM_25_DEG_DOWN_TO_FLAT_COVERED:
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_COVERED:
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_COVERED:
case TRACK_ELEM_S_BEND_LEFT_COVERED:
case TRACK_ELEM_S_BEND_RIGHT_COVERED:
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_COVERED:
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_COVERED:
return true;
default:
return false;
}
}

View File

@ -300,6 +300,17 @@ enum {
TRACK_CORKSCREW_DOWN = 224
};
enum {
TRACK_ELEM_FLAG_TURN_LEFT = (1 << 1),
TRACK_ELEM_FLAG_TURN_RIGHT = (1 << 2),
TRACK_ELEM_FLAG_TURN_BANKED = (1 << 3),
TRACK_ELEM_FLAG_TURN_SLOPED = (1 << 4),
TRACK_ELEM_FLAG_DOWN = (1 << 5),
TRACK_ELEM_FLAG_UP = (1 << 6),
TRACK_ELEM_FLAG_INVERSION = (1 << 7),
TRACK_ELEM_FLAG_HELIX = (1 << 11),
};
enum {
TRACK_ELEM_FLAT,
TRACK_ELEM_END_STATION,
@ -311,7 +322,7 @@ enum {
TRACK_ELEM_25_DEG_UP_TO_60_DEG_UP,
TRACK_ELEM_60_DEG_UP_TO_25_DEG_UP,
TRACK_ELEM_25_DEG_UP_TO_FLAT,
TRACK_ELEM_25_DEG_DOWN,
TRACK_ELEM_25_DEG_DOWN = 10,
TRACK_ELEM_60_DEG_DOWN,
TRACK_ELEM_FLAT_TO_25_DEG_DOWN,
TRACK_ELEM_25_DEG_DOWN_TO_60_DEG_DOWN,
@ -321,7 +332,7 @@ enum {
TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES,
TRACK_ELEM_FLAT_TO_LEFT_BANK,
TRACK_ELEM_FLAT_TO_RIGHT_BANK,
TRACK_ELEM_LEFT_BANK_TO_FLAT,
TRACK_ELEM_LEFT_BANK_TO_FLAT = 20,
TRACK_ELEM_RIGHT_BANK_TO_FLAT,
TRACK_ELEM_BANKED_LEFT_QUARTER_TURN_5_TILES,
TRACK_ELEM_BANKED_RIGHT_QUARTER_TURN_5_TILES,
@ -331,7 +342,7 @@ enum {
TRACK_ELEM_25_DEG_UP_TO_RIGHT_BANK,
TRACK_ELEM_LEFT_BANK_TO_25_DEG_DOWN,
TRACK_ELEM_RIGHT_BANK_TO_25_DEG_DOWN,
TRACK_ELEM_25_DEG_DOWN_TO_LEFT_BANK,
TRACK_ELEM_25_DEG_DOWN_TO_LEFT_BANK = 30,
TRACK_ELEM_25_DEG_DOWN_TO_RIGHT_BANK,
TRACK_ELEM_LEFT_BANK,
TRACK_ELEM_RIGHT_BANK,
@ -341,7 +352,7 @@ enum {
TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_DOWN,
TRACK_ELEM_S_BEND_LEFT,
TRACK_ELEM_S_BEND_RIGHT,
TRACK_ELEM_LEFT_VERTICAL_LOOP,
TRACK_ELEM_LEFT_VERTICAL_LOOP = 40,
TRACK_ELEM_RIGHT_VERTICAL_LOOP,
TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES,
TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES,
@ -351,7 +362,7 @@ enum {
TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP,
TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN,
TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN,
TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE,
TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE = 50,
TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE,
TRACK_ELEM_LEFT_TWIST_DOWN_TO_UP,
TRACK_ELEM_RIGHT_TWIST_DOWN_TO_UP,
@ -361,7 +372,7 @@ enum {
TRACK_ELEM_HALF_LOOP_DOWN,
TRACK_ELEM_LEFT_CORKSCREW_UP,
TRACK_ELEM_RIGHT_CORKSCREW_UP,
TRACK_ELEM_LEFT_CORKSCREW_DOWN,
TRACK_ELEM_LEFT_CORKSCREW_DOWN = 60,
TRACK_ELEM_RIGHT_CORKSCREW_DOWN,
TRACK_ELEM_FLAT_TO_60_DEG_UP,
TRACK_ELEM_60_DEG_UP_TO_FLAT,
@ -371,7 +382,7 @@ enum {
TRACK_ELEM_TOWER_SECTION,
TRACK_ELEM_FLAT_COVERED,
TRACK_ELEM_25_DEG_UP_COVERED,
TRACK_ELEM_60_DEG_UP_COVERED,
TRACK_ELEM_60_DEG_UP_COVERED = 70,
TRACK_ELEM_FLAT_TO_25_DEG_UP_COVERED,
TRACK_ELEM_25_DEG_UP_TO_60_DEG_UP_COVERED,
TRACK_ELEM_60_DEG_UP_TO_25_DEG_UP_COVERED,
@ -381,7 +392,7 @@ enum {
TRACK_ELEM_FLAT_TO_25_DEG_DOWN_COVERED,
TRACK_ELEM_25_DEG_DOWN_TO_60_DEG_DOWN_COVERED,
TRACK_ELEM_60_DEG_DOWN_TO_25_DEG_DOWN_COVERED,
TRACK_ELEM_25_DEG_DOWN_TO_FLAT_COVERED,
TRACK_ELEM_25_DEG_DOWN_TO_FLAT_COVERED = 80,
TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_COVERED,
TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_COVERED,
TRACK_ELEM_S_BEND_LEFT_COVERED,
@ -391,7 +402,7 @@ enum {
TRACK_ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL,
TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_UP_SMALL,
TRACK_ELEM_LEFT_HALF_BANKED_HELIX_DOWN_SMALL,
TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL,
TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL = 90,
TRACK_ELEM_LEFT_HALF_BANKED_HELIX_UP_LARGE,
TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_UP_LARGE,
TRACK_ELEM_LEFT_HALF_BANKED_HELIX_DOWN_LARGE,
@ -401,7 +412,7 @@ enum {
TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_DOWN,
TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_DOWN,
TRACK_ELEM_BRAKES,
TRACK_ELEM_ROTATION_CONTROL_TOGGLE,
TRACK_ELEM_ROTATION_CONTROL_TOGGLE = 100,
TRACK_ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP,
TRACK_ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_UP,
TRACK_ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_UP,
@ -411,7 +422,7 @@ enum {
TRACK_ELEM_RIGHT_QUARTER_HELIX_LARGE_UP,
TRACK_ELEM_LEFT_QUARTER_HELIX_LARGE_DOWN,
TRACK_ELEM_RIGHT_QUARTER_HELIX_LARGE_DOWN,
TRACK_ELEM_25_DEG_UP_LEFT_BANKED,
TRACK_ELEM_25_DEG_UP_LEFT_BANKED = 110,
TRACK_ELEM_25_DEG_UP_RIGHT_BANKED,
TRACK_ELEM_WATERFALL,
TRACK_ELEM_RAPIDS,
@ -421,7 +432,7 @@ enum {
TRACK_ELEM_WATER_SPLASH,
TRACK_ELEM_FLAT_TO_60_DEG_UP_LONG_BASE,
TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE,
TRACK_ELEM_WHIRLPOOL,
TRACK_ELEM_WHIRLPOOL = 120,
TRACK_ELEM_FLAT_TO_60_DEG_DOWN_LONG_BASE,
TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE_122,
TRACK_ELEM_CABLE_LIFT_HILL,
@ -431,7 +442,7 @@ enum {
TRACK_ELEM_90_DEG_DOWN,
TRACK_ELEM_60_DEG_UP_TO_90_DEG_UP,
TRACK_ELEM_90_DEG_DOWN_TO_60_DEG_DOWN,
TRACK_ELEM_90_DEG_UP_TO_60_DEG_UP,
TRACK_ELEM_90_DEG_UP_TO_60_DEG_UP = 130,
TRACK_ELEM_60_DEG_DOWN_TO_90_DEG_DOWN,
TRACK_ELEM_BRAKE_FOR_DROP,
TRACK_ELEM_LEFT_EIGHTH_TO_DIAG,
@ -441,7 +452,7 @@ enum {
TRACK_ELEM_LEFT_EIGHTH_BANK_TO_DIAG,
TRACK_ELEM_RIGHT_EIGHTH_BANK_TO_DIAG,
TRACK_ELEM_LEFT_EIGHTH_BANK_TO_ORTHOGONAL,
TRACK_ELEM_RIGHT_EIGHTH_BANK_TO_ORTHOGONAL,
TRACK_ELEM_RIGHT_EIGHTH_BANK_TO_ORTHOGONAL = 140,
TRACK_ELEM_DIAG_FLAT,
TRACK_ELEM_DIAG_25_DEG_UP,
TRACK_ELEM_DIAG_60_DEG_UP,
@ -451,7 +462,7 @@ enum {
TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT,
TRACK_ELEM_DIAG_25_DEG_DOWN,
TRACK_ELEM_DIAG_60_DEG_DOWN,
TRACK_ELEM_DIAG_FLAT_TO_25_DEG_DOWN,
TRACK_ELEM_DIAG_FLAT_TO_25_DEG_DOWN = 150,
TRACK_ELEM_DIAG_25_DEG_DOWN_TO_60_DEG_DOWN,
TRACK_ELEM_DIAG_60_DEG_DOWN_TO_25_DEG_DOWN,
TRACK_ELEM_DIAG_25_DEG_DOWN_TO_FLAT,
@ -461,7 +472,7 @@ enum {
TRACK_ELEM_DIAG_60_DEG_DOWN_TO_FLAT,
TRACK_ELEM_DIAG_FLAT_TO_LEFT_BANK,
TRACK_ELEM_DIAG_FLAT_TO_RIGHT_BANK,
TRACK_ELEM_DIAG_LEFT_BANK_TO_FLAT,
TRACK_ELEM_DIAG_LEFT_BANK_TO_FLAT = 160,
TRACK_ELEM_DIAG_RIGHT_BANK_TO_FLAT,
TRACK_ELEM_DIAG_LEFT_BANK_TO_25_DEG_UP,
TRACK_ELEM_DIAG_RIGHT_BANK_TO_25_DEG_UP,
@ -471,7 +482,7 @@ enum {
TRACK_ELEM_DIAG_RIGHT_BANK_TO_25_DEG_DOWN,
TRACK_ELEM_DIAG_25_DEG_DOWN_TO_LEFT_BANK,
TRACK_ELEM_DIAG_25_DEG_DOWN_TO_RIGHT_BANK,
TRACK_ELEM_DIAG_LEFT_BANK,
TRACK_ELEM_DIAG_LEFT_BANK = 170,
TRACK_ELEM_DIAG_RIGHT_BANK,
TRACK_ELEM_LOG_FLUME_REVERSER,
TRACK_ELEM_SPINNING_TUNNEL,
@ -481,13 +492,81 @@ enum {
TRACK_ELEM_RIGHT_BARREL_ROLL_DOWN_TO_UP,
TRACK_ELEM_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP,
TRACK_ELEM_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP,
TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_LEFT_BANK,
TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_LEFT_BANK = 180,
TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_RIGHT_BANK,
TRACK_ELEM_POWERED_LIFT,
TRACK_ELEM_LEFT_LARGE_HALF_LOOP_UP,
TRACK_ELEM_RIGHT_LARGE_HALF_LOOP_UP,
TRACK_ELEM_RIGHT_LARGE_HALF_LOOP_DOWN,
TRACK_ELEM_LEFT_LARGE_HALF_LOOP_DOWN
TRACK_ELEM_LEFT_LARGE_HALF_LOOP_DOWN,
TRACK_ELEM_LEFT_FLYER_TWIST_UP,
TRACK_ELEM_RIGHT_FLYER_TWIST_UP,
TRACK_ELEM_LEFT_FLYER_TWIST_DOWN,
TRACK_ELEM_RIGHT_FLYER_TWIST_DOWN,
TRACK_ELEM_FLYER_HALF_LOOP_UP,
TRACK_ELEM_FLYER_HALF_LOOP_DOWN,
TRACK_ELEM_LEFT_FLYER_CORKSCREW_UP,
TRACK_ELEM_RIGHT_FLYER_CORKSCREW_UP,
TRACK_ELEM_LEFT_FLYER_CORKSCREW_DOWN,
TRACK_ELEM_RIGHT_FLYER_CORKSCREW_DOWN,
TRACK_ELEM_HEARTLINE_TRANSFER_UP,
TRACK_ELEM_HEARTLINE_TRANSFER_DOWN,
TRACK_ELEM_LEFT_HEARTLINE_ROLL,
TRACK_ELEM_RIGHT_HEARTLINE_ROLL,
TRACK_ELEM_MINI_GOLF_HOLE_A,
TRACK_ELEM_MINI_GOLF_HOLE_B,
TRACK_ELEM_MINI_GOLF_HOLE_C,
TRACK_ELEM_MINI_GOLF_HOLE_D,
TRACK_ELEM_MINI_GOLF_HOLE_E,
TRACK_ELEM_MULTIDIM_INVERTED_FLAT_TO_90_DEG_QUARTER_LOOP_DOWN,
TRACK_ELEM_90_DEG_TO_INVERTED_FLAT_QUARTER_LOOP_UP,
TRACK_ELEM_INVERTED_FLAT_TO_90_DEG_QUARTER_LOOP_DOWN,
TRACK_ELEM_LEFT_CURVED_LIFT_HILL,
TRACK_ELEM_RIGHT_CURVED_LIFT_HILL,
TRACK_ELEM_LEFT_REVERSER,
TRACK_ELEM_RIGHT_REVERSER,
TRACK_ELEM_AIR_THRUST_TOP_CAP,
TRACK_ELEM_AIR_THRUST_VERTICAL_DOWN,
TRACK_ELEM_AIR_THRUST_VERTICAL_DOWN_TO_LEVEL,
TRACK_ELEM_BLOCK_BRAKES,
TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_3_TILE_25_DEG_UP,
TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_3_TILE_25_DEG_UP,
TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_3_TILE_25_DEG_DOWN,
TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_3_TILE_25_DEG_DOWN,
TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_5_TILE_25_DEG_UP,
TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_5_TILE_25_DEG_UP,
TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_5_TILE_25_DEG_DOWN,
TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_5_TILE_25_DEG_DOWN,
TRACK_ELEM_25_DEG_UP_TO_LEFT_BANKED_25_DEG_UP,
TRACK_ELEM_25_DEG_UP_TO_RIGHT_BANKED_25_DEG_UP,
TRACK_ELEM_LEFT_BANKED_25_DEG_UP_TO_25_DEG_UP,
TRACK_ELEM_RIGHT_BANKED_25_DEG_UP_TO_25_DEG_UP,
TRACK_ELEM_25_DEG_DOWN_TO_LEFT_BANKED_25_DEG_DOWN,
TRACK_ELEM_25_DEG_DOWN_TO_RIGHT_BANKED_25_DEG_DOWN,
TRACK_ELEM_LEFT_BANKED_25_DEG_DOWN_TO_25_DEG_DOWN,
TRACK_ELEM_RIGHT_BANKED_25_DEG_DOWN_TO_25_DEG_DOWN,
TRACK_ELEM_LEFT_BANKED_FLAT_TO_LEFT_BANKED_25_DEG_UP,
TRACK_ELEM_RIGHT_BANKED_FLAT_TO_RIGHT_BANKED_25_DEG_UP,
TRACK_ELEM_LEFT_BANKED_25_DEG_UP_TO_LEFT_BANKED_FLAT,
TRACK_ELEM_RIGHT_BANKED_25_DEG_UP_TO_RIGHT_BANKED_FLAT,
TRACK_ELEM_LEFT_BANKED_FLAT_TO_LEFT_BANKED_25_DEG_DOWN,
TRACK_ELEM_RIGHT_BANKED_FLAT_TO_RIGHT_BANKED_25_DEG_DOWN,
TRACK_ELEM_LEFT_BANKED_25_DEG_DOWN_TO_LEFT_BANKED_FLAT,
TRACK_ELEM_RIGHT_BANKED_25_DEG_DOWN_TO_RIGHT_BANKED_FLAT,
TRACK_ELEM_FLAT_TO_LEFT_BANKED_25_DEG_UP,
TRACK_ELEM_FLAT_TO_RIGHT_BANKED_25_DEG_UP,
TRACK_ELEM_LEFT_BANKED_25_DEG_UP_TO_FLAT,
TRACK_ELEM_RIGHT_BANKED_25_DEG_UP_TO_FLAT,
TRACK_ELEM_FLAT_TO_LEFT_BANKED_25_DEG_DOWN,
TRACK_ELEM_FLAT_TO_RIGHT_BANKED_25_DEG_DOWN,
TRACK_ELEM_LEFT_BANKED_25_DEG_DOWN_TO_FLAT,
TRACK_ELEM_RIGHT_BANKED_25_DEG_DOWN_TO_FLAT,
TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_90_DEG_UP,
TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_90_DEG_UP,
TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_90_DEG_DOWN,
TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_90_DEG_DOWN,
TRACK_ELEM_MULTIDIM_90_DEG_UP_TO_INVERTED_FLAT_QUARTER_LOOP,
TRACK_ELEM_MULTIDIM_FLAT_TO_90_DEG_DOWN_QUARTER_LOOP,
};
enum {
@ -547,9 +626,17 @@ void track_get_back(rct_xy_element *input, rct_xy_element *output);
void track_get_front(rct_xy_element *input, rct_xy_element *output);
bool track_element_is_lift_hill(rct_map_element *trackElement);
bool track_element_is_block_start(rct_map_element *trackElement);
bool track_element_is_cable_lift(rct_map_element *trackElement);
void track_element_set_cable_lift(rct_map_element *trackElement);
void track_element_clear_cable_lift(rct_map_element *trackElement);
int track_get_actual_bank(rct_map_element *mapElement, int bank);
int track_get_actual_bank_2(int rideType, int trackColour, int bank);
int track_get_actual_bank_3(rct_vehicle *vehicle, rct_map_element *mapElement);
bool track_element_is_station(rct_map_element *trackElement);
bool track_element_is_covered(int trackElementType);
#endif

View File

@ -82,7 +82,7 @@ static rct_xy16 loc_7667AC[] = {
/**
*
* rct2: 0x0142811C
* rct2: 0x0142811C
* Can be calculated as Rounddown(34*sin(x)+0.5)
* where x is in 7.5 deg segments.
*/
@ -178,9 +178,9 @@ static void top_spin_paint_vehicle(sint8 al, sint8 cl, uint8 rideIndex, uint8 di
uint32 seatImageId;
if (vehicle != NULL && vehicle->var_B5 >= 64) {
if (vehicle != NULL && vehicle->restraints_position >= 64) {
// Open Restraints
image_id = (vehicle->var_B5 - 64) >> 6;
image_id = (vehicle->restraints_position - 64) >> 6;
image_id += direction * 3;
image_id += rideEntry->vehicles[0].base_image_id;
image_id += 64;
@ -1028,7 +1028,7 @@ static void shop_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 directi
RCT2_GLOBAL(0x009DEA52, uint16) = 2;
RCT2_GLOBAL(0x009DEA54, uint16) = 2;
RCT2_GLOBAL(0x009DEA56, sint16) = height16;
sub_98199C(0, 45, imageId, 0, height, 28, 28, rotation);
sub_98199C(0, 45, imageId, 0, height, 28, 28, rotation);
} else {
RCT2_GLOBAL(0x009DEA52, uint16) = 2;
RCT2_GLOBAL(0x009DEA54, uint16) = 2;
@ -1099,7 +1099,7 @@ static void facility_paint_setup(uint8 rideIndex, uint8 trackSequence, uint8 dir
RCT2_GLOBAL(0x009DEA52, uint16) = direction == 3 ? 28 : 2;
RCT2_GLOBAL(0x009DEA54, uint16) = direction == 0 ? 28 : 2;
RCT2_GLOBAL(0x009DEA56, sint16) = height16;
sub_98199C(0, 29, imageId, 0, height, lengthY, lengthX, rotation);
sub_98199C(0, 29, imageId, 0, height, lengthY, lengthX, rotation);
} else {
// Door image or base
RCT2_GLOBAL(0x009DEA52, uint16) = direction == 3 ? 28 : 2;

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@ typedef struct {
uint16 rotation_frame_mask; // 0x00 , 0x1A
uint8 var_02; // 0x02 , 0x1C
uint8 var_03; // 0x03 , 0x1D
uint32 var_04; // 0x04 , 0x1E
uint32 spacing; // 0x04 , 0x1E
uint16 car_friction; // 0x08 , 0x22
sint8 tab_height; // 0x0A , 0x24
uint8 num_seats; // 0x0B , 0x25
@ -46,8 +46,8 @@ typedef struct {
uint8 sprite_height_negative; // 0x0F , 0x29
uint8 sprite_height_positive; // 0x10 , 0x2A
uint8 var_11; // 0x11 , 0x2B
uint16 var_12; // 0x12 , 0x2C
uint16 var_14; // 0x14 , 0x2E
uint16 flags_a; // 0x12 , 0x2C
uint16 flags_b; // 0x14 , 0x2E
uint16 var_16; // 0x16 , 0x30
uint32 base_image_id; // 0x18 , 0x32
uint32 var_1C; // 0x1C , 0x36
@ -67,7 +67,9 @@ typedef struct {
uint8 no_seating_rows; // 0x54 , 0x6E
uint8 spinning_inertia; // 0x55 , 0x6F
uint8 spinning_friction; // 0x56 , 0x70
uint8 pad_57[0x3];
uint8 var_57; // 0x57 , 0x71
uint8 var_58; // 0x58 , 0x72
uint8 sound_range; // 0x59 , 0x73
uint8 var_5A; // 0x5A , 0x74
uint8 powered_acceleration; // 0x5B , 0x75
uint8 powered_max_speed; // 0x5C , 0x76
@ -104,16 +106,23 @@ typedef struct {
uint8 var_1F;
uint8 var_20;
uint8 pad_21[3];
uint32 var_24;
sint32 remaining_distance; // 0x24
sint32 velocity; // 0x28
uint32 var_2C;
sint32 acceleration; // 0x2C
uint8 ride; // 0x30
uint8 vehicle_type; // 0x31
rct_vehicle_colour colours; // 0x32
uint16 var_34;
union {
uint16 track_progress; // 0x34
struct {
sint8 var_34;
uint8 var_35;
};
};
union {
sint16 track_direction; // 0x36 (0000 0000 0000 0011)
sint16 track_type; // 0x36 (0000 0011 1111 1100)
rct_xy8 boat_location; // 0x36
};
uint16 track_x; // 0x38
uint16 track_y; // 0x3A
@ -131,17 +140,24 @@ typedef struct {
uint16 update_flags; // 0x48
uint8 var_4A;
uint8 current_station; // 0x4B
uint16 var_4C;
union {
sint16 swinging_car_var_0; // 0x4C
sint16 current_time; // 0x4C
struct {
sint8 ferris_wheel_var_0; // 0x4C
sint8 ferris_wheel_var_1; // 0x4D
};
};
uint16 var_4E;
uint8 status; // 0x50
uint8 var_51;
uint8 sub_state; // 0x51
uint16 peep[32]; // 0x52
uint8 peep_tshirt_colours[32]; // 0x92
uint8 num_seats; // 0xB2
uint8 num_peeps; // 0xB3
uint8 next_free_seat; // 0xB4
uint8 var_B5;
uint16 var_B6;
uint8 restraints_position; // 0xB5 0 == Close, 255 == Open
sint16 var_B6;
uint16 var_B8;
uint8 var_BA;
uint8 sound1_id; // 0xBB
@ -149,20 +165,22 @@ typedef struct {
uint8 sound2_id; // 0xBD
uint8 sound2_volume; // 0xBE
sint8 var_BF;
uint8 pad_C0[2];
uint16 var_C0;
uint8 speed; // 0xC2
uint8 acceleration; // 0xC3
uint8 powered_acceleration; // 0xC3
uint8 var_C4;
uint8 var_C5;
uint8 pad_C6[2];
uint32 var_C8;
uint8 pad_C6[0x2];
uint16 var_C8;
uint16 var_CA;
uint8 scream_sound_id; // 0xCC
uint8 var_CD;
union {
uint8 var_CE;
uint8 num_laps; // 0xCE
};
uint8 pad_CF[0x03];
uint8 var_CF;
uint16 lost_time_out; // 0xD0
sint8 var_D2;
uint8 var_D3;
uint8 var_D4;
@ -178,6 +196,54 @@ typedef struct {
rct_vehicle *tail;
} train_ref;
// Size: 0x09
typedef struct {
uint16 x; // 0x00
uint16 y; // 0x02
uint16 z; // 0x04
uint8 direction; // 0x06
uint8 var_07;
uint8 var_08;
} rct_vehicle_info;
enum {
VEHICLE_ENTRY_FLAG_A_0 = 1 << 0,
VEHICLE_ENTRY_FLAG_A_1 = 1 << 1,
VEHICLE_ENTRY_FLAG_A_2 = 1 << 2,
VEHICLE_ENTRY_FLAG_A_3 = 1 << 3,
VEHICLE_ENTRY_FLAG_A_4 = 1 << 4,
VEHICLE_ENTRY_FLAG_A_5 = 1 << 5,
VEHICLE_ENTRY_FLAG_A_6 = 1 << 6,
VEHICLE_ENTRY_FLAG_A_7 = 1 << 7,
VEHICLE_ENTRY_FLAG_A_8 = 1 << 8,
VEHICLE_ENTRY_FLAG_A_9 = 1 << 9,
VEHICLE_ENTRY_FLAG_A_10 = 1 << 10,
VEHICLE_ENTRY_FLAG_A_11 = 1 << 11,
VEHICLE_ENTRY_FLAG_A_12 = 1 << 12,
VEHICLE_ENTRY_FLAG_A_13 = 1 << 13,
VEHICLE_ENTRY_FLAG_A_14 = 1 << 14,
VEHICLE_ENTRY_FLAG_A_15 = 1 << 15,
};
enum {
VEHICLE_ENTRY_FLAG_B_0 = 1 << 0,
VEHICLE_ENTRY_FLAG_B_SWINGING = 1 << 1,
VEHICLE_ENTRY_FLAG_B_SPINNING = 1 << 2,
VEHICLE_ENTRY_FLAG_B_3 = 1 << 3,
VEHICLE_ENTRY_FLAG_B_4 = 1 << 4,
VEHICLE_ENTRY_FLAG_B_5 = 1 << 5,
VEHICLE_ENTRY_FLAG_B_6 = 1 << 6,
VEHICLE_ENTRY_FLAG_B_7 = 1 << 7,
VEHICLE_ENTRY_FLAG_B_8 = 1 << 8,
VEHICLE_ENTRY_FLAG_B_9 = 1 << 9,
VEHICLE_ENTRY_FLAG_B_10 = 1 << 10,
VEHICLE_ENTRY_FLAG_B_11 = 1 << 11,
VEHICLE_ENTRY_FLAG_B_12 = 1 << 12,
VEHICLE_ENTRY_FLAG_B_13 = 1 << 13,
VEHICLE_ENTRY_FLAG_B_14 = 1 << 14,
VEHICLE_ENTRY_FLAG_B_15 = 1 << 15,
};
enum {
VEHICLE_STATUS_MOVING_TO_END_OF_STATION,
VEHICLE_STATUS_WAITING_FOR_PASSENGERS,
@ -186,22 +252,22 @@ enum {
VEHICLE_STATUS_TRAVELLING,
VEHICLE_STATUS_ARRIVING,
VEHICLE_STATUS_UNLOADING_PASSENGERS,
VEHICLE_STATUS_TRAVELLING_07,
VEHICLE_STATUS_TRAVELLING_BOAT,
VEHICLE_STATUS_CRASHING,
VEHICLE_STATUS_CRASHED,
VEHICLE_STATUS_TRAVELLING_0A,
VEHICLE_STATUS_TRAVELLING_BUMPER_CARS,
VEHICLE_STATUS_SWINGING,
VEHICLE_STATUS_ROTATING,
VEHICLE_STATUS_ROTATING_0D,
VEHICLE_STATUS_OPERATING,
VEHICLE_STATUS_FERRIS_WHEEL_ROTATING,
VEHICLE_STATUS_SIMULATOR_OPERATING,
VEHICLE_STATUS_SHOWING_FILM,
VEHICLE_STATUS_ROTATING_10,
VEHICLE_STATUS_OPERATING_11,
VEHICLE_STATUS_OPERATING_12,
VEHICLE_STATUS_SPACE_RINGS_OPERATING,
VEHICLE_STATUS_TOP_SPIN_OPERATING,
VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING,
VEHICLE_STATUS_DOING_CIRCUS_SHOW,
VEHICLE_STATUS_OPERATING_13,
VEHICLE_STATUS_CROOKED_HOUSE_OPERATING,
VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT,
VEHICLE_STATUS_TRAVELLING_15,
VEHICLE_STATUS_TRAVELLING_CABLE_LIFT,
VEHICLE_STATUS_STOPPING,
VEHICLE_STATUS_WAITING_FOR_PASSENGERS_17,
VEHICLE_STATUS_WAITING_TO_START,
@ -265,22 +331,42 @@ enum {
VEHICLE_VISUAL_SUBMARINE
};
enum {
VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_AT_STATION = 1 << 0,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_1 = 1 << 1,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_2 = 1 << 2,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_3 = 1 << 3,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_ON_LIFT_HILL = 1 << 4,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_5 = 1 << 5,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_DERAILED = 1 << 6,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_COLLISION = 1 << 7,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_8 = 1 << 8,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_9 = 1 << 9,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_10 = 1 << 10,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_11 = 1 << 11,
VEHICLE_UPDATE_MOTION_TRACK_FLAG_12 = 1 << 12,
};
#define VEHICLE_SEAT_PAIR_FLAG 0x80
#define VEHICLE_SEAT_NUM_MASK 0x7F
void vehicle_update_all();
int sub_6BC2F3(rct_vehicle* vehicle);
void sub_6BB9FF(rct_vehicle* vehicle);
void vehicle_sounds_update();
void vehicle_get_g_forces(rct_vehicle *vehicle, int *verticalG, int *lateralG);
void vehicle_set_map_toolbar(rct_vehicle *vehicle);
int vehicle_is_used_in_pairs(rct_vehicle *vehicle);
rct_vehicle *vehicle_get_head(rct_vehicle *vehicle);
void sub_6DEF56(rct_vehicle *cableLift);
rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int direction, uint16 var_44, uint32 var_24, bool head);
bool sub_6DD365(rct_vehicle *vehicle);
int sub_6DAB4C(rct_vehicle *vehicle, int *outStation);
int vehicle_update_track_motion(rct_vehicle *vehicle, int *outStation);
rct_ride_type_vehicle *vehicle_get_vehicle_entry(rct_vehicle *vehicle);
int vehicle_get_total_num_peeps(rct_vehicle *vehicle);
void vehicle_invalidate_window(rct_vehicle *vehicle);
void vehicle_update_test_finish(rct_vehicle* vehicle);
void vehicle_test_reset(rct_vehicle* vehicle);
void vehicle_peep_easteregg_here_we_are(rct_vehicle* vehicle);
rct_vehicle *vehicle_get_head(rct_vehicle *vehicle);
rct_vehicle *vehicle_get_tail(rct_vehicle *vehicle);
const rct_vehicle_info *vehicle_get_move_info(int cd, int typeAndDirection, int offset);
/** Helper macro until rides are stored in this module. */
#define GET_VEHICLE(sprite_index) &(g_sprite_list[sprite_index].vehicle)

View File

@ -1059,7 +1059,7 @@ static void window_ride_draw_tab_vehicle(rct_drawpixelinfo *dpi, rct_window *w)
spriteIndex = 32;
if (w->page == WINDOW_RIDE_PAGE_VEHICLE)
spriteIndex += w->frame_no;
spriteIndex /= (rideVehicleEntry->var_12 & 0x800) ? 4 : 2;
spriteIndex /= (rideVehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_11) ? 4 : 2;
spriteIndex &= rideVehicleEntry->rotation_frame_mask;
spriteIndex *= rideVehicleEntry->var_16;
spriteIndex += rideVehicleEntry->base_image_id;
@ -2114,7 +2114,12 @@ static rct_string_id window_ride_get_status_vehicle(rct_window *w, void *argumen
vehicle = &(g_sprite_list[vehicleSpriteIndex].vehicle);
if (vehicle->status != VEHICLE_STATUS_CRASHING && vehicle->status != VEHICLE_STATUS_CRASHED) {
int trackType = vehicle->track_type >> 2;
if (trackType == 216 || trackType == 123 || trackType == 9 || trackType == 63 || trackType == 147 || trackType == 155) {
if (trackType == 216 ||
trackType == TRACK_ELEM_CABLE_LIFT_HILL ||
trackType == TRACK_ELEM_25_DEG_UP_TO_FLAT ||
trackType == TRACK_ELEM_60_DEG_UP_TO_FLAT ||
trackType == TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT ||
trackType == TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT) {
if ((RCT2_ADDRESS(0x01357644, uint32)[ride->type] & 0x40) && vehicle->velocity == 0) {
RCT2_GLOBAL((int)arguments + 0, uint16) = STR_STOPPED_BY_BLOCK_BRAKES;
return 1191;
@ -2647,8 +2652,8 @@ static void window_ride_vehicle_scrollpaint(rct_window *w, rct_drawpixelinfo *dp
// For each car in train
for (j = 0; j < ride->num_cars_per_train; j++) {
rct_ride_type_vehicle* rideVehicleEntry = &rideEntry->vehicles[trainLayout[j]];
x += rideVehicleEntry->var_04 / 17432;
y -= (rideVehicleEntry->var_04 / 2) / 17432;
x += rideVehicleEntry->spacing / 17432;
y -= (rideVehicleEntry->spacing / 2) / 17432;
// Get colour of vehicle
switch (ride->colour_scheme_type & 3) {
@ -2665,7 +2670,7 @@ static void window_ride_vehicle_scrollpaint(rct_window *w, rct_drawpixelinfo *dp
vehicleColour = ride_get_vehicle_colour(ride, vehicleColourIndex);
spriteIndex = 16;
if (rideVehicleEntry->var_12 & 0x800)
if (rideVehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_11)
spriteIndex /= 2;
spriteIndex &= rideVehicleEntry->rotation_frame_mask;
@ -2680,8 +2685,8 @@ static void window_ride_vehicle_scrollpaint(rct_window *w, rct_drawpixelinfo *dp
nextSpriteToDraw->tertiary_colour = vehicleColour.additional_2;
nextSpriteToDraw++;
x += rideVehicleEntry->var_04 / 17432;
y -= (rideVehicleEntry->var_04 / 2) / 17432;
x += rideVehicleEntry->spacing / 17432;
y -= (rideVehicleEntry->spacing / 2) / 17432;
}
if (ride->type == RIDE_TYPE_REVERSER_ROLLER_COASTER) {
@ -2931,11 +2936,11 @@ static void window_ride_operating_mousedown(int widgetIndex, rct_window *w, rct_
window_ride_mode_tweak_decrease(w);
break;
case WIDX_LIFT_HILL_SPEED_INCREASE:
parameter_check = gConfigCheat.fast_lift_hill ? 255 : RCT2_GLOBAL(0x0097D7CA + (ride->type * 4), uint8);
parameter_check = gConfigCheat.fast_lift_hill ? 255 : RideLiftData[ride->type].maximum_speed;
set_operating_setting(w->number, 8, min(ride->lift_hill_speed + 1, parameter_check));
break;
case WIDX_LIFT_HILL_SPEED_DECREASE:
parameter_check = gConfigCheat.fast_lift_hill ? 0 : RCT2_GLOBAL(0x0097D7C9 + (ride->type * 4), uint8);
parameter_check = gConfigCheat.fast_lift_hill ? 0 : RideLiftData[ride->type].minimum_speed;
set_operating_setting(w->number, 8, max(ride->lift_hill_speed - 1, parameter_check));
break;
case WIDX_MINIMUM_LENGTH_INCREASE:
@ -4138,9 +4143,9 @@ static void window_ride_colour_invalidate(rct_window *w)
for (int i = 0; i < ride->num_cars_per_train; i++) {
uint8 vehicleTypeIndex = trainLayout[i];
colourFlags |= rideEntry->vehicles[vehicleTypeIndex].var_14;
colourFlags |= rideEntry->vehicles[vehicleTypeIndex].flags_b;
colourFlags = ror32(colourFlags, 16);
colourFlags |= rideEntry->vehicles[vehicleTypeIndex].var_12;
colourFlags |= rideEntry->vehicles[vehicleTypeIndex].flags_a;
colourFlags = ror32(colourFlags, 16);
}
@ -4330,7 +4335,7 @@ static void window_ride_colour_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi
y += rideVehicleEntry->tab_height;
// Draw the coloured spinning vehicle
spriteIndex = rideVehicleEntry->var_12 & 0x800 ? w->frame_no / 4 : w->frame_no / 2;
spriteIndex = rideVehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_11 ? w->frame_no / 4 : w->frame_no / 2;
spriteIndex &= rideVehicleEntry->rotation_frame_mask;
spriteIndex *= rideVehicleEntry->var_16;
spriteIndex += rideVehicleEntry->base_image_id;

View File

@ -5061,7 +5061,7 @@ void game_command_set_sign_style(int* eax, int* ebx, int* ecx, int* edx, int* es
}
/**
* Gets the map element at x, y, z.
* Gets the track element at x, y, z.
* @param x x units, not tiles.
* @param y y units, not tiles.
* @param z Base height.
@ -5080,10 +5080,11 @@ rct_map_element *map_get_track_element_at(int x, int y, int z)
}
/**
* Gets the map element at x, y, z.
* Gets the track element at x, y, z that is the given track type.
* @param x x units, not tiles.
* @param y y units, not tiles.
* @param z Base height.
* @param trackType
*/
rct_map_element *map_get_track_element_at_of_type(int x, int y, int z, int trackType)
{
@ -5098,3 +5099,26 @@ rct_map_element *map_get_track_element_at_of_type(int x, int y, int z, int track
return NULL;
}
/**
* Gets the track element at x, y, z that is the given track type and sequence.
* @param x x units, not tiles.
* @param y y units, not tiles.
* @param z Base height.
* @param trackType
* @param sequence
*/
rct_map_element *map_get_track_element_at_of_type_seq(int x, int y, int z, int trackType, int sequence)
{
rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5);
do {
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) continue;
if (mapElement->base_height != z) continue;
if (mapElement->properties.track.type != trackType) continue;
if ((mapElement->properties.track.sequence & 0x0F) != sequence) continue;
return mapElement;
} while (!map_element_is_last_for_tile(mapElement++));
return NULL;
}

View File

@ -141,6 +141,7 @@ enum {
enum {
MAP_ELEMENT_FLAG_GHOST = (1 << 4),
MAP_ELEMENT_FLAG_BROKEN = (1 << 5),
MAP_ELEMENT_FLAG_BLOCK_BREAK_CLOSED = (1 << 5),
MAP_ELEMENT_FLAG_LAST_TILE = (1 << 7)
};
@ -395,5 +396,6 @@ bool map_large_scenery_get_origin(
rct_map_element *map_get_track_element_at(int x, int y, int z);
rct_map_element *map_get_track_element_at_of_type(int x, int y, int z, int trackType);
rct_map_element *map_get_track_element_at_of_type_seq(int x, int y, int z, int trackType, int sequence);
#endif

View File

@ -16,14 +16,14 @@ void crashed_vehicle_particle_create(rct_vehicle_colour colours, int x, int y, i
sprite->sprite_height_negative = 8;
sprite->sprite_height_positive = 8;
sprite->sprite_identifier = SPRITE_IDENTIFIER_MISC;
sprite_move(x, y, z + 4, (rct_sprite*)sprite);
sprite_move(x, y, z, (rct_sprite*)sprite);
sprite->misc_identifier = SPRITE_MISC_CRASHED_VEHICLE_PARTICLE;
sprite->var_26 = (util_rand() & 0xFF) * 12;
sprite->var_24 = (util_rand() & 0x7F) + 140;
sprite->var_2E = ((util_rand() & 0xFF) * 5) >> 8;
sprite->acceleration_x = (util_rand() & 0xFFFF) * 4;
sprite->acceleration_y = (util_rand() & 0xFFFF) * 4;
sprite->acceleration_x = ((sint16)(util_rand() & 0xFFFF)) * 4;
sprite->acceleration_y = ((sint16)(util_rand() & 0xFFFF)) * 4;
sprite->acceleration_z = (util_rand() & 0xFFFF) * 4 + 0x10000;
sprite->velocity_x = 0;
sprite->velocity_y = 0;

View File

@ -275,18 +275,23 @@ void move_sprite_to_list(rct_sprite *sprite, uint8 cl)
*
* rct2: 0x00673200
*/
static void sprite_misc_0_update(rct_sprite *sprite)
static void sprite_steam_particle_update(rct_steam_particle *steam)
{
invalidate_sprite_2(sprite);
invalidate_sprite_2((rct_sprite*)steam);
int original_var24 = sprite->unknown.var_24;
sprite->unknown.var_24 += 0x5555;
if (sprite->unknown.var_24 < 0x5555) {
sprite_move(sprite->unknown.x, sprite->unknown.y, sprite->unknown.z + 1, sprite);
int original_var24 = steam->var_24;
steam->var_24 += 0x5555;
if (steam->var_24 < 0x5555) {
sprite_move(
steam->x,
steam->y,
steam->z + 1,
(rct_sprite*)steam
);
}
sprite->unknown.var_26 += 64;
if (sprite->unknown.var_26 >= (56 * 64)) {
sprite_remove(sprite);
steam->var_26 += 64;
if (steam->var_26 >= (56 * 64)) {
sprite_remove((rct_sprite*)steam);
}
}
@ -359,8 +364,8 @@ static void sprite_misc_5_update(rct_sprite *sprite)
void sprite_misc_update(rct_sprite *sprite)
{
switch (sprite->unknown.misc_identifier) {
case SPRITE_MISC_0:
sprite_misc_0_update(sprite);
case SPRITE_MISC_STEAM_PARTICLE:
sprite_steam_particle_update((rct_steam_particle*)sprite);
break;
case SPRITE_MISC_MONEY_EFFECT:
money_effect_update(&sprite->money_effect);

View File

@ -282,6 +282,35 @@ typedef struct {
uint16 var_26;
} rct_crash_splash;
typedef struct {
uint8 sprite_identifier; // 0x00
uint8 misc_identifier; // 0x01
uint16 next_in_quadrant; // 0x02
uint16 next; // 0x04
uint16 previous; // 0x06
uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_...
// Height from center of sprite to bottom
uint8 sprite_height_negative; // 0x09
uint16 sprite_index; // 0x0A
uint16 var_0C;
sint16 x; // 0x0E
sint16 y; // 0x10
sint16 z; // 0x12
// Width from center of sprite to edge
uint8 sprite_width; // 0x14
// Height from center of sprite to top
uint8 sprite_height_positive; // 0x15
sint16 sprite_left; // 0x16
sint16 sprite_top; // 0x18
sint16 sprite_right; // 0x1A
sint16 sprite_bottom; // 0x1C
uint8 sprite_direction; // 0x1E
uint8 pad_1F[3]; // 0x1F
uint16 name_string_idx; // 0x22
uint16 var_24;
uint16 var_26;
} rct_steam_particle;
/**
* Sprite structure.
* size: 0x0100
@ -298,6 +327,7 @@ typedef union {
rct_money_effect money_effect;
rct_crashed_vehicle_particle crashed_vehicle_particle;
rct_crash_splash crash_splash;
rct_steam_particle steam_particle;
} rct_sprite;
typedef struct {
@ -318,7 +348,7 @@ typedef struct {
} rct_sprite_entry;
enum {
SPRITE_MISC_0,
SPRITE_MISC_STEAM_PARTICLE,
SPRITE_MISC_MONEY_EFFECT,
SPRITE_MISC_CRASHED_VEHICLE_PARTICLE,
SPRITE_MISC_3, // (related to vehicle crash, probably crash particles)