Add vehicle_update_crossings for validating crossing tiles upon entering a tile

This commit is contained in:
Jeroen D Stout 2018-01-11 01:20:59 +01:00 committed by Ted John
parent 1f7dbe1178
commit 244209df56
1 changed files with 142 additions and 0 deletions

View File

@ -49,6 +49,7 @@
#include "../windows/Intent.h"
static void vehicle_update(rct_vehicle * vehicle);
static void vehicle_update_crossings(rct_vehicle * vehicle);
static void vehicle_update_showing_film(rct_vehicle * vehicle);
static void vehicle_update_doing_circus_show(rct_vehicle * vehicle);
@ -3357,6 +3358,9 @@ static void vehicle_update_departing(rct_vehicle * vehicle)
{
vehicle->update_flags ^= VEHICLE_UPDATE_FLAG_REVERSING_SHUTTLE;
vehicle->velocity = 0;
// We have turned, so treat it like entering a new tile
vehicle_update_crossings(vehicle);
}
}
@ -8277,6 +8281,8 @@ loc_6DAEB9:
uint16 trackTotalProgress = vehicle_get_move_info_size(vehicle->var_CD, vehicle->track_type);
if (regs.ax >= trackTotalProgress)
{
vehicle_update_crossings(vehicle);
if (!vehicle_update_track_motion_forwards_get_new_track(vehicle, trackType, ride, rideEntry))
{
goto loc_6DB94A;
@ -8622,6 +8628,8 @@ loc_6DBA33:;
regs.ax = vehicle->track_progress - 1;
if (regs.ax == -1)
{
vehicle_update_crossings(vehicle);
if (!vehicle_update_track_motion_backwards_get_new_track(vehicle, trackType, ride, (uint16 *)&regs.ax))
{
goto loc_6DBE5E;
@ -9896,3 +9904,137 @@ void vehicle_invalidate_window(rct_vehicle * vehicle)
intent.putExtra(INTENT_EXTRA_VEHICLE, vehicle);
context_broadcast_intent(&intent);
}
void vehicle_update_crossings(rct_vehicle * vehicle)
{
if (vehicle_get_head(vehicle) != vehicle)
{
return;
}
rct_vehicle *frontVehicle;
rct_vehicle *backVehicle;
bool travellingForwards = !(vehicle->update_flags & VEHICLE_UPDATE_FLAG_REVERSING_SHUTTLE);
if (travellingForwards)
{
frontVehicle = vehicle;
backVehicle = vehicle_get_tail(vehicle);
}
else
{
frontVehicle = vehicle_get_tail(vehicle);
backVehicle = vehicle;
}
CoordsXYE xyElement;
track_begin_end output;
sint32 z, direction;
xyElement.x = frontVehicle->track_x;
xyElement.y = frontVehicle->track_y;
z = frontVehicle->track_z;
xyElement.element = map_get_track_element_at_of_type_seq(
frontVehicle->track_x, frontVehicle->track_y, frontVehicle->track_z >> 3,
frontVehicle->track_type >> 2, 0
);
if (xyElement.element && vehicle->status != VEHICLE_STATUS_ARRIVING)
{
sint16 autoReserveAhead = 4 + abs(vehicle->velocity) / 150000;
bool keepReserving;
// vehicle positions mean we have to take larger
// margins for travelling backwards
if (!travellingForwards)
{
autoReserveAhead += 1;
}
while (true)
{
keepReserving = false;
rct_tile_element *tileElement = map_get_path_element_at(
xyElement.x / 32,
xyElement.y / 32,
xyElement.element->base_height
);
if (tileElement)
{
tileElement->flags |= TILE_ELEMENT_FLAG_BLOCKED_BY_VEHICLE;
keepReserving = true;
}
if (--autoReserveAhead <= 0 && !keepReserving)
{
break;
}
z = xyElement.element->base_height;
if (travellingForwards)
{
if (!track_block_get_next(&xyElement, &xyElement, &z, &direction))
{
break;
}
}
else
{
if (!track_block_get_previous(xyElement.x, xyElement.y, xyElement.element, &output))
{
break;
}
xyElement.x = output.begin_x;
xyElement.y = output.begin_y;
xyElement.element = output.begin_element;
}
if (xyElement.element->properties.track.type == TRACK_ELEM_BEGIN_STATION ||
xyElement.element->properties.track.type == TRACK_ELEM_MIDDLE_STATION ||
xyElement.element->properties.track.type == TRACK_ELEM_END_STATION)
{
break;
}
}
}
xyElement.x = backVehicle->track_x;
xyElement.y = backVehicle->track_y;
z = backVehicle->track_z;
xyElement.element = map_get_track_element_at_of_type_seq(
backVehicle->track_x, backVehicle->track_y, backVehicle->track_z >> 3,
backVehicle->track_type >> 2, 0
);
if (xyElement.element)
{
uint8 freeCount = travellingForwards? 3 : 1;
while (freeCount-- > 0)
{
if (travellingForwards)
{
if (track_block_get_previous(xyElement.x, xyElement.y, xyElement.element, &output))
{
xyElement.x = output.begin_x;
xyElement.y = output.begin_y;
xyElement.element = output.begin_element;
}
}
rct_tile_element *tileElement = map_get_path_element_at(
xyElement.x / 32,
xyElement.y / 32,
xyElement.element->base_height
);
if (tileElement)
{
tileElement->flags &= ~TILE_ELEMENT_FLAG_BLOCKED_BY_VEHICLE;
}
}
}
}