mirror of https://github.com/OpenRCT2/OpenRCT2.git
implement vehicle_update_motion_collision_detection
This commit is contained in:
parent
55f1032a9a
commit
f7520fd2ba
|
@ -71,7 +71,7 @@ static void vehicle_update_collision_setup(rct_vehicle* vehicle);
|
|||
static int vehicle_update_motion_bumper_car(rct_vehicle* vehicle);
|
||||
static bool vehicle_update_bumper_car_collision(rct_vehicle *vehicle, sint16 x, sint16 y, uint16 *spriteId);
|
||||
static void sub_6D63D4(rct_vehicle *vehicle);
|
||||
static bool sub_6DD078(rct_vehicle *vehicle, uint16* otherVehicleIndex);
|
||||
static bool vehicle_update_motion_collision_detection(rct_vehicle *vehicle, sint16 x, sint16 y, sint16 z, uint16 *otherVehicleIndex);
|
||||
static void vehicle_update_sound(rct_vehicle *vehicle);
|
||||
static int vehicle_update_scream_sound(rct_vehicle *vehicle);
|
||||
|
||||
|
@ -3175,8 +3175,7 @@ static void vehicle_update_travelling_boat(rct_vehicle* vehicle)
|
|||
static void loc_6DA9F9(rct_vehicle *vehicle, int x, int y, int bx, int dx)
|
||||
{
|
||||
vehicle->remaining_distance = 0;
|
||||
// z = vehicle->z;
|
||||
if (!sub_6DD078(vehicle, NULL)) {
|
||||
if (!vehicle_update_motion_collision_detection(vehicle, x, y, vehicle->z, NULL)) {
|
||||
vehicle->track_x = bx;
|
||||
vehicle->track_y = dx;
|
||||
|
||||
|
@ -3315,7 +3314,7 @@ static void vehicle_update_motion_boat_hire(rct_vehicle *vehicle)
|
|||
x = vehicle->x + RCT2_ADDRESS(0x009A36C4, sint16)[edi * 4];
|
||||
y = vehicle->y + RCT2_ADDRESS(0x009A36C6, sint16)[edi * 4];
|
||||
z = vehicle->z;
|
||||
if (sub_6DD078(vehicle, NULL)) {
|
||||
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, NULL)) {
|
||||
goto loc_6DAA79;
|
||||
}
|
||||
|
||||
|
@ -3376,8 +3375,7 @@ static void vehicle_update_motion_boat_hire(rct_vehicle *vehicle)
|
|||
|
||||
// loc_6DA9D1:
|
||||
vehicle->remaining_distance = 0;
|
||||
// z = vehicle->z;
|
||||
if (!sub_6DD078(vehicle, NULL)) {
|
||||
if (!vehicle_update_motion_collision_detection(vehicle, x, y, vehicle->z, NULL)) {
|
||||
unk_F64E20->x = x;
|
||||
unk_F64E20->y = y;
|
||||
}
|
||||
|
@ -6359,24 +6357,164 @@ static void sub_6DB807(rct_vehicle *vehicle)
|
|||
sprite_move(x, y, z, (rct_sprite*)vehicle);
|
||||
}
|
||||
|
||||
/** Collision?
|
||||
*
|
||||
/**
|
||||
* Collision Detection
|
||||
* rct2: 0x006DD078
|
||||
* @param vehicle (esi)
|
||||
* @param x (ax)
|
||||
* @param y (cx)
|
||||
* @param z (dx)
|
||||
* @param otherVehicleIndex (bp)
|
||||
*/
|
||||
static bool sub_6DD078(rct_vehicle *vehicle, uint16* otherVehicleIndex)
|
||||
{
|
||||
registers regs = { 0 };
|
||||
regs.esi = (int)vehicle;
|
||||
if (otherVehicleIndex != NULL) {
|
||||
regs.bp = *otherVehicleIndex;
|
||||
static bool vehicle_update_motion_collision_detection(
|
||||
rct_vehicle *vehicle, sint16 x, sint16 y, sint16 z, uint16* otherVehicleIndex
|
||||
) {
|
||||
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_1) return false;
|
||||
|
||||
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
||||
|
||||
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_6)){
|
||||
vehicle->var_C4 = 0;
|
||||
rct_vehicle* collideVehicle = GET_VEHICLE(*otherVehicleIndex);
|
||||
|
||||
if (vehicle == collideVehicle) return false;
|
||||
|
||||
sint32 x_diff = abs(x - collideVehicle->x);
|
||||
if (x_diff > 0x7FFF) return false;
|
||||
|
||||
sint32 y_diff = abs(y - collideVehicle->y);
|
||||
if (y_diff > 0x7FFF) return false;
|
||||
|
||||
if (x_diff + y_diff > 0xFFFF) return false;
|
||||
|
||||
sint32 z_diff = abs(z - collideVehicle->z);
|
||||
if (x_diff + y_diff + z_diff > 0xFFFF) return false;
|
||||
|
||||
uint16 ecx = min(vehicle->var_44 + collideVehicle->var_44, 560);
|
||||
ecx = ((ecx >> 1) * 30) >> 8;
|
||||
|
||||
if (x_diff + y_diff + z_diff >= ecx) return false;
|
||||
|
||||
uint8 direction = (vehicle->sprite_direction - collideVehicle->sprite_direction + 7) & 0x1F;
|
||||
if (direction >= 0xF) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
bool result = RCT2_CALLFUNC_Y(0x006DD078, ®s) & 0x100;
|
||||
if (otherVehicleIndex != NULL) {
|
||||
*otherVehicleIndex = regs.bp;
|
||||
|
||||
uint16 eax = ((x / 32) << 8) + (y / 32);
|
||||
// TODO change to using a better technique
|
||||
uint32* ebp = RCT2_ADDRESS(0x009A37C4, uint32);
|
||||
bool mayCollide = false;
|
||||
uint16 collideId = 0xFFFF;
|
||||
rct_vehicle* collideVehicle = NULL;
|
||||
for(; ebp <= RCT2_ADDRESS(0x009A37E4, uint32); ebp++){
|
||||
collideId = RCT2_ADDRESS(0x00F1EF60, uint16)[eax];
|
||||
for(; collideId != 0xFFFF; collideId = collideVehicle->next_in_quadrant){
|
||||
collideVehicle = GET_VEHICLE(collideId);
|
||||
if (collideVehicle == vehicle) continue;
|
||||
|
||||
if (collideVehicle->sprite_identifier != SPRITE_IDENTIFIER_VEHICLE) continue;
|
||||
|
||||
sint32 z_diff = abs(collideVehicle->z - z);
|
||||
|
||||
if (z_diff > 16) continue;
|
||||
|
||||
rct_ride_type_vehicle* collideType = vehicle_get_vehicle_entry(collideVehicle);
|
||||
|
||||
if (!(collideType->flags_b & VEHICLE_ENTRY_FLAG_B_6)) continue;
|
||||
|
||||
sint32 x_diff = abs(collideVehicle->x - x);
|
||||
if (x_diff > 0x7FFF) continue;
|
||||
|
||||
sint32 y_diff = abs(collideVehicle->y - y);
|
||||
if (y_diff > 0x7FFF) continue;
|
||||
|
||||
if (x_diff + y_diff > 0xFFFF) continue;
|
||||
|
||||
uint8 cl = min(vehicle->var_CD, collideVehicle->var_CD);
|
||||
uint8 ch = max(vehicle->var_CD, collideVehicle->var_CD);
|
||||
if (cl != ch){
|
||||
if (cl == 5 && ch == 6) continue;
|
||||
}
|
||||
|
||||
uint32 ecx = vehicle->var_44 + collideVehicle->var_44;
|
||||
ecx = ((ecx >> 1) * 30) >> 8;
|
||||
|
||||
if (x + y >= ecx) continue;
|
||||
|
||||
if (!(collideType->flags_b & VEHICLE_ENTRY_FLAG_B_14)){
|
||||
mayCollide = true;
|
||||
break;
|
||||
}
|
||||
|
||||
uint8 direction = (vehicle->sprite_direction - collideVehicle->sprite_direction - 6) & 0x1F;
|
||||
|
||||
if (direction < 0x14) continue;
|
||||
|
||||
sint16 next_x_diff = abs(x + RCT2_ADDRESS(0x009A3B04, sint16)[vehicle->sprite_direction*2]-collideVehicle->x);
|
||||
sint16 next_y_diff = abs(y + RCT2_ADDRESS(0x009A3B06, sint16)[vehicle->sprite_direction*2]-collideVehicle->y);
|
||||
|
||||
if (next_x_diff + next_y_diff < x_diff + y_diff){
|
||||
mayCollide = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (mayCollide == true) {
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO change this
|
||||
eax += *ebp;
|
||||
}
|
||||
return result;
|
||||
|
||||
if (mayCollide == false) {
|
||||
vehicle->var_C4 = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
vehicle->var_C4++;
|
||||
if (vehicle->var_C4 < 200) {
|
||||
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_6;
|
||||
*otherVehicleIndex = collideId;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO Is it possible for collideVehicle to be NULL?
|
||||
|
||||
if (vehicle->status == VEHICLE_STATUS_MOVING_TO_END_OF_STATION){
|
||||
if (vehicle->sprite_direction == 0) {
|
||||
if (vehicle->x <= collideVehicle->x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (vehicle->sprite_direction == 8) {
|
||||
if (vehicle->x >= collideVehicle->x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (vehicle->sprite_direction == 16) {
|
||||
if (vehicle->y >= collideVehicle->y) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (vehicle->sprite_direction == 24) {
|
||||
if (vehicle->y <= collideVehicle->y) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collideVehicle->status == VEHICLE_STATUS_TRAVELLING_BOAT &&
|
||||
vehicle->status != VEHICLE_STATUS_ARRIVING &&
|
||||
vehicle->status != VEHICLE_STATUS_TRAVELLING
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_6;
|
||||
*otherVehicleIndex = collideId;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -6799,7 +6937,7 @@ loc_6DB8A5:
|
|||
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
||||
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
||||
regs.bp = vehicle->prev_vehicle_on_ride;
|
||||
if (sub_6DD078(vehicle, (uint16 *)®s.bp)) {
|
||||
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16 *)®s.bp)) {
|
||||
goto loc_6DB967;
|
||||
}
|
||||
}
|
||||
|
@ -7078,7 +7216,7 @@ loc_6DBD42:
|
|||
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
||||
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
||||
regs.bp = vehicle->next_vehicle_on_ride;
|
||||
if (sub_6DD078(vehicle, (uint16 *)®s.bp)) {
|
||||
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16*)®s.bp)) {
|
||||
goto loc_6DBE7F;
|
||||
}
|
||||
}
|
||||
|
@ -7728,7 +7866,7 @@ loc_6DC8A1:
|
|||
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
||||
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
||||
regs.bp = vehicle->var_44;
|
||||
sub_6DD078(vehicle, (uint16 *)®s.bp);
|
||||
vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16*)®s.bp);
|
||||
}
|
||||
}
|
||||
goto loc_6DC99A;
|
||||
|
@ -7868,7 +8006,7 @@ loc_6DCC2C:
|
|||
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
||||
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
||||
regs.bp = vehicle->var_44;
|
||||
if (sub_6DD078(vehicle, (uint16 *)®s.bp)) {
|
||||
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16*)®s.bp)) {
|
||||
goto loc_6DCD6B;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue