add vehicle struct, enum labels and helper functions from implement-ride-create-vehicles branch.

This commit is contained in:
IntelOrca 2015-10-25 16:00:21 +00:00
parent 79a6e1adee
commit 4ac42ff1b2
14 changed files with 429 additions and 174 deletions

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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, &regs);
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, &regs) & 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];
}

View File

@ -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)

View File

@ -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);

View File

@ -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);
}
}
/**
* 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;
}

View File

@ -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