From 4ac42ff1b27d3a7dbcd771317c4ac3d2dff2ce3e Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sun, 25 Oct 2015 16:00:21 +0000 Subject: [PATCH] add vehicle struct, enum labels and helper functions from implement-ride-create-vehicles branch. --- src/interface/viewport.c | 34 +++---- src/object.c | 58 ++++++----- src/peep/peep.c | 12 +-- src/ride/ride.c | 203 +++++++++++++++++++++++++++++++++------ src/ride/ride.h | 46 --------- src/ride/ride_data.c | 31 +++--- src/ride/station.c | 2 +- src/ride/track.c | 5 + src/ride/track.h | 2 + src/ride/vehicle.c | 54 +++++++++-- src/ride/vehicle.h | 121 ++++++++++++++++++++--- src/windows/ride.c | 12 +-- src/world/map.c | 21 +++- src/world/map.h | 2 + 14 files changed, 429 insertions(+), 174 deletions(-) diff --git a/src/interface/viewport.c b/src/interface/viewport.c index 3678c97d7c..e25d1aa564 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -907,23 +907,23 @@ void viewport_vehicle_paint_setup(rct_vehicle *vehicle, int imageDirection) uint32 rct2VehiclePtrFormat = ((uint32)vehicleEntry) - offsetof(rct_ride_type, vehicles); RCT2_GLOBAL(0x00F64DFC, uint32) = rct2VehiclePtrFormat; - switch (vehicleEntry->var_5D) { - case 0: RCT2_CALLPROC_X(0x006D45F8, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 2: RCT2_CALLPROC_X(0x006D5FAB, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 3: RCT2_CALLPROC_X(0x006D6258, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 4: RCT2_CALLPROC_X(0x006D5889, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 5: RCT2_CALLPROC_X(0x006D42F0, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 6: RCT2_CALLPROC_X(0x006D43C6, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 7: RCT2_CALLPROC_X(0x006D4453, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 8: RCT2_CALLPROC_X(0x006D4295, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 9: RCT2_CALLPROC_X(0x006D5DA9, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 10: RCT2_CALLPROC_X(0x006D5600, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 11: RCT2_CALLPROC_X(0x006D5696, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 12: RCT2_CALLPROC_X(0x006D57EE, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 13: RCT2_CALLPROC_X(0x006D5783, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 14: RCT2_CALLPROC_X(0x006D5701, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 15: RCT2_CALLPROC_X(0x006D5B48, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; - case 16: RCT2_CALLPROC_X(0x006D44D5, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + switch (vehicleEntry->car_visual) { + case VEHICLE_VISUAL_DEFAULT: RCT2_CALLPROC_X(0x006D45F8, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_LAUNCHED_FREEFALL: RCT2_CALLPROC_X(0x006D5FAB, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_OBSERVATION_TOWER: RCT2_CALLPROC_X(0x006D6258, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_RIVER_RAPIDS: RCT2_CALLPROC_X(0x006D5889, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_MINI_GOLF_PLAYER: RCT2_CALLPROC_X(0x006D42F0, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_MINI_GOLF_BALL: RCT2_CALLPROC_X(0x006D43C6, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_REVERSER: RCT2_CALLPROC_X(0x006D4453, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_SPLASH_BOATS_OR_WATER_COASTER: RCT2_CALLPROC_X(0x006D4295, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_ROTO_DROP: RCT2_CALLPROC_X(0x006D5DA9, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case 10: RCT2_CALLPROC_X(0x006D5600, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case 11: RCT2_CALLPROC_X(0x006D5696, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case 12: RCT2_CALLPROC_X(0x006D57EE, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case 13: RCT2_CALLPROC_X(0x006D5783, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case 14: RCT2_CALLPROC_X(0x006D5701, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_VIRGINIA_REEL: RCT2_CALLPROC_X(0x006D5B48, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; + case VEHICLE_VISUAL_SUBMARINE: RCT2_CALLPROC_X(0x006D44D5, x, imageDirection, y, z, (int)vehicle, rct2VehiclePtrFormat, 0); break; } } diff --git a/src/object.c b/src/object.c index 85d69ccab6..96badbb090 100644 --- a/src/object.c +++ b/src/object.c @@ -480,20 +480,18 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp for (int i = 0; i < 4; ++i){ rct_ride_type_vehicle* rideVehicleEntry = &ride_type->vehicles[i]; - if (rideVehicleEntry->var_0C & 1){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT) { int al = 1; - if (rideVehicleEntry->var_14 & 2) - { + if (rideVehicleEntry->var_14 & 2) { al = 13; - if ((rideVehicleEntry->var_14 & 0x820) != 0x820) - { + if ((rideVehicleEntry->var_14 & 0x820) != 0x820) { al = 7; - if (!(rideVehicleEntry->var_14 & 0x20)) - { - if (!(rideVehicleEntry->var_14 & 0x800)) - { + if (!(rideVehicleEntry->var_14 & 0x20)) { + if (!(rideVehicleEntry->var_14 & 0x800)) { al = 5; - if (rideVehicleEntry->var_14 & 0x200) al = 3; + if (rideVehicleEntry->var_14 & 0x200) { + al = 3; + } } } } @@ -514,7 +512,7 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp } } } - if (rideVehicleEntry->var_12 & 0x1000) al = rideVehicleEntry->var_60; + if (rideVehicleEntry->var_12 & 0x1000) al = rideVehicleEntry->special_frames; rideVehicleEntry->var_02 = al; // 0x6DE946 @@ -522,16 +520,16 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp rideVehicleEntry->base_image_id = cur_vehicle_images_offset; int image_index = rideVehicleEntry->base_image_id; - if (rideVehicleEntry->var_5D != 4){ + if (rideVehicleEntry->car_visual != VEHICLE_VISUAL_RIVER_RAPIDS) { int b = rideVehicleEntry->var_16 * 32; if (rideVehicleEntry->var_12 & 0x800) b /= 2; - if (rideVehicleEntry->var_0C & 0x8000) b /= 8; + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_15) b /= 8; image_index += b; // Incline 25 - if (rideVehicleEntry->var_0C & 0x2){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPES) { rideVehicleEntry->var_20 = image_index; b = rideVehicleEntry->var_16 * 72; if (rideVehicleEntry->var_12 & 0x4000) @@ -541,81 +539,81 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp } // Incline 60 - if (rideVehicleEntry->var_0C & 0x4){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_STEEP_SLOPES) { rideVehicleEntry->var_24 = image_index; b = rideVehicleEntry->var_16 * 80; image_index += b; } // Verticle - if (rideVehicleEntry->var_0C & 0x8){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES) { rideVehicleEntry->var_28 = image_index; b = rideVehicleEntry->var_16 * 116; image_index += b; } // Unknown - if (rideVehicleEntry->var_0C & 0x10){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES) { rideVehicleEntry->var_2C = image_index; b = rideVehicleEntry->var_16 * 24; image_index += b; } // Bank - if (rideVehicleEntry->var_0C & 0x20){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_BANKED) { rideVehicleEntry->var_30 = image_index; b = rideVehicleEntry->var_16 * 80; image_index += b; } - if (rideVehicleEntry->var_0C & 0x40){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_INLINE_TWISTS) { rideVehicleEntry->var_34 = image_index; b = rideVehicleEntry->var_16 * 40; image_index += b; } // Track half? Up/Down - if (rideVehicleEntry->var_0C & 0x80){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS) { rideVehicleEntry->var_38 = image_index; b = rideVehicleEntry->var_16 * 128; image_index += b; } // Unknown - if (rideVehicleEntry->var_0C & 0x100){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS) { rideVehicleEntry->var_3C = image_index; b = rideVehicleEntry->var_16 * 16; image_index += b; } // Unknown - if (rideVehicleEntry->var_0C & 0x200){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS) { rideVehicleEntry->var_40 = image_index; b = rideVehicleEntry->var_16 * 16; image_index += b; } - if (rideVehicleEntry->var_0C & 0x400){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS) { rideVehicleEntry->var_44 = image_index; b = rideVehicleEntry->var_16 * 128; image_index += b; } - if (rideVehicleEntry->var_0C & 0x800){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS) { rideVehicleEntry->var_48 = image_index; b = rideVehicleEntry->var_16 * 16; image_index += b; } - if (rideVehicleEntry->var_0C & 0x1000){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_CORKSCREWS) { rideVehicleEntry->var_4C = image_index; b = rideVehicleEntry->var_16 * 80; image_index += b; } // Unknown - if (rideVehicleEntry->var_0C & 0x2000){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION) { rideVehicleEntry->var_1C = image_index; b = rideVehicleEntry->var_16 * 12; image_index += b; } - if (rideVehicleEntry->var_0C & 0x4000){ + if (rideVehicleEntry->sprite_flags & VEHICLE_SPRITE_FLAG_14) { // Same offset as above??? rideVehicleEntry->var_4C = image_index; b = rideVehicleEntry->var_16 * 32; @@ -715,9 +713,9 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp rideVehicleEntry->var_16 = 0; if (!(rideVehicleEntry->var_12 & 0x400)){ - rideVehicleEntry->var_0E = 0; - rideVehicleEntry->var_0F = 0; - rideVehicleEntry->var_10 = 0; + rideVehicleEntry->sprite_width = 0; + rideVehicleEntry->sprite_height_negative = 0; + rideVehicleEntry->sprite_height_positive = 0; } rideVehicleEntry->var_02 = 0; rideVehicleEntry->var_03 = 0; diff --git a/src/peep/peep.c b/src/peep/peep.c index c1ca5f5c1d..6591668e3a 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -2245,7 +2245,7 @@ static void peep_update_ride_sub_state_5(rct_peep* peep){ vehicle->num_peeps++; ride->var_120++; - vehicle->var_46 += seated_peep->var_41; + vehicle->friction += seated_peep->var_41; invalidate_sprite_2((rct_sprite*)seated_peep); sprite_move(0x8000, 0, 0, (rct_sprite*)seated_peep); @@ -2260,7 +2260,7 @@ static void peep_update_ride_sub_state_5(rct_peep* peep){ vehicle->num_peeps++; ride->var_120++; - vehicle->var_46 += peep->var_41; + vehicle->friction += peep->var_41; invalidate_sprite_2((rct_sprite*)vehicle); invalidate_sprite_2((rct_sprite*)peep); @@ -2300,7 +2300,7 @@ void peep_update_ride_sub_state_7(rct_peep* peep){ peep->action_sprite_image_offset = 0; vehicle->num_peeps--; - vehicle->var_46 -= peep->var_41; + vehicle->friction -= peep->var_41; invalidate_sprite_2((rct_sprite*)vehicle); peep->current_ride_station = ride_station; @@ -2321,16 +2321,16 @@ void peep_update_ride_sub_state_7(rct_peep* peep){ if (!(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_16)){ - for (; vehicle->var_01 != 0; vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_train)){ + for (; vehicle->is_child; vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride)){ uint16 eax = vehicle->var_36 / 4; if (eax == 0 || eax > 3) continue; - rct_map_element* inner_map = map_get_first_element_at(vehicle->var_38 / 32, vehicle->var_3A / 32); + rct_map_element* inner_map = map_get_first_element_at(vehicle->track_x / 32, vehicle->track_y / 32); for (;; inner_map++){ if (map_element_get_type(inner_map) != MAP_ELEMENT_TYPE_TRACK) continue; - if (inner_map->base_height == vehicle->var_3C / 8) + if (inner_map->base_height == vehicle->track_z / 8) break; } diff --git a/src/ride/ride.c b/src/ride/ride.c index 78e657938c..e9af8a942c 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -901,7 +901,7 @@ static void ride_remove_cable_lift(rct_ride *ride) ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CABLE_LIFT; spriteIndex = ride->cable_lift; do { - vehicle = &(g_sprite_list[spriteIndex].vehicle); + vehicle = GET_VEHICLE(spriteIndex); invalidate_sprite_2((rct_sprite*)vehicle); sprite_remove((rct_sprite*)vehicle); spriteIndex = vehicle->next_vehicle_on_train; @@ -926,7 +926,7 @@ static void ride_remove_vehicles(rct_ride *ride) for (i = 0; i < 32; i++) { spriteIndex = ride->vehicles[i]; while (spriteIndex != SPRITE_INDEX_NULL) { - vehicle = &(g_sprite_list[spriteIndex].vehicle); + vehicle = GET_VEHICLE(spriteIndex); invalidate_sprite_2((rct_sprite*)vehicle); sprite_remove((rct_sprite*)vehicle); spriteIndex = vehicle->next_vehicle_on_train; @@ -1448,7 +1448,7 @@ void ride_construction_set_default_next_piece() // Set track slope and lift hill _currentTrackSlopeEnd = slope; _previousTrackSlopeEnd = slope; - _currentTrackLiftHill = (mapElement->type & 0x80) != 0; + _currentTrackLiftHill = track_element_is_lift_hill(mapElement); break; } } @@ -1874,7 +1874,7 @@ static void ride_update(int rideIndex) if (ride->status == RIDE_STATUS_TESTING && gConfigGeneral.no_test_crashes) { for (int i = 0; i < ride->num_vehicles; i++) { - rct_vehicle *vehicle = &(g_sprite_list[ride->vehicles[i]].vehicle); + rct_vehicle *vehicle = GET_VEHICLE(ride->vehicles[i]); if (vehicle->status == VEHICLE_STATUS_CRASHED || vehicle->status == VEHICLE_STATUS_CRASHING) { ride_set_status(rideIndex, RIDE_STATUS_CLOSED); @@ -2241,14 +2241,14 @@ void ride_prepare_breakdown(int rideIndex, int breakdownReason) ride->broken_car = scenario_rand() % ride->num_cars_per_train; // Set flag on broken car - vehicle = &(g_sprite_list[ride->vehicles[ride->broken_vehicle]].vehicle); + vehicle = GET_VEHICLE(ride->vehicles[ride->broken_vehicle]); for (i = ride->broken_car; i > 0; i--) { if (vehicle->next_vehicle_on_train == (uint16)0xFFFFFFFF) { vehicle = NULL; break; } else { - vehicle = &(g_sprite_list[vehicle->next_vehicle_on_train].vehicle); + vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train); } } if (vehicle != NULL) @@ -2260,7 +2260,7 @@ void ride_prepare_breakdown(int rideIndex, int breakdownReason) ride->broken_car = 0; // Set flag on broken train, first car - vehicle = &(g_sprite_list[ride->vehicles[ride->broken_vehicle]].vehicle); + vehicle = GET_VEHICLE(ride->vehicles[ride->broken_vehicle]); vehicle->var_48 |= 0x200; break; case BREAKDOWN_BRAKES_FAILURE: @@ -2587,7 +2587,7 @@ static void ride_music_update(int rideIndex) } if (ride->type == RIDE_TYPE_CIRCUS_SHOW) { - vehicle = &(g_sprite_list[ride->vehicles[0]].vehicle); + vehicle = GET_VEHICLE(ride->vehicles[0]); if (vehicle->status != VEHICLE_STATUS_DOING_CIRCUS_SHOW) { ride->music_tune_id = 255; return; @@ -2678,7 +2678,7 @@ void ride_measurement_update(rct_ride_measurement *measurement) if (spriteIndex == SPRITE_INDEX_NULL) return; - vehicle = &(g_sprite_list[spriteIndex].vehicle); + vehicle = GET_VEHICLE(spriteIndex); if (measurement->flags & RIDE_MEASUREMENT_FLAG_UNLOADING) { if (vehicle->status != VEHICLE_STATUS_DEPARTING && vehicle->status != VEHICLE_STATUS_STOPPING) @@ -2766,7 +2766,7 @@ void ride_measurements_update() if (spriteIndex == SPRITE_INDEX_NULL) continue; - vehicle = &(g_sprite_list[spriteIndex].vehicle); + vehicle = GET_VEHICLE(spriteIndex); if (vehicle->status == VEHICLE_STATUS_DEPARTING || vehicle->status == VEHICLE_STATUS_STOPPING) { measurement->vehicle_index = j; measurement->current_station = vehicle->current_station; @@ -4156,13 +4156,152 @@ static int sub_69ED9E() return max(0, miscSpriteCount + unkCount - 300); } +void vehicle_unset_var_48_b1(rct_vehicle *head) +{ + uint16 spriteIndex; + rct_vehicle *vehicle = head; + while (true) { + vehicle->var_48 &= ~(1 << 1); + spriteIndex = vehicle->next_vehicle_on_train; + if (spriteIndex == SPRITE_INDEX_NULL) { + break; + } + vehicle = GET_VEHICLE(spriteIndex); + } +} + +/** + * + * rct2: 0x006DDE9E + */ +void ride_create_vehicles_find_first_block(rct_ride *ride, rct_xy_element *outXYElement) +{ + rct_vehicle *vehicle = GET_VEHICLE(ride->vehicles[0]); + int firstX = vehicle->track_x; + int firstY = vehicle->track_y; + int firstZ = vehicle->track_z; + rct_map_element *firstElement = map_get_track_element_at(firstX, firstY, firstZ / 8); + + assert(firstElement != NULL); + + int x = firstX; + int y = firstY; + int z = firstZ; + rct_map_element *trackElement = firstElement; + track_begin_end trackBeginEnd; + while (track_block_get_previous(x, y, trackElement, &trackBeginEnd)) { + x = trackBeginEnd.begin_x; + y = trackBeginEnd.begin_y; + trackElement = trackBeginEnd.begin_element; + if (x == firstX && y == firstY && trackElement == firstElement) { + break; + } + + int trackType = trackElement->properties.track.type; + switch (trackType) { + case TRACK_ELEM_25_DEG_UP_TO_FLAT: + case TRACK_ELEM_60_DEG_UP_TO_FLAT: + if (track_element_is_lift_hill(trackElement)) { + outXYElement->x = x; + outXYElement->y = y; + outXYElement->element = trackElement; + return; + } + break; + 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)) { + 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.sequence & 0x0F) != 0) continue; + if (mapElement->properties.track.type != trackType) continue; + break; + } while (!map_element_is_last_for_tile(mapElement)); + + outXYElement->x = x; + outXYElement->y = y; + outXYElement->element = mapElement; + return; + } + break; + case TRACK_ELEM_END_STATION: + case TRACK_ELEM_CABLE_LIFT_HILL: + case 216: + outXYElement->x = x; + outXYElement->y = y; + outXYElement->element = trackElement; + return; + } + } + + outXYElement->x = firstX; + outXYElement->y = firstY; + outXYElement->element = firstElement; +} + +/** + * + * rct2: 0x006DDF9C + */ +void loc_6DDF9C(rct_ride *ride, rct_map_element *mapElement) +{ + registers regs; + rct_vehicle *train, *car; + + for (int i = 0; i < ride->num_vehicles; i++) { + train = GET_VEHICLE(ride->vehicles[i]); + if (i == 0) { + sub_6DAB4C(train, NULL); + vehicle_unset_var_48_b1(train); + continue; + } + + do { + mapElement->flags |= (1 << 5); + car = train; + while (true) { + car->velocity = 0; + car->var_2C = 0; + car->var_4A = 0; + car->var_24 += 13962; + + uint16 spriteIndex = car->next_vehicle_on_train; + if (spriteIndex == SPRITE_INDEX_NULL) { + break; + } + car = GET_VEHICLE(spriteIndex); + } + } while (sub_6DAB4C(train, NULL) & 0x400); + + mapElement->flags |= (1 << 5); + car = train; + while (true) { + car->var_48 &= ~(1 << 1); + car->status = VEHICLE_STATUS_TRAVELLING; + regs.ax = car->var_36 >> 2; + if (regs.al == 1) { + car->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION; + } + + uint16 spriteIndex = car->next_vehicle_on_train; + if (spriteIndex == SPRITE_INDEX_NULL) { + break; + } + car = GET_VEHICLE(spriteIndex); + } + } +} + /** * * rct2: 0x006DD84C */ -int ride_create_vehicles(rct_ride *ride, int rideIndex, rct_xy_element *element, int isApplying) +bool ride_create_vehicles(rct_ride *ride, int rideIndex, rct_xy_element *element, int isApplying) { - return RCT2_CALLPROC_X(0x006DD84C, element->x, isApplying, element->y, rideIndex, (int)ride, (int)element->element, 0) & 0x100; + bool b = !(RCT2_CALLPROC_X(0x006DD84C, element->x, isApplying, element->y, rideIndex, (int)ride, (int)element->element, 0) & 0x100); + return b; } /** @@ -4325,13 +4464,13 @@ bool ride_create_cable_lift(int rideIndex, bool isApplying) head = current; } else { tail->next_vehicle_on_train = current->sprite_index; - tail->next_or_first_vehicle_on_train = current->sprite_index; - current->prev_vehicle_on_train = tail->sprite_index; + tail->next_vehicle_on_ride = current->sprite_index; + current->prev_vehicle_on_ride = tail->sprite_index; } tail = current; } - head->prev_vehicle_on_train = tail->sprite_index; - tail->next_or_first_vehicle_on_train = head->sprite_index; + head->prev_vehicle_on_ride = tail->sprite_index; + tail->next_vehicle_on_ride = head->sprite_index; ride->lifecycle_flags |= RIDE_LIFECYCLE_CABLE_LIFT; sub_6DEF56(head); @@ -4547,9 +4686,10 @@ int ride_is_valid_for_test(int rideIndex, int goingToBeOpen, int isApplying) if ( !ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_13) && !(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) - ) { - if (ride_create_vehicles(ride, rideIndex, &trackElement, isApplying)) + ) { + if (!ride_create_vehicles(ride, rideIndex, &trackElement, isApplying)) { return 0; + } } if ( @@ -4671,8 +4811,9 @@ int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying) !ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_13) && !(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK) ) { - if (ride_create_vehicles(ride, rideIndex, &trackElement, isApplying)) + if (!ride_create_vehicles(ride, rideIndex, &trackElement, isApplying)) { return 0; + } } if ( @@ -5890,9 +6031,9 @@ void set_vehicle_type_image_max_sizes(rct_ride_type_vehicle* vehicle_type, int n bl += 16; } - vehicle_type->var_0E = al; - vehicle_type->var_0F = bl; - vehicle_type->var_10 = bh; + vehicle_type->sprite_width = al; + vehicle_type->sprite_height_negative = bl; + vehicle_type->sprite_height_positive = bh; } /** @@ -6192,7 +6333,7 @@ void invalidate_test_results(int rideIndex) for (int i = 0; i < ride->num_vehicles; i++) { uint16 spriteIndex = ride->vehicles[i]; if (spriteIndex != SPRITE_INDEX_NULL) { - rct_vehicle *vehicle = &(g_sprite_list[spriteIndex].vehicle); + rct_vehicle *vehicle = GET_VEHICLE(spriteIndex); vehicle->var_48 &= ~(1 << 5); } } @@ -6220,7 +6361,7 @@ void ride_fix_breakdown(int rideIndex, int reliabilityIncreaseFactor) for (int i = 0; i < ride->num_vehicles; i++) { spriteIndex = ride->vehicles[i]; while (spriteIndex != SPRITE_INDEX_NULL) { - vehicle = &(g_sprite_list[spriteIndex].vehicle); + vehicle = GET_VEHICLE(spriteIndex); vehicle->var_48 &= ~(1 << 7); vehicle->var_48 &= ~(1 << 8); vehicle->var_48 &= ~(1 << 9); @@ -6254,7 +6395,7 @@ static void ride_update_vehicle_colours(int rideIndex) int carIndex = 0; spriteIndex = ride->vehicles[i]; while (spriteIndex != SPRITE_INDEX_NULL) { - vehicle = &(g_sprite_list[spriteIndex].vehicle); + vehicle = GET_VEHICLE(spriteIndex); switch (ride->colour_scheme_type & 3) { case RIDE_COLOUR_SCHEME_ALL_SAME: colours = ride->vehicle_colours[0]; @@ -6404,7 +6545,7 @@ void ride_update_max_vehicles(int rideIndex) for (int i = 0; i < numCars; i++) { vehicleEntry = &rideEntry->vehicles[trainLayout[i]]; trainLength += vehicleEntry->var_04; - totalFriction += vehicleEntry->var_08; + totalFriction += vehicleEntry->car_friction; } if (trainLength <= stationLength && totalFriction <= maxFriction) { @@ -6456,7 +6597,7 @@ void ride_update_max_vehicles(int rideIndex) } else { ride_entry_get_train_layout(ride->subtype, newCarsPerTrain, trainLayout); vehicleEntry = &rideEntry->vehicles[trainLayout[0]]; - int unk = vehicleEntry->var_5C; + int speed = vehicleEntry->powered_max_speed; int totalSpacing = 0; for (int i = 0; i < newCarsPerTrain; i++) { @@ -6466,9 +6607,9 @@ void ride_update_max_vehicles(int rideIndex) totalSpacing >>= 13; int trackLength = ride_get_track_length(ride) / 4; - if (unk > 10) trackLength = (trackLength * 3) / 4; - if (unk > 25) trackLength = (trackLength * 3) / 4; - if (unk > 40) trackLength = (trackLength * 3) / 4; + if (speed > 10) trackLength = (trackLength * 3) / 4; + if (speed > 25) trackLength = (trackLength * 3) / 4; + if (speed > 40) trackLength = (trackLength * 3) / 4; maxNumTrains = 0; int length = 0; @@ -6976,7 +7117,7 @@ void ride_crash(int rideIndex, int vehicleIndex) vehicleIndex &= 0xFF; ride = GET_RIDE(rideIndex); - vehicle = &(g_sprite_list[ride->vehicles[vehicleIndex]]).vehicle; + vehicle = GET_VEHICLE(ride->vehicles[vehicleIndex]); w = window_ride_open_vehicle(vehicle); if (w->viewport != NULL) { diff --git a/src/ride/ride.h b/src/ride/ride.h index a8d269a2a3..e1320f4da8 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -70,52 +70,6 @@ typedef struct { vehicle_colour list[256]; } vehicle_colour_preset_list; -/** - * Ride type vehicle structure. - * size: 0x65 - */ -typedef struct{ - uint16 var_00; // 0x00 , 0x1A - uint8 var_02; // 0x02 , 0x1C - uint8 var_03; // 0x03 , 0x1D - uint32 var_04; // 0x04 , 0x1E - uint16 var_08; // 0x08 , 0x22 - sint8 var_0A; // 0x0A , 0x24 - uint8 pad_0B; - uint16 var_0C; // 0x0C , 0x26 - uint8 var_0E; // 0x0E , 0x28 - uint8 var_0F; // 0x0F , 0x29 - uint8 var_10; // 0x10 , 0x2A - uint8 var_11; // 0x11 , 0x2B - uint16 var_12; // 0x12 , 0x2C - uint16 var_14; // 0x14 , 0x2E - uint16 var_16; // 0x16 , 0x30 - uint32 base_image_id; // 0x18 , 0x32 - uint32 var_1C; // 0x1C , 0x36 - uint32 var_20; // 0x20 , 0x3A - uint32 var_24; // 0x24 , 0x3E - uint32 var_28; // 0x28 , 0x42 - uint32 var_2C; // 0x2C , 0x46 - uint32 var_30; // 0x30 , 0x4A - uint32 var_34; // 0x34 , 0x4E - uint32 var_38; // 0x38 , 0x52 - uint32 var_3C; // 0x3C , 0x56 - uint32 var_40; // 0x40 , 0x5A - uint32 var_44; // 0x44 , 0x5E - uint32 var_48; // 0x48 , 0x62 - uint32 var_4C; // 0x4C , 0x66 - uint32 no_vehicle_images; // 0x50 , 0x6A - uint8 no_seating_rows; // 0x54 , 0x6E - uint8 pad_55[0x5]; - uint8 var_5A; // 0x5A , 0x74 - uint8 pad_5B; // 0x5B , 0x75 - uint8 var_5C; // 0x5C , 0x76 - uint8 var_5D; // 0x5D , 0x77 - uint8 pad_5E[0x2]; - uint8 var_60; // 0x60 , 0x7A - sint8* peep_loading_positions; // 0x61 , 0x7B -} rct_ride_type_vehicle; - /** * Ride type structure. * size: unknown diff --git a/src/ride/ride_data.c b/src/ride/ride_data.c index 5cd410bfae..c3679300e7 100644 --- a/src/ride/ride_data.c +++ b/src/ride/ride_data.c @@ -1253,17 +1253,17 @@ const uint32 ShopItemImage[SHOP_ITEM_COUNT] = { }; const rct_ride_type_vehicle CableLiftVehicle = { - .var_00 = 0x1F, + .rotation_frame_mask = 31, .var_02 = 0, .var_03 = 0, .var_04 = 0, - .var_08 = 0, - .var_0A = 0, - .pad_0B = 0, - .var_0C = 0x7, - .var_0E = 0, - .var_0F = 0, - .var_10 = 0, + .car_friction = 0, + .tab_height = 0, + .num_seats = 0, + .sprite_flags = 0x7, + .sprite_width = 0, + .sprite_height_negative = 0, + .sprite_height_positive = 0, .var_11 = 0, .var_12 = 0, .var_14 = 0, @@ -1284,12 +1284,15 @@ const rct_ride_type_vehicle CableLiftVehicle = { .var_4C = 0, .no_vehicle_images = 0, .no_seating_rows = 0, - .pad_55 = { 0,0xFF,0,0,0 }, + .spinning_inertia = 0, + .spinning_friction = 255, + .pad_57 = { 0,0,0 }, .var_5A = 0, - .pad_5B = 0, - .var_5C = 0, - .var_5D = 0, - .pad_5E = { 1,0xE }, - .var_60 = 0, + .powered_acceleration = 0, + .powered_max_speed = 0, + .car_visual = 0, + .pad_5E = { 1 }, + .draw_order = 14, + .special_frames = 0, .peep_loading_positions = NULL }; \ No newline at end of file diff --git a/src/ride/station.c b/src/ride/station.c index fcdda75918..5870e66050 100644 --- a/src/ride/station.c +++ b/src/ride/station.c @@ -252,7 +252,7 @@ static void ride_race_init_vehicle_speeds(rct_ride *ride) rideEntry = GET_RIDE_ENTRY(vehicle->ride_subtype); - vehicle->speed = (scenario_rand() & 16) - 8 + rideEntry->vehicles[vehicle->vehicle_type].var_5C; + vehicle->speed = (scenario_rand() & 16) - 8 + rideEntry->vehicles[vehicle->vehicle_type].powered_max_speed; if (vehicle->num_peeps != 0) { rct_peep *peep = &g_sprite_list[vehicle->peep[0]].peep; diff --git a/src/ride/track.c b/src/ride/track.c index 20ff56b066..06fe6d5179 100644 --- a/src/ride/track.c +++ b/src/ride/track.c @@ -4819,3 +4819,8 @@ void track_get_front(rct_xy_element *input, rct_xy_element *output) } while (result); *output = lastTrack; } + +bool track_element_is_lift_hill(rct_map_element *trackElement) +{ + return trackElement->type & 0x80; +} diff --git a/src/ride/track.h b/src/ride/track.h index 07d4a6343d..64d9ed5596 100644 --- a/src/ride/track.h +++ b/src/ride/track.h @@ -540,4 +540,6 @@ bool track_circuit_iterator_next(track_circuit_iterator *it); 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); + #endif diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index 285704aa1c..ca188b2251 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -138,7 +138,7 @@ int sub_6BC2F3(rct_vehicle* vehicle) int result = 0; rct_vehicle* vehicle_temp = vehicle; do { - result += vehicle_temp->var_46; + result += vehicle_temp->friction; } while (vehicle_temp->next_vehicle_on_train != (uint16)-1 && (vehicle_temp = GET_VEHICLE(vehicle_temp->next_vehicle_on_train))); sint32 v4 = vehicle->velocity; if (v4 < 0) { @@ -482,8 +482,9 @@ void vehicle_set_map_toolbar(rct_vehicle *vehicle) ride = GET_RIDE(vehicle->ride); - while (vehicle->var_01 != 0) - vehicle = &(g_sprite_list[vehicle->prev_vehicle_on_train].vehicle); + while (vehicle->is_child) { + vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); + } for (vehicleIndex = 0; vehicleIndex < 32; vehicleIndex++) if (ride->vehicles[vehicleIndex] == vehicle->sprite_index) @@ -507,7 +508,7 @@ rct_vehicle *vehicle_get_head(rct_vehicle *vehicle) rct_vehicle *prevVehicle; for (;;) { - prevVehicle = &(g_sprite_list[vehicle->prev_vehicle_on_train].vehicle); + prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride); if (prevVehicle->next_vehicle_on_train == SPRITE_INDEX_NULL) break; @@ -542,16 +543,16 @@ rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int d move_sprite_to_list((rct_sprite*)current, SPRITE_LINKEDLIST_OFFSET_VEHICLE); ride->cable_lift = current->sprite_index; } - current->var_01 = head ? 0 : 1; + current->is_child = head ? 0 : 1; current->var_44 = var_44; current->var_24 = var_24; current->sprite_width = 10; current->sprite_height_negative = 10; current->sprite_height_positive = 10; - current->var_46 = 100; + current->friction = 100; current->num_seats = 0; current->speed = 20; - current->var_C3 = 80; + current->acceleration = 80; current->velocity = 0; current->var_2C = 0; current->var_4A = 0; @@ -574,11 +575,11 @@ rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int d } current->var_CD = 0; current->sprite_direction = direction << 3; - current->var_38 = x; - current->var_3A = y; + current->track_x = x; + current->track_y = y; z = z * 8; - current->var_3C = z; + current->track_z = z; z += RCT2_GLOBAL(0x0097D21A + (ride->type * 8), uint8); sprite_move(16, 16, z, (rct_sprite*)current); @@ -591,3 +592,36 @@ rct_vehicle *cable_lift_segment_create(int rideIndex, int x, int y, int z, int d current->next_free_seat = 0; return current; } + +/** + * + * rct2: 0x006DAB4C + */ +int sub_6DAB4C(rct_vehicle *vehicle, int *outStation) +{ + registers regs; + regs.esi = (int)vehicle; + + RCT2_CALLFUNC_Y(0x006DAB4C, ®s); + + if (outStation != NULL) *outStation = regs.ebx; + return regs.eax; +} + +/** + * + * rct2: 0x006DD365 + */ +bool sub_6DD365(rct_vehicle *vehicle) +{ + registers regs; + regs.esi = (int)vehicle; + + return RCT2_CALLFUNC_Y(0x006DD365, ®s) & 0x100; +} + +rct_ride_type_vehicle *vehicle_get_vehicle_entry(rct_vehicle *vehicle) +{ + rct_ride_type *rideEntry = GET_RIDE_ENTRY(vehicle->ride_subtype); + return &rideEntry->vehicles[vehicle->vehicle_type]; +} diff --git a/src/ride/vehicle.h b/src/ride/vehicle.h index 542fac531a..a1869f2008 100644 --- a/src/ride/vehicle.h +++ b/src/ride/vehicle.h @@ -29,9 +29,58 @@ typedef struct{ uint8 trim_colour; } rct_vehicle_colour; +/** + * Ride type vehicle structure. + * size: 0x65 + */ +typedef struct { + uint16 rotation_frame_mask; // 0x00 , 0x1A + uint8 var_02; // 0x02 , 0x1C + uint8 var_03; // 0x03 , 0x1D + uint32 var_04; // 0x04 , 0x1E + uint16 car_friction; // 0x08 , 0x22 + sint8 tab_height; // 0x0A , 0x24 + uint8 num_seats; // 0x0B , 0x25 + uint16 sprite_flags; // 0x0C , 0x26 + uint8 sprite_width; // 0x0E , 0x28 + 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 var_16; // 0x16 , 0x30 + uint32 base_image_id; // 0x18 , 0x32 + uint32 var_1C; // 0x1C , 0x36 + uint32 var_20; // 0x20 , 0x3A + uint32 var_24; // 0x24 , 0x3E + uint32 var_28; // 0x28 , 0x42 + uint32 var_2C; // 0x2C , 0x46 + uint32 var_30; // 0x30 , 0x4A + uint32 var_34; // 0x34 , 0x4E + uint32 var_38; // 0x38 , 0x52 + uint32 var_3C; // 0x3C , 0x56 + uint32 var_40; // 0x40 , 0x5A + uint32 var_44; // 0x44 , 0x5E + uint32 var_48; // 0x48 , 0x62 + uint32 var_4C; // 0x4C , 0x66 + uint32 no_vehicle_images; // 0x50 , 0x6A + uint8 no_seating_rows; // 0x54 , 0x6E + uint8 spinning_inertia; // 0x55 , 0x6F + uint8 spinning_friction; // 0x56 , 0x70 + uint8 pad_57[0x3]; + uint8 var_5A; // 0x5A , 0x74 + uint8 powered_acceleration; // 0x5B , 0x75 + uint8 powered_max_speed; // 0x5C , 0x76 + uint8 car_visual; // 0x5D , 0x77 + uint8 pad_5E; + uint8 draw_order; + uint8 special_frames; // 0x60 , 0x7A + sint8* peep_loading_positions; // 0x61 , 0x7B +} rct_ride_type_vehicle; + typedef struct { uint8 sprite_identifier; // 0x00 - uint8 var_01; + uint8 is_child; // 0x01 uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 @@ -63,17 +112,19 @@ typedef struct { rct_vehicle_colour colours; // 0x32 uint16 var_34; sint16 var_36; - //x related - uint16 var_38; - // y related - uint16 var_3A; - // z related - uint16 var_3C; + uint16 track_x; // 0x38 + uint16 track_y; // 0x3A + uint16 track_z; // 0x3C uint16 next_vehicle_on_train; // 0x3E - uint16 prev_vehicle_on_train; // 0x40 - uint16 next_or_first_vehicle_on_train; // 0x42 + + // The previous vehicle on the same train or the last vehicle on the previous or only train. + uint16 prev_vehicle_on_ride; // 0x40 + + // The next vehicle on the same train or the first vehicle on the next or only train + uint16 next_vehicle_on_ride; // 0x42 + uint16 var_44; - uint16 var_46; + uint16 friction; // 0x46 uint16 var_48; uint8 var_4A; uint8 current_station; // 0x4B @@ -97,7 +148,7 @@ typedef struct { sint8 var_BF; uint8 pad_C0[2]; uint8 speed; // 0xC2 - uint8 var_C3; + uint8 acceleration; // 0xC3 uint8 var_C4; uint8 var_C5; uint8 pad_C6[2]; @@ -108,12 +159,21 @@ typedef struct { uint8 var_CE; uint8 num_laps; // 0xCE }; - uint8 pad_CF[0x06]; + uint8 pad_CF[0x04]; + uint8 var_D3; + uint8 var_D4; uint8 var_D5; uint8 ride_subtype; // 0xD6 uint8 colours_extended; // 0xD7 + uint8 var_D8; + uint8 var_D9; } rct_vehicle; +typedef struct { + rct_vehicle *head; + rct_vehicle *tail; +} train_ref; + enum { VEHICLE_STATUS_MOVING_TO_END_OF_STATION, VEHICLE_STATUS_WAITING_FOR_PASSENGERS, @@ -148,6 +208,40 @@ enum { VEHICLE_STATUS_STOPPED_BY_BLOCK_BRAKES }; +enum { + VEHICLE_SPRITE_FLAG_FLAT = (1 << 0), + VEHICLE_SPRITE_FLAG_GENTLE_SLOPES = (1 << 1), + VEHICLE_SPRITE_FLAG_STEEP_SLOPES = (1 << 2), + VEHICLE_SPRITE_FLAG_VERTICAL_SLOPES = (1 << 3), + VEHICLE_SPRITE_FLAG_DIAGONAL_SLOPES = (1 << 4), + VEHICLE_SPRITE_FLAG_FLAT_BANKED = (1 << 5), + VEHICLE_SPRITE_FLAG_INLINE_TWISTS = (1 << 6), + VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_BANKED_TRANSITIONS = (1 << 7), + VEHICLE_SPRITE_FLAG_DIAGONAL_GENTLE_SLOPE_BANKED_TRANSITIONS = (1 << 8), + VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TRANSITIONS = (1 << 9), + VEHICLE_SPRITE_FLAG_GENTLE_SLOPE_BANKED_TURNS = (1 << 10), + VEHICLE_SPRITE_FLAG_FLAT_TO_GENTLE_SLOPE_WHILE_BANKED_TRANSITIONS = (1 << 11), + VEHICLE_SPRITE_FLAG_CORKSCREWS = (1 << 12), + VEHICLE_SPRITE_FLAG_RESTRAINT_ANIMATION = (1 << 13), + VEHICLE_SPRITE_FLAG_14 = (1 << 14), + VEHICLE_SPRITE_FLAG_15 = (1 << 15), +}; + +enum { + VEHICLE_VISUAL_DEFAULT, + VEHICLE_VISUAL_FLAT_RIDE_OR_CAR_RIDE, + VEHICLE_VISUAL_LAUNCHED_FREEFALL, + VEHICLE_VISUAL_OBSERVATION_TOWER, + VEHICLE_VISUAL_RIVER_RAPIDS, + VEHICLE_VISUAL_MINI_GOLF_PLAYER, + VEHICLE_VISUAL_MINI_GOLF_BALL, + VEHICLE_VISUAL_REVERSER, + VEHICLE_VISUAL_SPLASH_BOATS_OR_WATER_COASTER, + VEHICLE_VISUAL_ROTO_DROP, + VEHICLE_VISUAL_VIRGINIA_REEL = 15, + VEHICLE_VISUAL_SUBMARINE +}; + #define VEHICLE_SEAT_PAIR_FLAG 0x80 #define VEHICLE_SEAT_NUM_MASK 0x7F @@ -161,6 +255,9 @@ 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); +int sub_6DAB4C(rct_vehicle *vehicle, int *outStation); +bool sub_6DD365(rct_vehicle *vehicle); +rct_ride_type_vehicle *vehicle_get_vehicle_entry(rct_vehicle *vehicle); /** Helper macro until rides are stored in this module. */ #define GET_VEHICLE(sprite_index) &(g_sprite_list[sprite_index].vehicle) diff --git a/src/windows/ride.c b/src/windows/ride.c index ad2ed10b8d..591fdd6489 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -1052,7 +1052,7 @@ static void window_ride_draw_tab_vehicle(rct_drawpixelinfo *dpi, rct_window *w) } rct_ride_type_vehicle* rideVehicleEntry = &rideEntry->vehicles[trainLayout[rideEntry->tab_vehicle]]; - height += rideVehicleEntry->var_0A; + height += rideVehicleEntry->tab_height; vehicleColour = ride_get_vehicle_colour(ride, 0); @@ -1060,7 +1060,7 @@ static void window_ride_draw_tab_vehicle(rct_drawpixelinfo *dpi, rct_window *w) if (w->page == WINDOW_RIDE_PAGE_VEHICLE) spriteIndex += w->frame_no; spriteIndex /= (rideVehicleEntry->var_12 & 0x800) ? 4 : 2; - spriteIndex &= rideVehicleEntry->var_00; + spriteIndex &= rideVehicleEntry->rotation_frame_mask; spriteIndex *= rideVehicleEntry->var_16; spriteIndex += rideVehicleEntry->base_image_id; spriteIndex |= (vehicleColour.additional_1 << 24) | (vehicleColour.main << 19); @@ -2633,7 +2633,7 @@ static void window_ride_vehicle_scrollpaint(rct_window *w, rct_drawpixelinfo *dp startY = widget->bottom - widget->top - 4; rct_ride_type_vehicle* rideVehicleEntry = &rideEntry->vehicles[trainLayout[0]]; - startY += rideVehicleEntry->var_0A; + startY += rideVehicleEntry->tab_height; // For each train for (i = 0; i < ride->num_vehicles; i++) { @@ -2665,7 +2665,7 @@ static void window_ride_vehicle_scrollpaint(rct_window *w, rct_drawpixelinfo *dp if (rideVehicleEntry->var_12 & 0x800) spriteIndex /= 2; - spriteIndex &= rideVehicleEntry->var_00; + spriteIndex &= rideVehicleEntry->rotation_frame_mask; spriteIndex *= rideVehicleEntry->var_16; spriteIndex += rideVehicleEntry->base_image_id; spriteIndex |= (vehicleColour.additional_1 << 24) | (vehicleColour.main << 19); @@ -4308,11 +4308,11 @@ static void window_ride_colour_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi rct_ride_type_vehicle* rideVehicleEntry = &rideEntry->vehicles[trainLayout[trainCarIndex]]; - y += rideVehicleEntry->var_0A; + y += rideVehicleEntry->tab_height; // Draw the coloured spinning vehicle spriteIndex = rideVehicleEntry->var_12 & 0x800 ? w->frame_no / 4 : w->frame_no / 2; - spriteIndex &= rideVehicleEntry->var_00; + spriteIndex &= rideVehicleEntry->rotation_frame_mask; spriteIndex *= rideVehicleEntry->var_16; spriteIndex += rideVehicleEntry->base_image_id; spriteIndex |= (vehicleColour.additional_1 << 24) | (vehicleColour.main << 19); diff --git a/src/world/map.c b/src/world/map.c index fe97d9e22c..6acc8e6ef9 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -4714,4 +4714,23 @@ void game_command_place_park_entrance(int* eax, int* ebx, int* ecx, int* edx, in *ecx & 0xFFFF, *edx & 0xFFFF, (*ebx >> 8) & 0xFF); -} \ No newline at end of file +} + +/** + * Gets the map element at x, y, z. + * @param x x units, not tiles. + * @param y y units, not tiles. + * @param z Base height. + */ +rct_map_element *map_get_track_element_at(int x, int y, int z) +{ + 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; + + return mapElement; + } while (!map_element_is_last_for_tile(mapElement++)); + + return NULL; +} diff --git a/src/world/map.h b/src/world/map.h index dad1e48030..703f257dd1 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -383,4 +383,6 @@ bool map_large_scenery_get_origin( int *outX, int *outY, int *outZ ); +rct_map_element *map_get_track_element_at(int x, int y, int z); + #endif