2014-05-25 19:40:11 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
* Copyright (c) 2014 Ted John
|
|
|
|
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
|
|
|
*
|
|
|
|
* This file is part of OpenRCT2.
|
|
|
|
*
|
|
|
|
* OpenRCT2 is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
2015-10-20 20:16:30 +02:00
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2015-10-20 20:16:30 +02:00
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "../addresses.h"
|
2015-11-20 01:04:07 +01:00
|
|
|
#include "../game.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "../audio/audio.h"
|
2014-10-07 20:10:16 +02:00
|
|
|
#include "../audio/mixer.h"
|
2015-07-15 00:38:56 +02:00
|
|
|
#include "../config.h"
|
2015-10-25 22:25:54 +01:00
|
|
|
#include "../hook.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "../interface/viewport.h"
|
2015-09-12 19:17:25 +02:00
|
|
|
#include "../openrct2.h"
|
2014-11-12 00:05:04 +01:00
|
|
|
#include "../scenario.h"
|
2015-11-22 15:55:46 +01:00
|
|
|
#include "../world/map_animation.h"
|
2014-10-06 18:36:58 +02:00
|
|
|
#include "../world/sprite.h"
|
2015-04-05 16:57:08 +02:00
|
|
|
#include "../world/scenery.h"
|
2015-12-16 19:37:45 +01:00
|
|
|
#include "cable_lift.h"
|
2015-04-05 13:36:02 +02:00
|
|
|
#include "track.h"
|
2014-09-13 19:51:58 +02:00
|
|
|
#include "ride.h"
|
2014-11-10 01:40:59 +01:00
|
|
|
#include "ride_data.h"
|
2015-09-12 19:17:25 +02:00
|
|
|
#include "track.h"
|
2015-12-14 13:30:28 +01:00
|
|
|
#include "track_data.h"
|
2014-05-25 19:40:11 +02:00
|
|
|
#include "vehicle.h"
|
|
|
|
|
|
|
|
static void vehicle_update(rct_vehicle *vehicle);
|
2014-11-12 02:32:20 +01:00
|
|
|
|
2015-11-19 21:28:07 +01:00
|
|
|
static void vehicle_update_showing_film(rct_vehicle *vehicle);
|
2014-11-12 02:32:20 +01:00
|
|
|
static void vehicle_update_doing_circus_show(rct_vehicle *vehicle);
|
2015-04-07 22:28:11 +02:00
|
|
|
static void vehicle_update_moving_to_end_of_station(rct_vehicle *vehicle);
|
2015-04-08 19:48:17 +02:00
|
|
|
static void vehicle_update_waiting_for_passengers(rct_vehicle* vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle);
|
2015-11-28 19:13:22 +01:00
|
|
|
static void vehicle_update_departing(rct_vehicle* vehicle);
|
2015-11-29 11:58:37 +01:00
|
|
|
static void vehicle_finish_departing(rct_vehicle* vehicle);
|
2015-11-29 15:42:04 +01:00
|
|
|
static void vehicle_update_travelling(rct_vehicle* vehicle);
|
2015-11-25 20:55:04 +01:00
|
|
|
static void vehicle_update_ferris_wheel_rotating(rct_vehicle* vehicle);
|
2015-11-25 23:25:13 +01:00
|
|
|
static void vehicle_update_rotating(rct_vehicle* vehicle);
|
2015-11-25 21:26:15 +01:00
|
|
|
static void vehicle_update_space_rings_operating(rct_vehicle* vehicle);
|
|
|
|
static void vehicle_update_haunted_house_operating(rct_vehicle* vehicle);
|
2015-11-25 21:39:59 +01:00
|
|
|
static void vehicle_update_crooked_house_operating(rct_vehicle* vehicle);
|
2015-11-21 11:46:24 +01:00
|
|
|
static void vehicle_update_bumpcar_mode(rct_vehicle* vehicle);
|
2015-11-21 12:35:02 +01:00
|
|
|
static void vehicle_update_swinging(rct_vehicle* vehicle);
|
2015-11-21 13:13:10 +01:00
|
|
|
static void vehicle_update_simulator_operating(rct_vehicle* vehicle);
|
2015-11-21 17:16:05 +01:00
|
|
|
static void vehicle_update_top_spin_operating(rct_vehicle* vehicle);
|
2015-11-20 01:04:07 +01:00
|
|
|
static void vehicle_update_crash(rct_vehicle *vehicle);
|
2015-12-11 14:07:22 +01:00
|
|
|
static void vehicle_update_travelling_boat(rct_vehicle* vehicle);
|
2015-12-21 22:33:17 +01:00
|
|
|
static void vehicle_update_motion_boat_hire(rct_vehicle *vehicle);
|
|
|
|
static void sub_6DA280(rct_vehicle *vehicle);
|
|
|
|
static bool vehicle_is_boat_on_water(rct_vehicle *vehicle, int x, int y);
|
2015-12-11 16:49:21 +01:00
|
|
|
static void vehicle_update_arriving(rct_vehicle* vehicle);
|
2015-12-11 18:35:24 +01:00
|
|
|
static void vehicle_update_unloading_passengers(rct_vehicle* vehicle);
|
2015-12-16 19:37:45 +01:00
|
|
|
static void vehicle_update_waiting_for_cable_lift(rct_vehicle *vehicle);
|
|
|
|
static void vehicle_update_travelling_cable_lift(rct_vehicle* vehicle);
|
2015-12-11 21:55:34 +01:00
|
|
|
static void vehicle_update_crash_setup(rct_vehicle* vehicle);
|
2015-12-12 13:21:13 +01:00
|
|
|
static void vehicle_update_collision_setup(rct_vehicle* vehicle);
|
2015-12-12 15:55:05 +01:00
|
|
|
static int vehicle_update_motion_bumper_car(rct_vehicle* vehicle);
|
2015-12-21 22:33:17 +01:00
|
|
|
static void sub_6D63D4(rct_vehicle *vehicle);
|
2015-12-27 12:46:15 +01:00
|
|
|
static bool vehicle_update_motion_collision_detection(rct_vehicle *vehicle, sint16 x, sint16 y, sint16 z, uint16 *otherVehicleIndex);
|
2014-11-12 00:05:04 +01:00
|
|
|
static void vehicle_update_sound(rct_vehicle *vehicle);
|
2014-11-12 02:04:50 +01:00
|
|
|
static int vehicle_update_scream_sound(rct_vehicle *vehicle);
|
|
|
|
|
2015-12-12 13:21:13 +01:00
|
|
|
static void vehicle_kill_all_passengers(rct_vehicle* vehicle);
|
2015-12-20 19:33:43 +01:00
|
|
|
static bool vehicle_can_depart_synchronised(rct_vehicle *vehicle);
|
2015-12-12 13:21:13 +01:00
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
#define NO_SCREAM 254
|
|
|
|
|
2015-12-14 22:56:00 +01:00
|
|
|
rct_xyz16 *unk_F64E20 = (rct_xyz16*)0x00F64E20;
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
const uint8 byte_9A3A14[] = { SOUND_SCREAM_8, SOUND_SCREAM_1 };
|
|
|
|
const uint8 byte_9A3A16[] = { SOUND_SCREAM_1, SOUND_SCREAM_6 };
|
|
|
|
const uint8 byte_9A3A18[] = {
|
|
|
|
SOUND_SCREAM_3, SOUND_SCREAM_1, SOUND_SCREAM_5, SOUND_SCREAM_6,
|
2015-12-11 21:26:26 +01:00
|
|
|
SOUND_SCREAM_7, SOUND_SCREAM_2, SOUND_SCREAM_4
|
2014-11-12 02:04:50 +01:00
|
|
|
};
|
2014-05-25 19:40:11 +02:00
|
|
|
|
2015-12-16 22:37:58 +01:00
|
|
|
const rct_vehicle_info *vehicle_get_move_info(int cd, int typeAndDirection, int offset)
|
2015-12-05 13:05:15 +01:00
|
|
|
{
|
2015-12-22 15:21:56 +01:00
|
|
|
const rct_vehicle_info **infoListList = RCT2_ADDRESS(0x008B8F30, const rct_vehicle_info**)[cd];
|
2015-12-05 13:05:15 +01:00
|
|
|
const rct_vehicle_info *infoList = infoListList[typeAndDirection];
|
|
|
|
return &infoList[offset];
|
|
|
|
}
|
|
|
|
|
2015-12-14 13:30:28 +01:00
|
|
|
const uint8 DoorOpenSoundIds[] = {
|
2016-01-02 17:19:06 +01:00
|
|
|
SOUND_DOOR_OPEN,
|
|
|
|
SOUND_62
|
2015-12-14 13:30:28 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const uint8 DoorCloseSoundIds[] = {
|
|
|
|
SOUND_DOOR_CLOSE,
|
|
|
|
SOUND_62
|
|
|
|
};
|
|
|
|
|
2015-12-20 13:50:33 +01:00
|
|
|
static const struct { sint8 x, y, z; } SteamParticleOffsets[] = {
|
|
|
|
{ -11, 0, 22 },
|
|
|
|
{ -10, 4, 22 },
|
|
|
|
{ -8, 8, 22 },
|
|
|
|
{ -4, 10, 22 },
|
|
|
|
{ 0, 11, 22 },
|
|
|
|
{ 4, 10, 22 },
|
|
|
|
{ 8, 8, 22 },
|
|
|
|
{ 10, 4, 22 },
|
|
|
|
{ 11, 0, 22 },
|
|
|
|
{ 10, -4, 22 },
|
|
|
|
{ 8, -8, 22 },
|
|
|
|
{ 4, -10, 22 },
|
|
|
|
{ 0, -11, 22 },
|
|
|
|
{ -4, -10, 22 },
|
|
|
|
{ -8, -8, 22 },
|
|
|
|
{ -10, -4, 22 },
|
|
|
|
{ -9, 0, 27 },
|
|
|
|
{ -8, 4, 27 },
|
|
|
|
{ -6, 6, 27 },
|
|
|
|
{ -4, 8, 27 },
|
|
|
|
{ 0, 9, 27 },
|
|
|
|
{ 4, 8, 27 },
|
|
|
|
{ 6, 6, 27 },
|
|
|
|
{ 8, 4, 27 },
|
|
|
|
{ 9, 0, 27 },
|
|
|
|
{ 8, -4, 27 },
|
|
|
|
{ 6, -6, 27 },
|
|
|
|
{ 4, -8, 27 },
|
|
|
|
{ 0, -9, 27 },
|
|
|
|
{ -4, -8, 27 },
|
|
|
|
{ -6, -6, 27 },
|
|
|
|
{ -8, -4, 27 },
|
|
|
|
{ -13, 0, 18 },
|
|
|
|
{ -12, 4, 17 },
|
|
|
|
{ -9, 9, 17 },
|
|
|
|
{ -4, 8, 17 },
|
|
|
|
{ 0, 13, 18 },
|
|
|
|
{ 4, 8, 17 },
|
|
|
|
{ 6, 6, 17 },
|
|
|
|
{ 8, 4, 17 },
|
|
|
|
{ 13, 0, 18 },
|
|
|
|
{ 8, -4, 17 },
|
|
|
|
{ 6, -6, 17 },
|
|
|
|
{ 4, -8, 17 },
|
|
|
|
{ 0, -13, 18 },
|
|
|
|
{ -4, -8, 17 },
|
|
|
|
{ -6, -6, 17 },
|
|
|
|
{ -8, -4, 17 }
|
|
|
|
};
|
|
|
|
|
2015-12-20 13:30:10 +01:00
|
|
|
void vehicle_invalidate(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
invalidate_sprite_2((rct_sprite*)vehicle);
|
|
|
|
}
|
|
|
|
|
2014-09-13 19:51:58 +02:00
|
|
|
/**
|
2015-12-16 19:37:45 +01:00
|
|
|
*
|
|
|
|
* rct2: 0x006BB9FF
|
|
|
|
*/
|
2014-10-07 04:21:55 +02:00
|
|
|
void vehicle_update_sound_params(rct_vehicle* vehicle)
|
2014-09-13 19:51:58 +02:00
|
|
|
{
|
2015-03-26 21:48:42 +01:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && (!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) || RCT2_GLOBAL(0x0141F570, uint8) == 6)) {
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle->sound1_id != (uint8)-1 || vehicle->sound2_id != (uint8)-1) {
|
2015-06-03 19:02:41 +02:00
|
|
|
if (vehicle->sprite_left != (sint16)0x8000) {
|
2014-11-10 18:23:13 +01:00
|
|
|
RCT2_GLOBAL(0x009AF5A0, sint16) = vehicle->sprite_left;
|
|
|
|
RCT2_GLOBAL(0x009AF5A2, sint16) = vehicle->sprite_top;
|
|
|
|
RCT2_GLOBAL(0x009AF5A4, sint16) = vehicle->sprite_right;
|
|
|
|
RCT2_GLOBAL(0x009AF5A6, sint16) = vehicle->sprite_bottom;
|
2014-09-13 19:51:58 +02:00
|
|
|
sint16 v4 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x;
|
|
|
|
sint16 v5 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y;
|
|
|
|
sint16 v6 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width / 4;
|
|
|
|
sint16 v7 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_height / 4;
|
|
|
|
if (!RCT2_GLOBAL(0x00F438A8, rct_window*)->classification) {
|
|
|
|
v4 -= v6;
|
|
|
|
v5 -= v7;
|
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
if (v4 < RCT2_GLOBAL(0x009AF5A4, sint16) && v5 < RCT2_GLOBAL(0x009AF5A6, sint16)) {
|
2014-09-13 19:51:58 +02:00
|
|
|
sint16 t8 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_width + v4;
|
|
|
|
sint16 t9 = RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_height + v5;
|
|
|
|
if (!RCT2_GLOBAL(0x00F438A8, rct_window*)->classification) {
|
|
|
|
t8 += v6 + v6;
|
|
|
|
t9 += v7 + v7;
|
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
if (t8 >= RCT2_GLOBAL(0x009AF5A0, sint16) && t9 >= RCT2_GLOBAL(0x009AF5A2, sint16)) {
|
2014-09-13 19:51:58 +02:00
|
|
|
uint16 v9 = sub_6BC2F3(vehicle);
|
2014-10-07 04:21:55 +02:00
|
|
|
rct_vehicle_sound_params* i;
|
|
|
|
for (i = &gVehicleSoundParamsList[0]; i < gVehicleSoundParamsListEnd && v9 <= i->var_A; i++);
|
|
|
|
if (i < &gVehicleSoundParamsList[countof(gVehicleSoundParamsList)]) {
|
|
|
|
if (gVehicleSoundParamsListEnd < &gVehicleSoundParamsList[countof(gVehicleSoundParamsList)]) {
|
|
|
|
gVehicleSoundParamsListEnd++;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
rct_vehicle_sound_params* j = gVehicleSoundParamsListEnd - 1;
|
2014-09-13 19:51:58 +02:00
|
|
|
while (j >= i) {
|
|
|
|
j--;
|
2014-09-15 23:12:25 +02:00
|
|
|
*(j + 1) = *j;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2014-09-22 20:35:47 +02:00
|
|
|
i->var_A = v9;
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan_x = (RCT2_GLOBAL(0x009AF5A0, sint16) / 2) + (RCT2_GLOBAL(0x009AF5A4, sint16) / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_x;
|
|
|
|
pan_x >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom;
|
|
|
|
pan_x += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->x;
|
2014-09-13 19:51:58 +02:00
|
|
|
|
2014-10-16 04:02:56 +02:00
|
|
|
uint16 screenwidth = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_WIDTH, uint16);
|
|
|
|
if (screenwidth < 64) {
|
|
|
|
screenwidth = 64;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
i->pan_x = ((((pan_x << 16) / screenwidth) - 0x8000) >> 4);
|
2014-09-13 19:51:58 +02:00
|
|
|
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan_y = (RCT2_GLOBAL(0x009AF5A2, sint16) / 2) + (RCT2_GLOBAL(0x009AF5A6, sint16) / 2) - RCT2_GLOBAL(0x00F438A4, rct_viewport*)->view_y;
|
|
|
|
pan_y >>= RCT2_GLOBAL(0x00F438A4, rct_viewport*)->zoom;
|
|
|
|
pan_y += RCT2_GLOBAL(0x00F438A4, rct_viewport*)->y;
|
2014-10-16 04:02:56 +02:00
|
|
|
|
|
|
|
uint16 screenheight = RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_HEIGHT, uint16);
|
|
|
|
if (screenheight < 64) {
|
|
|
|
screenheight = 64;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
i->pan_y = ((((pan_y << 16) / screenheight) - 0x8000) >> 4);
|
2014-10-16 04:02:56 +02:00
|
|
|
|
2014-09-19 23:17:14 +02:00
|
|
|
sint32 v19 = vehicle->velocity;
|
2014-09-13 19:51:58 +02:00
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type* ride_type = get_ride_entry(vehicle->ride_subtype);
|
2015-03-19 21:34:53 +01:00
|
|
|
uint8 test = ride_type->vehicles[vehicle->vehicle_type].var_5A;
|
2014-09-13 19:51:58 +02:00
|
|
|
|
|
|
|
if (test & 1) {
|
|
|
|
v19 *= 2;
|
|
|
|
}
|
|
|
|
if (v19 < 0) {
|
|
|
|
v19 = -v19;
|
|
|
|
}
|
|
|
|
v19 >>= 5;
|
2014-10-07 04:21:55 +02:00
|
|
|
v19 *= 5512;
|
2014-09-13 19:51:58 +02:00
|
|
|
v19 >>= 14;
|
2014-10-07 04:21:55 +02:00
|
|
|
v19 += 11025;
|
2014-09-13 19:51:58 +02:00
|
|
|
v19 += 16 * vehicle->var_BF;
|
|
|
|
i->frequency = (uint16)v19;
|
|
|
|
i->id = vehicle->sprite_index;
|
2014-10-16 04:02:56 +02:00
|
|
|
i->volume = 0;
|
2015-06-03 19:02:41 +02:00
|
|
|
if (vehicle->x != (sint16)0x8000) {
|
2014-10-16 04:02:56 +02:00
|
|
|
int tile_idx = (((vehicle->y & 0xFFE0) * 256) + (vehicle->x & 0xFFE0)) / 32;
|
2014-09-13 19:51:58 +02:00
|
|
|
rct_map_element* map_element;
|
2014-10-16 04:02:56 +02:00
|
|
|
for (map_element = RCT2_ADDRESS(RCT2_ADDRESS_TILE_MAP_ELEMENT_POINTERS, rct_map_element*)[tile_idx]; map_element->type & MAP_ELEMENT_TYPE_MASK; map_element++);
|
|
|
|
if (map_element->base_height * 8 > vehicle->z) { // vehicle underground
|
|
|
|
i->volume = 0x30;
|
2014-09-13 19:51:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-12-16 19:37:45 +01:00
|
|
|
*
|
|
|
|
* rct2: 0x006BC2F3
|
|
|
|
*/
|
2014-09-13 19:51:58 +02:00
|
|
|
int sub_6BC2F3(rct_vehicle* vehicle)
|
|
|
|
{
|
|
|
|
int result = 0;
|
|
|
|
rct_vehicle* vehicle_temp = vehicle;
|
|
|
|
do {
|
2015-10-25 17:00:21 +01:00
|
|
|
result += vehicle_temp->friction;
|
2014-09-13 19:51:58 +02:00
|
|
|
} while (vehicle_temp->next_vehicle_on_train != (uint16)-1 && (vehicle_temp = GET_VEHICLE(vehicle_temp->next_vehicle_on_train)));
|
2014-09-19 23:17:14 +02:00
|
|
|
sint32 v4 = vehicle->velocity;
|
2014-09-13 19:51:58 +02:00
|
|
|
if (v4 < 0) {
|
|
|
|
v4 = -v4;
|
|
|
|
}
|
|
|
|
result += ((uint16)v4) >> 13;
|
2014-10-16 04:02:56 +02:00
|
|
|
rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0];
|
2015-10-25 20:54:19 +01:00
|
|
|
|
2014-09-13 19:51:58 +02:00
|
|
|
while (vehicle_sound->id != vehicle->sprite_index) {
|
|
|
|
vehicle_sound++;
|
2015-10-25 20:54:19 +01:00
|
|
|
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle_sound >= &gVehicleSoundList[countof(gVehicleSoundList)]) {
|
2014-09-13 19:51:58 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result + 300;
|
|
|
|
}
|
|
|
|
|
2014-09-15 23:12:25 +02:00
|
|
|
/**
|
2015-12-16 19:37:45 +01:00
|
|
|
*
|
|
|
|
* rct2: 0x006BBC6B
|
|
|
|
*/
|
2014-09-15 23:12:25 +02:00
|
|
|
void vehicle_sounds_update()
|
|
|
|
{
|
2015-08-19 18:07:04 +02:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_SOUND_DEVICE, uint32) != -1 && !gGameSoundsOff && gConfigSound.sound && !gOpenRCT2Headless) {
|
2014-09-15 23:12:25 +02:00
|
|
|
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = (rct_viewport*)-1;
|
|
|
|
rct_viewport* viewport = (rct_viewport*)-1;
|
2014-11-10 16:23:42 +01:00
|
|
|
rct_window* window = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*);
|
|
|
|
while (1) {
|
|
|
|
window--;
|
|
|
|
if (window < RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window)) {
|
|
|
|
break;
|
|
|
|
}
|
2014-09-15 23:12:25 +02:00
|
|
|
viewport = window->viewport;
|
|
|
|
if (viewport && viewport->flags & VIEWPORT_FLAG_SOUND_ON) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = viewport;
|
|
|
|
if (viewport != (rct_viewport*)-1) {
|
|
|
|
if (window) {
|
|
|
|
RCT2_GLOBAL(0x00F438A8, rct_window*) = window;
|
2014-10-04 00:28:39 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 0;
|
2014-09-15 23:12:25 +02:00
|
|
|
if (viewport->zoom) {
|
2014-10-04 00:28:39 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 35;
|
2014-09-15 23:12:25 +02:00
|
|
|
if (viewport->zoom != 1) {
|
2014-10-04 00:28:39 +02:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 70;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
gVehicleSoundParamsListEnd = &gVehicleSoundParamsList[0];
|
2014-09-15 23:12:25 +02:00
|
|
|
for (uint16 i = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16); i != SPRITE_INDEX_NULL; i = g_sprite_list[i].vehicle.next) {
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_update_sound_params(&g_sprite_list[i].vehicle);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
for(int i = 0; i < countof(gVehicleSoundList); i++){
|
|
|
|
rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[i];
|
2014-09-15 23:12:25 +02:00
|
|
|
if (vehicle_sound->id != (uint16)-1) {
|
2014-10-07 04:21:55 +02:00
|
|
|
for (rct_vehicle_sound_params* vehicle_sound_params = &gVehicleSoundParamsList[0]; vehicle_sound_params != gVehicleSoundParamsListEnd; vehicle_sound_params++) {
|
|
|
|
if (vehicle_sound->id == vehicle_sound_params->id) {
|
2014-09-15 23:12:25 +02:00
|
|
|
goto label26;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (vehicle_sound->sound1_id != (uint16)-1) {
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound1_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
if (vehicle_sound->sound2_id != (uint16)-1) {
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound2_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
vehicle_sound->id = (uint16)-1;
|
|
|
|
}
|
|
|
|
label26:
|
2015-04-12 23:26:15 +02:00
|
|
|
;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
|
2014-10-07 04:21:55 +02:00
|
|
|
for (rct_vehicle_sound_params* vehicle_sound_params = &gVehicleSoundParamsList[0]; ; vehicle_sound_params++) {
|
2014-09-22 20:35:47 +02:00
|
|
|
label28:
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle_sound_params >= gVehicleSoundParamsListEnd) {
|
2014-09-22 20:35:47 +02:00
|
|
|
return;
|
|
|
|
}
|
2014-10-04 00:28:39 +02:00
|
|
|
uint8 vol1 = 0xFF;
|
|
|
|
uint8 vol2 = 0xFF;
|
2015-11-16 23:39:40 +01:00
|
|
|
sint16 pan_y = vehicle_sound_params->pan_y;
|
|
|
|
if (pan_y < 0) {
|
|
|
|
pan_y = -pan_y;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (pan_y > 0xFFF) {
|
|
|
|
pan_y = 0xFFF;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
pan_y -= 0x800;
|
|
|
|
if (pan_y > 0) {
|
|
|
|
pan_y -= 0x400;
|
|
|
|
pan_y = -pan_y;
|
|
|
|
pan_y = pan_y / 4;
|
|
|
|
vol1 = LOBYTE(pan_y);
|
|
|
|
if ((sint8)HIBYTE(pan_y) != 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = 0xFF;
|
2015-11-16 23:39:40 +01:00
|
|
|
if ((sint8)HIBYTE(pan_y) < 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = 0;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-16 23:39:40 +01:00
|
|
|
sint16 pan_x = vehicle_sound_params->pan_x;
|
|
|
|
if (pan_x < 0) {
|
|
|
|
pan_x = -pan_x;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (pan_x > 0xFFF) {
|
|
|
|
pan_x = 0xFFF;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
pan_x -= 0x800;
|
|
|
|
if (pan_x > 0) {
|
|
|
|
pan_x -= 0x400;
|
|
|
|
pan_x = -pan_x;
|
|
|
|
pan_x = pan_x / 4;
|
|
|
|
vol2 = LOBYTE(pan_x);
|
|
|
|
if ((sint8)HIBYTE(pan_x) != 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol2 = 0xFF;
|
2015-11-16 23:39:40 +01:00
|
|
|
if ((sint8)HIBYTE(pan_x) < 0) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol2 = 0;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-04 00:28:39 +02:00
|
|
|
if (vol1 >= vol2) {
|
|
|
|
vol1 = vol2;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-04 00:28:39 +02:00
|
|
|
if (vol1 < RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8)) {
|
|
|
|
vol1 = 0;
|
2014-09-19 04:48:04 +02:00
|
|
|
} else {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = vol1 - RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
|
2014-10-16 04:02:56 +02:00
|
|
|
rct_vehicle_sound* vehicle_sound = &gVehicleSoundList[0];
|
2014-10-07 04:21:55 +02:00
|
|
|
while (vehicle_sound_params->id != vehicle_sound->id) {
|
2015-10-16 10:25:56 +02:00
|
|
|
vehicle_sound++;
|
2014-10-07 04:21:55 +02:00
|
|
|
if (vehicle_sound >= &gVehicleSoundList[countof(gVehicleSoundList)]) {
|
2014-10-16 04:02:56 +02:00
|
|
|
vehicle_sound = &gVehicleSoundList[0];
|
2014-09-15 23:12:25 +02:00
|
|
|
int i = 0;
|
|
|
|
while (vehicle_sound->id != (uint16)-1) {
|
|
|
|
vehicle_sound++;
|
|
|
|
i++;
|
2015-10-16 10:25:56 +02:00
|
|
|
if (i >= countof(gVehicleSoundList)) {
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound_params = (rct_vehicle_sound_params*)((int)vehicle_sound_params + 10);
|
2014-09-15 23:12:25 +02:00
|
|
|
goto label28;
|
|
|
|
}
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->id = vehicle_sound_params->id;
|
2014-09-15 23:12:25 +02:00
|
|
|
vehicle_sound->sound1_id = (uint16)-1;
|
|
|
|
vehicle_sound->sound2_id = (uint16)-1;
|
2014-10-16 04:02:56 +02:00
|
|
|
vehicle_sound->volume = 0x30;
|
2014-09-15 23:12:25 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-16 04:02:56 +02:00
|
|
|
int tempvolume = vehicle_sound->volume;
|
|
|
|
if (tempvolume != vehicle_sound_params->volume) {
|
|
|
|
if (tempvolume < vehicle_sound_params->volume) {
|
|
|
|
tempvolume += 4;
|
2014-09-15 23:12:25 +02:00
|
|
|
} else {
|
2014-10-16 04:02:56 +02:00
|
|
|
tempvolume -= 4;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
vehicle_sound->volume = tempvolume;
|
|
|
|
if (vol1 < tempvolume) {
|
2014-10-04 00:28:39 +02:00
|
|
|
vol1 = 0;
|
2014-09-19 04:48:04 +02:00
|
|
|
} else {
|
2014-10-16 04:02:56 +02:00
|
|
|
vol1 = vol1 - tempvolume;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-16 04:02:56 +02:00
|
|
|
|
2014-09-15 23:12:25 +02:00
|
|
|
// do sound1 stuff, track noise
|
2014-10-07 04:21:55 +02:00
|
|
|
rct_sprite* sprite = &g_sprite_list[vehicle_sound_params->id];
|
2014-10-16 04:02:56 +02:00
|
|
|
int volume = sprite->vehicle.sound1_volume;
|
2014-10-04 00:28:39 +02:00
|
|
|
volume *= vol1;
|
2014-10-16 04:02:56 +02:00
|
|
|
volume = volume / 8;
|
2014-09-15 23:12:25 +02:00
|
|
|
volume -= 0x1FFF;
|
|
|
|
if (volume < -10000) {
|
|
|
|
volume = -10000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound1_id == (uint8)-1) {
|
2014-09-15 23:12:25 +02:00
|
|
|
if (vehicle_sound->sound1_id != (uint16)-1) {
|
|
|
|
vehicle_sound->sound1_id = -1;
|
2015-10-20 20:16:30 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound1_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (vehicle_sound->sound1_id == (uint16)-1) {
|
|
|
|
goto label69;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound1_id != vehicle_sound->sound1_id) {
|
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound1_channel);
|
2014-09-15 23:12:25 +02:00
|
|
|
label69:
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound1_id = sprite->vehicle.sound1_id;
|
2015-11-16 23:39:40 +01:00
|
|
|
vehicle_sound->sound1_pan = vehicle_sound_params->pan_x;
|
2014-09-15 23:12:25 +02:00
|
|
|
vehicle_sound->sound1_volume = volume;
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound1_freq = vehicle_sound_params->frequency;
|
|
|
|
uint16 frequency = vehicle_sound_params->frequency;
|
|
|
|
if (RCT2_ADDRESS(0x009AF51F, uint8)[2 * sprite->vehicle.sound1_id] & 2) {
|
2014-09-15 23:12:25 +02:00
|
|
|
frequency = (frequency / 2) + 4000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
uint8 looping = RCT2_ADDRESS(0x009AF51E, uint8)[2 * sprite->vehicle.sound1_id];
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan = vehicle_sound_params->pan_x;
|
2014-10-08 07:00:11 +02:00
|
|
|
vehicle_sound->sound1_channel = Mixer_Play_Effect(sprite->vehicle.sound1_id, looping ? MIXER_LOOP_INFINITE : MIXER_LOOP_NONE, DStoMixerVolume(volume), DStoMixerPan(pan), DStoMixerRate(frequency), 0);
|
2014-09-15 23:12:25 +02:00
|
|
|
goto label87;
|
|
|
|
}
|
|
|
|
if (volume != vehicle_sound->sound1_volume) {
|
|
|
|
vehicle_sound->sound1_volume = volume;
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Volume(vehicle_sound->sound1_channel, DStoMixerVolume(volume));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (vehicle_sound_params->pan_x != vehicle_sound->sound1_pan) {
|
|
|
|
vehicle_sound->sound1_pan = vehicle_sound_params->pan_x;
|
|
|
|
Mixer_Channel_Pan(vehicle_sound->sound1_channel, DStoMixerPan(vehicle_sound_params->pan_x));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 3) && vehicle_sound_params->frequency != vehicle_sound->sound1_freq) {
|
|
|
|
vehicle_sound->sound1_freq = vehicle_sound_params->frequency;
|
|
|
|
uint16 frequency = vehicle_sound_params->frequency;
|
|
|
|
if (RCT2_GLOBAL(0x009AF51F, uint8*)[2 * sprite->vehicle.sound1_id] & 2) {
|
2014-09-15 23:12:25 +02:00
|
|
|
frequency = (frequency / 2) + 4000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Rate(vehicle_sound->sound1_channel, DStoMixerRate(frequency));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
|
|
|
label87: // do sound2 stuff, screams
|
2014-10-07 04:21:55 +02:00
|
|
|
sprite = &g_sprite_list[vehicle_sound_params->id];
|
|
|
|
volume = sprite->vehicle.sound2_volume;
|
2014-10-04 00:28:39 +02:00
|
|
|
volume *= vol1;
|
2014-09-17 21:44:29 +02:00
|
|
|
volume = (uint16)volume / 8;
|
|
|
|
volume -= 0x1FFF;
|
|
|
|
if (volume < -10000) {
|
|
|
|
volume = -10000;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound2_id == (uint8)-1) {
|
2014-09-17 21:44:29 +02:00
|
|
|
if (vehicle_sound->sound2_id != (uint16)-1) {
|
|
|
|
vehicle_sound->sound2_id = -1;
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound2_channel);
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (vehicle_sound->sound2_id == (uint16)-1) {
|
|
|
|
goto label93;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (sprite->vehicle.sound2_id != vehicle_sound->sound2_id) {
|
|
|
|
Mixer_Stop_Channel(vehicle_sound->sound2_channel);
|
2014-09-17 21:44:29 +02:00
|
|
|
label93:
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound2_id = sprite->vehicle.sound2_id;
|
2015-11-16 23:39:40 +01:00
|
|
|
vehicle_sound->sound2_pan = vehicle_sound_params->pan_x;
|
2014-09-17 21:44:29 +02:00
|
|
|
vehicle_sound->sound2_volume = volume;
|
2014-10-07 04:21:55 +02:00
|
|
|
vehicle_sound->sound2_freq = vehicle_sound_params->frequency;
|
|
|
|
uint16 frequency = vehicle_sound_params->frequency;
|
|
|
|
if (RCT2_ADDRESS(0x009AF51F, uint8)[2 * sprite->vehicle.sound2_id] & 1) {
|
2014-09-17 21:44:29 +02:00
|
|
|
frequency = 12649;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-09-17 21:44:29 +02:00
|
|
|
frequency = (frequency * 2) - 3248;
|
|
|
|
if (frequency > 25700) {
|
|
|
|
frequency = 25700;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
uint8 looping = RCT2_ADDRESS(0x009AF51E, uint8)[2 * sprite->vehicle.sound2_id];
|
2015-11-16 23:39:40 +01:00
|
|
|
int pan = vehicle_sound_params->pan_x;
|
2014-10-08 07:00:11 +02:00
|
|
|
vehicle_sound->sound2_channel = Mixer_Play_Effect(sprite->vehicle.sound2_id, looping ? MIXER_LOOP_INFINITE : MIXER_LOOP_NONE, DStoMixerVolume(volume), DStoMixerPan(pan), DStoMixerRate(frequency), 0);
|
2014-09-17 21:44:29 +02:00
|
|
|
goto label114;
|
|
|
|
}
|
|
|
|
if (volume != vehicle_sound->sound2_volume) {
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Volume(vehicle_sound->sound2_channel, DStoMixerVolume(volume));
|
|
|
|
vehicle_sound->sound2_volume = volume;
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
2015-11-16 23:39:40 +01:00
|
|
|
if (vehicle_sound_params->pan_x != vehicle_sound->sound2_pan) {
|
|
|
|
vehicle_sound->sound2_pan = vehicle_sound_params->pan_x;
|
|
|
|
Mixer_Channel_Pan(vehicle_sound->sound2_channel, DStoMixerPan(vehicle_sound_params->pan_x));
|
2014-09-17 21:44:29 +02:00
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 3) && vehicle_sound_params->frequency != vehicle_sound->sound2_freq) {
|
|
|
|
vehicle_sound->sound2_freq = vehicle_sound_params->frequency;
|
|
|
|
if (!(RCT2_ADDRESS(0x009AF51F, uint8)[2 * sprite->vehicle.sound2_id] & 1)) {
|
|
|
|
uint16 frequency = (vehicle_sound_params->frequency * 2) - 3248;
|
2014-09-15 23:12:25 +02:00
|
|
|
if (frequency > 25700) {
|
|
|
|
frequency = 25700;
|
|
|
|
}
|
2014-10-07 04:21:55 +02:00
|
|
|
Mixer_Channel_Rate(vehicle_sound->sound2_channel, DStoMixerRate(frequency));
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-09-17 21:44:29 +02:00
|
|
|
label114:
|
2015-04-12 23:26:15 +02:00
|
|
|
;
|
2014-09-15 23:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-05-25 19:40:11 +02:00
|
|
|
* rct2: 0x006D4204
|
|
|
|
*/
|
|
|
|
void vehicle_update_all()
|
|
|
|
{
|
|
|
|
uint16 sprite_index;
|
|
|
|
rct_vehicle *vehicle;
|
|
|
|
|
2015-03-26 21:48:42 +01:00
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR)
|
2014-05-25 19:40:11 +02:00
|
|
|
return;
|
|
|
|
|
2015-03-26 21:48:42 +01:00
|
|
|
if ((RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_DESIGNER) && RCT2_GLOBAL(0x0141F570, uint8) != 6)
|
2014-05-25 19:40:11 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
sprite_index = RCT2_GLOBAL(RCT2_ADDRESS_SPRITES_START_VEHICLE, uint16);
|
|
|
|
while (sprite_index != SPRITE_INDEX_NULL) {
|
2014-06-29 15:51:18 +02:00
|
|
|
vehicle = &(g_sprite_list[sprite_index].vehicle);
|
2014-05-25 19:40:11 +02:00
|
|
|
sprite_index = vehicle->next;
|
|
|
|
|
|
|
|
vehicle_update(vehicle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D6956
|
|
|
|
* @returns 0 when all closed
|
2015-04-12 18:28:55 +02:00
|
|
|
*/
|
|
|
|
static int vehicle_close_restraints(rct_vehicle* vehicle){
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-04-12 18:28:55 +02:00
|
|
|
int ebp = 0;
|
|
|
|
uint16 vehicle_id = vehicle->sprite_index;
|
|
|
|
|
|
|
|
do {
|
|
|
|
vehicle = GET_VEHICLE(vehicle_id);
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_BROKEN_CAR &&
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->restraints_position != 0 &&
|
2015-04-12 18:28:55 +02:00
|
|
|
(
|
|
|
|
ride->breakdown_reason_pending == BREAKDOWN_RESTRAINTS_STUCK_OPEN ||
|
|
|
|
ride->breakdown_reason_pending == BREAKDOWN_DOORS_STUCK_OPEN)
|
|
|
|
){
|
|
|
|
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)){
|
|
|
|
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_BROKEN_DOWN;
|
|
|
|
|
|
|
|
ride_breakdown_add_news_item(vehicle->ride);
|
|
|
|
|
|
|
|
ride->window_invalidate_flags |=
|
|
|
|
RIDE_INVALIDATE_RIDE_MAIN |
|
|
|
|
RIDE_INVALIDATE_RIDE_LIST |
|
|
|
|
RIDE_INVALIDATE_RIDE_MAINTENANCE;
|
|
|
|
|
|
|
|
ride->mechanic_status = RIDE_MECHANIC_STATUS_CALLING;
|
|
|
|
|
|
|
|
rct_vehicle* broken_vehicle = GET_VEHICLE(ride->vehicles[ride->broken_vehicle]);
|
|
|
|
ride->inspection_station = broken_vehicle->current_station;
|
|
|
|
|
|
|
|
ride->breakdown_reason = ride->breakdown_reason_pending;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
2015-11-19 19:44:24 +01:00
|
|
|
if (vehicle->restraints_position - 20 < 0){
|
|
|
|
vehicle->restraints_position = 0;
|
2015-04-12 18:28:55 +02:00
|
|
|
continue;
|
|
|
|
}
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->restraints_position -= 20;
|
2015-12-12 11:21:49 +01:00
|
|
|
}
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-04-12 18:28:55 +02:00
|
|
|
ebp++;
|
|
|
|
} while ((vehicle_id = vehicle->next_vehicle_on_train) != 0xFFFF);
|
|
|
|
|
|
|
|
return ebp;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D6A2C
|
|
|
|
* @returns 0 when all open
|
2015-04-12 18:28:55 +02:00
|
|
|
*/
|
|
|
|
static int vehicle_open_restraints(rct_vehicle* vehicle){
|
2015-04-08 19:48:17 +02:00
|
|
|
int ebp = 0;
|
|
|
|
uint16 vehicle_id = vehicle->sprite_index;
|
|
|
|
|
|
|
|
do {
|
|
|
|
vehicle = GET_VEHICLE(vehicle_id);
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->swinging_car_var_0 = 0;
|
2015-04-08 19:48:17 +02:00
|
|
|
vehicle->var_4E = 0;
|
|
|
|
vehicle->var_4A = 0;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-04-08 19:48:17 +02:00
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SPINNING) {
|
2015-11-19 19:44:24 +01:00
|
|
|
if (abs(vehicle->var_B6) <= 700 &&
|
|
|
|
!(vehicle->var_BA & 0x30) &&
|
|
|
|
(
|
2015-12-16 20:12:58 +01:00
|
|
|
!(vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_14) ||
|
2015-11-19 19:44:24 +01:00
|
|
|
!(vehicle->var_BA & 0xF8))
|
|
|
|
){
|
|
|
|
vehicle->var_B6 = 0;
|
2015-04-08 19:48:17 +02:00
|
|
|
}
|
2015-11-19 19:44:24 +01:00
|
|
|
else {
|
|
|
|
ebp++;
|
2015-04-08 19:48:17 +02:00
|
|
|
|
2015-11-19 19:44:24 +01:00
|
|
|
if (abs(vehicle->var_B6) < 600) {
|
|
|
|
vehicle->var_B6 = 600;
|
|
|
|
}
|
|
|
|
sint16 value = vehicle->var_B6 / 256;
|
|
|
|
vehicle->var_BA += value;
|
|
|
|
vehicle->var_B6 -= value;
|
2015-04-08 19:48:17 +02:00
|
|
|
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-19 19:44:24 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2015-11-18 21:12:24 +01:00
|
|
|
if (vehicleEntry->var_11 == 6 &&
|
2015-04-08 19:48:17 +02:00
|
|
|
vehicle->var_C5 != 0){
|
|
|
|
|
|
|
|
if (vehicle->var_C8 + 0x3333 < 0xFFFF){
|
|
|
|
vehicle->var_C8 = vehicle->var_C8 + 0x3333 - 0xFFFF;
|
|
|
|
vehicle->var_C5++;
|
|
|
|
vehicle->var_C5 &= 7;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-04-08 19:48:17 +02:00
|
|
|
}
|
|
|
|
else{
|
|
|
|
vehicle->var_C8 += 0x3333;
|
|
|
|
}
|
|
|
|
ebp++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-04-12 17:47:02 +02:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_BROKEN_CAR &&
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->restraints_position != 0xFF &&
|
2015-04-08 19:48:17 +02:00
|
|
|
(
|
|
|
|
ride->breakdown_reason_pending == BREAKDOWN_RESTRAINTS_STUCK_CLOSED ||
|
|
|
|
ride->breakdown_reason_pending == BREAKDOWN_DOORS_STUCK_CLOSED)
|
|
|
|
){
|
|
|
|
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)){
|
|
|
|
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_BROKEN_DOWN;
|
|
|
|
|
|
|
|
ride_breakdown_add_news_item(vehicle->ride);
|
|
|
|
|
|
|
|
ride->window_invalidate_flags |=
|
|
|
|
RIDE_INVALIDATE_RIDE_MAIN |
|
|
|
|
RIDE_INVALIDATE_RIDE_LIST |
|
|
|
|
RIDE_INVALIDATE_RIDE_MAINTENANCE;
|
|
|
|
|
|
|
|
ride->mechanic_status = RIDE_MECHANIC_STATUS_CALLING;
|
|
|
|
|
|
|
|
rct_vehicle* broken_vehicle = GET_VEHICLE(ride->vehicles[ride->broken_vehicle]);
|
|
|
|
ride->inspection_station = broken_vehicle->current_station;
|
|
|
|
|
|
|
|
ride->breakdown_reason = ride->breakdown_reason_pending;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
2015-11-19 19:44:24 +01:00
|
|
|
if (vehicle->restraints_position + 20 > 0xFF){
|
|
|
|
vehicle->restraints_position = 255;
|
2015-04-08 19:48:17 +02:00
|
|
|
continue;
|
|
|
|
}
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->restraints_position += 20;
|
2015-04-08 19:48:17 +02:00
|
|
|
}
|
2016-01-09 17:17:04 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
ebp++;
|
2015-04-08 19:48:17 +02:00
|
|
|
} while ((vehicle_id = vehicle->next_vehicle_on_train) != 0xFFFF);
|
|
|
|
|
2015-04-12 18:28:55 +02:00
|
|
|
return ebp;
|
2015-04-08 19:48:17 +02:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D6D1F
|
|
|
|
*/
|
2015-04-05 16:57:08 +02:00
|
|
|
static void vehicle_update_measurements(rct_vehicle *vehicle)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
|
|
|
rct_ride *ride;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
ride = get_ride(vehicle->ride);
|
2015-04-05 10:38:37 +02:00
|
|
|
|
2015-12-11 14:07:22 +01:00
|
|
|
if (vehicle->status == VEHICLE_STATUS_TRAVELLING_BOAT){
|
2015-04-05 10:38:37 +02:00
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_TESTED;
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_NO_RAW_STATS;
|
|
|
|
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_TEST_IN_PROGRESS;
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_TESTING;
|
2015-04-05 10:38:37 +02:00
|
|
|
window_invalidate_by_number(WC_RIDE, vehicle->ride);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-02-17 19:22:38 +01:00
|
|
|
uint8 stationId = ride->current_test_station;
|
|
|
|
if (ride->entrances[stationId] != 0xFFFF){
|
2015-11-28 19:13:22 +01:00
|
|
|
uint8 test_segment = ride->current_test_segment;
|
2015-04-05 10:38:37 +02:00
|
|
|
|
2016-02-18 21:58:22 +01:00
|
|
|
ride->average_speed_test_timeout++;
|
|
|
|
if (ride->average_speed_test_timeout >= 32)ride->average_speed_test_timeout = 0;
|
2015-04-05 10:38:37 +02:00
|
|
|
|
|
|
|
sint32 velocity = abs(vehicle->velocity);
|
|
|
|
if (velocity > ride->max_speed){
|
|
|
|
ride->max_speed = velocity;
|
|
|
|
}
|
|
|
|
|
2016-02-18 21:58:22 +01:00
|
|
|
if (ride->average_speed_test_timeout == 0 && velocity > 0x8000){
|
2015-04-05 10:38:37 +02:00
|
|
|
ride->average_speed += velocity;
|
2015-11-28 19:13:22 +01:00
|
|
|
ride->time[test_segment]++;
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
sint32 distance = abs(((vehicle->velocity + vehicle->acceleration) >> 10) * 42);
|
2015-04-05 16:57:08 +02:00
|
|
|
if (vehicle->var_CE == 0){
|
2015-11-28 19:13:22 +01:00
|
|
|
ride->length[test_segment] += distance;
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
|
|
|
|
2016-01-15 00:04:17 +01:00
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_G_FORCES)){
|
2015-04-05 10:38:37 +02:00
|
|
|
int vertical_g, lateral_g;
|
|
|
|
vehicle_get_g_forces(vehicle, &vertical_g, &lateral_g);
|
|
|
|
|
|
|
|
vertical_g += ride->previous_vertical_g;
|
|
|
|
lateral_g += ride->previous_lateral_g;
|
2015-11-17 22:49:45 +01:00
|
|
|
vertical_g >>= 1;
|
|
|
|
lateral_g >>= 1;
|
2015-04-05 10:38:37 +02:00
|
|
|
|
|
|
|
ride->previous_vertical_g = vertical_g;
|
|
|
|
ride->previous_lateral_g = lateral_g;
|
|
|
|
|
|
|
|
if (vertical_g <= 0){
|
|
|
|
ride->total_air_time++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vertical_g > ride->max_positive_vertical_g)
|
|
|
|
ride->max_positive_vertical_g = vertical_g;
|
|
|
|
|
|
|
|
if (vertical_g < ride->max_negative_vertical_g)
|
|
|
|
ride->max_negative_vertical_g = vertical_g;
|
|
|
|
|
|
|
|
lateral_g = abs(lateral_g);
|
|
|
|
|
|
|
|
if (lateral_g > ride->max_lateral_g)
|
|
|
|
ride->max_lateral_g = lateral_g;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-18 21:58:22 +01:00
|
|
|
// If we have already evaluated this track piece skip to next section
|
2015-06-08 20:07:30 +02:00
|
|
|
uint16 map_location = (vehicle->track_x / 32) | ((vehicle->track_y / 32) << 8);
|
2016-02-18 21:58:22 +01:00
|
|
|
if (vehicle->track_z / 8 != ride->cur_test_track_z || map_location != ride->cur_test_track_location.xy){
|
|
|
|
ride->cur_test_track_z = vehicle->track_z / 8;
|
|
|
|
ride->cur_test_track_location.xy = map_location;
|
2015-04-05 10:38:37 +02:00
|
|
|
|
2016-02-17 19:22:38 +01:00
|
|
|
if (ride->entrances[ride->current_test_station] == 0xFFFF)
|
2015-04-05 19:28:42 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
uint16 track_elem_type = vehicle->track_type / 4;
|
2015-11-17 22:49:45 +01:00
|
|
|
if (track_elem_type == TRACK_ELEM_POWERED_LIFT || (vehicle->update_flags & VEHICLE_UPDATE_FLAG_0)){
|
2015-04-05 21:22:27 +02:00
|
|
|
if (!(ride->testing_flags & RIDE_TESTING_POWERED_LIFT)){
|
|
|
|
ride->testing_flags |= RIDE_TESTING_POWERED_LIFT;
|
2015-04-05 19:28:42 +02:00
|
|
|
if (ride->drops + 64 < 0xFF){
|
|
|
|
ride->drops += 64;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else{
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags &= ~RIDE_TESTING_POWERED_LIFT;
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-04-05 13:36:02 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (ride->type == RIDE_TYPE_WATER_COASTER){
|
|
|
|
if (track_elem_type >= TRACK_ELEM_FLAT_COVERED && track_elem_type <= TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_COVERED){
|
2015-04-05 16:57:08 +02:00
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-04-05 10:38:37 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
switch (track_elem_type)
|
|
|
|
{
|
|
|
|
case TRACK_ELEM_RAPIDS:
|
|
|
|
case TRACK_ELEM_SPINNING_TUNNEL:
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_WATERFALL:
|
|
|
|
case TRACK_ELEM_LOG_FLUME_REVERSER:
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_REVERSER_OR_WATERFALL;
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_WHIRLPOOL:
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_WHIRLPOOL;
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_WATER_SPLASH:
|
|
|
|
if (vehicle->velocity >= 0xB0000){
|
|
|
|
ride->special_track_elements |= RIDE_ELEMENT_TUNNEL_SPLASH_OR_RAPIDS;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-04-05 13:36:02 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
// ax
|
|
|
|
uint16 track_flags = RCT2_ADDRESS(0x0099423C, uint16)[track_elem_type];
|
2015-04-05 13:36:02 +02:00
|
|
|
|
2015-04-05 21:22:27 +02:00
|
|
|
uint32 testing_flags = ride->testing_flags;
|
2015-12-12 11:21:49 +01:00
|
|
|
if (testing_flags & RIDE_TESTING_TURN_LEFT &&
|
2015-04-05 21:22:27 +02:00
|
|
|
track_flags & TRACK_ELEM_FLAG_TURN_LEFT){
|
|
|
|
// 0x800 as this is masked to CURRENT_TURN_COUNT_MASK
|
|
|
|
ride->turn_count_default += 0x800;
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
else if (testing_flags & RIDE_TESTING_TURN_RIGHT &&
|
2015-04-05 21:22:27 +02:00
|
|
|
track_flags & TRACK_ELEM_FLAG_TURN_RIGHT){
|
|
|
|
// 0x800 as this is masked to CURRENT_TURN_COUNT_MASK
|
|
|
|
ride->turn_count_default += 0x800;
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
else if (testing_flags & RIDE_TESTING_TURN_RIGHT ||
|
2015-04-05 21:22:27 +02:00
|
|
|
testing_flags & RIDE_TESTING_TURN_LEFT){
|
|
|
|
|
|
|
|
ride->testing_flags &= ~(
|
2015-12-12 11:21:49 +01:00
|
|
|
RIDE_TESTING_TURN_LEFT |
|
|
|
|
RIDE_TESTING_TURN_RIGHT |
|
|
|
|
RIDE_TESTING_TURN_BANKED |
|
2015-04-05 21:22:27 +02:00
|
|
|
RIDE_TESTING_TURN_SLOPED);
|
|
|
|
|
|
|
|
uint8 turn_type = 1;
|
|
|
|
if (!(testing_flags & RIDE_TESTING_TURN_BANKED)){
|
|
|
|
turn_type = 2;
|
|
|
|
if (!(testing_flags & RIDE_TESTING_TURN_SLOPED)){
|
|
|
|
turn_type = 0;
|
2015-04-05 13:36:02 +02:00
|
|
|
}
|
|
|
|
}
|
2015-04-05 21:22:27 +02:00
|
|
|
switch (ride->turn_count_default >> 11){
|
2015-04-05 19:28:42 +02:00
|
|
|
case 0:
|
2015-04-05 21:22:27 +02:00
|
|
|
increment_turn_count_1_element(ride, turn_type);
|
2015-04-05 19:28:42 +02:00
|
|
|
break;
|
|
|
|
case 1:
|
2015-04-05 21:22:27 +02:00
|
|
|
increment_turn_count_2_elements(ride, turn_type);
|
2015-04-05 19:28:42 +02:00
|
|
|
break;
|
|
|
|
case 2:
|
2015-04-05 21:22:27 +02:00
|
|
|
increment_turn_count_3_elements(ride, turn_type);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-04-05 21:22:27 +02:00
|
|
|
default:
|
|
|
|
increment_turn_count_4_plus_elements(ride, turn_type);
|
2015-04-05 19:28:42 +02:00
|
|
|
break;
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_LEFT){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags |= RIDE_TESTING_TURN_LEFT;
|
|
|
|
ride->turn_count_default &= ~CURRENT_TURN_COUNT_MASK;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_BANKED){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags |= RIDE_TESTING_TURN_BANKED;
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_SLOPED){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags |= RIDE_TESTING_TURN_SLOPED;
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_RIGHT){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags |= RIDE_TESTING_TURN_RIGHT;
|
|
|
|
ride->turn_count_default &= ~CURRENT_TURN_COUNT_MASK;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_BANKED){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags |= RIDE_TESTING_TURN_BANKED;
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_TURN_SLOPED){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags |= RIDE_TESTING_TURN_SLOPED;
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-04-05 21:22:27 +02:00
|
|
|
if (testing_flags & RIDE_TESTING_DROP_DOWN){
|
2015-04-05 19:28:42 +02:00
|
|
|
if (vehicle->velocity < 0 || !(track_flags & TRACK_ELEM_FLAG_DOWN)){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags &= ~RIDE_TESTING_DROP_DOWN;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
sint16 z = vehicle->z / 8 - ride->start_drop_height;
|
|
|
|
if (z < 0){
|
|
|
|
z = abs(z);
|
|
|
|
if (z > ride->highest_drop_height){
|
|
|
|
ride->highest_drop_height = (uint8)z;
|
|
|
|
}
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else if (track_flags & TRACK_ELEM_FLAG_DOWN && vehicle->velocity >= 0){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags &= ~RIDE_TESTING_DROP_UP;
|
|
|
|
ride->testing_flags |= RIDE_TESTING_DROP_DOWN;
|
2015-04-05 19:28:42 +02:00
|
|
|
|
|
|
|
uint8 drops = ride->drops & 0x3F;
|
|
|
|
if (drops != 0x3F)
|
|
|
|
drops++;
|
|
|
|
ride->drops &= ~0x3F;
|
|
|
|
ride->drops |= drops;
|
|
|
|
|
|
|
|
ride->start_drop_height = vehicle->z / 8;
|
2015-04-05 21:22:27 +02:00
|
|
|
testing_flags &= ~RIDE_TESTING_DROP_UP;
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 21:22:27 +02:00
|
|
|
if (testing_flags & RIDE_TESTING_DROP_UP){
|
2015-04-05 19:28:42 +02:00
|
|
|
if (vehicle->velocity > 0 || !(track_flags & TRACK_ELEM_FLAG_UP)){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags &= ~RIDE_TESTING_DROP_UP;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
sint16 z = vehicle->z / 8 - ride->start_drop_height;
|
|
|
|
if (z < 0){
|
|
|
|
z = abs(z);
|
|
|
|
if (z > ride->highest_drop_height){
|
|
|
|
ride->highest_drop_height = (uint8)z;
|
|
|
|
}
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
2015-04-05 19:28:42 +02:00
|
|
|
}
|
|
|
|
else if (track_flags & TRACK_ELEM_FLAG_UP && vehicle->velocity <= 0){
|
2015-04-05 21:22:27 +02:00
|
|
|
ride->testing_flags &= ~RIDE_TESTING_DROP_DOWN;
|
|
|
|
ride->testing_flags |= RIDE_TESTING_DROP_UP;
|
2015-04-05 19:28:42 +02:00
|
|
|
|
|
|
|
uint8 drops = ride->drops & 0x3F;
|
|
|
|
if (drops != 0x3F)
|
|
|
|
drops++;
|
|
|
|
ride->drops &= ~0x3F;
|
|
|
|
ride->drops |= drops;
|
|
|
|
|
|
|
|
ride->start_drop_height = vehicle->z / 8;
|
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
if (track_flags & TRACK_ELEM_FLAG_INVERSION){
|
|
|
|
uint8 inversions = ride->inversions & 0x1F;
|
|
|
|
if (inversions != 0x1F)
|
|
|
|
inversions++;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-04-05 19:28:42 +02:00
|
|
|
ride->inversions &= ~0x1F;
|
|
|
|
ride->inversions |= inversions;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (track_flags & TRACK_ELEM_FLAG_HELIX){
|
|
|
|
uint8 helixes = ride_get_helix_sections(ride);
|
|
|
|
if (helixes != 0x1F)
|
|
|
|
helixes++;
|
|
|
|
|
|
|
|
ride->special_track_elements &= ~0x1F;
|
|
|
|
ride->special_track_elements |= helixes;
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-04-05 10:38:37 +02:00
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2016-02-17 19:22:38 +01:00
|
|
|
if (ride->entrances[ride->current_test_station] == 0xFFFF)
|
2015-04-05 16:57:08 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
sint16 x, y;
|
|
|
|
x = vehicle->x;
|
|
|
|
y = vehicle->y;
|
|
|
|
|
|
|
|
if (x == SPRITE_LOCATION_NULL){
|
2015-04-07 19:44:55 +02:00
|
|
|
ride->testing_flags &= ~RIDE_TESTING_SHELTERED;
|
2015-04-05 16:57:08 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_map_element* map_element = map_get_surface_element_at(x / 32, y / 32);
|
2015-04-05 22:51:49 +02:00
|
|
|
if (map_element->base_height * 8 <= vehicle->z){
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-11-18 20:26:01 +01:00
|
|
|
bool cover_found = false;
|
|
|
|
do{
|
|
|
|
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_SCENERY_MULTIPLE) {
|
|
|
|
cover_found = true;
|
2015-04-05 16:57:08 +02:00
|
|
|
break;
|
2015-11-18 20:26:01 +01:00
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
2015-11-18 20:26:01 +01:00
|
|
|
if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_PATH) {
|
|
|
|
cover_found = true;
|
2015-04-05 16:57:08 +02:00
|
|
|
break;
|
2015-11-18 20:26:01 +01:00
|
|
|
}
|
2015-04-05 16:57:08 +02:00
|
|
|
|
|
|
|
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY)
|
|
|
|
continue;
|
|
|
|
|
2015-11-18 20:26:01 +01:00
|
|
|
rct_scenery_entry* scenery = g_smallSceneryEntries[map_element->properties.scenery.type];
|
|
|
|
if (scenery->small_scenery.flags & SMALL_SCENERY_FLAG_FULL_TILE) {
|
|
|
|
cover_found = true;
|
2015-04-05 16:57:08 +02:00
|
|
|
break;
|
2015-11-18 20:26:01 +01:00
|
|
|
}
|
|
|
|
} while (!map_element_is_last_for_tile(map_element++));
|
|
|
|
|
|
|
|
if (cover_found == false) {
|
2015-11-18 21:12:24 +01:00
|
|
|
ride->testing_flags &= ~RIDE_TESTING_SHELTERED;
|
|
|
|
return;
|
2015-04-05 16:57:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-07 19:44:55 +02:00
|
|
|
if (!(ride->testing_flags & RIDE_TESTING_SHELTERED)){
|
|
|
|
ride->testing_flags |= RIDE_TESTING_SHELTERED;
|
2015-04-05 16:57:08 +02:00
|
|
|
|
|
|
|
uint8 num_sheltered_sections = ride->num_sheltered_sections & 0x1F;
|
|
|
|
if (num_sheltered_sections != 0x1F)
|
|
|
|
num_sheltered_sections++;
|
|
|
|
ride->num_sheltered_sections &= ~0x1F;
|
|
|
|
ride->num_sheltered_sections |= num_sheltered_sections;
|
|
|
|
|
|
|
|
if (vehicle->var_1F != 0){
|
|
|
|
ride->num_sheltered_sections |= (1 << 5);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->var_20 != 0){
|
|
|
|
ride->num_sheltered_sections |= (1 << 6);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
sint32 distance = ((vehicle->velocity + vehicle->acceleration) >> 10) * 42;
|
2015-04-05 16:57:08 +02:00
|
|
|
if (distance < 0)return;
|
|
|
|
|
|
|
|
ride->sheltered_length += distance;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
static uint16 sub_6D7AC0(int currentSoundId, int currentVolume, int targetSoundId, int targetVolume)
|
2014-11-12 00:05:04 +01:00
|
|
|
{
|
2014-11-12 02:04:50 +01:00
|
|
|
if (currentSoundId != 255) {
|
|
|
|
if (currentSoundId == targetSoundId) {
|
|
|
|
currentVolume = min(currentVolume + 15, targetVolume);
|
|
|
|
return (currentVolume << 8) | currentSoundId;
|
2014-11-12 00:05:04 +01:00
|
|
|
} else {
|
2014-11-12 02:04:50 +01:00
|
|
|
currentVolume -= 9;
|
|
|
|
if (currentVolume >= 80)
|
|
|
|
return (currentVolume << 8) | currentSoundId;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
// Begin sound at quarter volume
|
|
|
|
currentSoundId = targetSoundId;
|
|
|
|
currentVolume = targetVolume == 255 ? 255 : targetVolume / 4;
|
2014-11-12 00:05:04 +01:00
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
return (currentVolume << 8) | currentSoundId;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-05-25 19:40:11 +02:00
|
|
|
/**
|
2015-10-20 20:16:30 +02:00
|
|
|
*
|
2014-05-25 19:40:11 +02:00
|
|
|
* rct2: 0x006D77F2
|
|
|
|
*/
|
|
|
|
static void vehicle_update(rct_vehicle *vehicle)
|
|
|
|
{
|
2014-11-12 00:05:04 +01:00
|
|
|
rct_ride *ride;
|
|
|
|
rct_ride_type *rideEntry;
|
|
|
|
|
2015-11-30 22:11:22 +01:00
|
|
|
// The cable lift uses the ride type of NULL
|
2015-04-07 20:05:41 +02:00
|
|
|
if (vehicle->ride_subtype == RIDE_TYPE_NULL) {
|
2015-12-16 19:37:45 +01:00
|
|
|
cable_lift_update(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2014-11-12 00:05:04 +01:00
|
|
|
|
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
ride = get_ride(vehicle->ride);
|
2015-04-12 17:47:02 +02:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_TESTING)
|
2015-04-05 16:57:08 +02:00
|
|
|
vehicle_update_measurements(vehicle);
|
2014-11-12 00:05:04 +01:00
|
|
|
|
|
|
|
RCT2_GLOBAL(0x00F64E34, uint8) = 255;
|
|
|
|
if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN)) {
|
|
|
|
RCT2_GLOBAL(0x00F64E34, uint8) = ride->breakdown_reason_pending;
|
2015-12-16 20:12:58 +01:00
|
|
|
if ((vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3) && ride->breakdown_reason_pending == BREAKDOWN_SAFETY_CUT_OUT) {
|
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_13) ||
|
2014-11-12 00:05:04 +01:00
|
|
|
(
|
|
|
|
vehicle->var_1F == 2 &&
|
|
|
|
vehicle->velocity <= 0x20000
|
|
|
|
)
|
|
|
|
) {
|
2015-04-12 18:47:52 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_7;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
switch (vehicle->status) {
|
|
|
|
case VEHICLE_STATUS_MOVING_TO_END_OF_STATION:
|
2015-04-07 22:28:11 +02:00
|
|
|
vehicle_update_moving_to_end_of_station(vehicle);
|
|
|
|
break;
|
2014-11-12 02:32:20 +01:00
|
|
|
case VEHICLE_STATUS_WAITING_FOR_PASSENGERS:
|
2015-04-08 19:48:17 +02:00
|
|
|
vehicle_update_waiting_for_passengers(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
|
|
|
case VEHICLE_STATUS_WAITING_TO_DEPART:
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle_update_waiting_to_depart(vehicle);
|
|
|
|
break;
|
2015-11-20 01:04:07 +01:00
|
|
|
case VEHICLE_STATUS_CRASHING:
|
|
|
|
case VEHICLE_STATUS_CRASHED:
|
|
|
|
vehicle_update_crash(vehicle);
|
2015-04-08 19:48:17 +02:00
|
|
|
break;
|
2015-11-30 22:11:22 +01:00
|
|
|
case VEHICLE_STATUS_TRAVELLING_BUMPER_CARS:
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle_update_bumpcar_mode(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-11-21 12:35:02 +01:00
|
|
|
case VEHICLE_STATUS_SWINGING:
|
|
|
|
vehicle_update_swinging(vehicle);
|
2015-11-21 11:46:24 +01:00
|
|
|
break;
|
2015-11-21 13:13:10 +01:00
|
|
|
case VEHICLE_STATUS_SIMULATOR_OPERATING:
|
|
|
|
vehicle_update_simulator_operating(vehicle);
|
|
|
|
break;
|
2015-11-21 17:16:05 +01:00
|
|
|
case VEHICLE_STATUS_TOP_SPIN_OPERATING:
|
|
|
|
vehicle_update_top_spin_operating(vehicle);
|
|
|
|
break;
|
2015-11-25 20:55:04 +01:00
|
|
|
case VEHICLE_STATUS_FERRIS_WHEEL_ROTATING:
|
|
|
|
vehicle_update_ferris_wheel_rotating(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-11-25 21:26:15 +01:00
|
|
|
case VEHICLE_STATUS_SPACE_RINGS_OPERATING:
|
|
|
|
vehicle_update_space_rings_operating(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-11-25 21:26:15 +01:00
|
|
|
case VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING:
|
|
|
|
vehicle_update_haunted_house_operating(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-11-25 21:39:59 +01:00
|
|
|
case VEHICLE_STATUS_CROOKED_HOUSE_OPERATING:
|
|
|
|
vehicle_update_crooked_house_operating(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-11-25 23:25:13 +01:00
|
|
|
case VEHICLE_STATUS_ROTATING:
|
|
|
|
vehicle_update_rotating(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2014-11-12 02:32:20 +01:00
|
|
|
case VEHICLE_STATUS_DEPARTING:
|
2015-11-28 19:13:22 +01:00
|
|
|
vehicle_update_departing(vehicle);
|
|
|
|
break;
|
2014-11-12 02:32:20 +01:00
|
|
|
case VEHICLE_STATUS_TRAVELLING:
|
2015-11-29 15:42:04 +01:00
|
|
|
vehicle_update_travelling(vehicle);
|
|
|
|
break;
|
2015-12-11 14:07:22 +01:00
|
|
|
case VEHICLE_STATUS_TRAVELLING_CABLE_LIFT:
|
|
|
|
vehicle_update_travelling_cable_lift(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-12-11 14:07:22 +01:00
|
|
|
case VEHICLE_STATUS_TRAVELLING_BOAT:
|
|
|
|
vehicle_update_travelling_boat(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2014-11-12 02:32:20 +01:00
|
|
|
case VEHICLE_STATUS_ARRIVING:
|
2015-12-11 16:49:21 +01:00
|
|
|
vehicle_update_arriving(vehicle);
|
|
|
|
break;
|
2014-11-12 02:32:20 +01:00
|
|
|
case VEHICLE_STATUS_UNLOADING_PASSENGERS:
|
2015-12-11 18:35:24 +01:00
|
|
|
vehicle_update_unloading_passengers(vehicle);
|
2014-11-12 02:32:20 +01:00
|
|
|
break;
|
2015-11-19 21:53:13 +01:00
|
|
|
case VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT:
|
|
|
|
vehicle_update_waiting_for_cable_lift(vehicle);
|
|
|
|
break;
|
2015-11-19 21:28:07 +01:00
|
|
|
case VEHICLE_STATUS_SHOWING_FILM:
|
|
|
|
vehicle_update_showing_film(vehicle);
|
|
|
|
break;
|
2014-11-12 02:32:20 +01:00
|
|
|
case VEHICLE_STATUS_DOING_CIRCUS_SHOW:
|
|
|
|
vehicle_update_doing_circus_show(vehicle);
|
|
|
|
}
|
2014-11-12 00:05:04 +01:00
|
|
|
|
|
|
|
vehicle_update_sound(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-04-07 22:28:11 +02:00
|
|
|
/**
|
2015-12-16 19:37:45 +01:00
|
|
|
*
|
|
|
|
* rct2: 0x006D7BCC
|
|
|
|
*/
|
2015-04-07 22:28:11 +02:00
|
|
|
static void vehicle_update_moving_to_end_of_station(rct_vehicle *vehicle){
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-04-07 22:28:11 +02:00
|
|
|
int eax, ebx;
|
|
|
|
|
|
|
|
switch (ride->mode){
|
|
|
|
case RIDE_MODE_UPWARD_LAUNCH:
|
|
|
|
case RIDE_MODE_ROTATING_LIFT:
|
|
|
|
case RIDE_MODE_DOWNWARD_LAUNCH:
|
|
|
|
case RIDE_MODE_FREEFALL_DROP:
|
|
|
|
if (vehicle->velocity >= -131940){
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -3298;
|
2015-04-07 22:28:11 +02:00
|
|
|
}
|
|
|
|
if (vehicle->velocity < -131940){
|
|
|
|
vehicle->velocity = vehicle->velocity / 16;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
}
|
|
|
|
|
2015-12-15 19:56:19 +01:00
|
|
|
eax = vehicle_update_track_motion(vehicle, &ebx);
|
2015-04-07 22:28:11 +02:00
|
|
|
if (!(eax&(1 << 5)))
|
|
|
|
break;
|
|
|
|
//Fall through to next case
|
|
|
|
case RIDE_MODE_BUMPERCAR:
|
|
|
|
case RIDE_MODE_SWING:
|
|
|
|
case RIDE_MODE_ROTATION:
|
|
|
|
case RIDE_MODE_FORWARD_ROTATION:
|
|
|
|
case RIDE_MODE_BACKWARD_ROTATION:
|
|
|
|
case RIDE_MODE_FILM_AVENGING_AVIATORS:
|
|
|
|
case RIDE_MODE_FILM_THRILL_RIDERS:
|
|
|
|
case RIDE_MODE_BEGINNERS:
|
|
|
|
case RIDE_MODE_INTENSE:
|
|
|
|
case RIDE_MODE_BERSERK:
|
|
|
|
case RIDE_MODE_3D_FILM_MOUSE_TAILS:
|
|
|
|
case RIDE_MODE_3D_FILM_STORM_CHASERS:
|
|
|
|
case RIDE_MODE_3D_FILM_SPACE_RAIDERS:
|
|
|
|
case RIDE_MODE_SPACE_RINGS:
|
|
|
|
case RIDE_MODE_HAUNTED_HOUSE:
|
|
|
|
case RIDE_MODE_CROOKED_HOUSE:
|
|
|
|
case RIDE_MODE_CIRCUS_SHOW:
|
|
|
|
vehicle->current_station = 0;
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-04-07 22:28:11 +02:00
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3)){
|
2015-04-07 22:28:11 +02:00
|
|
|
if (vehicle->velocity <= 131940){
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 3298;
|
2015-04-07 22:28:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (vehicle->velocity > 131940){
|
|
|
|
vehicle->velocity = vehicle->velocity / 16;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int station;
|
2015-12-15 19:56:19 +01:00
|
|
|
eax = vehicle_update_track_motion(vehicle, &station);
|
2015-04-07 22:28:11 +02:00
|
|
|
|
|
|
|
if (eax & (1 << 1)){
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state++;
|
2015-04-07 22:28:11 +02:00
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_RACE &&
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state >= 40){
|
2015-04-07 22:28:11 +02:00
|
|
|
vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
if (vehicle->velocity > 98955){
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(eax & (1 << 0)))
|
|
|
|
break;
|
|
|
|
|
|
|
|
vehicle->current_station = station;
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 0;
|
2015-04-07 22:28:11 +02:00
|
|
|
vehicle_invalidate_window(vehicle);
|
2015-12-12 11:21:49 +01:00
|
|
|
break;
|
2015-04-07 22:28:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D7FB4
|
|
|
|
*/
|
2015-04-10 13:41:23 +02:00
|
|
|
static void train_ready_to_depart(rct_vehicle* vehicle, uint8 num_peeps_on_train, uint8 num_used_seats){
|
|
|
|
|
|
|
|
if (num_peeps_on_train != num_used_seats)
|
|
|
|
return;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-04-10 13:41:23 +02:00
|
|
|
|
|
|
|
if (ride->status == RIDE_STATUS_OPEN &&
|
|
|
|
!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) &&
|
2015-04-12 17:47:02 +02:00
|
|
|
!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART)){
|
2015-04-10 13:41:23 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)){
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED ||
|
|
|
|
ride->num_riders != 0){
|
|
|
|
ride->train_at_station[vehicle->current_station] = 0xFF;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 2;
|
2015-04-10 13:41:23 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_FORWARD_ROTATION ||
|
|
|
|
ride->mode == RIDE_MODE_BACKWARD_ROTATION){
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-04-10 13:41:23 +02:00
|
|
|
uint8 peep = ((-vehicle->var_1F) / 8) & 0xF;
|
|
|
|
if (vehicle->peep[peep] != 0xFFFF){
|
|
|
|
ride->train_at_station[vehicle->current_station] = 0xFF;
|
|
|
|
vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS;
|
2016-01-14 19:40:35 +01:00
|
|
|
vehicle->sub_state = 0;
|
2015-04-10 13:41:23 +02:00
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->num_peeps == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ride->train_at_station[vehicle->current_station] = 0xFF;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 2;
|
2015-04-10 13:41:23 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (num_peeps_on_train == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ride->train_at_station[vehicle->current_station] = 0xFF;
|
2016-01-14 19:40:35 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_WAITING_FOR_PASSENGERS;
|
|
|
|
vehicle->sub_state = 0;
|
2015-04-10 13:41:23 +02:00
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D7DA1
|
|
|
|
*/
|
2015-04-08 19:48:17 +02:00
|
|
|
static void vehicle_update_waiting_for_passengers(rct_vehicle* vehicle){
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-04-08 19:48:17 +02:00
|
|
|
|
2015-11-19 19:44:24 +01:00
|
|
|
if (vehicle->sub_state == 0){
|
|
|
|
if (vehicle_open_restraints(vehicle))
|
2015-04-08 19:48:17 +02:00
|
|
|
return;
|
2015-04-10 09:24:36 +02:00
|
|
|
|
|
|
|
if (ride->entrances[vehicle->current_station] == 0xFFFF){
|
|
|
|
ride->train_at_station[vehicle->current_station] = 0xFF;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 2;
|
2015-04-10 09:24:36 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 train_index = 0;
|
|
|
|
while (ride->vehicles[train_index] != vehicle->sprite_index)train_index++;
|
|
|
|
|
|
|
|
if (ride->train_at_station[vehicle->current_station] != 0xFF)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ride->train_at_station[vehicle->current_station] = train_index;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 1;
|
2015-04-10 09:24:36 +02:00
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-04-10 09:24:36 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-11-19 19:44:24 +01:00
|
|
|
else if (vehicle->sub_state == 1){
|
2015-04-10 09:24:36 +02:00
|
|
|
if (vehicle->var_C0 != 0xFFFF)
|
|
|
|
vehicle->var_C0++;
|
|
|
|
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 09:24:36 +02:00
|
|
|
|
|
|
|
// 0xF64E31, 0xF64E32, 0xF64E33
|
|
|
|
uint8 num_peeps_on_train = 0, num_used_seats_on_train = 0, num_seats_on_train = 0;
|
|
|
|
|
|
|
|
for (uint16 sprite_id = vehicle->sprite_index; sprite_id != 0xFFFF;){
|
|
|
|
rct_vehicle* train_vehicle = GET_VEHICLE(sprite_id);
|
|
|
|
|
|
|
|
num_peeps_on_train += train_vehicle->num_peeps;
|
|
|
|
num_used_seats_on_train += train_vehicle->next_free_seat;
|
|
|
|
num_seats_on_train += train_vehicle->num_seats;
|
|
|
|
|
|
|
|
sprite_id = train_vehicle->next_vehicle_on_train;
|
|
|
|
}
|
|
|
|
|
|
|
|
num_seats_on_train &= 0x7F;
|
|
|
|
|
2016-01-15 00:04:17 +01:00
|
|
|
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE)){
|
2015-04-10 09:24:36 +02:00
|
|
|
if (vehicle->var_C0 < 20){
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
2015-04-10 09:24:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
if (num_peeps_on_train == 0){
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
2015-04-10 09:24:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-15 00:04:17 +01:00
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS)){
|
2015-04-10 09:24:36 +02:00
|
|
|
if (ride->depart_flags & RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH){
|
|
|
|
if (ride->min_waiting_time * 32 > vehicle->var_C0){
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
2015-04-10 09:24:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ride->depart_flags & RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH){
|
|
|
|
if (ride->max_waiting_time * 32 < vehicle->var_C0){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
2015-04-10 09:24:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->depart_flags & RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES){
|
|
|
|
|
|
|
|
for (int i = 0; i < 32; ++i){
|
|
|
|
uint16 train_id = ride->vehicles[i];
|
|
|
|
if (train_id == 0xFFFF)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (train_id == vehicle->sprite_index)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rct_vehicle* train = GET_VEHICLE(train_id);
|
|
|
|
|
|
|
|
if (train->status == VEHICLE_STATUS_UNLOADING_PASSENGERS ||
|
|
|
|
train->status == VEHICLE_STATUS_MOVING_TO_END_OF_STATION){
|
|
|
|
if (train->current_station == vehicle->current_station){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
2015-04-10 09:24:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-04-10 13:41:23 +02:00
|
|
|
|
2016-01-15 00:04:17 +01:00
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_HAS_LOAD_OPTIONS) &&
|
2015-04-10 13:41:23 +02:00
|
|
|
ride->depart_flags & RIDE_DEPART_WAIT_FOR_LOAD){
|
|
|
|
|
|
|
|
if (num_peeps_on_train == num_seats_on_train){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 load = ride->depart_flags & RIDE_DEPART_WAIT_FOR_LOAD_MASK;
|
|
|
|
if (load == 3){
|
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8 three_quater_seats = (3 * num_seats_on_train) / 4;
|
|
|
|
if (three_quater_seats != 0 && num_peeps_on_train >= three_quater_seats){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (load == 2){
|
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (num_seats_on_train / 2 != 0 && num_peeps_on_train >= num_seats_on_train / 2){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (load == 1){
|
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (num_seats_on_train / 4 != 0 && num_peeps_on_train >= num_seats_on_train / 4){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (load == 0){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (num_peeps_on_train != 0){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-12-12 11:21:49 +01:00
|
|
|
}
|
2015-04-12 17:25:22 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
2015-04-10 13:41:23 +02:00
|
|
|
}
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TRAIN_READY_DEPART;
|
2015-04-10 13:41:23 +02:00
|
|
|
train_ready_to_depart(vehicle, num_peeps_on_train, num_used_seats_on_train);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-12 18:28:55 +02:00
|
|
|
if (vehicle_close_restraints(vehicle))
|
2015-04-10 13:41:23 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
vehicle->velocity = 0;
|
2015-04-12 16:33:28 +02:00
|
|
|
vehicle->status = VEHICLE_STATUS_WAITING_TO_DEPART;
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 0;
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT;
|
2015-04-10 13:41:23 +02:00
|
|
|
|
|
|
|
if (ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS){
|
2015-04-12 17:47:02 +02:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT;
|
2015-04-08 19:48:17 +02:00
|
|
|
}
|
2015-04-10 13:41:23 +02:00
|
|
|
|
|
|
|
vehicle_invalidate_window(vehicle);
|
2015-04-08 19:48:17 +02:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D91BF
|
|
|
|
*/
|
2015-11-21 11:46:24 +01:00
|
|
|
static void vehicle_update_bumpcar_mode(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-11-21 15:47:12 +01:00
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
2015-11-21 11:46:24 +01:00
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_7 && vehicle->var_C5 != 1) {
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->var_C5 = 1;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-21 11:46:24 +01:00
|
|
|
}
|
|
|
|
|
2015-12-12 15:55:05 +01:00
|
|
|
vehicle_update_motion_bumper_car(vehicle);
|
2015-11-21 11:46:24 +01:00
|
|
|
|
|
|
|
// Update the length of time vehicle has been in bumper mode
|
|
|
|
if (vehicle->sub_state++ == 0xFF) {
|
|
|
|
vehicle->var_CE++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vehicle->var_C5 = 0;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
2016-01-15 20:17:00 +01:00
|
|
|
* rct2: 0x006D80BE
|
2015-12-16 19:37:45 +01:00
|
|
|
*/
|
2015-11-21 00:41:50 +01:00
|
|
|
static void vehicle_update_waiting_to_depart(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-21 00:41:50 +01:00
|
|
|
bool shouldBreak = false;
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) {
|
|
|
|
switch (ride->breakdown_reason_pending) {
|
|
|
|
case BREAKDOWN_RESTRAINTS_STUCK_CLOSED:
|
|
|
|
case BREAKDOWN_RESTRAINTS_STUCK_OPEN:
|
|
|
|
case BREAKDOWN_DOORS_STUCK_CLOSED:
|
|
|
|
case BREAKDOWN_DOORS_STUCK_OPEN:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
shouldBreak = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool skipCheck = false;
|
2015-11-21 11:46:24 +01:00
|
|
|
if (shouldBreak == true || ride->status != RIDE_STATUS_OPEN) {
|
2015-11-21 00:41:50 +01:00
|
|
|
if (ride->mode == RIDE_MODE_FORWARD_ROTATION ||
|
|
|
|
ride->mode == RIDE_MODE_BACKWARD_ROTATION) {
|
|
|
|
uint8 bl = ((-vehicle->var_1F) >> 3) & 0xF;
|
|
|
|
if (vehicle->peep[bl] == 0xFFFF) {
|
|
|
|
if (vehicle->num_peeps == 0) {
|
|
|
|
skipCheck = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (ride->exits[vehicle->current_station] != 0xFFFF) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* curVehicle; spriteId != 0xFFFF; spriteId = curVehicle->next_vehicle_on_train) {
|
|
|
|
curVehicle = GET_VEHICLE(spriteId);
|
|
|
|
|
|
|
|
if (curVehicle->num_peeps != 0) {
|
|
|
|
if (ride->exits[vehicle->current_station] != 0xFFFF) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (skipCheck == false) {
|
|
|
|
if (!(ride->station_depart[vehicle->current_station] & STATION_DEPART_FLAG))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-15 00:04:17 +01:00
|
|
|
if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_CAN_SYNCHRONISE_ADJACENT_STATIONS)) {
|
2015-11-21 00:41:50 +01:00
|
|
|
if (ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS) {
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT) {
|
2015-12-20 19:33:43 +01:00
|
|
|
if (vehicle_can_depart_synchronised(vehicle)) {
|
2015-11-21 00:41:50 +01:00
|
|
|
return;
|
2015-12-20 15:21:06 +01:00
|
|
|
}
|
2015-11-21 00:41:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->status = VEHICLE_STATUS_DEPARTING;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT) {
|
|
|
|
RCT2_GLOBAL(0x00F441D2, uint8) = vehicle->ride;
|
|
|
|
rct_xy_element track;
|
|
|
|
int z;
|
|
|
|
int direction;
|
|
|
|
|
|
|
|
if (track_block_get_next_from_zero(
|
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z,
|
|
|
|
vehicle->ride,
|
2015-11-21 11:46:24 +01:00
|
|
|
(uint8)(vehicle->track_direction & 0x3),
|
2015-11-21 00:41:50 +01:00
|
|
|
&track,
|
|
|
|
&z,
|
|
|
|
&direction)) {
|
|
|
|
|
|
|
|
if (track_element_is_cable_lift(track.element)) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_WAITING_FOR_CABLE_LIFT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (ride->mode) {
|
|
|
|
case RIDE_MODE_BUMPERCAR:
|
2015-11-30 22:11:22 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_TRAVELLING_BUMPER_CARS;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle_invalidate_window(vehicle);
|
2015-11-21 11:46:24 +01:00
|
|
|
// Bumper mode uses sub_state / var_CE to tell how long
|
|
|
|
// the vehicle has been ridden.
|
|
|
|
vehicle->sub_state = 0;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle->var_CE = 0;
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle_update_bumpcar_mode(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_SWING:
|
|
|
|
vehicle->status = VEHICLE_STATUS_SWINGING;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_CE = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-21 12:35:02 +01:00
|
|
|
vehicle_update_swinging(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_ROTATION:
|
|
|
|
vehicle->status = VEHICLE_STATUS_ROTATING;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_CE = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-25 23:25:13 +01:00
|
|
|
vehicle_update_rotating(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_FILM_AVENGING_AVIATORS:
|
|
|
|
case RIDE_MODE_FILM_THRILL_RIDERS:
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_SIMULATOR_OPERATING;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle->sub_state = 0;
|
|
|
|
if (ride->mode == RIDE_MODE_FILM_THRILL_RIDERS)
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-21 13:13:10 +01:00
|
|
|
vehicle_update_simulator_operating(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_BEGINNERS:
|
|
|
|
case RIDE_MODE_INTENSE:
|
|
|
|
case RIDE_MODE_BERSERK:
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_TOP_SPIN_OPERATING;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
|
|
|
|
switch (ride->mode) {
|
|
|
|
case RIDE_MODE_BEGINNERS:
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
break;
|
|
|
|
case RIDE_MODE_INTENSE:
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
break;
|
|
|
|
case RIDE_MODE_BERSERK:
|
|
|
|
vehicle->sub_state = 2;
|
|
|
|
break;
|
|
|
|
}
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle->var_1F = 0;
|
|
|
|
vehicle->var_20 = 0;
|
2015-11-21 17:16:05 +01:00
|
|
|
vehicle_update_top_spin_operating(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_FORWARD_ROTATION:
|
|
|
|
case RIDE_MODE_BACKWARD_ROTATION:
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_FERRIS_WHEEL_ROTATING;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle->sub_state = vehicle->var_1F;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_CE = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->ferris_wheel_var_0 = 8;
|
|
|
|
vehicle->ferris_wheel_var_1 = 8;
|
2015-11-25 20:55:04 +01:00
|
|
|
vehicle_update_ferris_wheel_rotating(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_3D_FILM_MOUSE_TAILS:
|
|
|
|
case RIDE_MODE_3D_FILM_STORM_CHASERS:
|
|
|
|
case RIDE_MODE_3D_FILM_SPACE_RAIDERS:
|
|
|
|
vehicle->status = VEHICLE_STATUS_SHOWING_FILM;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
switch (ride->mode) {
|
|
|
|
case RIDE_MODE_3D_FILM_MOUSE_TAILS:
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
break;
|
|
|
|
case RIDE_MODE_3D_FILM_STORM_CHASERS:
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
break;
|
|
|
|
case RIDE_MODE_3D_FILM_SPACE_RAIDERS:
|
|
|
|
vehicle->sub_state = 2;
|
|
|
|
break;
|
|
|
|
}
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle_update_showing_film(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_CIRCUS_SHOW:
|
|
|
|
vehicle->status = VEHICLE_STATUS_DOING_CIRCUS_SHOW;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle_update_doing_circus_show(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_SPACE_RINGS:
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_SPACE_RINGS_OPERATING;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_1F = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-25 21:26:15 +01:00
|
|
|
vehicle_update_space_rings_operating(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_HAUNTED_HOUSE:
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_HAUNTED_HOUSE_OPERATING;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_1F = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-25 21:26:15 +01:00
|
|
|
vehicle_update_haunted_house_operating(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_CROOKED_HOUSE:
|
2015-11-21 11:46:24 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_CROOKED_HOUSE_OPERATING;
|
2015-11-21 00:41:50 +01:00
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_1F = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-25 21:39:59 +01:00
|
|
|
vehicle_update_crooked_house_operating(vehicle);
|
2015-11-21 00:41:50 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_CE = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-20 19:33:43 +01:00
|
|
|
typedef struct {
|
|
|
|
uint8 ride_id;
|
|
|
|
uint8 station_id;
|
|
|
|
uint16 vehicle_id;
|
|
|
|
} rct_synchrnoised_vehicle;
|
|
|
|
|
|
|
|
// 8 synchrnoised vehicle info
|
|
|
|
rct_synchrnoised_vehicle *_synchrnoisedVehicles = (rct_synchrnoised_vehicle*)0x00F64E4C;
|
|
|
|
|
|
|
|
#define _lastSynchrnoisedVehicle RCT2_GLOBAL(0x00F64E48, rct_synchrnoised_vehicle*)
|
|
|
|
#define MaxSynchrnoisedVehicle ((rct_synchrnoised_vehicle*)0x00F64E6C)
|
|
|
|
|
2015-12-21 19:26:41 +01:00
|
|
|
/**
|
|
|
|
* Checks if a map position contains a synchrnoised ride station and adds the vehicle
|
|
|
|
* to synchrnoise to the vehicle synchronisation list.
|
|
|
|
* rct2: 0x006DE1A4
|
|
|
|
*/
|
|
|
|
static bool try_add_synchronised_station(int x, int y, int z)
|
|
|
|
{
|
|
|
|
bool foundMapElement = false;
|
|
|
|
rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5);
|
|
|
|
if (mapElement != NULL) {
|
|
|
|
do {
|
|
|
|
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK) continue;
|
|
|
|
if (z != mapElement->base_height &&
|
|
|
|
z != mapElement->base_height - 2 &&
|
|
|
|
z != mapElement->base_height + 2
|
|
|
|
) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
foundMapElement = true;
|
|
|
|
break;
|
|
|
|
} while (!map_element_is_last_for_tile(mapElement++));
|
|
|
|
}
|
|
|
|
if (!foundMapElement) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-21 19:26:41 +01:00
|
|
|
int rideIndex = mapElement->properties.track.ride_index;
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(rideIndex);
|
2015-12-21 19:26:41 +01:00
|
|
|
if (!(ride->depart_flags & RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int stationIndex = map_get_station(mapElement);
|
|
|
|
|
|
|
|
rct_synchrnoised_vehicle *sv = _lastSynchrnoisedVehicle;
|
|
|
|
sv->ride_id = rideIndex;
|
|
|
|
sv->station_id = stationIndex;
|
|
|
|
sv->vehicle_id = SPRITE_INDEX_NULL;
|
|
|
|
_lastSynchrnoisedVehicle++;
|
|
|
|
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < ride->num_vehicles; i++) {
|
|
|
|
uint16 spriteIndex = ride->vehicles[i];
|
|
|
|
if (spriteIndex == SPRITE_INDEX_NULL) continue;
|
|
|
|
|
|
|
|
rct_vehicle *vehicle = GET_VEHICLE(spriteIndex);
|
|
|
|
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART) continue;
|
|
|
|
if (vehicle->sub_state != 0) continue;
|
|
|
|
if (!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT)) continue;
|
|
|
|
if (vehicle->current_station != stationIndex) continue;
|
|
|
|
|
|
|
|
sv->vehicle_id = spriteIndex;
|
|
|
|
return true;
|
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
return false;
|
2015-12-21 19:26:41 +01:00
|
|
|
}
|
|
|
|
|
2015-12-20 19:33:43 +01:00
|
|
|
/**
|
|
|
|
* Checks whether a vehicle can depart a station when set to synchrnoise with adjacent stations.
|
2015-12-20 15:21:06 +01:00
|
|
|
* rct2: 0x006DE287
|
2015-12-20 19:33:43 +01:00
|
|
|
* @param vehicle The vehicle waiting to depart.
|
|
|
|
* @returns true if the vehicle can depart (all adjacent trains are ready or broken down), otherwise false.
|
2015-12-20 15:21:06 +01:00
|
|
|
*/
|
2015-12-20 19:33:43 +01:00
|
|
|
static bool vehicle_can_depart_synchronised(rct_vehicle *vehicle)
|
2015-12-20 15:21:06 +01:00
|
|
|
{
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
2015-12-20 19:33:43 +01:00
|
|
|
int station = vehicle->current_station;
|
|
|
|
uint16 xy = ride->station_starts[station];
|
|
|
|
int x = (xy & 0xFF) * 32;
|
|
|
|
int y = (xy >> 8) * 32;
|
|
|
|
int z = ride->station_heights[station];
|
|
|
|
|
|
|
|
rct_map_element *mapElement = map_get_track_element_at(x, y, z);
|
|
|
|
int direction = (mapElement->type + 1) & 3;
|
|
|
|
_lastSynchrnoisedVehicle = _synchrnoisedVehicles;
|
|
|
|
|
|
|
|
while (_lastSynchrnoisedVehicle < MaxSynchrnoisedVehicle) {
|
|
|
|
x += TileDirectionDelta[direction].x;
|
|
|
|
y += TileDirectionDelta[direction].y;
|
2015-12-21 19:26:41 +01:00
|
|
|
if (!try_add_synchronised_station(x, y, z)) {
|
2015-12-20 19:33:43 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (_lastSynchrnoisedVehicle < MaxSynchrnoisedVehicle) {
|
|
|
|
x += TileDirectionDelta[direction].x;
|
|
|
|
y += TileDirectionDelta[direction].y;
|
2015-12-21 19:26:41 +01:00
|
|
|
if (!try_add_synchronised_station(x, y, z)) {
|
2015-12-20 19:33:43 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_lastSynchrnoisedVehicle == _synchrnoisedVehicles) {
|
|
|
|
// No adjacent stations, allow depart
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rct_synchrnoised_vehicle *sv = _synchrnoisedVehicles; sv < _lastSynchrnoisedVehicle; sv++) {
|
|
|
|
if (ride_is_block_sectioned(ride)) {
|
|
|
|
if (!(ride->station_depart[sv->station_id] & 0x80)) {
|
|
|
|
sv = _synchrnoisedVehicles;
|
|
|
|
uint8 rideId = 0xFF;
|
|
|
|
for (; sv < _lastSynchrnoisedVehicle; sv++) {
|
|
|
|
if (rideId == 0xFF) {
|
|
|
|
rideId = sv->ride_id;
|
|
|
|
}
|
|
|
|
if (rideId != sv->ride_id) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
ride = get_ride(rideId);
|
2015-12-20 19:33:43 +01:00
|
|
|
for (int i = 0; i < ride->num_vehicles; i++) {
|
|
|
|
rct_vehicle *v = GET_VEHICLE(ride->vehicles[i]);
|
|
|
|
if (v->status != VEHICLE_STATUS_WAITING_TO_DEPART && v->velocity != 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) {
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED) {
|
|
|
|
if (sv->vehicle_id == SPRITE_INDEX_NULL) {
|
|
|
|
if (_lastSynchrnoisedVehicle > &_synchrnoisedVehicles[1]) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
uint8 someRideIndex = _synchrnoisedVehicles[0].ride_id;
|
|
|
|
// uint8 currentStation = _synchrnoisedVehicles[0].station_id
|
|
|
|
if (someRideIndex != vehicle->ride) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
ride = get_ride(someRideIndex);
|
2015-12-20 19:33:43 +01:00
|
|
|
int numAdjacentTrainsAtStation = 0;
|
|
|
|
int numTravelingTrains = 0;
|
|
|
|
int currentStation = vehicle->current_station;
|
|
|
|
for (int i = 0; i < ride->num_vehicles; i++) {
|
|
|
|
uint16 spriteIndex = ride->vehicles[i];
|
|
|
|
if (spriteIndex != SPRITE_INDEX_NULL) {
|
|
|
|
rct_vehicle *otherVehicle = GET_VEHICLE(spriteIndex);
|
|
|
|
if (otherVehicle->status != VEHICLE_STATUS_TRAVELLING) {
|
|
|
|
if (currentStation == otherVehicle->current_station) {
|
|
|
|
if (otherVehicle->status == VEHICLE_STATUS_WAITING_TO_DEPART ||
|
|
|
|
otherVehicle->status == VEHICLE_STATUS_MOVING_TO_END_OF_STATION
|
|
|
|
) {
|
|
|
|
numAdjacentTrainsAtStation++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
numTravelingTrains++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int totalTrains = numAdjacentTrainsAtStation + numTravelingTrains;
|
|
|
|
if (totalTrains != ride->num_vehicles || numTravelingTrains >= ride->num_vehicles / 2) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (rct_synchrnoised_vehicle *sv = _synchrnoisedVehicles; sv < _lastSynchrnoisedVehicle; sv++) {
|
|
|
|
if (sv->vehicle_id != SPRITE_INDEX_NULL) {
|
|
|
|
rct_vehicle *v = GET_VEHICLE(sv->vehicle_id);
|
|
|
|
v->update_flags &= ~VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_WAIT_ON_ADJACENT;
|
|
|
|
return false;
|
2015-12-20 15:21:06 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9EB0
|
|
|
|
*/
|
|
|
|
void vehicle_peep_easteregg_here_we_are(rct_vehicle* vehicle) {
|
2015-11-28 19:13:22 +01:00
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
do {
|
|
|
|
vehicle = GET_VEHICLE(spriteId);
|
|
|
|
for (int i = 0; i < vehicle->num_peeps; ++i) {
|
|
|
|
rct_peep* peep = GET_PEEP(vehicle->peep[i]);
|
|
|
|
if (peep->flags & PEEP_FLAGS_HERE_WE_ARE) {
|
|
|
|
peep_insert_new_thought(peep, PEEP_THOUGHT_HERE_WE_ARE, peep->current_ride);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while ((spriteId = vehicle->next_vehicle_on_train) != 0xFFFF);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
2015-11-29 14:30:48 +01:00
|
|
|
* Performed when vehicle has completed a full circuit
|
2015-12-16 19:37:45 +01:00
|
|
|
* rct2: 0x006D7338
|
2015-11-29 14:30:48 +01:00
|
|
|
*/
|
2015-12-16 19:37:45 +01:00
|
|
|
void vehicle_update_test_finish(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-29 14:30:48 +01:00
|
|
|
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_TEST_IN_PROGRESS;
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_TESTING;
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_TESTED;
|
|
|
|
|
|
|
|
for (int i = ride->num_stations - 1; i >= 1; i--) {
|
|
|
|
if (ride->time[i - 1] != 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
uint16 oldTime = ride->time[i - 1];
|
|
|
|
ride->time[i - 1] = ride->time[i];
|
|
|
|
ride->time[i] = oldTime;
|
|
|
|
|
|
|
|
sint32 oldLength = ride->length[i - 1];
|
|
|
|
ride->length[i - 1] = ride->length[i];
|
|
|
|
ride->length[i] = oldLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 totalTime = 0;
|
|
|
|
for (uint8 i = 0; i < ride->num_stations; ++i) {
|
|
|
|
totalTime += ride->time[i];
|
|
|
|
}
|
|
|
|
|
2016-01-02 17:19:06 +01:00
|
|
|
totalTime = max(totalTime, 1);
|
2015-11-29 14:30:48 +01:00
|
|
|
ride->average_speed = ride->average_speed / totalTime;
|
|
|
|
|
|
|
|
window_invalidate_by_number(WC_RIDE, vehicle->ride);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
2015-12-12 11:21:49 +01:00
|
|
|
*
|
2015-12-16 19:37:45 +01:00
|
|
|
* rct2: 0x006D6BE7
|
2015-11-29 14:30:48 +01:00
|
|
|
*/
|
2015-12-16 19:37:45 +01:00
|
|
|
void vehicle_test_reset(rct_vehicle* vehicle) {
|
2015-12-12 11:21:49 +01:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_TESTING;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-29 14:30:48 +01:00
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_TEST_IN_PROGRESS;
|
|
|
|
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_NO_RAW_STATS;
|
|
|
|
ride->max_speed = 0;
|
|
|
|
ride->average_speed = 0;
|
|
|
|
ride->current_test_segment = 0;
|
2016-02-18 21:58:22 +01:00
|
|
|
ride->average_speed_test_timeout = 0;
|
2015-11-29 14:30:48 +01:00
|
|
|
ride->max_positive_vertical_g = FIXED_2DP(1, 0);
|
|
|
|
ride->max_negative_vertical_g = FIXED_2DP(1, 0);
|
|
|
|
ride->max_lateral_g = 0;
|
|
|
|
ride->previous_vertical_g = 0;
|
|
|
|
ride->previous_lateral_g = 0;
|
|
|
|
ride->testing_flags = 0;
|
2016-02-18 21:58:22 +01:00
|
|
|
ride->cur_test_track_location.xy = 0xFFFF;
|
|
|
|
ride->cur_test_track_z = 0xFF;
|
2015-11-29 14:30:48 +01:00
|
|
|
ride->turn_count_default = 0;
|
|
|
|
ride->turn_count_banked = 0;
|
|
|
|
ride->turn_count_sloped = 0;
|
|
|
|
ride->inversions = 0;
|
|
|
|
ride->drops = 0;
|
|
|
|
ride->sheltered_length = 0;
|
|
|
|
ride->var_11C = 0;
|
|
|
|
ride->num_sheltered_sections = 0;
|
|
|
|
ride->highest_drop_height = 0;
|
|
|
|
ride->special_track_elements = 0;
|
|
|
|
memset(&ride->length, 0, 4 * 4);
|
|
|
|
memset(&ride->time, 0, 4 * 2);
|
2016-01-14 19:56:29 +01:00
|
|
|
ride->total_air_time = 0;
|
2016-02-17 19:22:38 +01:00
|
|
|
ride->current_test_station = vehicle->current_station;
|
2015-11-29 14:30:48 +01:00
|
|
|
window_invalidate_by_number(WC_RIDE, vehicle->ride);
|
|
|
|
}
|
|
|
|
|
2015-11-29 15:42:04 +01:00
|
|
|
static bool vehicle_next_tower_element_is_top(rct_vehicle* vehicle) {
|
|
|
|
rct_map_element* mapElement = map_get_track_element_at_of_type(
|
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z / 8,
|
|
|
|
vehicle->track_type >> 2);
|
|
|
|
|
|
|
|
if (mapElement->flags & MAP_ELEMENT_FLAG_LAST_TILE) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mapElement->clearance_height == (mapElement + 1)->base_height) {
|
|
|
|
if ((mapElement + 1)->properties.track.type == TRACK_ELEM_TOWER_SECTION) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mapElement + 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mapElement->clearance_height != (mapElement + 2)->base_height) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mapElement + 2)->properties.track.type == TRACK_ELEM_TOWER_SECTION) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D986C
|
|
|
|
*/
|
2015-12-11 14:07:22 +01:00
|
|
|
static void vehicle_update_travelling_boat_hire_setup(rct_vehicle* vehicle) {
|
|
|
|
vehicle->var_34 = vehicle->sprite_direction;
|
|
|
|
vehicle->track_x = vehicle->x & 0xFFE0;
|
|
|
|
vehicle->track_y = vehicle->y & 0xFFE0;
|
|
|
|
|
|
|
|
rct_xy8 location = {
|
|
|
|
.x = (vehicle->track_x + RCT2_ADDRESS(0x00993CCC, sint16)[2 * (vehicle->sprite_direction >> 3)]) / 32,
|
|
|
|
.y = (vehicle->track_y + RCT2_ADDRESS(0x00993CCE, sint16)[2 * (vehicle->sprite_direction >> 3)]) / 32
|
|
|
|
};
|
|
|
|
|
|
|
|
vehicle->boat_location = location;
|
|
|
|
vehicle->var_35 = 0;
|
|
|
|
vehicle->status = VEHICLE_STATUS_TRAVELLING_BOAT;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance += 27924;
|
2015-12-11 14:07:22 +01:00
|
|
|
|
|
|
|
vehicle_update_travelling_boat(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D982F
|
|
|
|
*/
|
2015-12-11 14:07:22 +01:00
|
|
|
static void vehicle_update_departing_boat_hire(rct_vehicle* vehicle) {
|
|
|
|
vehicle->lost_time_out = 0;
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-11 14:07:22 +01:00
|
|
|
|
|
|
|
ride->station_depart[vehicle->current_station] &= STATION_DEPART_FLAG;
|
|
|
|
uint8 waitingTime = max(ride->min_waiting_time, 3);
|
|
|
|
waitingTime = min(waitingTime, 127);
|
|
|
|
ride->station_depart[vehicle->current_station] |= waitingTime;
|
|
|
|
vehicle_update_travelling_boat_hire_setup(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D845B
|
|
|
|
*/
|
2015-11-28 19:13:22 +01:00
|
|
|
static void vehicle_update_departing(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-11-28 19:13:22 +01:00
|
|
|
|
|
|
|
if (vehicle->sub_state == 0) {
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_BROKEN_TRAIN) {
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_BROKEN_DOWN;
|
|
|
|
ride_breakdown_add_news_item(vehicle->ride);
|
|
|
|
|
|
|
|
ride->window_invalidate_flags |=
|
|
|
|
RIDE_INVALIDATE_RIDE_MAIN |
|
|
|
|
RIDE_INVALIDATE_RIDE_LIST |
|
|
|
|
RIDE_INVALIDATE_RIDE_MAINTENANCE;
|
2016-01-09 16:57:55 +01:00
|
|
|
ride->mechanic_status = RIDE_MECHANIC_STATUS_CALLING;
|
2015-11-28 19:13:22 +01:00
|
|
|
ride->inspection_station = vehicle->current_station;
|
|
|
|
ride->breakdown_reason = ride->breakdown_reason_pending;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_peep_easteregg_here_we_are(vehicle);
|
|
|
|
|
|
|
|
if (rideEntry->flags & RIDE_ENTRY_FLAG_3) {
|
|
|
|
uint8 soundId = (rideEntry->vehicles[0].sound_range == 4) ?
|
|
|
|
SOUND_TRAM :
|
|
|
|
SOUND_TRAIN_CHUGGING;
|
|
|
|
|
|
|
|
audio_play_sound_at_location(
|
2015-12-12 11:21:49 +01:00
|
|
|
soundId,
|
2015-11-28 19:13:22 +01:00
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_UPWARD_LAUNCH ||
|
|
|
|
(ride->mode == RIDE_MODE_DOWNWARD_LAUNCH && vehicle->var_CE > 1)) {
|
|
|
|
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_RIDE_LAUNCH_2,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) {
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_TESTING) {
|
|
|
|
if (ride->current_test_segment + 1 < ride->num_stations) {
|
|
|
|
ride->current_test_segment++;
|
2016-02-17 19:22:38 +01:00
|
|
|
ride->current_test_station = vehicle->current_station;
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-11-29 14:30:48 +01:00
|
|
|
vehicle_update_test_finish(vehicle);
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TEST_IN_PROGRESS)) {
|
2015-11-29 14:30:48 +01:00
|
|
|
vehicle_test_reset(vehicle);
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
switch (ride->mode) {
|
|
|
|
case RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE:
|
|
|
|
if (vehicle->velocity >= -131940)
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -3298;
|
2015-11-28 19:13:22 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_POWERED_LAUNCH_PASSTROUGH:
|
|
|
|
case RIDE_MODE_POWERED_LAUNCH:
|
|
|
|
case RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED:
|
|
|
|
case RIDE_MODE_LIM_POWERED_LAUNCH:
|
|
|
|
case RIDE_MODE_UPWARD_LAUNCH:
|
|
|
|
if (ride->type == RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER) {
|
|
|
|
if ((ride->launch_speed << 16) > vehicle->velocity) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = ride->launch_speed << 13;
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ride->launch_speed << 16) > vehicle->velocity)
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = ride->launch_speed << 12;
|
2015-11-28 19:13:22 +01:00
|
|
|
break;
|
|
|
|
case RIDE_MODE_DOWNWARD_LAUNCH:
|
2015-11-29 11:39:17 +01:00
|
|
|
if (vehicle->var_CE >= 1) {
|
2015-11-28 19:13:22 +01:00
|
|
|
if ((14 << 16) > vehicle->velocity)
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 14 << 12;
|
2015-11-28 19:13:22 +01:00
|
|
|
break;
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
// Fall through
|
2015-11-28 19:13:22 +01:00
|
|
|
case RIDE_MODE_CONTINUOUS_CIRCUIT:
|
|
|
|
case RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED:
|
|
|
|
case RIDE_MODE_ROTATING_LIFT:
|
|
|
|
case RIDE_MODE_FREEFALL_DROP:
|
|
|
|
case RIDE_MODE_BOAT_HIRE:
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3)
|
2015-11-28 19:13:22 +01:00
|
|
|
break;
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-28 19:13:22 +01:00
|
|
|
if (vehicle->velocity <= 131940)
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 3298;
|
2015-11-28 19:13:22 +01:00
|
|
|
break;
|
|
|
|
}
|
2015-11-29 00:18:02 +01:00
|
|
|
|
2015-12-15 19:56:19 +01:00
|
|
|
uint32 flags = vehicle_update_track_motion(vehicle, NULL);
|
2015-11-28 19:13:22 +01:00
|
|
|
|
|
|
|
if (flags & (1 << 8)) {
|
2015-11-29 00:18:02 +01:00
|
|
|
if (ride->mode == RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE) {
|
2015-11-28 19:13:22 +01:00
|
|
|
vehicle->velocity = -vehicle->velocity;
|
2015-11-29 11:58:37 +01:00
|
|
|
vehicle_finish_departing(vehicle);
|
2015-11-29 11:39:17 +01:00
|
|
|
return;
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-28 19:13:22 +01:00
|
|
|
if (flags & ((1 << 5) | (1 << 12))) {
|
2015-11-29 00:18:02 +01:00
|
|
|
if (ride->mode == RIDE_MODE_BOAT_HIRE) {
|
2015-12-11 16:28:07 +01:00
|
|
|
vehicle_update_departing_boat_hire(vehicle);
|
2015-11-29 00:18:02 +01:00
|
|
|
return;
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
2015-11-29 00:18:02 +01:00
|
|
|
else if (ride->mode == RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE) {
|
2015-11-28 19:13:22 +01:00
|
|
|
vehicle->velocity = -vehicle->velocity;
|
2015-11-29 11:58:37 +01:00
|
|
|
vehicle_finish_departing(vehicle);
|
2015-11-29 11:39:17 +01:00
|
|
|
return;
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
2015-11-29 00:18:02 +01:00
|
|
|
else if (ride->mode == RIDE_MODE_SHUTTLE) {
|
2015-11-28 19:13:22 +01:00
|
|
|
vehicle->update_flags ^= VEHICLE_UPDATE_FLAG_3;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-12-17 00:39:38 +01:00
|
|
|
if (flags & VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_ON_LIFT_HILL) {
|
2015-11-28 19:13:22 +01:00
|
|
|
vehicle->var_B8 |= (1 << 1);
|
2015-11-29 00:18:02 +01:00
|
|
|
if (ride->mode != RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE) {
|
2015-11-28 19:13:22 +01:00
|
|
|
sint32 speed = ride->lift_hill_speed * 31079;
|
|
|
|
if (vehicle->velocity <= speed) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 15539;
|
2015-11-28 19:13:22 +01:00
|
|
|
if (vehicle->velocity != 0) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == BREAKDOWN_SAFETY_CUT_OUT) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_7;
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sint32 speed = ride->lift_hill_speed * -31079;
|
|
|
|
if (vehicle->velocity >= speed) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -15539;
|
2015-11-28 19:13:22 +01:00
|
|
|
if (vehicle->velocity != 0) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == BREAKDOWN_SAFETY_CUT_OUT) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_7;
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-29 00:18:02 +01:00
|
|
|
if (ride->mode == RIDE_MODE_FREEFALL_DROP) {
|
|
|
|
vehicle->var_C5++;
|
|
|
|
}else{
|
|
|
|
bool shouldLaunch = true;
|
|
|
|
if (ride->mode == RIDE_MODE_DOWNWARD_LAUNCH) {
|
|
|
|
if (vehicle->var_CE < 1)
|
|
|
|
shouldLaunch = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldLaunch) {
|
|
|
|
if (!(flags & (1 << 3)) || (RCT2_GLOBAL(0x00F64E1C, uint8) != vehicle->current_station)) {
|
2015-11-29 11:58:37 +01:00
|
|
|
vehicle_finish_departing(vehicle);
|
2015-11-29 11:39:17 +01:00
|
|
|
return;
|
2015-11-29 00:18:02 +01:00
|
|
|
}
|
|
|
|
|
2015-11-29 11:39:17 +01:00
|
|
|
if (!(flags & (1 << 5)))
|
2015-11-29 00:18:02 +01:00
|
|
|
return;
|
|
|
|
if (ride->mode == RIDE_MODE_BOAT_HIRE ||
|
|
|
|
ride->mode == RIDE_MODE_ROTATING_LIFT ||
|
|
|
|
ride->mode == RIDE_MODE_SHUTTLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_SIX_FLAGS_DEPRECATED)
|
|
|
|
return;
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-12-11 21:55:34 +01:00
|
|
|
vehicle_update_crash_setup(vehicle);
|
2015-11-29 00:18:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-29 15:42:04 +01:00
|
|
|
if (vehicle_next_tower_element_is_top(vehicle) == false) {
|
2015-11-29 00:18:02 +01:00
|
|
|
if (ride->mode == RIDE_MODE_FREEFALL_DROP)
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-29 00:18:02 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-29 11:58:37 +01:00
|
|
|
vehicle_finish_departing(vehicle);
|
2015-11-29 11:39:17 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
2015-12-12 11:21:49 +01:00
|
|
|
* Part of vehicle_update_departing
|
|
|
|
* Called after finishing departing sequence to enter
|
2015-11-29 11:58:37 +01:00
|
|
|
* traveling state.
|
|
|
|
* Vertical rides class the lift to the top of the tower
|
|
|
|
* as the departing sequence. After this point station
|
|
|
|
* boosters do not affect the ride.
|
2015-12-16 19:37:45 +01:00
|
|
|
* rct2: 0x006D8858
|
2015-11-29 11:58:37 +01:00
|
|
|
*/
|
|
|
|
static void vehicle_finish_departing(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-29 11:39:17 +01:00
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_DOWNWARD_LAUNCH ) {
|
|
|
|
if (vehicle->var_CE >= 1 && (14 << 16) > vehicle->velocity)
|
|
|
|
return;
|
|
|
|
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_RIDE_LAUNCH_1,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_UPWARD_LAUNCH) {
|
|
|
|
if ((ride->launch_speed << 16) > vehicle->velocity)
|
|
|
|
return;
|
|
|
|
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_RIDE_LAUNCH_1,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode != RIDE_MODE_RACE &&
|
|
|
|
ride->mode != RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED &&
|
|
|
|
ride->mode != RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED) {
|
|
|
|
|
|
|
|
ride->station_depart[vehicle->current_station] &= STATION_DEPART_FLAG;
|
|
|
|
uint8 waitingTime = 3;
|
|
|
|
if (ride->depart_flags & RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH) {
|
|
|
|
waitingTime = max(ride->min_waiting_time, 3);
|
|
|
|
waitingTime = min(waitingTime, 127);
|
|
|
|
}
|
|
|
|
|
|
|
|
ride->station_depart[vehicle->current_station] |= waitingTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->status = VEHICLE_STATUS_TRAVELLING;
|
2015-12-12 11:21:49 +01:00
|
|
|
vehicle_invalidate_window(vehicle);
|
2015-11-30 18:46:23 +01:00
|
|
|
vehicle->lost_time_out = 0;
|
2015-11-29 11:39:17 +01:00
|
|
|
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
if (vehicle->velocity < 0)
|
|
|
|
vehicle->sub_state = 0;
|
2015-11-28 19:13:22 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DE5CB
|
|
|
|
*/
|
2015-11-29 20:45:01 +01:00
|
|
|
static void vehicle_check_if_missing(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-29 20:45:01 +01:00
|
|
|
|
|
|
|
if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED ||
|
|
|
|
ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_27))
|
|
|
|
return;
|
|
|
|
|
2015-11-30 18:46:23 +01:00
|
|
|
vehicle->lost_time_out++;
|
2015-11-29 20:45:01 +01:00
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_11)
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint16 limit = ride->type == RIDE_TYPE_BOAT_RIDE ? 15360 : 9600;
|
|
|
|
|
2015-11-30 18:46:23 +01:00
|
|
|
if (vehicle->lost_time_out <= limit)
|
2015-11-29 20:45:01 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_11;
|
|
|
|
|
2016-01-11 12:55:33 +01:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, rct_string_id)
|
2015-11-29 20:45:01 +01:00
|
|
|
= RCT2_ADDRESS(0x0097C98E, rct_string_id)[ride->type * 4] + 6;
|
|
|
|
|
|
|
|
uint8 vehicleIndex = 0;
|
|
|
|
for (; vehicleIndex < ride->num_vehicles; ++vehicleIndex)
|
|
|
|
if (ride->vehicles[vehicleIndex] == vehicle->sprite_index) break;
|
|
|
|
|
|
|
|
vehicleIndex++;
|
2016-01-11 12:55:33 +01:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint16) = vehicleIndex;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, rct_string_id) = ride->name;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 6, uint32) = ride->name_arguments;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 10, rct_string_id) =
|
2015-11-29 20:45:01 +01:00
|
|
|
RCT2_ADDRESS(0x0097C98E, rct_string_id)[ride->type * 4 + 2];
|
|
|
|
|
|
|
|
news_item_add_to_queue(NEWS_ITEM_RIDE, 2218, vehicle->ride);
|
|
|
|
}
|
|
|
|
|
2015-12-12 13:21:13 +01:00
|
|
|
/**
|
2015-12-22 15:21:56 +01:00
|
|
|
* Setup function for a vehicle colliding with
|
2015-12-12 13:21:13 +01:00
|
|
|
* another vehicle.
|
|
|
|
*
|
|
|
|
* rct2: 0x006DA059
|
|
|
|
*/
|
|
|
|
static void vehicle_update_collision_setup(rct_vehicle* vehicle) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_CRASHED;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-12 13:21:13 +01:00
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) {
|
|
|
|
rct_vehicle* frontVehicle = vehicle;
|
|
|
|
while (frontVehicle->is_child != 0)frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride);
|
|
|
|
|
|
|
|
uint8 trainIndex = 0;
|
|
|
|
while (ride->vehicles[trainIndex] != frontVehicle->sprite_index)
|
|
|
|
trainIndex++;
|
|
|
|
|
|
|
|
ride_crash(vehicle->ride, trainIndex);
|
|
|
|
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED) {
|
|
|
|
ride_set_status(vehicle->ride, RIDE_STATUS_CLOSED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED;
|
|
|
|
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
|
|
|
|
vehicle_kill_all_passengers(vehicle);
|
|
|
|
|
|
|
|
rct_vehicle* lastVehicle = vehicle;
|
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* train; spriteId != 0xFFFF; spriteId = train->next_vehicle_on_train) {
|
|
|
|
train = GET_VEHICLE(spriteId);
|
|
|
|
lastVehicle = train;
|
|
|
|
|
|
|
|
train->sub_state = 2;
|
|
|
|
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_CRASH,
|
|
|
|
train->x,
|
|
|
|
train->y,
|
|
|
|
train->z
|
|
|
|
);
|
|
|
|
|
|
|
|
sprite_misc_3_create(
|
|
|
|
train->x,
|
|
|
|
train->y,
|
|
|
|
train->z
|
|
|
|
);
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
|
|
crashed_vehicle_particle_create(
|
|
|
|
train->colours,
|
|
|
|
train->x,
|
|
|
|
train->y,
|
|
|
|
train->z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
train->var_0C |= (1 << 7);
|
|
|
|
train->var_C8 = scenario_rand();
|
|
|
|
train->var_CA = scenario_rand();
|
|
|
|
|
|
|
|
train->var_C5 = train->var_CA & 0x7;
|
|
|
|
train->sprite_width = 13;
|
|
|
|
train->sprite_height_negative = 45;
|
|
|
|
train->sprite_height_positive = 5;
|
|
|
|
|
|
|
|
sprite_move(train->x, train->y, train->z, (rct_sprite*)train);
|
|
|
|
invalidate_sprite_2((rct_sprite*)train);
|
|
|
|
|
|
|
|
train->var_4E = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
(GET_VEHICLE(vehicle->prev_vehicle_on_ride))->next_vehicle_on_ride = lastVehicle->next_vehicle_on_ride;
|
|
|
|
(GET_VEHICLE(lastVehicle->next_vehicle_on_ride))->prev_vehicle_on_ride = vehicle->prev_vehicle_on_ride;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9EFE
|
|
|
|
*/
|
2015-12-11 21:55:34 +01:00
|
|
|
static void vehicle_update_crash_setup(rct_vehicle* vehicle) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_CRASHING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
|
|
|
|
int num_peeps = vehicle_get_total_num_peeps(vehicle);
|
|
|
|
if (num_peeps != 0) {
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_HAUNTED_HOUSE_SCREAM_2,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
int edx = vehicle->velocity >> 10;
|
|
|
|
|
|
|
|
rct_vehicle* lastVehicle = vehicle;
|
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* trainVehicle; spriteId != 0xFFFF; spriteId = trainVehicle->next_vehicle_on_train) {
|
|
|
|
trainVehicle = GET_VEHICLE(spriteId);
|
|
|
|
lastVehicle = trainVehicle;
|
|
|
|
|
|
|
|
trainVehicle->sub_state = 0;
|
2016-01-12 18:32:16 +01:00
|
|
|
int x = RCT2_ADDRESS(0x009A3AC4, sint16)[trainVehicle->sprite_direction & 0xFE];
|
|
|
|
int y = RCT2_ADDRESS(0x009A3AC6, sint16)[trainVehicle->sprite_direction & 0xFE];
|
2015-12-11 21:55:34 +01:00
|
|
|
|
|
|
|
int ecx = RCT2_ADDRESS(0x009A37E4, uint32)[trainVehicle->var_1F] >> 15;
|
|
|
|
x *= ecx;
|
|
|
|
y *= ecx;
|
|
|
|
x >>= 16;
|
|
|
|
y >>= 16;
|
|
|
|
ecx = RCT2_ADDRESS(0x009A38D4, uint32)[trainVehicle->var_1F] >> 23;
|
|
|
|
x *= edx;
|
|
|
|
y *= edx;
|
|
|
|
ecx *= edx;
|
|
|
|
x >>= 8;
|
|
|
|
y >>= 8;
|
|
|
|
ecx >>= 8;
|
|
|
|
|
|
|
|
trainVehicle->var_B6 = x;
|
|
|
|
trainVehicle->var_C0 = y;
|
|
|
|
trainVehicle->var_4E = ecx;
|
|
|
|
trainVehicle->var_B6 += (scenario_rand() & 0xF) - 8;
|
|
|
|
trainVehicle->var_C0 += (scenario_rand() & 0xF) - 8;
|
|
|
|
trainVehicle->var_4E += (scenario_rand() & 0xF) - 8;
|
|
|
|
|
|
|
|
trainVehicle->track_x = 0;
|
|
|
|
trainVehicle->track_y = 0;
|
|
|
|
trainVehicle->track_z = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
(GET_VEHICLE(vehicle->prev_vehicle_on_ride))->next_vehicle_on_ride = lastVehicle->next_vehicle_on_ride;
|
|
|
|
(GET_VEHICLE(lastVehicle->next_vehicle_on_ride))->prev_vehicle_on_ride = vehicle->prev_vehicle_on_ride;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D8937
|
|
|
|
*/
|
2015-11-29 15:42:04 +01:00
|
|
|
static void vehicle_update_travelling(rct_vehicle* vehicle) {
|
2015-11-29 20:45:01 +01:00
|
|
|
vehicle_check_if_missing(vehicle);
|
2015-11-29 15:42:04 +01:00
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-29 15:42:04 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0 && ride->mode == RIDE_MODE_ROTATING_LIFT)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (vehicle->sub_state == 2) {
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-11-29 15:42:04 +01:00
|
|
|
vehicle->var_C0--;
|
|
|
|
if (vehicle->var_C0 == 0)
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_FREEFALL_DROP &&
|
|
|
|
vehicle->var_C5 != 0) {
|
|
|
|
|
|
|
|
vehicle->var_C5++;
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-29 15:42:04 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:56:19 +01:00
|
|
|
uint32 flags = vehicle_update_track_motion(vehicle, NULL);
|
2015-11-29 15:42:04 +01:00
|
|
|
|
|
|
|
bool skipCheck = false;
|
2015-12-12 11:21:49 +01:00
|
|
|
if (flags & ((1 << 8) | (1 << 9)) &&
|
2015-11-29 15:42:04 +01:00
|
|
|
ride->mode == RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE &&
|
|
|
|
vehicle->sub_state == 0) {
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
skipCheck = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!skipCheck) {
|
|
|
|
if (flags & (1 << 6)) {
|
2015-12-11 21:55:34 +01:00
|
|
|
vehicle_update_crash_setup(vehicle);
|
2015-11-29 15:42:04 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & (1 << 7)) {
|
2015-12-12 13:21:13 +01:00
|
|
|
vehicle_update_collision_setup(vehicle);
|
2015-11-29 15:42:04 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-11-29 20:45:01 +01:00
|
|
|
if (flags & ((1 << 5) | (1 << 12))) {
|
2015-11-29 15:42:04 +01:00
|
|
|
if (ride->mode == RIDE_MODE_ROTATING_LIFT) {
|
|
|
|
if (vehicle->sub_state <= 1) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2015-12-11 14:07:22 +01:00
|
|
|
else if (ride->mode == RIDE_MODE_BOAT_HIRE) {
|
|
|
|
vehicle_update_travelling_boat_hire_setup(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
2015-11-29 15:42:04 +01:00
|
|
|
else if (ride->mode == RIDE_MODE_SHUTTLE) {
|
|
|
|
vehicle->update_flags ^= VEHICLE_UPDATE_FLAG_3;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_SIX_FLAGS_DEPRECATED) {
|
|
|
|
if (vehicle->sub_state != 0) {
|
|
|
|
vehicle->update_flags ^= VEHICLE_UPDATE_FLAG_3;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (vehicle->sub_state != 0) {
|
2015-12-11 21:55:34 +01:00
|
|
|
vehicle_update_crash_setup(vehicle);
|
2015-11-29 15:42:04 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_ROTATING_LIFT &&
|
|
|
|
vehicle->sub_state <= 1) {
|
|
|
|
|
|
|
|
if (vehicle->sub_state == 0) {
|
|
|
|
if (vehicle->velocity >= -131940)
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -3298;
|
2015-11-29 15:42:04 +01:00
|
|
|
vehicle->velocity = max(vehicle->velocity, -131940);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (vehicle_next_tower_element_is_top(vehicle) == true) {
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
vehicle->sub_state = 2;
|
|
|
|
vehicle->var_C0 = 150;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (vehicle->velocity <= 131940)
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 3298;
|
2015-11-29 15:42:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-17 00:39:38 +01:00
|
|
|
if (flags & VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_ON_LIFT_HILL) {
|
2015-11-29 15:42:04 +01:00
|
|
|
if (ride->mode == RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE) {
|
|
|
|
if (vehicle->sub_state == 0) {
|
|
|
|
if (vehicle->velocity != 0)
|
|
|
|
vehicle->var_B8 |= (1 << 1);
|
|
|
|
|
|
|
|
if (!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_12)) {
|
2015-11-29 20:45:01 +01:00
|
|
|
if (vehicle->velocity >= ride->lift_hill_speed * -31079) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -15539;
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-29 20:45:01 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0) {
|
|
|
|
vehicle->var_B8 &= ~(1 << 1);
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_7;
|
|
|
|
}
|
2015-11-29 15:42:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vehicle->var_B8 |= (1 << 1);
|
|
|
|
if (vehicle->velocity <= ride->lift_hill_speed * 31079) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 15539;
|
2015-11-29 15:42:04 +01:00
|
|
|
if (vehicle->velocity != 0) {
|
2015-11-29 20:45:01 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_7;
|
|
|
|
vehicle->var_B8 &= ~(1 << 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vehicle->var_B8 &= ~(1 << 1);
|
2015-11-29 15:42:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(flags & (1 << 3)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE &&
|
|
|
|
vehicle->velocity >= 0 &&
|
|
|
|
!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_12)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_POWERED_LAUNCH_PASSTROUGH &&
|
|
|
|
vehicle->velocity < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle->current_station = RCT2_GLOBAL(0x00F64E1C, uint8);
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
if (vehicle->velocity < 0)
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D8C36
|
|
|
|
*/
|
2015-12-11 16:28:07 +01:00
|
|
|
static void vehicle_update_arriving(rct_vehicle* vehicle) {
|
|
|
|
RCT2_GLOBAL(0x00F64E35, uint8) = 1;
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-11 16:28:07 +01:00
|
|
|
|
|
|
|
switch (ride->mode) {
|
|
|
|
case RIDE_MODE_SWING:
|
|
|
|
case RIDE_MODE_ROTATION:
|
|
|
|
case RIDE_MODE_FORWARD_ROTATION:
|
|
|
|
case RIDE_MODE_BACKWARD_ROTATION:
|
|
|
|
case RIDE_MODE_FILM_AVENGING_AVIATORS:
|
|
|
|
case RIDE_MODE_FILM_THRILL_RIDERS:
|
|
|
|
case RIDE_MODE_BEGINNERS:
|
|
|
|
case RIDE_MODE_INTENSE:
|
|
|
|
case RIDE_MODE_BERSERK:
|
|
|
|
case RIDE_MODE_3D_FILM_MOUSE_TAILS:
|
|
|
|
case RIDE_MODE_3D_FILM_STORM_CHASERS:
|
|
|
|
case RIDE_MODE_3D_FILM_SPACE_RAIDERS:
|
|
|
|
case RIDE_MODE_CIRCUS_SHOW:
|
|
|
|
case RIDE_MODE_SPACE_RINGS:
|
|
|
|
case RIDE_MODE_HAUNTED_HOUSE:
|
|
|
|
case RIDE_MODE_CROOKED_HOUSE:
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_12;
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-11 16:28:07 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN &&
|
|
|
|
ride->breakdown_reason_pending == BREAKDOWN_BRAKES_FAILURE &&
|
|
|
|
ride->inspection_station == vehicle->current_station &&
|
|
|
|
ride->mechanic_status != RIDE_MECHANIC_STATUS_4)
|
|
|
|
RCT2_GLOBAL(0x00F64E35, uint8) = 0;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-12-11 16:28:07 +01:00
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
if (vehicle->sub_state == 0) {
|
|
|
|
if (ride->mode == RIDE_MODE_RACE &&
|
|
|
|
ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) {
|
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->velocity <= 131940) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 3298;
|
2015-12-11 16:28:07 +01:00
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint32 velocity_diff = vehicle->velocity;
|
|
|
|
if (velocity_diff >= 1572864)
|
|
|
|
velocity_diff /= 8;
|
2015-12-12 11:21:49 +01:00
|
|
|
else
|
2015-12-11 16:28:07 +01:00
|
|
|
velocity_diff /= 16;
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x00F64E35, uint8) == 0) {
|
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->num_circuits != 1) {
|
|
|
|
if (vehicle->num_laps + 1 < ride->num_circuits) {
|
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vehicle->velocity -= velocity_diff;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-11 16:28:07 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3) &&
|
2015-12-11 16:28:07 +01:00
|
|
|
vehicle->velocity >= -131940) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -3298;
|
2015-12-11 16:28:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->velocity >= -131940) {
|
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint32 velocity_diff = vehicle->velocity;
|
|
|
|
if (velocity_diff < -1572864)
|
|
|
|
velocity_diff /= 8;
|
|
|
|
else
|
|
|
|
velocity_diff /= 16;
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x00F64E35, uint8) == 0) {
|
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->num_laps + 1 < ride->num_circuits) {
|
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-12-11 16:28:07 +01:00
|
|
|
if (vehicle->num_laps + 1 != ride->num_circuits) {
|
|
|
|
vehicle->velocity -= velocity_diff;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-11 16:28:07 +01:00
|
|
|
goto loc_6D8E36;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_ALLOW_MULTIPLE_CIRCUITS &&
|
|
|
|
ride->mode != RIDE_MODE_SHUTTLE &&
|
|
|
|
ride->mode != RIDE_MODE_POWERED_LAUNCH) {
|
2015-12-11 16:49:21 +01:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_12;
|
2015-12-11 16:28:07 +01:00
|
|
|
}
|
|
|
|
else{
|
|
|
|
vehicle->velocity -= velocity_diff;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-11 16:28:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32 flags;
|
|
|
|
loc_6D8E36:
|
2015-12-15 19:56:19 +01:00
|
|
|
flags = vehicle_update_track_motion(vehicle, NULL);
|
2015-12-11 16:28:07 +01:00
|
|
|
if (flags & (1 << 7) &&
|
|
|
|
RCT2_GLOBAL(0x00F64E35, uint8) == 0) {
|
2015-12-12 13:21:13 +01:00
|
|
|
vehicle_update_collision_setup(vehicle);
|
2015-12-11 16:28:07 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flags & (1 << 0) &&
|
|
|
|
RCT2_GLOBAL(0x00F64E35, uint8) == 0) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_DEPARTING;
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(flags & ((1 << 0) | (1 << 1) | (1 << 5)))) {
|
|
|
|
if (vehicle->velocity > 98955)
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->var_C0++;
|
|
|
|
if (flags & (1 << 1) &&
|
2015-12-16 20:12:58 +01:00
|
|
|
vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_14 &&
|
2015-12-11 16:28:07 +01:00
|
|
|
vehicle->var_C0 < 40){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_map_element* mapElement = map_get_track_element_at(
|
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z / 8
|
|
|
|
);
|
|
|
|
|
|
|
|
vehicle->current_station = map_get_station(mapElement);
|
|
|
|
vehicle->num_laps++;
|
|
|
|
|
|
|
|
if (vehicle->sub_state != 0) {
|
|
|
|
if (vehicle->num_laps < ride->num_circuits) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_DEPARTING;
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->num_laps == ride->num_circuits &&
|
|
|
|
vehicle->update_flags & VEHICLE_UPDATE_FLAG_12) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_DEPARTING;
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->num_circuits != 1 &&
|
|
|
|
vehicle->num_laps < ride->num_circuits) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_DEPARTING;
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ride->mode == RIDE_MODE_UPWARD_LAUNCH ||
|
|
|
|
ride->mode == RIDE_MODE_DOWNWARD_LAUNCH) &&
|
|
|
|
vehicle->var_CE < 2) {
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_RIDE_LAUNCH_2,
|
2015-12-12 11:21:49 +01:00
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
2015-12-11 16:28:07 +01:00
|
|
|
vehicle->z);
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-11 16:28:07 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_DEPARTING;
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_RACE &&
|
|
|
|
ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_DEPARTING;
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_12;
|
|
|
|
vehicle->velocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-11 16:28:07 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_UNLOADING_PASSENGERS;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9002
|
|
|
|
*/
|
2015-12-11 18:35:24 +01:00
|
|
|
static void vehicle_update_unloading_passengers(rct_vehicle* vehicle) {
|
|
|
|
if (vehicle->sub_state == 0) {
|
|
|
|
if (!vehicle_open_restraints(vehicle)) {
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-11 18:35:24 +01:00
|
|
|
if (ride->mode == RIDE_MODE_FORWARD_ROTATION ||
|
|
|
|
ride->mode == RIDE_MODE_BACKWARD_ROTATION) {
|
|
|
|
uint8 seat = ((-vehicle->var_1F) >> 3) & 0xF;
|
|
|
|
if (vehicle->restraints_position == 255 &&
|
|
|
|
(vehicle->peep[seat * 2] != 0xFFFF)) {
|
|
|
|
vehicle->next_free_seat -= 2;
|
|
|
|
|
|
|
|
rct_peep* peep = GET_PEEP(vehicle->peep[seat * 2]);
|
|
|
|
vehicle->peep[seat * 2] = 0xFFFF;
|
|
|
|
|
|
|
|
peep_decrement_num_riders(peep);
|
|
|
|
peep->sub_state = 7;
|
|
|
|
peep->state = PEEP_STATE_LEAVING_RIDE;
|
|
|
|
peep_window_state_update(peep);
|
|
|
|
|
|
|
|
peep = GET_PEEP(vehicle->peep[seat * 2 + 1]);
|
|
|
|
vehicle->peep[seat * 2 + 1] = 0xFFFF;
|
|
|
|
|
|
|
|
peep_decrement_num_riders(peep);
|
|
|
|
peep->sub_state = 7;
|
|
|
|
peep->state = PEEP_STATE_LEAVING_RIDE;
|
|
|
|
peep_window_state_update(peep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (ride->exits[vehicle->current_station] == 0xFFFF) {
|
|
|
|
if (vehicle->sub_state != 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) &&
|
|
|
|
vehicle->update_flags & VEHICLE_UPDATE_FLAG_TESTING &&
|
|
|
|
ride->current_test_segment + 1 >= ride->num_stations) {
|
|
|
|
vehicle_update_test_finish(vehicle);
|
|
|
|
}
|
|
|
|
vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* train; spriteId != 0xFFFF; spriteId = train->next_vehicle_on_train) {
|
|
|
|
train = GET_VEHICLE(spriteId);
|
|
|
|
if (train->restraints_position != 255)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (train->next_free_seat == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
train->next_free_seat = 0;
|
|
|
|
for (uint8 peepIndex = 0; peepIndex < train->num_peeps; peepIndex++) {
|
|
|
|
rct_peep* peep = GET_PEEP(train->peep[peepIndex]);
|
|
|
|
peep_decrement_num_riders(peep);
|
|
|
|
peep->sub_state = 7;
|
|
|
|
peep->state = PEEP_STATE_LEAVING_RIDE;
|
|
|
|
peep_window_state_update(peep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-12-11 18:35:24 +01:00
|
|
|
if (vehicle->sub_state != 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* train; spriteId != 0xFFFF; spriteId = train->next_vehicle_on_train) {
|
|
|
|
train = GET_VEHICLE(spriteId);
|
|
|
|
if (train->num_peeps != train->next_free_seat)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED) &&
|
|
|
|
vehicle->update_flags & VEHICLE_UPDATE_FLAG_TESTING &&
|
|
|
|
ride->current_test_segment + 1 >= ride->num_stations) {
|
|
|
|
vehicle_update_test_finish(vehicle);
|
|
|
|
}
|
|
|
|
vehicle->status = VEHICLE_STATUS_MOVING_TO_END_OF_STATION;
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9CE9
|
|
|
|
*/
|
|
|
|
static void vehicle_update_waiting_for_cable_lift(rct_vehicle *vehicle)
|
|
|
|
{
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-16 19:37:45 +01:00
|
|
|
|
|
|
|
rct_vehicle* cableLift = GET_VEHICLE(ride->cable_lift);
|
|
|
|
|
|
|
|
if (cableLift->status != VEHICLE_STATUS_WAITING_FOR_PASSENGERS)
|
|
|
|
return;
|
|
|
|
|
|
|
|
cableLift->status = VEHICLE_STATUS_WAITING_TO_DEPART;
|
|
|
|
cableLift->var_C0 = vehicle->sprite_index;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9D21
|
|
|
|
*/
|
|
|
|
static void vehicle_update_travelling_cable_lift(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-16 19:37:45 +01:00
|
|
|
|
|
|
|
if (vehicle->sub_state == 0) {
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_BROKEN_TRAIN) {
|
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_BROKEN_DOWN;
|
|
|
|
ride_breakdown_add_news_item(vehicle->ride);
|
|
|
|
ride->window_invalidate_flags |=
|
|
|
|
RIDE_INVALIDATE_RIDE_MAIN |
|
|
|
|
RIDE_INVALIDATE_RIDE_LIST |
|
|
|
|
RIDE_INVALIDATE_RIDE_MAINTENANCE;
|
|
|
|
|
|
|
|
ride->mechanic_status = RIDE_MECHANIC_STATUS_CALLING;
|
|
|
|
ride->inspection_station = vehicle->current_station;
|
|
|
|
ride->breakdown_reason = ride->breakdown_reason_pending;
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_peep_easteregg_here_we_are(vehicle);
|
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TESTED)) {
|
2016-01-19 13:41:20 +01:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_TESTING) {
|
|
|
|
if (ride->current_test_segment + 1 < ride->num_stations) {
|
|
|
|
ride->current_test_segment++;
|
2016-02-17 19:22:38 +01:00
|
|
|
ride->current_test_station = vehicle->current_station;
|
2015-12-16 19:37:45 +01:00
|
|
|
}
|
|
|
|
else {
|
2016-01-19 13:41:20 +01:00
|
|
|
vehicle_update_test_finish(vehicle);
|
2015-12-16 19:37:45 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-19 13:41:20 +01:00
|
|
|
else if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_TEST_IN_PROGRESS)) {
|
|
|
|
vehicle_test_reset(vehicle);
|
|
|
|
}
|
2015-12-16 19:37:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-12-16 19:37:45 +01:00
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
if (vehicle->velocity <= 439800) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 4398;
|
2015-12-16 19:37:45 +01:00
|
|
|
}
|
|
|
|
int flags = vehicle_update_track_motion(vehicle, NULL);
|
|
|
|
|
2016-01-11 19:35:36 +01:00
|
|
|
if (flags & VEHICLE_UPDATE_MOTION_TRACK_FLAG_11) {
|
2015-12-16 19:37:45 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_TRAVELLING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle->lost_time_out = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->sub_state == 2)
|
|
|
|
return;
|
|
|
|
|
2016-01-11 19:35:36 +01:00
|
|
|
if (flags & VEHICLE_UPDATE_MOTION_TRACK_FLAG_3 && vehicle->current_station == RCT2_GLOBAL(0x00F64E1C, uint8))
|
2015-12-16 19:37:45 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
vehicle->sub_state = 2;
|
|
|
|
|
|
|
|
if (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED ||
|
|
|
|
ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// This is slightly different to the vanilla function
|
|
|
|
ride->station_depart[vehicle->current_station] &= STATION_DEPART_FLAG;
|
|
|
|
uint8 waitingTime = 3;
|
|
|
|
if (ride->depart_flags & RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH) {
|
|
|
|
waitingTime = max(ride->min_waiting_time, 3);
|
|
|
|
waitingTime = min(waitingTime, 127);
|
|
|
|
}
|
|
|
|
|
|
|
|
ride->station_depart[vehicle->current_station] |= waitingTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9820
|
|
|
|
*/
|
2015-12-20 15:21:06 +01:00
|
|
|
static void vehicle_update_travelling_boat(rct_vehicle* vehicle)
|
|
|
|
{
|
2015-12-11 14:07:22 +01:00
|
|
|
vehicle_check_if_missing(vehicle);
|
2015-12-21 22:33:17 +01:00
|
|
|
vehicle_update_motion_boat_hire(vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void loc_6DA9F9(rct_vehicle *vehicle, int x, int y, int bx, int dx)
|
|
|
|
{
|
|
|
|
vehicle->remaining_distance = 0;
|
2015-12-27 12:46:15 +01:00
|
|
|
if (!vehicle_update_motion_collision_detection(vehicle, x, y, vehicle->z, NULL)) {
|
2015-12-21 22:33:17 +01:00
|
|
|
vehicle->track_x = bx;
|
|
|
|
vehicle->track_y = dx;
|
|
|
|
|
|
|
|
rct_map_element *mapElement = map_get_track_element_at(
|
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z >> 3
|
|
|
|
);
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
2015-12-21 22:33:17 +01:00
|
|
|
vehicle->track_type =
|
|
|
|
(mapElement->properties.track.type << 2) |
|
|
|
|
(ride->boat_hire_return_direction & 3);
|
|
|
|
|
2015-12-31 11:27:33 +01:00
|
|
|
vehicle->track_progress = 0;
|
2015-12-21 22:33:17 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_TRAVELLING;
|
|
|
|
unk_F64E20->x = x;
|
|
|
|
unk_F64E20->y = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DA717
|
|
|
|
*/
|
|
|
|
static void vehicle_update_motion_boat_hire(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) = 0;
|
|
|
|
vehicle->velocity += vehicle->acceleration;
|
|
|
|
RCT2_GLOBAL(0x00F64E08, sint32) = vehicle->velocity;
|
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) = (vehicle->velocity >> 10) * 42;
|
|
|
|
|
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
if (vehicleEntry->flags_b & (VEHICLE_ENTRY_FLAG_B_7 | VEHICLE_ENTRY_FLAG_B_8)) {
|
|
|
|
sub_6D63D4(vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32) = 1;
|
|
|
|
vehicle->acceleration = 0;
|
|
|
|
vehicle->remaining_distance += RCT2_GLOBAL(0x00F64E0C, sint32);
|
|
|
|
if (vehicle->remaining_distance >= 0x368A) {
|
|
|
|
vehicle->var_B8 &= ~(1 << 1);
|
|
|
|
unk_F64E20->x = vehicle->x;
|
|
|
|
unk_F64E20->y = vehicle->y;
|
|
|
|
unk_F64E20->z = vehicle->z;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
|
|
|
|
for (;;) {
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DA7A5
|
2015-12-21 22:33:17 +01:00
|
|
|
vehicle->var_35++;
|
|
|
|
int x = (vehicle->boat_location.x * 32) + 16;
|
|
|
|
int y = (vehicle->boat_location.y * 32) + 16;
|
|
|
|
int z;
|
|
|
|
uint8 bl;
|
|
|
|
|
|
|
|
x -= vehicle->x;
|
|
|
|
if (x >= 0) {
|
|
|
|
y -= vehicle->y;
|
|
|
|
if (y < 0) {
|
|
|
|
// loc_6DA81A:
|
|
|
|
y = -y;
|
|
|
|
bl = 24;
|
|
|
|
if (y <= x * 4) {
|
|
|
|
bl = 16;
|
|
|
|
if (x <= y * 4) {
|
|
|
|
bl = 20;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
bl = 8;
|
|
|
|
if (y <= x * 4) {
|
|
|
|
bl = 16;
|
|
|
|
if (x <= y * 4) {
|
|
|
|
bl = 12;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
y -= vehicle->y;
|
|
|
|
if (y < 0) {
|
|
|
|
// loc_6DA83D:
|
|
|
|
x = -x;
|
|
|
|
y = -y;
|
|
|
|
bl = 24;
|
|
|
|
if (y <= x * 4) {
|
|
|
|
bl = 0;
|
|
|
|
if (x <= y * 4) {
|
|
|
|
bl = 28;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
x = -x;
|
|
|
|
bl = 8;
|
|
|
|
if (y <= x * 4) {
|
|
|
|
bl = 0;
|
|
|
|
if (x <= y * 4) {
|
|
|
|
bl = 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_6DA861:
|
|
|
|
vehicle->var_34 = bl;
|
|
|
|
x += y;
|
|
|
|
if (x <= 12) {
|
|
|
|
sub_6DA280(vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(vehicle->var_35 & (1 << 0))) {
|
|
|
|
uint8 spriteDirection = vehicle->sprite_direction;
|
|
|
|
if (spriteDirection != vehicle->var_34) {
|
|
|
|
uint8 dl = (vehicle->var_34 + 16 - spriteDirection) & 0x1E;
|
|
|
|
if (dl >= 16) {
|
|
|
|
spriteDirection += 2;
|
|
|
|
if (dl > 24) {
|
|
|
|
vehicle->var_35--;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
spriteDirection -= 2;
|
|
|
|
if (dl < 8) {
|
|
|
|
vehicle->var_35--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->sprite_direction = spriteDirection & 0x1E;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int edi = (vehicle->sprite_direction | (vehicle->var_35 & 1)) & 0x1F;
|
|
|
|
x = vehicle->x + RCT2_ADDRESS(0x009A36C4, sint16)[edi * 4];
|
|
|
|
y = vehicle->y + RCT2_ADDRESS(0x009A36C6, sint16)[edi * 4];
|
|
|
|
z = vehicle->z;
|
2015-12-27 12:46:15 +01:00
|
|
|
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, NULL)) {
|
2016-01-10 10:24:56 +01:00
|
|
|
vehicle->remaining_distance = 0;
|
|
|
|
if (vehicle->sprite_direction == vehicle->var_34) {
|
|
|
|
vehicle->sprite_direction ^= (1 << 4);
|
|
|
|
sub_6DA280(vehicle);
|
|
|
|
vehicle->sprite_direction ^= (1 << 4);
|
|
|
|
}
|
|
|
|
break;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int bx = floor2(x, 32);
|
|
|
|
int dx = floor2(y, 32);
|
|
|
|
if (bx != vehicle->track_x || dx != vehicle->track_y) {
|
|
|
|
if (vehicle_is_boat_on_water(vehicle, x, y)) {
|
|
|
|
// loc_6DA939:
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-21 22:33:17 +01:00
|
|
|
bool do_loc_6DAA97 = false;
|
|
|
|
if (vehicle->sub_state != 1) {
|
|
|
|
do_loc_6DAA97 = true;
|
|
|
|
} else {
|
|
|
|
uint16 xy = (((dx >> 5) << 8) | (bx >> 5));
|
|
|
|
if (xy != ride->boat_hire_return_position) {
|
|
|
|
do_loc_6DAA97 = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_6DAA97:
|
|
|
|
if (do_loc_6DAA97) {
|
|
|
|
vehicle->remaining_distance = 0;
|
|
|
|
if (vehicle->sprite_direction == vehicle->var_34) {
|
|
|
|
sub_6DA280(vehicle);
|
|
|
|
}
|
2016-01-10 10:24:56 +01:00
|
|
|
break;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ride->boat_hire_return_direction & 1)) {
|
|
|
|
uint16 bp = y & 0x1F;
|
|
|
|
if (bp == 16) {
|
|
|
|
loc_6DA9F9(vehicle, x, y, bx, dx);
|
2016-01-10 10:24:56 +01:00
|
|
|
break;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
|
|
|
if (bp <= 16) {
|
|
|
|
x = unk_F64E20->x;
|
|
|
|
y = unk_F64E20->y + 1;
|
|
|
|
} else {
|
|
|
|
x = unk_F64E20->x;
|
|
|
|
y = unk_F64E20->y - 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// loc_6DA9A2:
|
|
|
|
uint16 bp = x & 0x1F;
|
|
|
|
if (bp == 16) {
|
|
|
|
loc_6DA9F9(vehicle, x, y, bx, dx);
|
2016-01-10 10:24:56 +01:00
|
|
|
break;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
|
|
|
if (bp <= 16) {
|
|
|
|
x = unk_F64E20->x + 1;
|
|
|
|
y = unk_F64E20->y;
|
|
|
|
} else {
|
|
|
|
x = unk_F64E20->x - 1;
|
|
|
|
y = unk_F64E20->y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_6DA9D1:
|
|
|
|
vehicle->remaining_distance = 0;
|
2015-12-27 12:46:15 +01:00
|
|
|
if (!vehicle_update_motion_collision_detection(vehicle, x, y, vehicle->z, NULL)) {
|
2015-12-21 22:33:17 +01:00
|
|
|
unk_F64E20->x = x;
|
|
|
|
unk_F64E20->y = y;
|
|
|
|
}
|
2016-01-10 10:24:56 +01:00
|
|
|
break;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
|
|
|
vehicle->track_x = bx;
|
|
|
|
vehicle->track_y = dx;
|
|
|
|
}
|
|
|
|
|
2015-12-31 10:53:23 +01:00
|
|
|
vehicle->remaining_distance -= RCT2_ADDRESS(0x009A36C8, uint32)[edi * 2];
|
2015-12-21 22:33:17 +01:00
|
|
|
unk_F64E20->x = x;
|
|
|
|
unk_F64E20->y = y;
|
|
|
|
if (vehicle->remaining_distance < 0x368A) {
|
2016-01-10 10:24:56 +01:00
|
|
|
break;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprite_move(
|
|
|
|
unk_F64E20->x,
|
|
|
|
unk_F64E20->y,
|
|
|
|
unk_F64E20->z,
|
|
|
|
(rct_sprite*)vehicle
|
|
|
|
);
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
// loc_6DAAC9:
|
|
|
|
{
|
|
|
|
int edx = vehicle->velocity >> 8;
|
|
|
|
edx = (edx * edx);
|
|
|
|
if (vehicle->velocity < 0) {
|
|
|
|
edx = -edx;
|
|
|
|
}
|
|
|
|
edx >>= 5;
|
2016-01-25 19:17:25 +01:00
|
|
|
|
|
|
|
// Hack to fix people messing with boat hire
|
|
|
|
int friction = vehicle->friction == 0 ? 1 : vehicle->friction;
|
|
|
|
|
|
|
|
int eax = ((vehicle->velocity >> 1) + edx) / friction;
|
2015-12-21 22:33:17 +01:00
|
|
|
int ecx = -eax;
|
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3) {
|
|
|
|
eax = vehicle->speed << 14;
|
2016-01-25 19:17:25 +01:00
|
|
|
int ebx = (vehicle->speed * friction) >> 2;
|
2015-12-21 22:33:17 +01:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_3) {
|
|
|
|
eax = -eax;
|
|
|
|
}
|
|
|
|
eax -= vehicle->velocity;
|
|
|
|
edx = vehicle->powered_acceleration * 2;
|
|
|
|
ecx += (eax * edx) / ebx;
|
|
|
|
}
|
|
|
|
vehicle->acceleration = ecx;
|
|
|
|
}
|
|
|
|
// eax = RCT2_GLOBAL(0x00F64E18, uint32);
|
|
|
|
// ebx = RCT2_GLOBAL(0x00F64E1C, uint32);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DA280
|
|
|
|
*/
|
|
|
|
static void sub_6DA280(rct_vehicle *vehicle)
|
|
|
|
{
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-29 13:06:11 +01:00
|
|
|
|
|
|
|
rct_xy8 location = {
|
|
|
|
.x = (vehicle->x + RCT2_ADDRESS(0x00993CCC, sint16)[2 * (ride->boat_hire_return_direction & 3)]) / 32,
|
|
|
|
.y = (vehicle->y + RCT2_ADDRESS(0x00993CCE, sint16)[2 * (ride->boat_hire_return_direction & 3)]) / 32
|
|
|
|
};
|
|
|
|
|
|
|
|
if (*((uint16*)&location) == ride->boat_hire_return_position) {
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle->boat_location = location;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
uint8 curDirection = ((vehicle->sprite_direction + 19) >> 3) & 3;
|
|
|
|
uint8 randDirection = scenario_rand() & 3;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-12-29 13:06:11 +01:00
|
|
|
if (scenario_rand() & 1 && (!(rideEntry->flags & RIDE_ENTRY_FLAG_7) || vehicle->lost_time_out > 1920)) {
|
|
|
|
location = *((rct_xy8*)&ride->boat_hire_return_position);
|
|
|
|
rct_xy16 destLocation = {
|
|
|
|
.x = location.x * 32 - RCT2_ADDRESS(0x00993CCC, sint16)[2 * (ride->boat_hire_return_direction & 3)] + 16,
|
|
|
|
.y = location.y * 32 - RCT2_ADDRESS(0x00993CCE, sint16)[2 * (ride->boat_hire_return_direction & 3)] + 16
|
|
|
|
};
|
|
|
|
|
|
|
|
destLocation.x -= vehicle->x;
|
|
|
|
destLocation.y -= vehicle->y;
|
|
|
|
|
|
|
|
if (abs(destLocation.x) <= abs(destLocation.y)) {
|
2015-12-31 10:53:23 +01:00
|
|
|
randDirection = destLocation.y < 0 ? 3 : 1;
|
2015-12-29 13:06:11 +01:00
|
|
|
} else {
|
2015-12-31 10:53:23 +01:00
|
|
|
randDirection = destLocation.x < 0 ? 0 : 2;
|
2015-12-29 13:06:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const sint8 rotations[] = { 0, 1, -1, 2 };
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
if (randDirection + rotations[i] == curDirection) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint16 x = vehicle->track_x + RCT2_ADDRESS(0x00993CCC, sint16)[2 * (randDirection + rotations[i] & 3)];
|
|
|
|
sint16 y = vehicle->track_y + RCT2_ADDRESS(0x00993CCE, sint16)[2 * (randDirection + rotations[i] & 3)];
|
|
|
|
|
2015-12-31 10:53:23 +01:00
|
|
|
if (vehicle_is_boat_on_water(vehicle, x, y)) {
|
2015-12-29 13:06:11 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
vehicle->boat_location.x = x / 32;
|
|
|
|
vehicle->boat_location.y = y / 32;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
sint16 x = vehicle->track_x + RCT2_ADDRESS(0x00993CCC, sint16)[2 * (curDirection & 3)];
|
|
|
|
sint16 y = vehicle->track_y + RCT2_ADDRESS(0x00993CCE, sint16)[2 * (curDirection & 3)];
|
|
|
|
vehicle->boat_location.x = x / 32;
|
|
|
|
vehicle->boat_location.y = y / 32;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DA22A
|
|
|
|
*/
|
|
|
|
static bool vehicle_is_boat_on_water(rct_vehicle *vehicle, int x, int y)
|
|
|
|
{
|
|
|
|
int z = vehicle->track_z >> 3;
|
|
|
|
rct_map_element *mapElement = map_get_first_element_at(x >> 5, y >> 5);
|
|
|
|
do {
|
|
|
|
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_SURFACE) {
|
|
|
|
int waterZ = (mapElement->properties.surface.terrain & 0x1F) * 2;
|
|
|
|
if (z != waterZ) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (z > mapElement->base_height - 2 && z < mapElement->clearance_height + 2) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (!map_element_is_last_for_tile(mapElement++));
|
|
|
|
return false;
|
2015-12-11 14:07:22 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9249
|
|
|
|
*/
|
2015-11-21 12:35:02 +01:00
|
|
|
static void vehicle_update_swinging(rct_vehicle* vehicle) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-11-21 12:35:02 +01:00
|
|
|
|
|
|
|
// SubState for this ride means swinging state
|
|
|
|
// 0 == first swing
|
|
|
|
// 3 == full swing
|
|
|
|
uint8 swingState = vehicle->sub_state;
|
|
|
|
if (rideEntry->flags & RIDE_ENTRY_FLAG_ALTERNATIVE_SWING_MODE_1) {
|
|
|
|
swingState += 4;
|
|
|
|
if (rideEntry->flags & RIDE_ENTRY_FLAG_ALTERNATIVE_SWING_MODE_2)
|
|
|
|
swingState += 4;
|
|
|
|
}
|
|
|
|
uint8* edi = RCT2_ADDRESS(0x0099F9D0, uint8*)[swingState];
|
2016-01-04 10:36:29 +01:00
|
|
|
uint8 al = edi[(uint16)(vehicle->current_time + 1)];
|
2015-11-21 12:35:02 +01:00
|
|
|
|
|
|
|
// 0x80 indicates that a complete swing has been
|
|
|
|
// completed and the next swing can start
|
|
|
|
if (al != 0x80) {
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time++;
|
2015-11-21 12:35:02 +01:00
|
|
|
if (al == vehicle->var_1F)
|
|
|
|
return;
|
|
|
|
// Used to know which sprite to draw
|
|
|
|
vehicle->var_1F = al;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-21 12:35:02 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-21 12:35:02 +01:00
|
|
|
vehicle->var_CE++;
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED) {
|
|
|
|
// It takes 3 swings to get into full swing
|
|
|
|
// ride->rotations already takes this into account
|
|
|
|
if (vehicle->var_CE + 3 < ride->rotations) {
|
|
|
|
// Go to the next swing state until we
|
|
|
|
// are at full swing.
|
|
|
|
if (vehicle->sub_state != 3) {
|
|
|
|
vehicle->sub_state++;
|
|
|
|
}
|
|
|
|
vehicle_update_swinging(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// To get to this part of the code the
|
|
|
|
// swing has to be in slowing down phase
|
|
|
|
if (vehicle->sub_state == 0) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Go towards first swing state
|
|
|
|
vehicle->sub_state--;
|
|
|
|
vehicle_update_swinging(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9413
|
|
|
|
*/
|
2015-11-25 20:55:04 +01:00
|
|
|
static void vehicle_update_ferris_wheel_rotating(rct_vehicle* vehicle) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2016-01-04 10:36:29 +01:00
|
|
|
if ((vehicle->ferris_wheel_var_1 -= 1) != 0)
|
2015-11-25 20:55:04 +01:00
|
|
|
return;
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
sint8 ferris_wheel_var_0 = vehicle->ferris_wheel_var_0;
|
2015-11-25 20:55:04 +01:00
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
if (ferris_wheel_var_0 == 3) {
|
|
|
|
vehicle->ferris_wheel_var_0 = ferris_wheel_var_0;
|
|
|
|
vehicle->ferris_wheel_var_1 = ferris_wheel_var_0;
|
2015-11-25 20:55:04 +01:00
|
|
|
}
|
2016-01-04 10:36:29 +01:00
|
|
|
else if (ferris_wheel_var_0 < 3) {
|
|
|
|
if (ferris_wheel_var_0 != -8)
|
|
|
|
ferris_wheel_var_0--;
|
|
|
|
vehicle->ferris_wheel_var_0 = ferris_wheel_var_0;
|
|
|
|
vehicle->ferris_wheel_var_1 = -ferris_wheel_var_0;
|
2015-11-25 20:55:04 +01:00
|
|
|
}
|
|
|
|
else {
|
2016-01-04 10:36:29 +01:00
|
|
|
ferris_wheel_var_0--;
|
|
|
|
vehicle->ferris_wheel_var_0 = ferris_wheel_var_0;
|
|
|
|
vehicle->ferris_wheel_var_1 = ferris_wheel_var_0;
|
2015-11-25 20:55:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8 rotation = vehicle->var_1F;
|
2016-02-14 03:29:41 +01:00
|
|
|
if (ride->mode == RIDE_MODE_FORWARD_ROTATION)
|
2015-11-25 20:55:04 +01:00
|
|
|
rotation++;
|
|
|
|
else
|
|
|
|
rotation--;
|
|
|
|
|
|
|
|
rotation &= 0x7F;
|
|
|
|
vehicle->var_1F = rotation;
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-25 20:55:04 +01:00
|
|
|
if (rotation == vehicle->sub_state)
|
|
|
|
vehicle->var_CE++;
|
|
|
|
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-25 20:55:04 +01:00
|
|
|
|
|
|
|
uint8 subState = vehicle->sub_state;
|
2016-02-14 03:29:41 +01:00
|
|
|
if (ride->mode == RIDE_MODE_FORWARD_ROTATION)
|
2015-11-25 20:55:04 +01:00
|
|
|
subState++;
|
|
|
|
else
|
|
|
|
subState--;
|
|
|
|
subState &= 0x7F;
|
|
|
|
|
|
|
|
if (subState == vehicle->var_1F) {
|
|
|
|
bool shouldStop = true;
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED) {
|
2016-02-12 01:18:48 +01:00
|
|
|
if (vehicle->var_CE < ride->rotations)
|
2015-11-25 20:55:04 +01:00
|
|
|
shouldStop = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldStop) {
|
2016-01-04 10:36:29 +01:00
|
|
|
ferris_wheel_var_0 = vehicle->ferris_wheel_var_0;
|
|
|
|
vehicle->ferris_wheel_var_0 = -abs(ferris_wheel_var_0);
|
2016-02-12 22:11:10 +01:00
|
|
|
vehicle->ferris_wheel_var_1 = abs(ferris_wheel_var_0);
|
2015-11-25 20:55:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
if (vehicle->ferris_wheel_var_0 != -8)
|
2015-11-25 20:55:04 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
subState = vehicle->sub_state;
|
2016-02-14 03:29:41 +01:00
|
|
|
if (ride->mode == RIDE_MODE_FORWARD_ROTATION)
|
2015-11-25 20:55:04 +01:00
|
|
|
subState += 8;
|
|
|
|
else
|
|
|
|
subState -= 8;
|
|
|
|
subState &= 0x7F;
|
|
|
|
|
|
|
|
if (subState != vehicle->var_1F)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D94F2
|
|
|
|
*/
|
2015-11-21 13:13:10 +01:00
|
|
|
static void vehicle_update_simulator_operating(rct_vehicle* vehicle) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint8* edi = RCT2_ADDRESS(0x009A042C, uint8*)[vehicle->sub_state];
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
uint8 al = edi[(uint16)(vehicle->current_time + 1)];
|
2015-11-21 13:13:10 +01:00
|
|
|
if (al != 0xFF) {
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time++;
|
2015-11-21 13:13:10 +01:00
|
|
|
if (al == vehicle->var_1F)
|
|
|
|
return;
|
|
|
|
vehicle->var_1F = al;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-21 13:13:10 +01:00
|
|
|
return;
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-21 17:16:05 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D92FF
|
|
|
|
*/
|
2015-11-25 23:25:13 +01:00
|
|
|
static void vehicle_update_rotating(rct_vehicle* vehicle) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-11-25 23:25:13 +01:00
|
|
|
|
|
|
|
uint8* edi;
|
|
|
|
if (rideEntry->flags & RIDE_ENTRY_FLAG_ALTERNATIVE_ROTATION_MODE_1) {
|
|
|
|
edi = RCT2_ADDRESS(0x0099F0F4, uint8*)[vehicle->sub_state];
|
|
|
|
}
|
|
|
|
else if (rideEntry->flags & RIDE_ENTRY_FLAG_ALTERNATIVE_ROTATION_MODE_2) {
|
|
|
|
edi = RCT2_ADDRESS(0x009A2428, uint8*)[vehicle->sub_state];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
edi = RCT2_ADDRESS(0x0099EB1C, uint8*)[vehicle->sub_state];
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
sint32 var_4C = (sint16)vehicle->current_time;
|
2015-11-25 23:25:13 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == BREAKDOWN_CONTROL_FAILURE) {
|
2016-02-17 19:22:38 +01:00
|
|
|
var_4C += (ride->breakdown_sound_modifier >> 6) + 1;
|
2015-11-25 23:25:13 +01:00
|
|
|
}
|
|
|
|
var_4C++;
|
|
|
|
|
|
|
|
uint8 al = edi[(uint32)var_4C];
|
|
|
|
if (al != 0xFF) {
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = (uint16)var_4C;
|
2015-11-25 23:25:13 +01:00
|
|
|
if (al == vehicle->var_1F)
|
|
|
|
return;
|
|
|
|
vehicle->var_1F = al;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-25 23:25:13 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = -1;
|
2015-11-25 23:25:13 +01:00
|
|
|
vehicle->var_CE++;
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) != BREAKDOWN_CONTROL_FAILURE) {
|
|
|
|
bool shouldStop = true;
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED) {
|
|
|
|
al = vehicle->var_CE + 1;
|
|
|
|
if (ride->type == RIDE_TYPE_ENTERPRISE)
|
|
|
|
al += 9;
|
|
|
|
|
|
|
|
if (al < ride->rotations)
|
|
|
|
shouldStop = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldStop == true) {
|
|
|
|
if (vehicle->sub_state == 2) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
vehicle->sub_state++;
|
|
|
|
vehicle_update_rotating(vehicle);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ride->type == RIDE_TYPE_ENTERPRISE &&
|
|
|
|
vehicle->sub_state == 2) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->sub_state = 1;
|
|
|
|
vehicle_update_rotating(vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D97CB
|
|
|
|
*/
|
2015-11-25 21:26:15 +01:00
|
|
|
static void vehicle_update_space_rings_operating(rct_vehicle* vehicle) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint8* edi = RCT2_ADDRESS(0x009A0ACC, uint8*)[vehicle->sub_state];
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
uint8 al = edi[(uint16)(vehicle->current_time + 1)];
|
2015-11-25 21:26:15 +01:00
|
|
|
if (al != 0xFF) {
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time++;
|
2015-11-25 21:26:15 +01:00
|
|
|
if (al == vehicle->var_1F)
|
|
|
|
return;
|
|
|
|
vehicle->var_1F = al;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-25 21:26:15 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9641
|
|
|
|
*/
|
2015-11-25 21:26:15 +01:00
|
|
|
static void vehicle_update_haunted_house_operating(rct_vehicle* vehicle) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (vehicle->var_1F != 0) {
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 1) {
|
|
|
|
vehicle->var_1F++;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-25 21:26:15 +01:00
|
|
|
|
|
|
|
if (vehicle->var_1F == 19)
|
|
|
|
vehicle->var_1F = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16* edi = RCT2_ADDRESS(0x009A0ABC, uint16*)[vehicle->sub_state];
|
|
|
|
|
|
|
|
uint16 ax = *edi;
|
2016-01-04 10:36:29 +01:00
|
|
|
if ((uint16)(vehicle->current_time + 1) > ax) {
|
2015-11-25 21:26:15 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time++;
|
|
|
|
switch (vehicle->current_time) {
|
2015-11-25 21:26:15 +01:00
|
|
|
case 45:
|
|
|
|
audio_play_sound_at_location(
|
2015-12-12 11:21:49 +01:00
|
|
|
SOUND_HAUNTED_HOUSE_SCARE,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
2015-11-25 21:26:15 +01:00
|
|
|
vehicle->z);
|
|
|
|
break;
|
|
|
|
case 75:
|
|
|
|
vehicle->var_1F = 1;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-25 21:26:15 +01:00
|
|
|
break;
|
|
|
|
case 400:
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_HAUNTED_HOUSE_SCREAM_1,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z);
|
|
|
|
break;
|
|
|
|
case 745:
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_HAUNTED_HOUSE_SCARE,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z);
|
|
|
|
break;
|
|
|
|
case 775:
|
|
|
|
vehicle->var_1F = 1;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-25 21:26:15 +01:00
|
|
|
break;
|
|
|
|
case 1100:
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_HAUNTED_HOUSE_SCREAM_2,
|
|
|
|
vehicle->x,
|
|
|
|
vehicle->y,
|
|
|
|
vehicle->z);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006d9781
|
|
|
|
*/
|
2015-11-25 21:39:59 +01:00
|
|
|
static void vehicle_update_crooked_house_operating(rct_vehicle* vehicle) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
if ((uint16)(vehicle->current_time + 1) > RideCrookedHouseLength[vehicle->sub_state]) {
|
2015-11-25 21:39:59 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time++;
|
2015-11-25 21:39:59 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D9547
|
|
|
|
*/
|
2015-11-21 17:16:05 +01:00
|
|
|
static void vehicle_update_top_spin_operating(rct_vehicle* vehicle) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint8* edi = RCT2_ADDRESS(0x009A12E0, uint8*)[vehicle->sub_state];
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
uint8 al = edi[(vehicle->current_time + 1) * 2];
|
2015-11-21 17:16:05 +01:00
|
|
|
if (al != 0xFF) {
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = vehicle->current_time + 1;
|
2015-11-21 17:16:05 +01:00
|
|
|
if (al != vehicle->var_1F) {
|
|
|
|
vehicle->var_1F = al;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-21 17:16:05 +01:00
|
|
|
}
|
2016-01-04 10:36:29 +01:00
|
|
|
al = edi[vehicle->current_time * 2 + 1];
|
2015-11-21 17:16:05 +01:00
|
|
|
if (al != vehicle->var_20) {
|
|
|
|
vehicle->var_20 = al;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-21 17:16:05 +01:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-11-21 13:13:10 +01:00
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
}
|
|
|
|
|
2015-11-19 21:53:13 +01:00
|
|
|
/**
|
2015-12-16 19:37:45 +01:00
|
|
|
*
|
|
|
|
* rct2: 0x006D95AD
|
|
|
|
*/
|
2015-11-19 21:28:07 +01:00
|
|
|
static void vehicle_update_showing_film(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
int currentTime, totalTime;
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
totalTime = RideFilmLength[vehicle->sub_state];
|
2016-01-04 10:36:29 +01:00
|
|
|
currentTime = vehicle->current_time + 1;
|
2015-11-19 21:28:07 +01:00
|
|
|
if (currentTime <= totalTime) {
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = currentTime;
|
2015-11-19 21:28:07 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
vehicle->sub_state = 0;
|
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 02:32:20 +01:00
|
|
|
/**
|
2015-12-12 11:21:49 +01:00
|
|
|
*
|
2014-11-12 02:32:20 +01:00
|
|
|
* rct2: 0x006D95F7
|
|
|
|
*/
|
|
|
|
static void vehicle_update_doing_circus_show(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
int currentTime, totalTime;
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0)
|
|
|
|
return;
|
|
|
|
|
2015-11-19 19:44:24 +01:00
|
|
|
totalTime = *(RCT2_ADDRESS(0x009A0AB4, uint16*)[vehicle->sub_state]);
|
2016-01-04 10:36:29 +01:00
|
|
|
currentTime = vehicle->current_time + 1;
|
2014-11-12 02:32:20 +01:00
|
|
|
if (currentTime <= totalTime) {
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->current_time = currentTime;
|
2014-11-12 02:32:20 +01:00
|
|
|
} else {
|
|
|
|
vehicle->status = VEHICLE_STATUS_ARRIVING;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
2015-11-19 19:44:24 +01:00
|
|
|
vehicle->sub_state = 0;
|
2014-11-12 02:32:20 +01:00
|
|
|
vehicle->var_C0 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x0068B8BD
|
|
|
|
* @returns the map element that the vehicle will collide with or NULL if no collisions.
|
2015-11-20 01:04:07 +01:00
|
|
|
*/
|
|
|
|
static rct_map_element* vehicle_check_collision(sint16 x, sint16 y, sint16 z) {
|
|
|
|
rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32);
|
2015-12-18 21:33:45 +01:00
|
|
|
if (mapElement == NULL)
|
2015-12-22 15:21:56 +01:00
|
|
|
// Can't return null as that implies no collision,
|
|
|
|
// but should still cause a crash when dereferenced.
|
|
|
|
return (rct_map_element *) -1;
|
2015-11-20 01:04:07 +01:00
|
|
|
|
|
|
|
uint8 bl;
|
|
|
|
if ((x & 0x1F) >= 16) {
|
|
|
|
bl = 1;
|
|
|
|
if ((y & 0x1F) < 16)
|
|
|
|
bl = 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bl = 4;
|
|
|
|
if ((y & 0x1F) >= 16)
|
|
|
|
bl = 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
|
|
|
if (z / 8 < mapElement->base_height)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (z / 8 >= mapElement->clearance_height)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (mapElement->flags & bl)
|
|
|
|
return mapElement;
|
|
|
|
} while (!map_element_is_last_for_tile(mapElement++));
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DE6C6
|
|
|
|
*/
|
2015-11-20 19:15:15 +01:00
|
|
|
static void vehicle_kill_all_passengers(rct_vehicle* vehicle) {
|
|
|
|
uint16 numFatalities = 0;
|
2015-11-21 00:41:50 +01:00
|
|
|
|
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* curVehicle; spriteId != 0xFFFF; spriteId = curVehicle->next_vehicle_on_train) {
|
|
|
|
curVehicle = GET_VEHICLE(spriteId);
|
2015-11-20 19:15:15 +01:00
|
|
|
numFatalities += curVehicle->num_peeps;
|
|
|
|
}
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-20 19:15:15 +01:00
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, uint16) = numFatalities;
|
|
|
|
|
|
|
|
uint8 crashType = numFatalities == 0 ?
|
|
|
|
RIDE_CRASH_TYPE_NO_FATALITIES :
|
|
|
|
RIDE_CRASH_TYPE_FATALITIES;
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-20 19:15:15 +01:00
|
|
|
if (crashType >= ride->last_crash_type)
|
|
|
|
ride->last_crash_type = crashType;
|
|
|
|
|
|
|
|
if (numFatalities != 0) {
|
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_SIX_FLAGS_DEPRECATED)) {
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 2, uint16) = ride->name;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 4, uint32) = ride->name_arguments;
|
|
|
|
|
|
|
|
news_item_add_to_queue(NEWS_ITEM_RIDE, 2219, vehicle->ride);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x135882E, uint16) < 500) {
|
|
|
|
RCT2_GLOBAL(0x135882E, uint16) += 200;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-21 00:41:50 +01:00
|
|
|
spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* curVehicle; spriteId != 0xFFFF; spriteId = curVehicle->next_vehicle_on_train) {
|
|
|
|
curVehicle = GET_VEHICLE(spriteId);
|
|
|
|
|
2015-11-20 19:15:15 +01:00
|
|
|
if (curVehicle->num_peeps != curVehicle->next_free_seat)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (curVehicle->num_peeps == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (uint8 i = 0; i < curVehicle->num_peeps; i++) {
|
|
|
|
rct_peep* peep = GET_PEEP(curVehicle->peep[i]);
|
|
|
|
if (peep->outside_of_park == 0) {
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)--;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_BTM_TOOLBAR_DIRTY_FLAGS, uint16) |=
|
|
|
|
BTM_TB_DIRTY_FLAG_PEEP_COUNT;
|
|
|
|
}
|
|
|
|
ride->num_riders--;
|
|
|
|
peep_sprite_remove(peep);
|
|
|
|
}
|
|
|
|
|
|
|
|
curVehicle->num_peeps = 0;
|
|
|
|
curVehicle->next_free_seat = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-20 01:04:07 +01:00
|
|
|
static void vehicle_crash_on_land(rct_vehicle* vehicle) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_CRASHED;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-20 01:04:07 +01:00
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) {
|
|
|
|
|
|
|
|
rct_vehicle* frontVehicle = vehicle;
|
|
|
|
while (frontVehicle->is_child != 0)frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride);
|
|
|
|
|
|
|
|
uint8 trainIndex = 0;
|
|
|
|
while (ride->vehicles[trainIndex] != frontVehicle->sprite_index)
|
|
|
|
trainIndex++;
|
|
|
|
|
|
|
|
ride_crash(vehicle->ride, trainIndex);
|
|
|
|
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED) {
|
|
|
|
ride_set_status(vehicle->ride, RIDE_STATUS_CLOSED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED;
|
|
|
|
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
|
|
|
|
|
|
|
|
if (vehicle->is_child == 0) {
|
2015-11-20 19:15:15 +01:00
|
|
|
vehicle_kill_all_passengers(vehicle);
|
2015-11-20 01:04:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->sub_state = 2;
|
|
|
|
audio_play_sound_at_location(SOUND_CRASH, vehicle->x, vehicle->y, vehicle->z);
|
|
|
|
|
|
|
|
sprite_misc_3_create(vehicle->x, vehicle->y, vehicle->z);
|
|
|
|
sprite_misc_5_create(vehicle->x, vehicle->y, vehicle->z);
|
|
|
|
|
|
|
|
uint8 numParticles = min(vehicle->sprite_width, 7);
|
|
|
|
|
|
|
|
while (numParticles-- != 0)
|
|
|
|
crashed_vehicle_particle_create(vehicle->colours, vehicle->x, vehicle->y, vehicle->z);
|
|
|
|
|
|
|
|
vehicle->var_0C |= (1 << 7);
|
|
|
|
vehicle->var_C5 = 0;
|
|
|
|
vehicle->var_C8 = 0;
|
|
|
|
vehicle->sprite_width = 13;
|
|
|
|
vehicle->sprite_height_negative = 45;
|
|
|
|
vehicle->sprite_height_positive = 5;
|
|
|
|
|
|
|
|
sprite_move(vehicle->x, vehicle->y, vehicle->z, (rct_sprite*)vehicle);
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-20 01:04:07 +01:00
|
|
|
|
|
|
|
vehicle->var_4E = 0;
|
|
|
|
}
|
|
|
|
|
2015-11-20 20:23:25 +01:00
|
|
|
static void vehicle_crash_on_water(rct_vehicle* vehicle) {
|
|
|
|
vehicle->status = VEHICLE_STATUS_CRASHED;
|
|
|
|
vehicle_invalidate_window(vehicle);
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-11-20 20:23:25 +01:00
|
|
|
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED)) {
|
|
|
|
|
|
|
|
rct_vehicle* frontVehicle = vehicle;
|
|
|
|
while (frontVehicle->is_child != 0)frontVehicle = GET_VEHICLE(frontVehicle->prev_vehicle_on_ride);
|
|
|
|
|
|
|
|
uint8 trainIndex = 0;
|
|
|
|
while (ride->vehicles[trainIndex] != frontVehicle->sprite_index)
|
|
|
|
trainIndex++;
|
|
|
|
|
|
|
|
ride_crash(vehicle->ride, trainIndex);
|
|
|
|
|
|
|
|
if (ride->status != RIDE_STATUS_CLOSED) {
|
|
|
|
ride_set_status(vehicle->ride, RIDE_STATUS_CLOSED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ride->lifecycle_flags |= RIDE_LIFECYCLE_CRASHED;
|
|
|
|
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST;
|
|
|
|
|
|
|
|
if (vehicle->is_child == 0) {
|
|
|
|
vehicle_kill_all_passengers(vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->sub_state = 2;
|
|
|
|
audio_play_sound_at_location(SOUND_WATER_1, vehicle->x, vehicle->y, vehicle->z);
|
|
|
|
|
|
|
|
crash_splash_create(vehicle->x, vehicle->y, vehicle->z);
|
|
|
|
crash_splash_create(vehicle->x - 8, vehicle->y - 9, vehicle->z);
|
|
|
|
crash_splash_create(vehicle->x + 11, vehicle->y - 9, vehicle->z);
|
|
|
|
crash_splash_create(vehicle->x + 11, vehicle->y + 8, vehicle->z);
|
|
|
|
crash_splash_create(vehicle->x - 4, vehicle->y + 8, vehicle->z);
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
|
|
crashed_vehicle_particle_create(vehicle->colours, vehicle->x - 4, vehicle->y + 8, vehicle->z);
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-20 20:23:25 +01:00
|
|
|
vehicle->var_0C |= (1 << 7);
|
|
|
|
vehicle->var_C5 = 0;
|
|
|
|
vehicle->var_C8 = 0;
|
|
|
|
vehicle->sprite_width = 13;
|
|
|
|
vehicle->sprite_height_negative = 45;
|
|
|
|
vehicle->sprite_height_positive = 5;
|
|
|
|
|
|
|
|
sprite_move(vehicle->x, vehicle->y, vehicle->z, (rct_sprite*)vehicle);
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-11-20 20:23:25 +01:00
|
|
|
|
|
|
|
vehicle->var_4E = 0xFFFF;
|
|
|
|
}
|
|
|
|
|
2015-12-11 14:07:22 +01:00
|
|
|
/**
|
2015-12-16 19:37:45 +01:00
|
|
|
*
|
|
|
|
* rct2: 0x006D98CA
|
|
|
|
*/
|
2015-11-20 01:04:07 +01:00
|
|
|
static void vehicle_update_crash(rct_vehicle *vehicle){
|
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
rct_vehicle* curVehicle;
|
|
|
|
do {
|
|
|
|
curVehicle = GET_VEHICLE(spriteId);
|
|
|
|
if (curVehicle->sub_state > 1) {
|
|
|
|
if (curVehicle->var_4E <= 96) {
|
|
|
|
curVehicle->var_4E++;
|
|
|
|
if ((scenario_rand() & 0xFFFF) <= 0x1555) {
|
|
|
|
sprite_misc_3_create(
|
|
|
|
curVehicle->x + (scenario_rand() & 2 - 1),
|
|
|
|
curVehicle->y + (scenario_rand() & 2 - 1),
|
|
|
|
curVehicle->z
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (curVehicle->var_C8 + 7281 > 0xFFFF) {
|
|
|
|
curVehicle->var_C5++;
|
|
|
|
if (curVehicle->var_C5 >= 8)
|
|
|
|
curVehicle->var_C5 = 0;
|
|
|
|
invalidate_sprite_2((rct_sprite*)curVehicle);
|
|
|
|
}
|
|
|
|
curVehicle->var_C8 += 7281;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_map_element* collideElement = vehicle_check_collision(curVehicle->x, curVehicle->y, curVehicle->z);
|
|
|
|
if (collideElement == NULL) {
|
|
|
|
curVehicle->sub_state = 1;
|
|
|
|
}
|
|
|
|
else if (curVehicle->sub_state == 1){
|
|
|
|
vehicle_crash_on_land(curVehicle);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int z = map_element_height(curVehicle->x, curVehicle->y);
|
|
|
|
sint16 waterHeight = (z >> 16) & 0xFFFF;
|
|
|
|
z = (sint16)(z & 0xFFFF);
|
2015-11-20 20:23:25 +01:00
|
|
|
sint16 zDiff;
|
2015-11-20 01:04:07 +01:00
|
|
|
if (waterHeight != 0) {
|
2015-11-20 20:23:25 +01:00
|
|
|
zDiff = curVehicle->z - waterHeight;
|
|
|
|
if (zDiff <= 0 && zDiff >= -20) {
|
|
|
|
vehicle_crash_on_water(curVehicle);
|
|
|
|
continue;
|
2015-11-20 01:04:07 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2015-11-20 20:23:25 +01:00
|
|
|
zDiff = curVehicle->z - z;
|
2015-11-20 19:15:15 +01:00
|
|
|
if ((zDiff <= 0 && zDiff >= -20) || curVehicle->z < 16){
|
2015-11-20 01:04:07 +01:00
|
|
|
vehicle_crash_on_land(curVehicle);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidate_sprite_2((rct_sprite*)curVehicle);
|
|
|
|
|
|
|
|
rct_xyz16 curPosition = {
|
|
|
|
.x = curVehicle->x,
|
|
|
|
.y = curVehicle->y,
|
|
|
|
.z = curVehicle->z
|
|
|
|
};
|
|
|
|
|
|
|
|
curPosition.x += (sint8)(curVehicle->var_B6 >> 8);
|
|
|
|
curPosition.y += (sint8)(curVehicle->var_C0 >> 8);
|
|
|
|
curPosition.z += (sint8)(curVehicle->var_4E >> 8);
|
|
|
|
curVehicle->track_x += (sint16)(curVehicle->var_B6 << 8);
|
2015-11-20 19:15:15 +01:00
|
|
|
curVehicle->track_y += (sint16)(curVehicle->var_C0 << 8);
|
|
|
|
curVehicle->track_z += (sint16)(curVehicle->var_4E << 8);
|
2015-11-20 01:04:07 +01:00
|
|
|
|
|
|
|
if (curPosition.x > 0x1FFF ||
|
|
|
|
curPosition.y > 0x1FFF) {
|
|
|
|
vehicle_crash_on_land(curVehicle);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
sprite_move(curPosition.x, curPosition.y, curPosition.z, (rct_sprite*)curVehicle);
|
|
|
|
invalidate_sprite_2((rct_sprite*)curVehicle);
|
|
|
|
|
|
|
|
if (curVehicle->sub_state == 1) {
|
|
|
|
curVehicle->var_4E += 0xFFEC;
|
|
|
|
}
|
|
|
|
} while ((spriteId = curVehicle->next_vehicle_on_train) != 0xFFFF);
|
|
|
|
}
|
2014-11-12 00:05:04 +01:00
|
|
|
/**
|
2015-12-12 11:21:49 +01:00
|
|
|
*
|
2014-11-12 00:05:04 +01:00
|
|
|
* rct2: 0x006D7888
|
|
|
|
*/
|
|
|
|
static void vehicle_update_sound(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
rct_ride *ride;
|
|
|
|
rct_ride_type *rideEntry;
|
2016-01-12 18:55:19 +01:00
|
|
|
// frictionVolume (bl) should be set before hand
|
|
|
|
uint8 frictionVolume = 255, frictionId = 255;
|
2015-11-21 15:47:12 +01:00
|
|
|
// bh screamVolume should be set before hand
|
|
|
|
uint8 screamId, screamVolume = 255;
|
2014-11-12 02:04:50 +01:00
|
|
|
uint16 soundIdVolume;
|
2014-11-12 00:05:04 +01:00
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
ride = get_ride(vehicle->ride);
|
|
|
|
rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2014-11-12 00:05:04 +01:00
|
|
|
|
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
int ecx = abs(vehicle->velocity) - 0x10000;
|
|
|
|
if (ecx >= 0) {
|
2016-01-12 18:55:19 +01:00
|
|
|
frictionId = vehicleEntry->friction_sound_id;
|
2014-11-12 00:05:04 +01:00
|
|
|
ecx >>= 15;
|
2016-01-12 18:55:19 +01:00
|
|
|
frictionVolume = min(208 + (ecx & 0xFF), 255);
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
switch (vehicleEntry->sound_range) {
|
|
|
|
case 3:
|
2015-11-21 15:47:12 +01:00
|
|
|
screamId = vehicle->scream_sound_id;
|
2014-11-12 00:05:04 +01:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) {
|
2014-11-12 02:04:50 +01:00
|
|
|
if (vehicle->velocity < 0x40000 || vehicle->scream_sound_id != 255)
|
2014-11-12 00:05:04 +01:00
|
|
|
goto loc_6D7A97;
|
|
|
|
|
|
|
|
if ((scenario_rand() & 0xFFFF) <= 0x5555) {
|
2014-11-12 02:04:50 +01:00
|
|
|
vehicle->scream_sound_id = SOUND_TRAIN_WHISTLE;
|
2015-11-21 15:47:12 +01:00
|
|
|
screamVolume = 255;
|
2014-11-12 02:04:50 +01:00
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-11 21:26:26 +01:00
|
|
|
if (screamId == NO_SCREAM) screamId = 255;
|
2015-11-21 15:47:12 +01:00
|
|
|
screamVolume = 255;
|
2014-11-12 02:04:50 +01:00
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
case 4:
|
2015-11-21 15:47:12 +01:00
|
|
|
screamId = vehicle->scream_sound_id;
|
2014-11-12 00:05:04 +01:00
|
|
|
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x7F)) {
|
2014-11-12 02:04:50 +01:00
|
|
|
if (vehicle->velocity < 0x40000 || vehicle->scream_sound_id != 255)
|
2014-11-12 00:05:04 +01:00
|
|
|
goto loc_6D7A97;
|
|
|
|
|
|
|
|
if ((scenario_rand() & 0xFFFF) <= 0x5555) {
|
2014-11-12 02:04:50 +01:00
|
|
|
vehicle->scream_sound_id = SOUND_TRAM;
|
2015-11-21 15:47:12 +01:00
|
|
|
screamVolume = 255;
|
2014-11-12 02:04:50 +01:00
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-11 21:26:26 +01:00
|
|
|
if (screamId == NO_SCREAM) screamId = 255;
|
2015-11-21 15:47:12 +01:00
|
|
|
screamVolume = 255;
|
2014-11-12 02:04:50 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2015-12-16 20:12:58 +01:00
|
|
|
if ((vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_4)) {
|
2014-11-12 02:04:50 +01:00
|
|
|
screamId = vehicle_update_scream_sound(vehicle);
|
2015-11-25 23:36:11 +01:00
|
|
|
if (screamId == NO_SCREAM)
|
|
|
|
screamId = 255;
|
2014-11-12 02:04:50 +01:00
|
|
|
if (screamId == 255)
|
2014-11-12 00:05:04 +01:00
|
|
|
goto loc_6D7A97;
|
2014-11-12 02:04:50 +01:00
|
|
|
break;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
loc_6D7A97:
|
|
|
|
vehicle->scream_sound_id = 255;
|
2015-12-12 11:21:49 +01:00
|
|
|
assert(ride->type < countof(RideLiftData));
|
2015-11-21 16:53:56 +01:00
|
|
|
// Get lift hill sound
|
|
|
|
screamId = RideLiftData[ride->type].sound_id;
|
2015-11-21 15:47:12 +01:00
|
|
|
screamVolume = 243;
|
2014-11-12 02:04:50 +01:00
|
|
|
if (!(vehicle->var_B8 & 2))
|
2015-11-21 15:47:12 +01:00
|
|
|
screamId = 255;
|
2014-11-12 00:05:04 +01:00
|
|
|
}
|
|
|
|
|
2014-11-12 02:04:50 +01:00
|
|
|
// Friction sound
|
2016-01-12 18:55:19 +01:00
|
|
|
soundIdVolume = sub_6D7AC0(vehicle->sound1_id, vehicle->sound1_volume, frictionId, frictionVolume);
|
2014-11-12 00:05:04 +01:00
|
|
|
vehicle->sound1_id = soundIdVolume & 0xFF;
|
|
|
|
vehicle->sound1_volume = (soundIdVolume >> 8) & 0xFF;
|
2014-11-12 02:04:50 +01:00
|
|
|
|
|
|
|
// Scream sound
|
|
|
|
soundIdVolume = sub_6D7AC0(vehicle->sound2_id, vehicle->sound2_volume, screamId, screamVolume);
|
2014-11-12 00:05:04 +01:00
|
|
|
vehicle->sound2_id = soundIdVolume & 0xFF;
|
|
|
|
vehicle->sound2_volume = (soundIdVolume >> 8) & 0xFF;
|
|
|
|
|
|
|
|
{
|
|
|
|
int ebx = RCT2_ADDRESS(0x009A3684, sint16)[vehicle->sprite_direction];
|
|
|
|
int eax = ((vehicle->velocity >> 14) * ebx) >> 14;
|
2015-12-11 21:26:26 +01:00
|
|
|
eax = clamp(-127, eax, 127);
|
2015-12-12 11:21:49 +01:00
|
|
|
|
2014-11-12 00:05:04 +01:00
|
|
|
vehicle->var_BF = eax & 0xFF;
|
|
|
|
}
|
2014-09-21 14:50:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-12-12 11:21:49 +01:00
|
|
|
*
|
2014-11-12 02:04:50 +01:00
|
|
|
* rct2: 0x006D796B
|
|
|
|
*/
|
|
|
|
static int vehicle_update_scream_sound(rct_vehicle *vehicle)
|
|
|
|
{
|
2015-12-11 21:26:26 +01:00
|
|
|
uint32 r;
|
2014-11-12 02:04:50 +01:00
|
|
|
uint16 spriteIndex;
|
|
|
|
rct_ride_type *rideEntry;
|
|
|
|
rct_vehicle *vehicle2;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2014-11-12 02:04:50 +01:00
|
|
|
|
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
|
|
|
int totalNumPeeps = vehicle_get_total_num_peeps(vehicle);
|
|
|
|
if (totalNumPeeps == 0)
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
if (vehicle->velocity < 0) {
|
|
|
|
if (vehicle->velocity > -0x2C000)
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
spriteIndex = vehicle->sprite_index;
|
|
|
|
do {
|
|
|
|
vehicle2 = &(g_sprite_list[spriteIndex].vehicle);
|
|
|
|
if (vehicle2->var_1F < 1)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 4)
|
|
|
|
goto produceScream;
|
|
|
|
if (vehicle2->var_1F < 9)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 15)
|
|
|
|
goto produceScream;
|
|
|
|
} while ((spriteIndex = vehicle2->next_vehicle_on_train) != SPRITE_INDEX_NULL);
|
|
|
|
return 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->velocity < 0x2C000)
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
spriteIndex = vehicle->sprite_index;
|
|
|
|
do {
|
|
|
|
vehicle2 = &(g_sprite_list[spriteIndex].vehicle);
|
|
|
|
if (vehicle2->var_1F < 5)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 8)
|
|
|
|
goto produceScream;
|
|
|
|
if (vehicle2->var_1F < 17)
|
|
|
|
continue;
|
|
|
|
if (vehicle2->var_1F <= 23)
|
|
|
|
goto produceScream;
|
|
|
|
} while ((spriteIndex = vehicle2->next_vehicle_on_train) != SPRITE_INDEX_NULL);
|
|
|
|
return 255;
|
|
|
|
|
|
|
|
produceScream:
|
|
|
|
if (vehicle->scream_sound_id == 255) {
|
|
|
|
r = scenario_rand();
|
2015-12-12 12:48:28 +01:00
|
|
|
if (totalNumPeeps >= (int)(r % 16)) {
|
2014-11-12 02:04:50 +01:00
|
|
|
switch (vehicleEntry->sound_range) {
|
|
|
|
case 0:
|
|
|
|
vehicle->scream_sound_id = byte_9A3A14[r % 2];
|
|
|
|
break;
|
|
|
|
case 1:
|
2015-12-11 21:26:26 +01:00
|
|
|
vehicle->scream_sound_id = byte_9A3A18[r % 7];
|
2014-11-12 02:04:50 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
vehicle->scream_sound_id = byte_9A3A16[r % 2];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vehicle->scream_sound_id = NO_SCREAM;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
vehicle->scream_sound_id = NO_SCREAM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return vehicle->scream_sound_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-12-12 11:21:49 +01:00
|
|
|
*
|
2014-09-21 14:50:35 +02:00
|
|
|
* rct2: 0x006D73D0
|
|
|
|
* ax: verticalG
|
|
|
|
* dx: lateralG
|
|
|
|
* esi: vehicle
|
|
|
|
*/
|
|
|
|
void vehicle_get_g_forces(rct_vehicle *vehicle, int *verticalG, int *lateralG)
|
|
|
|
{
|
2015-12-15 18:47:30 +01:00
|
|
|
int gForceVert = (((sint64)0x280000) * RCT2_ADDRESS(0x009A37E4, sint32)[vehicle->var_1F]) >> 32;
|
|
|
|
gForceVert = (((sint64)gForceVert) * RCT2_ADDRESS(0x009A39C4, sint32)[vehicle->var_20]) >> 32;
|
|
|
|
int lateralFactor = 0, vertFactor = 0;
|
2015-12-12 21:25:20 +01:00
|
|
|
|
2015-12-22 15:21:56 +01:00
|
|
|
// Note shr has meant some of the below functions cast a known negative number to
|
2015-12-15 18:47:30 +01:00
|
|
|
// unsigned. Possibly an original bug but will be left implemented.
|
2015-12-12 21:25:20 +01:00
|
|
|
switch (vehicle->track_type >> 2) {
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_FLAT:
|
|
|
|
case TRACK_ELEM_END_STATION:
|
|
|
|
case TRACK_ELEM_BEGIN_STATION:
|
|
|
|
case TRACK_ELEM_MIDDLE_STATION:
|
|
|
|
case TRACK_ELEM_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_60_DEG_UP: //
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_60_DEG_DOWN: //
|
|
|
|
case TRACK_ELEM_FLAT_TO_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_FLAT_TO_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_LEFT_BANK_TO_FLAT:
|
|
|
|
case TRACK_ELEM_RIGHT_BANK_TO_FLAT://
|
|
|
|
case TRACK_ELEM_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_TOWER_BASE:
|
|
|
|
case TRACK_ELEM_TOWER_SECTION:
|
|
|
|
case TRACK_ELEM_FLAT_COVERED:
|
|
|
|
case TRACK_ELEM_25_DEG_UP_COVERED:
|
|
|
|
case TRACK_ELEM_60_DEG_UP_COVERED:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_COVERED:
|
|
|
|
case TRACK_ELEM_60_DEG_DOWN_COVERED:
|
|
|
|
case TRACK_ELEM_BRAKES:
|
|
|
|
case TRACK_ELEM_ROTATION_CONTROL_TOGGLE:
|
|
|
|
case TRACK_ELEM_INVERTED_90_DEG_UP_TO_FLAT_QUARTER_LOOP:
|
|
|
|
case TRACK_ELEM_25_DEG_UP_LEFT_BANKED:
|
|
|
|
case TRACK_ELEM_25_DEG_UP_RIGHT_BANKED:
|
|
|
|
case TRACK_ELEM_WATERFALL:
|
|
|
|
case TRACK_ELEM_RAPIDS:
|
|
|
|
case TRACK_ELEM_ON_RIDE_PHOTO:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_LEFT_BANKED:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_RIGHT_BANKED:
|
|
|
|
case TRACK_ELEM_WHIRLPOOL:
|
|
|
|
case TRACK_ELEM_REVERSE_WHOA_BELLY_VERTICAL:
|
|
|
|
case TRACK_ELEM_90_DEG_UP:
|
|
|
|
case TRACK_ELEM_90_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_DIAG_FLAT:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_DIAG_60_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_DIAG_FLAT_TO_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_DIAG_FLAT_TO_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_DIAG_LEFT_BANK_TO_FLAT:
|
|
|
|
case TRACK_ELEM_DIAG_RIGHT_BANK_TO_FLAT:
|
|
|
|
case TRACK_ELEM_DIAG_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_DIAG_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_LOG_FLUME_REVERSER:
|
|
|
|
case TRACK_ELEM_SPINNING_TUNNEL:
|
|
|
|
case TRACK_ELEM_POWERED_LIFT:
|
|
|
|
case TRACK_ELEM_MINI_GOLF_HOLE_A:
|
|
|
|
case TRACK_ELEM_MINI_GOLF_HOLE_B:
|
|
|
|
case TRACK_ELEM_MINI_GOLF_HOLE_C:
|
|
|
|
case TRACK_ELEM_MINI_GOLF_HOLE_D:
|
|
|
|
case TRACK_ELEM_MINI_GOLF_HOLE_E:
|
|
|
|
case TRACK_ELEM_LEFT_REVERSER:
|
|
|
|
case TRACK_ELEM_RIGHT_REVERSER:
|
|
|
|
case TRACK_ELEM_AIR_THRUST_VERTICAL_DOWN:
|
|
|
|
case TRACK_ELEM_BLOCK_BRAKES:
|
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_LEFT_BANKED_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_RIGHT_BANKED_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_25_DEG_UP_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_25_DEG_UP_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_LEFT_BANKED_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_RIGHT_BANKED_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_25_DEG_DOWN_TO_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_25_DEG_DOWN_TO_25_DEG_DOWN:
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_90_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_90_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_90_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_90_DEG_DOWN:
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d73FF
|
2015-12-14 22:42:06 +01:00
|
|
|
// Do nothing
|
2015-12-12 21:25:20 +01:00
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_FLAT_TO_25_DEG_UP://
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_FLAT://
|
|
|
|
case TRACK_ELEM_LEFT_BANK_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_BANK_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_FLAT_TO_25_DEG_UP_COVERED:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_FLAT_COVERED:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_FLAT_TO_LEFT_BANKED_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_FLAT_TO_RIGHT_BANKED_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_25_DEG_DOWN_TO_LEFT_BANKED_FLAT:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_25_DEG_DOWN_TO_RIGHT_BANKED_FLAT:
|
|
|
|
case TRACK_ELEM_FLAT_TO_LEFT_BANKED_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_FLAT_TO_RIGHT_BANKED_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_25_DEG_DOWN_TO_FLAT:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_25_DEG_DOWN_TO_FLAT:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 103;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7509
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_FLAT://
|
|
|
|
case TRACK_ELEM_FLAT_TO_25_DEG_DOWN://
|
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_LEFT_BANK_TO_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_BANK_TO_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_FLAT_COVERED:
|
|
|
|
case TRACK_ELEM_FLAT_TO_25_DEG_DOWN_COVERED:
|
|
|
|
case TRACK_ELEM_CABLE_LIFT_HILL:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_25_DEG_UP_TO_LEFT_BANKED_FLAT:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_25_DEG_UP_TO_RIGHT_BANKED_FLAT:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_FLAT_TO_LEFT_BANKED_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_FLAT_TO_RIGHT_BANKED_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_25_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_25_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_FLAT_TO_LEFT_BANKED_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_FLAT_TO_RIGHT_BANKED_25_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -103;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7569
|
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_60_DEG_UP://
|
|
|
|
case TRACK_ELEM_60_DEG_DOWN_TO_25_DEG_DOWN://
|
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_60_DEG_UP_COVERED:
|
|
|
|
case TRACK_ELEM_60_DEG_DOWN_TO_25_DEG_DOWN_COVERED:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 82;
|
2015-12-14 22:42:06 +01:00
|
|
|
//6d7545
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_60_DEG_UP_TO_25_DEG_UP://
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_60_DEG_DOWN://
|
|
|
|
case TRACK_ELEM_60_DEG_UP_TO_25_DEG_UP_COVERED:
|
|
|
|
case TRACK_ELEM_25_DEG_DOWN_TO_60_DEG_DOWN_COVERED:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -82;
|
2015-12-14 22:42:06 +01:00
|
|
|
//6d7551
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES://
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_TWIST_DOWN_TO_UP:
|
|
|
|
case TRACK_ELEM_LEFT_TWIST_UP_TO_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_HELIX_LARGE_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_FLYER_TWIST_UP:
|
|
|
|
case TRACK_ELEM_LEFT_FLYER_TWIST_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_HEARTLINE_ROLL:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = 98;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7590
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES://
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_TWIST_DOWN_TO_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_TWIST_UP_TO_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_HELIX_LARGE_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_FLYER_TWIST_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_FLYER_TWIST_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_HEARTLINE_ROLL:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = -98;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d75B7
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_BANKED_LEFT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_UP_LARGE:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_DOWN_LARGE:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 200;
|
|
|
|
lateralFactor = 160;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d75E1
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_BANKED_RIGHT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_UP_LARGE:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 200;
|
|
|
|
lateralFactor = -160;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d75F0
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_S_BEND_LEFT:
|
|
|
|
case TRACK_ELEM_S_BEND_LEFT_COVERED:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = (vehicle->track_progress < 48) ? 98 : -98;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d75FF
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_S_BEND_RIGHT:
|
|
|
|
case TRACK_ELEM_S_BEND_RIGHT_COVERED:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = (vehicle->track_progress < 48) ? -98 : 98;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7608
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_VERTICAL_LOOP:
|
|
|
|
case TRACK_ELEM_RIGHT_VERTICAL_LOOP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = (abs(vehicle->track_progress - 155) / 2) + 28;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7690
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_LEFT_CURVED_LIFT_HILL:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = 59;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7704
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_RIGHT_CURVED_LIFT_HILL:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = -59;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7710
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_BANK:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_DOWN_SMALL:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 100;
|
|
|
|
lateralFactor = 100;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7782
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_BANK:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_UP_SMALL:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 100;
|
|
|
|
lateralFactor = -100;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d778E
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = 45;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d779A
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = -45;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d77A3
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_HALF_LOOP_UP:
|
|
|
|
case TRACK_ELEM_FLYER_HALF_LOOP_UP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = (((uint16)(-(vehicle->track_progress - 155))) / 2) + 28;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d763E
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_HALF_LOOP_DOWN:
|
|
|
|
case TRACK_ELEM_FLYER_HALF_LOOP_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = (vehicle->track_progress / 2) + 28;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7656
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_CORKSCREW_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_CORKSCREW_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_FLYER_CORKSCREW_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_FLYER_CORKSCREW_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 52;
|
|
|
|
lateralFactor = 70;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d76AA
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_CORKSCREW_UP:
|
|
|
|
case TRACK_ELEM_LEFT_CORKSCREW_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_FLYER_CORKSCREW_UP:
|
|
|
|
case TRACK_ELEM_LEFT_FLYER_CORKSCREW_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 52;
|
|
|
|
lateralFactor = -70;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d76B9
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_FLAT_TO_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_60_DEG_DOWN_TO_FLAT:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 56;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d747C
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_60_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_FLAT_TO_60_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_BRAKE_FOR_DROP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -56;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7488
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = 88;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7770
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = -88;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7779
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_WATER_SPLASH:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -150;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 32)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 150;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 64)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 0;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 96)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 150;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 128)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -150;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7408
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_FLAT_TO_60_DEG_UP_LONG_BASE:
|
|
|
|
case TRACK_ELEM_FLAT_TO_60_DEG_DOWN_LONG_BASE:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 160;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d74F1
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE:
|
|
|
|
case TRACK_ELEM_60_DEG_UP_TO_FLAT_LONG_BASE_122:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -160;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d74FD
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_REVERSE_WHOA_BELLY_SLOPE:
|
|
|
|
case TRACK_ELEM_AIR_THRUST_VERTICAL_DOWN_TO_LEVEL:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 120;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7458
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_60_DEG_UP_TO_90_DEG_UP:
|
|
|
|
case TRACK_ELEM_90_DEG_DOWN_TO_60_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 110;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7515
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_90_DEG_UP_TO_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_60_DEG_DOWN_TO_90_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -110;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7521
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_TO_DIAG:
|
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_TO_ORTHOGONAL:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = 137;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7575
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_TO_DIAG:
|
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_TO_ORTHOGONAL:
|
2015-12-15 18:47:30 +01:00
|
|
|
lateralFactor = -137;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d759C
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_BANK_TO_DIAG:
|
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_BANK_TO_ORTHOGONAL:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 270;
|
|
|
|
lateralFactor = 200;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d75C3
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_BANK_TO_DIAG:
|
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_BANK_TO_ORTHOGONAL:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 270;
|
|
|
|
lateralFactor = -200;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d75D2
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_DIAG_FLAT_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_DOWN_TO_FLAT:
|
|
|
|
case TRACK_ELEM_DIAG_LEFT_BANK_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_RIGHT_BANK_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_DOWN_TO_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_DOWN_TO_RIGHT_BANK:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 113;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7494
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_DIAG_FLAT_TO_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_UP_TO_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_UP_TO_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_DIAG_LEFT_BANK_TO_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_DIAG_RIGHT_BANK_TO_25_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -113;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d755D
|
2015-12-22 15:21:56 +01:00
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_DIAG_25_DEG_UP_TO_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_60_DEG_DOWN_TO_25_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 95;
|
2015-12-14 22:42:06 +01:00
|
|
|
//6D752D
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_DIAG_60_DEG_UP_TO_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_DOWN_TO_60_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -95;
|
2015-12-14 22:42:06 +01:00
|
|
|
//6D7539
|
2015-12-12 21:25:20 +01:00
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_DIAG_FLAT_TO_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_DIAG_60_DEG_DOWN_TO_FLAT:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 60;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6D7464
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_DIAG_FLAT_TO_60_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -60;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7470
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_BARREL_ROLL_UP_TO_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_BARREL_ROLL_DOWN_TO_UP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 170;
|
|
|
|
lateralFactor = 115;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7581
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_BARREL_ROLL_UP_TO_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_BARREL_ROLL_DOWN_TO_UP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 170;
|
|
|
|
lateralFactor = -115;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d75A8
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -(vehicle->track_progress / 2) + 134;
|
|
|
|
lateralFactor = 90;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d771C
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -(vehicle->track_progress / 2) + 134;
|
|
|
|
lateralFactor = -90;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6D7746
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_LEFT_BANK:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -(vehicle->track_progress / 2) + 134;
|
|
|
|
lateralFactor = 90;
|
2015-12-14 22:42:06 +01:00
|
|
|
//6D7731 identical to 6d771c
|
2015-12-12 21:25:20 +01:00
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_RIGHT_BANK:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -(vehicle->track_progress / 2) + 134;
|
|
|
|
lateralFactor = -90;
|
2015-12-14 22:42:06 +01:00
|
|
|
//6D775B identical to 6d7746
|
2015-12-12 21:25:20 +01:00
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_LEFT_LARGE_HALF_LOOP_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_LARGE_HALF_LOOP_UP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = (((uint16)(-(vehicle->track_progress - 311))) / 4) + 46;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d7666
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_RIGHT_LARGE_HALF_LOOP_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_LARGE_HALF_LOOP_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = (vehicle->track_progress / 4) + 46;
|
2015-12-12 21:25:20 +01:00
|
|
|
//6d767F
|
|
|
|
break;
|
2015-12-13 16:33:01 +01:00
|
|
|
case TRACK_ELEM_HEARTLINE_TRANSFER_UP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 103;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 32)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -103;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 64)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 0;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 96)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 103;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 128)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -103;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6d74A0
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_HEARTLINE_TRANSFER_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -103;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 32)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 103;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 64)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 0;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 96)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -103;
|
2015-12-14 22:42:06 +01:00
|
|
|
if (vehicle->track_progress < 128)
|
|
|
|
break;
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 103;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6D74CA
|
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_MULTIDIM_INVERTED_FLAT_TO_90_DEG_QUARTER_LOOP_DOWN:
|
|
|
|
case TRACK_ELEM_INVERTED_FLAT_TO_90_DEG_QUARTER_LOOP_DOWN:
|
|
|
|
case TRACK_ELEM_MULTIDIM_FLAT_TO_90_DEG_DOWN_QUARTER_LOOP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = (vehicle->track_progress / 4) + 55;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6d762D
|
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_90_DEG_TO_INVERTED_FLAT_QUARTER_LOOP_UP:
|
|
|
|
case TRACK_ELEM_MULTIDIM_90_DEG_UP_TO_INVERTED_FLAT_QUARTER_LOOP:
|
2015-12-13 16:33:01 +01:00
|
|
|
case 255:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = (((uint16)(-(vehicle->track_progress - 137))) / 4) + 55;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6D7614
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_AIR_THRUST_TOP_CAP:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = -60;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6D744C
|
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_3_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_3_TILE_25_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 200;
|
|
|
|
lateralFactor = 100;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6d76C8
|
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_3_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_3_TILE_25_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 200;
|
|
|
|
lateralFactor = -100;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6d76d7
|
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_5_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_5_TILE_25_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 200;
|
|
|
|
lateralFactor = 160;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6D76E6
|
|
|
|
break;
|
2015-12-14 22:42:06 +01:00
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_5_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_5_TILE_25_DEG_DOWN:
|
2015-12-15 18:47:30 +01:00
|
|
|
vertFactor = 200;
|
|
|
|
lateralFactor = -160;
|
2015-12-13 16:33:01 +01:00
|
|
|
//6d76F5
|
|
|
|
break;
|
2015-12-12 21:25:20 +01:00
|
|
|
}
|
|
|
|
|
2015-12-15 18:47:30 +01:00
|
|
|
int gForceLateral = 0;
|
|
|
|
|
|
|
|
if (vertFactor != 0) {
|
|
|
|
gForceVert += abs(vehicle->velocity) * 98 / vertFactor;
|
2015-12-14 22:42:06 +01:00
|
|
|
}
|
|
|
|
|
2015-12-15 18:47:30 +01:00
|
|
|
if (lateralFactor != 0) {
|
|
|
|
gForceLateral += abs(vehicle->velocity) * 98 / lateralFactor;
|
2015-12-14 22:42:06 +01:00
|
|
|
}
|
|
|
|
|
2015-12-15 18:47:30 +01:00
|
|
|
gForceVert *= 10;
|
|
|
|
gForceLateral *= 10;
|
|
|
|
gForceVert >>= 16;
|
|
|
|
gForceLateral >>= 16;
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-15 18:47:30 +01:00
|
|
|
if (verticalG != NULL) *verticalG = (sint16)(gForceVert & 0xFFFF);
|
|
|
|
if (lateralG != NULL) *lateralG = (sint16)(gForceLateral & 0xFFFF);
|
2014-11-10 01:40:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void vehicle_set_map_toolbar(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
rct_ride *ride;
|
|
|
|
int vehicleIndex;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
ride = get_ride(vehicle->ride);
|
2014-11-10 01:40:59 +01:00
|
|
|
|
2015-10-25 17:00:21 +01:00
|
|
|
while (vehicle->is_child) {
|
|
|
|
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
|
|
|
}
|
2014-11-10 01:40:59 +01:00
|
|
|
|
|
|
|
for (vehicleIndex = 0; vehicleIndex < 32; vehicleIndex++)
|
|
|
|
if (ride->vehicles[vehicleIndex] == vehicle->sprite_index)
|
|
|
|
break;
|
|
|
|
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 0, uint16) = 2215;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 2, uint16) = 1165;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 4, uint16) = ride->name;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 6, uint32) = ride->name_arguments;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 10, uint16) = RideNameConvention[ride->type].vehicle_name + 2;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 12, uint16) = vehicleIndex + 1;
|
|
|
|
|
|
|
|
int arg0, arg1;
|
|
|
|
ride_get_status(vehicle->ride, &arg0, &arg1);
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 14, uint16) = (uint16)arg0;
|
|
|
|
RCT2_GLOBAL(RCT2_ADDRESS_MAP_TOOLTIP_ARGS + 16, uint32) = (uint16)arg1;
|
2014-11-29 16:55:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
rct_vehicle *vehicle_get_head(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
rct_vehicle *prevVehicle;
|
|
|
|
|
|
|
|
for (;;) {
|
2015-10-25 17:00:21 +01:00
|
|
|
prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
2014-11-29 16:55:44 +01:00
|
|
|
if (prevVehicle->next_vehicle_on_train == SPRITE_INDEX_NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
vehicle = prevVehicle;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vehicle;
|
2015-03-21 13:26:28 +01:00
|
|
|
}
|
|
|
|
|
2015-10-25 22:25:54 +01:00
|
|
|
rct_vehicle *vehicle_get_tail(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
uint16 spriteIndex;
|
|
|
|
|
|
|
|
while ((spriteIndex = vehicle->next_vehicle_on_train) != SPRITE_INDEX_NULL) {
|
|
|
|
vehicle = GET_VEHICLE(spriteIndex);
|
|
|
|
}
|
|
|
|
return vehicle;
|
|
|
|
}
|
|
|
|
|
2015-03-21 13:26:28 +01:00
|
|
|
int vehicle_is_used_in_pairs(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
return vehicle->num_seats & VEHICLE_SEAT_PAIR_FLAG;
|
2015-09-12 19:17:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2015-12-16 19:37:45 +01:00
|
|
|
* rct2: 0x006DA44E
|
2015-09-12 19:17:25 +02:00
|
|
|
*/
|
2015-12-12 15:55:05 +01:00
|
|
|
static int vehicle_update_motion_bumper_car(rct_vehicle* vehicle) {
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) = 0;
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride* ride = get_ride(vehicle->ride);
|
2015-12-12 15:55:05 +01:00
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
sint32 nextVelocity = vehicle->velocity + vehicle->acceleration;
|
2015-12-12 15:55:05 +01:00
|
|
|
if (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN) &&
|
|
|
|
ride->breakdown_reason_pending == BREAKDOWN_SAFETY_CUT_OUT) {
|
|
|
|
nextVelocity = 0;
|
|
|
|
}
|
|
|
|
vehicle->velocity = nextVelocity;
|
|
|
|
|
|
|
|
RCT2_GLOBAL(0x00F64E08, sint32) = nextVelocity;
|
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) = (nextVelocity / 1024) * 42;
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32) = 1;
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-12-12 15:55:05 +01:00
|
|
|
if (!(ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN)) ||
|
|
|
|
ride->breakdown_reason_pending != BREAKDOWN_SAFETY_CUT_OUT) {
|
|
|
|
if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 1 &&
|
|
|
|
vehicle->var_34 != 0) {
|
|
|
|
|
|
|
|
if (vehicle->var_34 > 0) {
|
|
|
|
vehicle->var_34--;
|
|
|
|
vehicle->sprite_direction += 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vehicle->var_34++;
|
|
|
|
vehicle->sprite_direction -= 2;
|
|
|
|
}
|
|
|
|
vehicle->sprite_direction &= 0x1E;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-12 15:55:05 +01:00
|
|
|
}
|
|
|
|
else if ((scenario_rand() & 0xFFFF) <= 2849) {
|
|
|
|
if (vehicle->var_35 & (1 << 6))
|
|
|
|
vehicle->sprite_direction -= 2;
|
|
|
|
else
|
|
|
|
vehicle->sprite_direction += 2;
|
|
|
|
vehicle->sprite_direction &= 0x1E;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-12 15:55:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 collideSprite = 0xFFFF;
|
|
|
|
|
|
|
|
if (vehicle->var_C4 != 0) {
|
|
|
|
uint8 oldC4 = vehicle->var_C4 & 0x1E;
|
|
|
|
vehicle->var_C4 = 0;
|
|
|
|
|
|
|
|
rct_xyz16 location = {
|
|
|
|
.x = vehicle->x,
|
|
|
|
.y = vehicle->y,
|
|
|
|
.z = vehicle->z
|
|
|
|
};
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-12 15:55:05 +01:00
|
|
|
location.x += RCT2_ADDRESS(0x009A36C4, sint16)[oldC4 * 4];
|
|
|
|
location.y += RCT2_ADDRESS(0x009A36C6, sint16)[oldC4 * 4];
|
|
|
|
location.x += RCT2_ADDRESS(0x009A36CC, sint16)[oldC4 * 4];
|
|
|
|
location.y += RCT2_ADDRESS(0x009A36CE, sint16)[oldC4 * 4];
|
|
|
|
|
|
|
|
if (!vehicle_update_bumper_car_collision(vehicle, location.x, location.y, &collideSprite)) {
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-12 15:55:05 +01:00
|
|
|
sprite_move(
|
|
|
|
location.x,
|
|
|
|
location.y,
|
|
|
|
location.z,
|
|
|
|
(rct_sprite*)vehicle
|
|
|
|
);
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-12 15:55:05 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance += RCT2_GLOBAL(0x00F64E0C, sint32);
|
2015-12-12 15:55:05 +01:00
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
if (vehicle->remaining_distance >= 13962) {
|
2015-12-12 15:55:05 +01:00
|
|
|
vehicle->var_B8 &= ~(1 << 1);
|
|
|
|
rct_xyz16 *unk_F64E20 = RCT2_ADDRESS(0x00F64E20, rct_xyz16);
|
|
|
|
unk_F64E20->x = vehicle->x;
|
|
|
|
unk_F64E20->y = vehicle->y;
|
|
|
|
unk_F64E20->z = vehicle->z;
|
|
|
|
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-12 15:55:05 +01:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
vehicle->var_35++;
|
|
|
|
uint8 direction = vehicle->sprite_direction;
|
|
|
|
direction |= vehicle->var_35 & 1;
|
|
|
|
|
|
|
|
rct_xyz16 location = *unk_F64E20;
|
|
|
|
location.x += RCT2_ADDRESS(0x009A36C4, sint16)[direction * 4];
|
|
|
|
location.y += RCT2_ADDRESS(0x009A36C6, sint16)[direction * 4];
|
|
|
|
|
|
|
|
if (vehicle_update_bumper_car_collision(vehicle, location.x, location.y, &collideSprite))
|
|
|
|
break;
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= RCT2_ADDRESS(0x009A36C8, sint16)[direction * 4];
|
2015-12-12 15:55:05 +01:00
|
|
|
unk_F64E20->x = location.x;
|
|
|
|
unk_F64E20->y = location.y;
|
2015-12-20 22:36:11 +01:00
|
|
|
if (vehicle->remaining_distance < 13962) {
|
2015-12-12 15:55:05 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
}
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
if (vehicle->remaining_distance >= 13962) {
|
2015-12-12 15:55:05 +01:00
|
|
|
sint32 oldVelocity = vehicle->velocity;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance = 0;
|
2015-12-12 15:55:05 +01:00
|
|
|
vehicle->velocity = 0;
|
|
|
|
uint8 direction = vehicle->sprite_direction | 1;
|
|
|
|
|
|
|
|
if (collideSprite != 0xFFFF) {
|
|
|
|
vehicle->var_34 = scenario_rand() & 1 ? 1 : -1;
|
|
|
|
|
|
|
|
if (oldVelocity >= 131072) {
|
|
|
|
rct_vehicle* collideVehicle = GET_VEHICLE(collideSprite);
|
|
|
|
collideVehicle->var_C4 = direction;
|
|
|
|
vehicle->var_C4 = direction ^ (1 << 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
vehicle->var_34 = scenario_rand() & 1 ? 6 : -6;
|
|
|
|
|
|
|
|
if (oldVelocity >= 131072) {
|
|
|
|
vehicle->var_C4 = direction ^ (1 << 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-12 15:55:05 +01:00
|
|
|
sprite_move(
|
|
|
|
unk_F64E20->x,
|
|
|
|
unk_F64E20->y,
|
|
|
|
unk_F64E20->z,
|
|
|
|
(rct_sprite*)vehicle
|
|
|
|
);
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-12 15:55:05 +01:00
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-12 15:55:05 +01:00
|
|
|
sint32 eax = vehicle->velocity / 2;
|
|
|
|
sint32 edx = vehicle->velocity >> 8;
|
|
|
|
edx *= edx;
|
|
|
|
if (vehicle->velocity < 0)
|
|
|
|
edx = -edx;
|
|
|
|
edx >>= 5;
|
|
|
|
eax += edx;
|
|
|
|
eax /= vehicle->friction;
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type* rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-12-12 15:55:05 +01:00
|
|
|
rct_ride_type_vehicle* vehicleEntry = &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3)) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -eax;
|
2015-12-12 15:55:05 +01:00
|
|
|
return RCT2_GLOBAL(0x00F64E18, uint32);
|
|
|
|
}
|
|
|
|
|
|
|
|
sint32 ebx = (vehicle->speed * vehicle->friction) >> 2;
|
|
|
|
sint32 _eax = vehicle->speed << 14;
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_3) {
|
|
|
|
_eax = -_eax;
|
|
|
|
}
|
|
|
|
_eax -= vehicle->velocity;
|
2015-12-20 22:36:11 +01:00
|
|
|
_eax *= vehicle->powered_acceleration * 2;
|
2015-12-12 15:55:05 +01:00
|
|
|
_eax /= ebx;
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = _eax - eax;
|
2015-12-12 15:55:05 +01:00
|
|
|
return RCT2_GLOBAL(0x00F64E18, uint32);
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
|
2015-10-25 17:00:21 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2015-10-25 22:25:54 +01:00
|
|
|
* rct2: 0x006DD365
|
2015-10-25 17:00:21 +01:00
|
|
|
*/
|
2016-01-15 20:44:06 +01:00
|
|
|
bool vehicle_update_bumper_car_collision(rct_vehicle *vehicle, sint16 x, sint16 y, uint16 *spriteId)
|
2015-10-25 17:00:21 +01:00
|
|
|
{
|
2015-12-12 18:59:03 +01:00
|
|
|
uint16 bp = (vehicle->var_44 * 30) >> 9;
|
|
|
|
uint32 trackType = vehicle->track_type >> 2;
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-12 18:59:03 +01:00
|
|
|
sint16 rideLeft = vehicle->track_x + RCT2_ADDRESS(0x0099E228, uint8)[trackType * 4];
|
|
|
|
sint16 rideRight = vehicle->track_x + RCT2_ADDRESS(0x0099E22A, uint8)[trackType * 4];
|
|
|
|
sint16 rideTop = vehicle->track_y + RCT2_ADDRESS(0x0099E229, uint8)[trackType * 4];
|
|
|
|
sint16 rideBottom = vehicle->track_y + RCT2_ADDRESS(0x0099E22B, uint8)[trackType * 4];
|
|
|
|
|
|
|
|
if (x - bp < rideLeft ||
|
|
|
|
y - bp < rideTop ||
|
|
|
|
x + bp > rideRight ||
|
|
|
|
y + bp > rideBottom) {
|
|
|
|
if (spriteId != NULL)
|
|
|
|
*spriteId = 0xFFFF;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 location = (y / 32) | ((x / 32) << 8);
|
|
|
|
|
|
|
|
|
|
|
|
uint8 rideIndex = vehicle->ride;
|
|
|
|
for (sint32* ebp = RCT2_ADDRESS(0x009A37C4, sint32); ebp <= RCT2_ADDRESS(0x009A37E4, sint32); ebp++) {
|
|
|
|
uint16 spriteIdx = RCT2_ADDRESS(0xF1EF60, uint16)[location];
|
|
|
|
for (rct_vehicle* vehicle2 = GET_VEHICLE(spriteIdx); spriteIdx != 0xFFFF; spriteIdx = vehicle2->next_in_quadrant) {
|
|
|
|
vehicle2 = GET_VEHICLE(spriteIdx);
|
|
|
|
|
|
|
|
if (vehicle2 == vehicle)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (vehicle2->sprite_identifier != SPRITE_IDENTIFIER_VEHICLE)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (vehicle2->ride != rideIndex)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int distX = abs(x - vehicle2->x);
|
|
|
|
if (distX > 32768)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int distY = abs(y - vehicle2->y);
|
|
|
|
if (distY > 32768)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
int ecx = (vehicle->var_44 + vehicle2->var_44) / 2;
|
|
|
|
ecx *= 30;
|
|
|
|
ecx >>= 8;
|
|
|
|
if (max(distX, distY) < ecx) {
|
|
|
|
if (spriteId != NULL)
|
|
|
|
*spriteId = vehicle2->sprite_index;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
location += *ebp;
|
|
|
|
}
|
2015-10-25 17:00:21 +01:00
|
|
|
|
2015-12-12 18:59:03 +01:00
|
|
|
return false;
|
2015-10-25 17:00:21 +01:00
|
|
|
}
|
|
|
|
|
2015-12-16 19:37:45 +01:00
|
|
|
// rct2: 0x009A2970
|
2015-10-25 20:23:42 +01:00
|
|
|
const sint32 *dword_9A2970 = (sint32*)0x009A2970;
|
2015-10-25 17:34:04 +01:00
|
|
|
|
2015-10-25 17:00:21 +01:00
|
|
|
/**
|
|
|
|
*
|
2015-12-15 19:56:19 +01:00
|
|
|
* rct2: 0x006DAB90
|
2015-10-25 17:00:21 +01:00
|
|
|
*/
|
2015-12-15 19:56:19 +01:00
|
|
|
static void vehicle_update_track_motion_up_stop_check(rct_vehicle *vehicle)
|
2015-10-25 17:34:04 +01:00
|
|
|
{
|
2015-10-25 18:49:54 +01:00
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
2015-10-25 17:34:04 +01:00
|
|
|
int verticalG, lateralG;
|
|
|
|
|
2015-12-15 19:56:19 +01:00
|
|
|
// No up stops (coaster types)
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_1) {
|
2015-10-25 20:23:42 +01:00
|
|
|
int trackType = vehicle->track_type >> 2;
|
2015-12-15 19:56:19 +01:00
|
|
|
if (!track_element_is_covered(trackType)) {
|
2015-10-25 17:34:04 +01:00
|
|
|
vehicle_get_g_forces(vehicle, &verticalG, &lateralG);
|
|
|
|
lateralG = abs(lateralG);
|
|
|
|
if (lateralG <= 150) {
|
2015-10-25 20:23:42 +01:00
|
|
|
if (dword_9A2970[vehicle->var_1F] < 0) {
|
2015-10-25 17:34:04 +01:00
|
|
|
if (verticalG > -40) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (verticalG > -80) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->var_1F != 8) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_DERAILED;
|
2015-10-25 17:34:04 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-16 20:12:58 +01:00
|
|
|
} else if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_2) {
|
2015-12-15 19:56:19 +01:00
|
|
|
// No up stops bobsleigh type
|
2015-10-25 20:23:42 +01:00
|
|
|
int trackType = vehicle->track_type >> 2;
|
2015-12-15 19:56:19 +01:00
|
|
|
if (!track_element_is_covered(trackType)) {
|
2015-10-25 17:34:04 +01:00
|
|
|
vehicle_get_g_forces(vehicle, &verticalG, &lateralG);
|
|
|
|
|
2015-10-25 20:23:42 +01:00
|
|
|
if (dword_9A2970[vehicle->var_1F] < 0) {
|
2015-10-25 17:34:04 +01:00
|
|
|
if (verticalG > -45) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (verticalG > -80) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->var_1F != 8 && vehicle->var_1F != 55) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_DERAILED;
|
2015-10-25 17:34:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-25 18:49:54 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DAC43
|
|
|
|
*/
|
|
|
|
static void sub_6DAB4C_chunk_2(rct_vehicle *vehicle)
|
|
|
|
{
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
2015-10-25 18:49:54 +01:00
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
|
2015-12-15 23:32:11 +01:00
|
|
|
// Is chair lift type
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_12) {
|
2015-10-25 18:49:54 +01:00
|
|
|
sint32 velocity = ride->speed << 16;
|
|
|
|
if (RCT2_GLOBAL(0x00F64E34, uint8) == 0) {
|
|
|
|
velocity = 0;
|
|
|
|
}
|
|
|
|
vehicle->velocity = velocity;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-10-25 18:49:54 +01:00
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-10-25 20:23:42 +01:00
|
|
|
int trackType = vehicle->track_type >> 2;
|
2015-10-25 18:49:54 +01:00
|
|
|
switch (trackType) {
|
2015-12-15 23:32:11 +01:00
|
|
|
case TRACK_ELEM_END_STATION:
|
|
|
|
case TRACK_ELEM_BLOCK_BRAKES:
|
2015-10-25 18:49:54 +01:00
|
|
|
if (ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT || ride_is_block_sectioned(ride)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
2015-12-15 23:32:11 +01:00
|
|
|
case TRACK_ELEM_25_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_60_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_CABLE_LIFT_HILL:
|
|
|
|
case TRACK_ELEM_DIAG_25_DEG_UP_TO_FLAT:
|
|
|
|
case TRACK_ELEM_DIAG_60_DEG_UP_TO_FLAT:
|
2015-10-25 18:49:54 +01:00
|
|
|
if (ride_is_block_sectioned(ride)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_map_element *trackElement = map_get_track_element_at_of_type(
|
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z >> 3,
|
|
|
|
trackType
|
|
|
|
);
|
2015-12-15 23:32:11 +01:00
|
|
|
if (trackType == TRACK_ELEM_END_STATION) {
|
2015-10-25 18:49:54 +01:00
|
|
|
if (trackElement->flags & (1 << 5)) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_10;
|
2015-10-25 18:49:54 +01:00
|
|
|
}
|
2015-12-15 23:32:11 +01:00
|
|
|
} else if (trackType == TRACK_ELEM_CABLE_LIFT_HILL || trackType == TRACK_ELEM_BLOCK_BRAKES || track_element_is_lift_hill(trackElement)) {
|
2015-10-25 18:49:54 +01:00
|
|
|
if (!(trackElement->flags & (1 << 5))) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (trackType == TRACK_ELEM_BLOCK_BRAKES && vehicle->velocity >= 0) {
|
2015-10-25 18:49:54 +01:00
|
|
|
if (vehicle->velocity <= 0x20364) {
|
|
|
|
vehicle->velocity = 0x20364;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-10-25 18:49:54 +01:00
|
|
|
} else {
|
|
|
|
vehicle->velocity -= vehicle->velocity >> 4;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-10-25 18:49:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_10;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-10-25 18:49:54 +01:00
|
|
|
if (vehicle->velocity <= 0x20000) {
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
vehicle->velocity -= vehicle->velocity >> 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-25 19:31:51 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DADAE
|
|
|
|
*/
|
|
|
|
static void sub_6DAB4C_chunk_3(rct_vehicle *vehicle)
|
|
|
|
{
|
2015-12-20 22:36:11 +01:00
|
|
|
sint32 nextVelocity = vehicle->acceleration + vehicle->velocity;
|
2015-10-25 21:09:53 +01:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_7) {
|
2015-10-25 19:31:51 +01:00
|
|
|
nextVelocity = 0;
|
|
|
|
}
|
2016-02-18 22:47:24 +01:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_ON_BREAK_FOR_DROP) {
|
|
|
|
vehicle->vertical_drop_countdown--;
|
|
|
|
if (vehicle->vertical_drop_countdown == -70) {
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_ON_BREAK_FOR_DROP;
|
2015-10-25 19:31:51 +01:00
|
|
|
}
|
2016-02-18 22:47:24 +01:00
|
|
|
if (vehicle->vertical_drop_countdown >= 0) {
|
2015-10-25 19:31:51 +01:00
|
|
|
nextVelocity = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0;
|
2015-10-25 19:31:51 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
vehicle->velocity = nextVelocity;
|
|
|
|
|
|
|
|
RCT2_GLOBAL(0x00F64E08, sint32) = nextVelocity;
|
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) = (nextVelocity >> 10) * 42;
|
|
|
|
}
|
|
|
|
|
2016-01-02 18:04:39 +01:00
|
|
|
static void vehicle_update_block_breaks_open_previous_section(rct_vehicle *vehicle, rct_map_element *mapElement)
|
2015-11-01 16:50:38 +01:00
|
|
|
{
|
|
|
|
int x = vehicle->track_x;
|
|
|
|
int y = vehicle->track_y;
|
|
|
|
int z = vehicle->track_z;
|
|
|
|
track_begin_end trackBeginEnd;
|
|
|
|
do {
|
|
|
|
if (!track_block_get_previous(x, y, mapElement, &trackBeginEnd)) {
|
|
|
|
return;
|
|
|
|
}
|
2016-01-02 18:04:39 +01:00
|
|
|
if (trackBeginEnd.begin_x == vehicle->track_x &&
|
|
|
|
trackBeginEnd.begin_y == vehicle->track_y &&
|
|
|
|
mapElement == trackBeginEnd.begin_element) {
|
2015-11-01 16:50:38 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-18 00:12:08 +01:00
|
|
|
x = trackBeginEnd.end_x;
|
|
|
|
y = trackBeginEnd.end_y;
|
2015-11-01 16:50:38 +01:00
|
|
|
z = trackBeginEnd.begin_z;
|
2015-12-18 00:12:08 +01:00
|
|
|
mapElement = trackBeginEnd.begin_element;
|
|
|
|
} while (!track_element_is_block_start(trackBeginEnd.begin_element));
|
2015-11-01 16:50:38 +01:00
|
|
|
|
2016-01-11 19:35:36 +01:00
|
|
|
// Get the start of the track block instead of the end
|
|
|
|
x = trackBeginEnd.begin_x;
|
|
|
|
y = trackBeginEnd.begin_y;
|
|
|
|
z = trackBeginEnd.begin_z;
|
2015-11-01 16:50:38 +01:00
|
|
|
mapElement = map_get_track_element_at(x, y, z >> 3);
|
2015-12-22 15:21:56 +01:00
|
|
|
if (mapElement == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
2016-01-02 18:04:39 +01:00
|
|
|
mapElement->flags &= ~MAP_ELEMENT_FLAG_BLOCK_BREAK_CLOSED;
|
2015-11-01 16:50:38 +01:00
|
|
|
map_invalidate_element(x, y, mapElement);
|
|
|
|
|
|
|
|
int trackType = mapElement->properties.track.type;
|
2015-12-18 00:12:08 +01:00
|
|
|
if (trackType == TRACK_ELEM_BLOCK_BRAKES || trackType == TRACK_ELEM_END_STATION) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
2015-11-01 16:50:38 +01:00
|
|
|
if (ride_is_block_sectioned(ride)) {
|
2015-11-21 12:59:38 +01:00
|
|
|
audio_play_sound_at_location(SOUND_48, x, y, z);
|
2015-11-01 16:50:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-20 16:22:51 +01:00
|
|
|
static int vehicle_get_swing_amount(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
int trackType = vehicle->track_type >> 2;
|
|
|
|
switch (trackType) {
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_BANKED_LEFT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_5_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_UP_LARGE:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_DOWN_LARGE:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_BANKED_HELIX_LARGE_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_HELIX_LARGE_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_5_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_5_TILE_25_DEG_DOWN:
|
|
|
|
// loc_6D67E1
|
|
|
|
return 14;
|
|
|
|
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_BANKED_RIGHT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_5_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_UP_LARGE:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_LARGE:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_BANKED_HELIX_LARGE_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_HELIX_LARGE_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_HELIX_LARGE_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_5_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_5_TILE_25_DEG_DOWN:
|
|
|
|
// loc_6D6804
|
|
|
|
return -14;
|
|
|
|
|
|
|
|
case TRACK_ELEM_S_BEND_LEFT:
|
|
|
|
case TRACK_ELEM_S_BEND_LEFT_COVERED:
|
|
|
|
// loc_6D67EF
|
2016-01-23 19:50:36 +01:00
|
|
|
if (vehicle->track_progress < 48) {
|
2015-12-20 16:22:51 +01:00
|
|
|
return 14;
|
|
|
|
} else {
|
|
|
|
return -15;
|
|
|
|
}
|
|
|
|
|
|
|
|
case TRACK_ELEM_S_BEND_RIGHT:
|
|
|
|
case TRACK_ELEM_S_BEND_RIGHT_COVERED:
|
|
|
|
// loc_6D67CC
|
2016-01-23 19:50:36 +01:00
|
|
|
if (vehicle->track_progress < 48) {
|
2015-12-20 16:22:51 +01:00
|
|
|
return -14;
|
|
|
|
} else {
|
|
|
|
return 15;
|
|
|
|
}
|
|
|
|
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_BANK:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_UP_SMALL:
|
|
|
|
case TRACK_ELEM_LEFT_HALF_BANKED_HELIX_DOWN_SMALL:
|
|
|
|
case TRACK_ELEM_LEFT_BANK_TO_LEFT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_LEFT_CURVED_LIFT_HILL:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_3_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_BANKED_QUARTER_TURN_3_TILE_25_DEG_DOWN:
|
|
|
|
// loc_6D67BE
|
|
|
|
return 13;
|
|
|
|
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_BANK:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_COVERED:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_UP_SMALL:
|
|
|
|
case TRACK_ELEM_RIGHT_HALF_BANKED_HELIX_DOWN_SMALL:
|
|
|
|
case TRACK_ELEM_RIGHT_BANK_TO_RIGHT_QUARTER_TURN_3_TILES_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_25_DEG_DOWN_TO_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_RIGHT_CURVED_LIFT_HILL:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_3_TILE_25_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_BANKED_QUARTER_TURN_3_TILE_25_DEG_DOWN:
|
|
|
|
// loc_6D67B0
|
|
|
|
return -13;
|
|
|
|
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE_60_DEG_DOWN:
|
|
|
|
// loc_6D67A2
|
|
|
|
return 12;
|
|
|
|
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_UP:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE_60_DEG_DOWN:
|
|
|
|
// loc_6D6794
|
|
|
|
return -12;
|
|
|
|
|
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_TO_DIAG:
|
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_TO_ORTHOGONAL:
|
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_BANK_TO_DIAG:
|
|
|
|
case TRACK_ELEM_LEFT_EIGHTH_BANK_TO_ORTHOGONAL:
|
|
|
|
// loc_6D67D3
|
|
|
|
return 15;
|
|
|
|
|
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_TO_DIAG:
|
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_TO_ORTHOGONAL:
|
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_BANK_TO_DIAG:
|
|
|
|
case TRACK_ELEM_RIGHT_EIGHTH_BANK_TO_ORTHOGONAL:
|
|
|
|
// loc_6D67F6
|
|
|
|
return -15;
|
|
|
|
}
|
2015-12-20 21:58:30 +01:00
|
|
|
return 0;
|
2015-12-20 16:22:51 +01:00
|
|
|
}
|
|
|
|
|
2015-10-25 20:23:42 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D6776
|
|
|
|
*/
|
2015-12-17 00:39:38 +01:00
|
|
|
static void vehicle_update_swinging_car(rct_vehicle *vehicle)
|
2015-10-25 20:23:42 +01:00
|
|
|
{
|
2015-12-20 16:22:51 +01:00
|
|
|
sint32 dword_F64E08 = RCT2_GLOBAL(0x00F64E08, sint32);
|
2016-01-16 11:11:56 +01:00
|
|
|
vehicle->var_4E += (-vehicle->swinging_car_var_0) >> 6;
|
2015-12-20 16:22:51 +01:00
|
|
|
int swingAmount = vehicle_get_swing_amount(vehicle);
|
|
|
|
if (swingAmount < 0) {
|
|
|
|
vehicle->var_4E -= dword_F64E08 >> (-swingAmount);
|
2015-12-20 21:58:30 +01:00
|
|
|
}
|
|
|
|
else if (swingAmount > 0){
|
2015-12-20 16:22:51 +01:00
|
|
|
vehicle->var_4E += dword_F64E08 >> swingAmount;
|
|
|
|
}
|
|
|
|
|
2015-11-01 14:12:43 +01:00
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
2015-12-20 16:22:51 +01:00
|
|
|
sint16 dx = 3185;
|
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_5) {
|
|
|
|
dx = 5006;
|
|
|
|
}
|
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_9) {
|
|
|
|
dx = 1820;
|
|
|
|
}
|
|
|
|
sint16 cx = -dx;
|
|
|
|
|
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_11) {
|
|
|
|
dx = 5370;
|
|
|
|
cx = -5370;
|
|
|
|
|
|
|
|
int trackType = vehicle->track_type >> 2;
|
|
|
|
switch (trackType) {
|
|
|
|
case TRACK_ELEM_BANKED_LEFT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_LEFT_BANK:
|
|
|
|
case TRACK_ELEM_LEFT_QUARTER_TURN_3_TILES_BANK:
|
|
|
|
dx = 10831;
|
|
|
|
cx = -819;
|
|
|
|
break;
|
|
|
|
case TRACK_ELEM_BANKED_RIGHT_QUARTER_TURN_5_TILES:
|
|
|
|
case TRACK_ELEM_RIGHT_BANK:
|
|
|
|
case TRACK_ELEM_RIGHT_QUARTER_TURN_3_TILES_BANK:
|
|
|
|
dx = 819;
|
|
|
|
cx = -10831;
|
|
|
|
break;
|
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-20 16:22:51 +01:00
|
|
|
switch (trackType) {
|
|
|
|
case TRACK_ELEM_END_STATION:
|
|
|
|
case TRACK_ELEM_BEGIN_STATION:
|
|
|
|
case TRACK_ELEM_MIDDLE_STATION:
|
|
|
|
case TRACK_ELEM_BRAKES:
|
|
|
|
case TRACK_ELEM_BLOCK_BRAKES:
|
|
|
|
dx = 0;
|
|
|
|
cx = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_0) {
|
|
|
|
dx = 0;
|
|
|
|
cx = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->swinging_car_var_0 += vehicle->var_4E;
|
2015-12-20 16:22:51 +01:00
|
|
|
vehicle->var_4E -= vehicle->var_4E >> 5;
|
2016-01-04 10:36:29 +01:00
|
|
|
sint16 ax = vehicle->swinging_car_var_0;
|
2015-12-20 16:22:51 +01:00
|
|
|
if (ax > dx) {
|
|
|
|
ax = dx;
|
|
|
|
vehicle->var_4E = 0;
|
|
|
|
}
|
|
|
|
if (ax < cx) {
|
|
|
|
ax = cx;
|
|
|
|
vehicle->var_4E = 0;
|
|
|
|
}
|
|
|
|
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->swinging_car_var_0 = ax;
|
2015-12-20 16:22:51 +01:00
|
|
|
uint8 bl = 11;
|
|
|
|
if (ax >= -10012) {
|
|
|
|
bl = 12;
|
|
|
|
if (ax <= 10012) {
|
|
|
|
bl = 9;
|
|
|
|
if (ax >= -8191) {
|
|
|
|
bl = 10;
|
|
|
|
if (ax <= 8191) {
|
|
|
|
bl = 7;
|
|
|
|
if (ax >= -6371) {
|
|
|
|
bl = 8;
|
|
|
|
if (ax <= 6371) {
|
|
|
|
bl = 5;
|
|
|
|
if (ax >= -4550) {
|
|
|
|
bl = 6;
|
|
|
|
if (ax <= 4550) {
|
|
|
|
bl = 3;
|
|
|
|
if (ax >= -2730) {
|
|
|
|
bl = 4;
|
|
|
|
if (ax <= 2730) {
|
|
|
|
ax = 1;
|
|
|
|
if (ax >= -910) {
|
|
|
|
bl = 2;
|
|
|
|
if (ax <= 910) {
|
|
|
|
bl = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (bl != vehicle->var_4A) {
|
|
|
|
vehicle->var_4A = bl;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
2015-10-25 20:23:42 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 21:08:15 +01:00
|
|
|
#pragma region off_9A2E84
|
|
|
|
|
|
|
|
enum {
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D6711,
|
|
|
|
loc_6D66D6,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D669A,
|
|
|
|
loc_6D6684,
|
|
|
|
loc_6D665A,
|
|
|
|
loc_6D6708,
|
|
|
|
loc_6D6703,
|
|
|
|
loc_6D66DD,
|
|
|
|
loc_6D6718
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint8 off_9A2E84[256] = {
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D6711,
|
|
|
|
loc_6D66D6,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D669A,
|
|
|
|
loc_6D6684,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D6711,
|
|
|
|
loc_6D66D6,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D669A,
|
|
|
|
loc_6D6684,
|
|
|
|
loc_6D669A,
|
|
|
|
loc_6D6684,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D665A,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D6708,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D6703,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66DD,
|
|
|
|
loc_6D6718,
|
|
|
|
loc_6D66DD,
|
|
|
|
loc_6D6718,
|
|
|
|
loc_6D66DD,
|
|
|
|
loc_6D6718,
|
|
|
|
loc_6D66DD,
|
|
|
|
loc_6D6718,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66C3,
|
|
|
|
loc_6D66B0,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D66F0,
|
|
|
|
loc_6D672B,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C,
|
|
|
|
loc_6D673C
|
|
|
|
};
|
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
2015-10-25 20:23:42 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D661F
|
|
|
|
*/
|
2015-12-17 00:39:38 +01:00
|
|
|
static void vehicle_update_spinning_car(rct_vehicle *vehicle)
|
2015-10-25 20:23:42 +01:00
|
|
|
{
|
2015-12-14 21:08:15 +01:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_13) {
|
|
|
|
vehicle->var_B6 = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
int spinningInertia = vehicleEntry->spinning_inertia;
|
|
|
|
int trackType = vehicle->track_type >> 2;
|
|
|
|
sint32 dword_F64E08 = RCT2_GLOBAL(0x00F64E08, sint32);
|
|
|
|
int unk;
|
|
|
|
switch (off_9A2E84[trackType]) {
|
|
|
|
case loc_6D665A:
|
|
|
|
spinningInertia += 6;
|
|
|
|
unk = dword_F64E08 >> spinningInertia;
|
|
|
|
if (vehicle->sprite_index & 1) {
|
|
|
|
vehicle->var_B6 -= unk;
|
|
|
|
} else {
|
|
|
|
vehicle->var_B6 += unk;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case loc_6D6684:
|
|
|
|
case loc_6D6703:
|
|
|
|
spinningInertia += 5;
|
|
|
|
vehicle->var_B6 -= dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
case loc_6D669A:
|
|
|
|
spinningInertia += 5;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
case loc_6D66B0:
|
|
|
|
spinningInertia += 7;
|
|
|
|
vehicle->var_B6 -= dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
case loc_6D66C3:
|
|
|
|
spinningInertia += 7;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
case loc_6D66D6:
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress < 48) {
|
2015-12-14 21:08:15 +01:00
|
|
|
spinningInertia += 8;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case loc_6D66DD:
|
|
|
|
spinningInertia += 9;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
case loc_6D66F0:
|
|
|
|
spinningInertia += 8;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
case loc_6D6708:
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress > 22) {
|
2015-12-14 21:08:15 +01:00
|
|
|
spinningInertia += 5;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case loc_6D6711:
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress < 48) {
|
2015-12-14 21:08:15 +01:00
|
|
|
spinningInertia += 8;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case loc_6D6718:
|
|
|
|
spinningInertia += 9;
|
|
|
|
vehicle->var_B6 -= dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
case loc_6D672B:
|
|
|
|
spinningInertia += 8;
|
|
|
|
vehicle->var_B6 += dword_F64E08 >> spinningInertia;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
unk = clamp(-0x600, vehicle->var_B6, 0x600);
|
|
|
|
vehicle->var_B6 = unk;
|
|
|
|
vehicle->var_BA += unk >> 8;
|
|
|
|
vehicle->var_B6 -= unk >> vehicleEntry->spinning_friction;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006734B2
|
|
|
|
*/
|
2015-12-20 13:50:33 +01:00
|
|
|
static void steam_particle_create(sint16 x, sint16 y, sint16 z)
|
2015-12-20 13:30:10 +01:00
|
|
|
{
|
2015-12-20 13:50:33 +01:00
|
|
|
rct_map_element *mapElement = map_get_surface_element_at(x >> 5, y >> 5);
|
|
|
|
if (mapElement != NULL && z > mapElement->base_height * 8) {
|
|
|
|
rct_steam_particle *steam = (rct_steam_particle*)create_sprite(2);
|
|
|
|
steam->sprite_width = 20;
|
|
|
|
steam->sprite_height_negative = 18;
|
|
|
|
steam->sprite_height_positive = 16;
|
|
|
|
steam->sprite_identifier = SPRITE_IDENTIFIER_MISC;
|
|
|
|
steam->misc_identifier = SPRITE_MISC_STEAM_PARTICLE;
|
|
|
|
steam->var_26 = 256;
|
|
|
|
steam->var_24 = 0;
|
|
|
|
sprite_move(x, y, z, (rct_sprite*)steam);
|
|
|
|
}
|
2015-10-25 20:23:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006D63D4
|
|
|
|
*/
|
|
|
|
static void sub_6D63D4(rct_vehicle *vehicle)
|
|
|
|
{
|
2015-12-20 13:30:10 +01:00
|
|
|
uint8 al, ah;
|
|
|
|
uint32 eax;
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-20 13:30:10 +01:00
|
|
|
uint32 *var_C8 = (uint32*)&vehicle->var_C8;
|
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
switch (vehicleEntry->var_11) {
|
|
|
|
case 1: // loc_6D652B
|
|
|
|
*var_C8 += RCT2_GLOBAL(0x00F64E08, uint32);
|
|
|
|
al = (*var_C8 >> 20) & 3;
|
|
|
|
if (vehicle->var_C5 != al) {
|
|
|
|
ah = al;
|
|
|
|
al = vehicle->var_C5;
|
|
|
|
vehicle->var_C5 = ah;
|
|
|
|
al &= 0x02;
|
|
|
|
ah &= 0x02;
|
|
|
|
if (al != ah) {
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
2015-12-20 13:30:10 +01:00
|
|
|
if (ride->entrance_style == RIDE_ENTRANCE_STYLE_PLAIN ||
|
|
|
|
(vehicle->status != VEHICLE_STATUS_MOVING_TO_END_OF_STATION &&
|
|
|
|
vehicle->status != VEHICLE_STATUS_ARRIVING)
|
|
|
|
) {
|
|
|
|
int index = vehicle->sprite_direction >> 1;
|
|
|
|
if (vehicle->var_1F == 2) {
|
|
|
|
index += 16;
|
|
|
|
}
|
|
|
|
if (vehicle->var_1F == 6) {
|
|
|
|
index += 32;
|
|
|
|
}
|
2015-12-20 13:50:33 +01:00
|
|
|
steam_particle_create(
|
|
|
|
vehicle->x + SteamParticleOffsets[index].x,
|
|
|
|
vehicle->y + SteamParticleOffsets[index].y,
|
|
|
|
vehicle->z + SteamParticleOffsets[index].z
|
2015-12-20 13:30:10 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 2: // loc_6D6424
|
|
|
|
*var_C8 += RCT2_GLOBAL(0x00F64E08, uint32);
|
|
|
|
al = (*var_C8 >> 18) & 2;
|
|
|
|
if (vehicle->var_C5 != al) {
|
|
|
|
vehicle->var_C5 = al;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3: // loc_6D6482
|
|
|
|
*var_C8 += RCT2_GLOBAL(0x00F64E08, uint32);
|
|
|
|
eax = ((*var_C8 >> 13) & 0xFF) * 6;
|
|
|
|
ah = (eax >> 8) & 0xFF;
|
|
|
|
if (vehicle->var_C5 != ah) {
|
|
|
|
vehicle->var_C5 = ah;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4: // loc_6D64F7
|
|
|
|
*var_C8 += RCT2_GLOBAL(0x00F64E08, uint32);
|
|
|
|
eax = ((*var_C8 >> 13) & 0xFF) * 7;
|
|
|
|
ah = (eax >> 8) & 0xFF;
|
|
|
|
if (vehicle->var_C5 != ah) {
|
|
|
|
vehicle->var_C5 = ah;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 5: // loc_6D6453
|
|
|
|
*var_C8 += RCT2_GLOBAL(0x00F64E08, uint32);
|
|
|
|
al = (*var_C8 >> 19) & 1;
|
|
|
|
if (vehicle->var_C5 != al) {
|
|
|
|
vehicle->var_C5 = al;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 6: // loc_6D65C3
|
|
|
|
if (vehicle->var_C8 <= 0xCCCC) {
|
|
|
|
vehicle->var_C8 += 0x3333;
|
|
|
|
} else {
|
|
|
|
vehicle->var_C8 += 0x3333;
|
2016-01-24 09:15:10 +01:00
|
|
|
vehicle->var_C5 += 1;
|
|
|
|
vehicle->var_C5 &= 7;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 7: // loc_6D63F5
|
|
|
|
*var_C8 += RCT2_GLOBAL(0x00F64E08, uint32);
|
|
|
|
al = (*var_C8 >> 18) & 3;
|
|
|
|
if (vehicle->var_C5 != al) {
|
|
|
|
vehicle->var_C5 = al;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 8: // loc_6D64B6
|
|
|
|
if (vehicle->num_peeps != 0) {
|
|
|
|
*var_C8 += RCT2_GLOBAL(0x00F64E08, uint32);
|
|
|
|
eax = ((*var_C8 >> 13) & 0xFF) << 2;
|
|
|
|
ah = (eax >> 8) & 0xFF;
|
|
|
|
if (vehicle->var_C5 != ah) {
|
|
|
|
vehicle->var_C5 = ah;
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 9: // loc_6D65E1
|
2016-02-18 22:47:24 +01:00
|
|
|
if (vehicle->seat_rotation != vehicle->target_seat_rotation) {
|
2015-12-20 13:30:10 +01:00
|
|
|
if (vehicle->var_C8 <= 0xCCCC) {
|
|
|
|
vehicle->var_C8 += 0x3333;
|
|
|
|
} else {
|
|
|
|
vehicle->var_C8 += 0x3333;
|
2016-02-18 22:47:24 +01:00
|
|
|
|
|
|
|
if (vehicle->seat_rotation >= vehicle->target_seat_rotation)
|
|
|
|
vehicle->seat_rotation--;
|
|
|
|
|
|
|
|
else
|
|
|
|
vehicle->seat_rotation++;
|
|
|
|
|
|
|
|
vehicle->var_C5 = (vehicle->seat_rotation - 4) & 7;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2015-10-25 20:23:42 +01:00
|
|
|
}
|
|
|
|
|
2015-12-14 13:30:28 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DEDB1
|
|
|
|
*/
|
2015-12-22 15:21:56 +01:00
|
|
|
static void vehicle_play_scenery_door_open_sound(rct_vehicle *vehicle, rct_map_element *mapElement)
|
2015-12-14 13:30:28 +01:00
|
|
|
{
|
|
|
|
rct_scenery_entry *wallEntry = g_wallSceneryEntries[mapElement->properties.fence.type];
|
|
|
|
int doorSoundType = (wallEntry->wall.flags2 >> 1) & 3;
|
|
|
|
if (doorSoundType != 0) {
|
2016-01-02 17:19:06 +01:00
|
|
|
int soundId = DoorOpenSoundIds[doorSoundType - 1];
|
2015-12-14 13:30:28 +01:00
|
|
|
if (soundId != 255) {
|
2016-01-02 17:19:06 +01:00
|
|
|
audio_play_sound_at_location(soundId, vehicle->x, vehicle->track_y, vehicle->track_z);
|
2015-12-14 13:30:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DED7A
|
|
|
|
*/
|
2015-12-22 15:21:56 +01:00
|
|
|
static void vehicle_play_scenery_door_close_sound(rct_vehicle *vehicle, rct_map_element *mapElement)
|
2015-12-14 13:30:28 +01:00
|
|
|
{
|
|
|
|
rct_scenery_entry *wallEntry = g_wallSceneryEntries[mapElement->properties.fence.type];
|
|
|
|
int doorSoundType = (wallEntry->wall.flags2 >> 1) & 3;
|
|
|
|
if (doorSoundType != 0) {
|
2016-01-02 17:19:06 +01:00
|
|
|
int soundId = DoorCloseSoundIds[doorSoundType - 1];
|
2015-12-14 13:30:28 +01:00
|
|
|
if (soundId != 255) {
|
2016-01-02 17:19:06 +01:00
|
|
|
audio_play_sound_at_location(soundId, vehicle->x, vehicle->track_y, vehicle->track_z);
|
2015-12-14 13:30:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-21 15:20:52 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DEE93
|
|
|
|
*/
|
|
|
|
static void vehicle_update_scenery_door(rct_vehicle *vehicle)
|
|
|
|
{
|
2015-12-14 16:28:36 +01:00
|
|
|
int trackType = vehicle->track_type >> 2;
|
2015-12-22 15:21:56 +01:00
|
|
|
const rct_preview_track *trackBlock = TrackBlocks[trackType];
|
2015-12-14 16:28:36 +01:00
|
|
|
while ((trackBlock + 1)->index != 255) {
|
|
|
|
trackBlock++;
|
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
const rct_track_coordinates *trackCoordinates = &TrackCoordinates[trackType];
|
2015-12-14 16:28:36 +01:00
|
|
|
int x = floor2(vehicle->x, 32);
|
|
|
|
int y = floor2(vehicle->y, 32);
|
|
|
|
int z = (vehicle->track_z - trackBlock->z + trackCoordinates->z_end) >> 3;
|
|
|
|
int direction = (vehicle->track_direction + trackCoordinates->rotation_end) & 3;
|
|
|
|
|
|
|
|
rct_map_element *mapElement = map_get_fence_element_at(x, y, z, direction);
|
|
|
|
if (mapElement == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) {
|
2015-12-18 22:05:49 +01:00
|
|
|
mapElement->properties.fence.item[2] &= 7;
|
|
|
|
mapElement->properties.fence.item[2] |= 8;
|
2015-12-14 16:28:36 +01:00
|
|
|
map_animation_create(MAP_ANIMATION_TYPE_WALL_UNKNOWN, x, y, z);
|
|
|
|
vehicle_play_scenery_door_open_sound(vehicle, mapElement);
|
|
|
|
} else {
|
2015-12-18 22:05:49 +01:00
|
|
|
mapElement->properties.fence.item[2] &= 7;
|
|
|
|
mapElement->properties.fence.item[2] |= 0x30;
|
2015-12-14 16:28:36 +01:00
|
|
|
vehicle_play_scenery_door_close_sound(vehicle, mapElement);
|
|
|
|
}
|
2015-11-21 15:20:52 +01:00
|
|
|
}
|
|
|
|
|
2015-11-22 13:14:53 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DB38B
|
|
|
|
*/
|
|
|
|
static bool loc_6DB38B(rct_vehicle *vehicle, rct_map_element *mapElement)
|
|
|
|
{
|
|
|
|
// Get bank
|
2015-12-13 17:10:30 +01:00
|
|
|
int bankStart = track_get_actual_bank_3(vehicle, mapElement);
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-11-22 13:14:53 +01:00
|
|
|
// Get vangle
|
2015-12-13 17:10:30 +01:00
|
|
|
int trackType = mapElement->properties.track.type;
|
2015-11-22 13:14:53 +01:00
|
|
|
int vangleStart = gTrackDefinitions[trackType].vangle_start;
|
|
|
|
|
|
|
|
// ?
|
|
|
|
uint16 angleAndBank = vangleStart | (bankStart << 8);
|
|
|
|
if (angleAndBank != RCT2_GLOBAL(0x00F64E36, uint16)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-11-22 15:55:46 +01:00
|
|
|
void loc_6DB481(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
uint16 probability = 0x8000;
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_6) {
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_6;
|
|
|
|
} else {
|
|
|
|
probability = 0x0A3D;
|
|
|
|
}
|
|
|
|
if ((scenario_rand() & 0xFFFF) <= probability) {
|
|
|
|
vehicle->var_CD += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DB545
|
|
|
|
*/
|
|
|
|
static void vehicle_trigger_on_ride_photo(rct_vehicle *vehicle, rct_map_element *mapElement)
|
|
|
|
{
|
|
|
|
mapElement->properties.track.sequence &= 0x0F;
|
|
|
|
mapElement->properties.track.sequence |= 0x30;
|
|
|
|
map_animation_create(
|
|
|
|
MAP_ANIMATION_TYPE_TRACK_ONRIDEPHOTO,
|
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
mapElement->base_height
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DEDE8
|
|
|
|
*/
|
|
|
|
static void sub_6DEDE8(rct_vehicle *vehicle)
|
|
|
|
{
|
2015-12-14 13:30:28 +01:00
|
|
|
int trackType = vehicle->track_type >> 2;
|
2015-12-22 15:21:56 +01:00
|
|
|
const rct_preview_track *trackBlock = TrackBlocks[trackType];
|
|
|
|
const rct_track_coordinates *trackCoordinates = &TrackCoordinates[trackType];
|
2015-12-14 16:28:36 +01:00
|
|
|
int x = vehicle->track_x;
|
|
|
|
int y = vehicle->track_y;
|
|
|
|
int z = (vehicle->track_z - trackBlock->z + trackCoordinates->z_begin) >> 3;
|
2015-12-14 13:30:28 +01:00
|
|
|
int direction = (vehicle->track_direction + trackCoordinates->rotation_begin) & 3;
|
|
|
|
direction ^= 2;
|
|
|
|
|
|
|
|
rct_map_element *mapElement = map_get_fence_element_at(x, y, z, direction);
|
|
|
|
if (mapElement == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->next_vehicle_on_train != SPRITE_INDEX_NULL) {
|
2015-12-18 22:05:49 +01:00
|
|
|
mapElement->properties.fence.item[2] &= 7;
|
|
|
|
mapElement->properties.fence.item[2] |= 0x88;
|
2015-12-14 13:30:28 +01:00
|
|
|
map_animation_create(MAP_ANIMATION_TYPE_WALL_UNKNOWN, x, y, z);
|
|
|
|
vehicle_play_scenery_door_open_sound(vehicle, mapElement);
|
|
|
|
} else {
|
2015-12-18 22:05:49 +01:00
|
|
|
mapElement->properties.fence.item[2] &= 7;
|
|
|
|
mapElement->properties.fence.item[2] |= 0xB0;
|
2015-12-14 13:30:28 +01:00
|
|
|
vehicle_play_scenery_door_close_sound(vehicle, mapElement);
|
|
|
|
}
|
2015-11-22 15:55:46 +01:00
|
|
|
}
|
|
|
|
|
2015-11-22 18:50:33 +01:00
|
|
|
static void vehicle_update_play_water_splash_sound()
|
|
|
|
{
|
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) <= 0x20364) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
audio_play_sound_at_location(
|
|
|
|
SOUND_WATER_SPLASH,
|
2015-11-28 18:09:56 +01:00
|
|
|
unk_F64E20->x,
|
|
|
|
unk_F64E20->y,
|
|
|
|
unk_F64E20->z
|
2015-11-22 18:50:33 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DB59E
|
|
|
|
*/
|
|
|
|
static void vehicle_update_handle_water_splash(rct_vehicle *vehicle)
|
|
|
|
{
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type *rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-11-22 18:50:33 +01:00
|
|
|
int trackType = vehicle->track_type >> 2;
|
|
|
|
|
|
|
|
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_8)) {
|
|
|
|
if (rideEntry->flags & RIDE_ENTRY_FLAG_9) {
|
|
|
|
if (!vehicle->is_child) {
|
|
|
|
if (track_element_is_covered(trackType)) {
|
|
|
|
rct_vehicle *nextVehicle = GET_VEHICLE(vehicle->next_vehicle_on_ride);
|
|
|
|
rct_vehicle *nextNextVehicle = GET_VEHICLE(nextVehicle->next_vehicle_on_ride);
|
|
|
|
if (!track_element_is_covered(nextNextVehicle->track_type >> 2)) {
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress == 4) {
|
2015-11-22 18:50:33 +01:00
|
|
|
vehicle_update_play_water_splash_sound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (trackType == TRACK_ELEM_25_DEG_DOWN_TO_FLAT) {
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress == 12) {
|
2015-11-22 18:50:33 +01:00
|
|
|
vehicle_update_play_water_splash_sound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!vehicle->is_child) {
|
|
|
|
if (trackType == TRACK_ELEM_WATER_SPLASH) {
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress == 48) {
|
2015-11-22 18:50:33 +01:00
|
|
|
vehicle_update_play_water_splash_sound();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-28 18:09:56 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DB807
|
|
|
|
*/
|
|
|
|
static void sub_6DB807(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
const rct_vehicle_info *moveInfo = vehicle_get_move_info(
|
|
|
|
vehicle->var_CD,
|
|
|
|
vehicle->track_type,
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress
|
2015-11-28 18:09:56 +01:00
|
|
|
);
|
|
|
|
int x = vehicle->track_x + moveInfo->x;
|
|
|
|
int y = vehicle->track_y + moveInfo->y;
|
|
|
|
int z = vehicle->z;
|
|
|
|
sprite_move(x, y, z, (rct_sprite*)vehicle);
|
|
|
|
}
|
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
/**
|
|
|
|
* Collision Detection
|
2015-11-28 18:49:51 +01:00
|
|
|
* rct2: 0x006DD078
|
|
|
|
* @param vehicle (esi)
|
2015-12-27 12:46:15 +01:00
|
|
|
* @param x (ax)
|
|
|
|
* @param y (cx)
|
|
|
|
* @param z (dx)
|
2015-11-28 18:49:51 +01:00
|
|
|
* @param otherVehicleIndex (bp)
|
|
|
|
*/
|
2015-12-27 12:46:15 +01:00
|
|
|
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;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_6)){
|
|
|
|
vehicle->var_C4 = 0;
|
2016-01-25 19:17:25 +01:00
|
|
|
|
|
|
|
// If hacking boat hire rides you can end up here
|
|
|
|
if (otherVehicleIndex == NULL) return false;
|
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
rct_vehicle* collideVehicle = GET_VEHICLE(*otherVehicleIndex);
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (vehicle == collideVehicle) return false;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
sint32 x_diff = abs(x - collideVehicle->x);
|
|
|
|
if (x_diff > 0x7FFF) return false;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
sint32 y_diff = abs(y - collideVehicle->y);
|
|
|
|
if (y_diff > 0x7FFF) return false;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (x_diff + y_diff > 0xFFFF) return false;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
sint32 z_diff = abs(z - collideVehicle->z);
|
|
|
|
if (x_diff + y_diff + z_diff > 0xFFFF) return false;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
uint16 ecx = min(vehicle->var_44 + collideVehicle->var_44, 560);
|
|
|
|
ecx = ((ecx >> 1) * 30) >> 8;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (x_diff + y_diff + z_diff >= ecx) return false;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
uint8 direction = (vehicle->sprite_direction - collideVehicle->sprite_direction + 7) & 0x1F;
|
|
|
|
if (direction >= 0xF) return false;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
return true;
|
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
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;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (collideVehicle->sprite_identifier != SPRITE_IDENTIFIER_VEHICLE) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
sint32 z_diff = abs(collideVehicle->z - z);
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (z_diff > 16) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
rct_ride_type_vehicle* collideType = vehicle_get_vehicle_entry(collideVehicle);
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (!(collideType->flags_b & VEHICLE_ENTRY_FLAG_B_6)) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
uint32 x_diff = abs(collideVehicle->x - x);
|
2015-12-27 12:46:15 +01:00
|
|
|
if (x_diff > 0x7FFF) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
uint32 y_diff = abs(collideVehicle->y - y);
|
2015-12-27 12:46:15 +01:00
|
|
|
if (y_diff > 0x7FFF) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (x_diff + y_diff > 0xFFFF) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
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;
|
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
uint32 ecx = vehicle->var_44 + collideVehicle->var_44;
|
|
|
|
ecx = ((ecx >> 1) * 30) >> 8;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-31 10:53:23 +01:00
|
|
|
if (x_diff + y_diff >= ecx) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (!(collideType->flags_b & VEHICLE_ENTRY_FLAG_B_14)){
|
|
|
|
mayCollide = true;
|
|
|
|
break;
|
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
uint8 direction = (vehicle->sprite_direction - collideVehicle->sprite_direction - 6) & 0x1F;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (direction < 0x14) continue;
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
uint32 next_x_diff = abs(x + RCT2_ADDRESS(0x009A3B04, sint16)[((4 + vehicle->sprite_direction) >> 3) * 2] - collideVehicle->x);
|
|
|
|
uint32 next_y_diff = abs(y + RCT2_ADDRESS(0x009A3B06, sint16)[((4 + vehicle->sprite_direction) >> 3) * 2] - collideVehicle->y);
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (next_x_diff + next_y_diff < x_diff + y_diff){
|
|
|
|
mayCollide = true;
|
|
|
|
break;
|
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
}
|
|
|
|
if (mayCollide == true) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO change this
|
|
|
|
eax += *ebp;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (mayCollide == false) {
|
|
|
|
vehicle->var_C4 = 0;
|
|
|
|
return false;
|
2015-12-21 22:33:17 +01:00
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
vehicle->var_C4++;
|
|
|
|
if (vehicle->var_C4 < 200) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_6;
|
2015-12-31 10:53:23 +01:00
|
|
|
if (otherVehicleIndex != NULL)
|
|
|
|
*otherVehicleIndex = collideId;
|
2015-12-27 12:46:15 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO Is it possible for collideVehicle to be NULL?
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
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) {
|
2016-01-02 11:45:59 +01:00
|
|
|
if (vehicle->y >= collideVehicle->y) {
|
2015-12-27 12:46:15 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (vehicle->sprite_direction == 16) {
|
2016-01-02 11:45:59 +01:00
|
|
|
if (vehicle->x >= collideVehicle->x) {
|
2015-12-27 12:46:15 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (vehicle->sprite_direction == 24) {
|
|
|
|
if (vehicle->y <= collideVehicle->y) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
if (collideVehicle->status == VEHICLE_STATUS_TRAVELLING_BOAT &&
|
|
|
|
vehicle->status != VEHICLE_STATUS_ARRIVING &&
|
|
|
|
vehicle->status != VEHICLE_STATUS_TRAVELLING
|
|
|
|
) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-01-02 15:52:37 +01:00
|
|
|
|
2015-12-27 12:46:15 +01:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_6;
|
2015-12-31 10:53:23 +01:00
|
|
|
if (otherVehicleIndex != NULL)
|
|
|
|
*otherVehicleIndex = collideId;
|
2015-12-27 12:46:15 +01:00
|
|
|
return true;
|
2015-11-28 18:49:51 +01:00
|
|
|
}
|
|
|
|
|
2015-11-28 18:09:56 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DB7D6
|
|
|
|
*/
|
|
|
|
static void sub_6DB7D6(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
rct_vehicle *previousVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
|
|
|
rct_vehicle *nextVehicle = GET_VEHICLE(vehicle->next_vehicle_on_ride);
|
|
|
|
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress = 168;
|
2015-11-28 18:09:56 +01:00
|
|
|
vehicle->vehicle_type ^= 1;
|
|
|
|
|
2015-12-15 19:26:44 +01:00
|
|
|
previousVehicle->track_progress = 86;
|
|
|
|
nextVehicle->track_progress = 158;
|
2015-11-28 18:09:56 +01:00
|
|
|
|
|
|
|
sub_6DB807(nextVehicle);
|
|
|
|
sub_6DB807(previousVehicle);
|
|
|
|
}
|
|
|
|
|
2015-11-29 12:54:13 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DBF3E
|
|
|
|
*/
|
|
|
|
void sub_6DBF3E(rct_vehicle *vehicle)
|
2015-10-25 17:00:21 +01:00
|
|
|
{
|
2015-11-29 12:54:13 +01:00
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = (uint32)((sint32)vehicle->acceleration / RCT2_GLOBAL(0x00F64E10, sint32));
|
2015-11-29 12:54:13 +01:00
|
|
|
if (vehicle->var_CD == 2) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int trackType = vehicle->track_type >> 2;
|
|
|
|
if (!(RCT2_GLOBAL(0x0099BA64 + (trackType * 16), uint32) & 0x10)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_3;
|
2015-11-29 12:54:13 +01:00
|
|
|
|
|
|
|
rct_map_element *mapElement = map_get_track_element_at_of_type_seq(
|
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z >> 3,
|
|
|
|
trackType,
|
|
|
|
0
|
|
|
|
);
|
|
|
|
if (RCT2_GLOBAL(0x00F64E1C, uint32) == 0xFFFFFFFF) {
|
|
|
|
RCT2_GLOBAL(0x00F64E1C, uint32) = (mapElement->properties.track.sequence >> 4) & 7;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trackType == TRACK_ELEM_TOWER_BASE &&
|
|
|
|
vehicle == RCT2_GLOBAL(0x00F64E04, rct_vehicle*)
|
|
|
|
) {
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress > 3 && !(vehicle->update_flags & VEHICLE_UPDATE_FLAG_3)) {
|
2015-11-29 12:54:13 +01:00
|
|
|
rct_xy_element input, output;
|
|
|
|
int outputZ, outputDirection;
|
|
|
|
|
|
|
|
input.x = vehicle->track_x;
|
|
|
|
input.y = vehicle->track_y;
|
|
|
|
input.element = mapElement;
|
2015-12-18 00:45:58 +01:00
|
|
|
if (!track_block_get_next(&input, &output, &outputZ, &outputDirection)) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_12;
|
2015-11-29 12:54:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:26:44 +01:00
|
|
|
if (vehicle->track_progress <= 3) {
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_AT_STATION;
|
2015-11-29 12:54:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trackType != TRACK_ELEM_END_STATION ||
|
|
|
|
vehicle != RCT2_GLOBAL(0x00F64E04, rct_vehicle*)
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-12-15 19:26:44 +01:00
|
|
|
uint16 ax = vehicle->track_progress;
|
2015-12-15 23:32:11 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
2015-11-29 12:54:13 +01:00
|
|
|
if (ax <= 22) {
|
2015-12-15 19:26:44 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_AT_STATION;
|
2015-11-29 12:54:13 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
uint16 cx = 17;
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_12) {
|
2015-11-29 12:54:13 +01:00
|
|
|
cx = 6;
|
|
|
|
}
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_14) {
|
2015-11-29 12:54:13 +01:00
|
|
|
cx = vehicle->var_CD == 6 ? 18 : 20;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ax > cx) {
|
2015-12-15 19:26:44 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_AT_STATION;
|
2015-11-29 12:54:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-25 17:00:21 +01:00
|
|
|
/**
|
|
|
|
*
|
2015-12-15 23:32:11 +01:00
|
|
|
* rct2: 0x006DB08C
|
2015-10-25 17:00:21 +01:00
|
|
|
*/
|
2015-12-15 23:32:11 +01:00
|
|
|
bool vehicle_update_track_motion_forwards_get_new_track(rct_vehicle *vehicle, uint16 trackType, rct_ride* ride, rct_ride_type* rideEntry) {
|
2015-12-13 21:32:29 +01:00
|
|
|
registers regs = { 0 };
|
2015-10-25 17:00:21 +01:00
|
|
|
|
2015-11-01 15:58:46 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E36, uint8) = gTrackDefinitions[trackType].vangle_end;
|
|
|
|
RCT2_GLOBAL(0x00F64E37, uint8) = gTrackDefinitions[trackType].bank_end;
|
2015-12-15 23:32:11 +01:00
|
|
|
rct_map_element *mapElement = map_get_track_element_at_of_type_seq(
|
2015-11-01 15:58:46 +01:00
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z >> 3,
|
|
|
|
trackType,
|
|
|
|
0
|
2015-12-13 17:10:30 +01:00
|
|
|
);
|
2015-11-01 15:58:46 +01:00
|
|
|
if (trackType == TRACK_ELEM_CABLE_LIFT_HILL && vehicle == RCT2_GLOBAL(0x00F64E04, rct_vehicle*)) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_11;
|
2015-11-01 15:58:46 +01:00
|
|
|
}
|
|
|
|
|
2015-11-01 16:50:38 +01:00
|
|
|
if (track_element_is_block_start(mapElement)) {
|
|
|
|
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL) {
|
2016-01-02 18:04:39 +01:00
|
|
|
mapElement->flags |= MAP_ELEMENT_FLAG_BLOCK_BREAK_CLOSED;
|
2015-12-18 00:12:08 +01:00
|
|
|
if (trackType == TRACK_ELEM_BLOCK_BRAKES || trackType == TRACK_ELEM_END_STATION) {
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(rideEntry->vehicles[0].flags_b & VEHICLE_ENTRY_FLAG_B_3)) {
|
2015-11-21 12:59:38 +01:00
|
|
|
audio_play_sound_at_location(SOUND_49, vehicle->track_x, vehicle->track_y, vehicle->track_z);
|
2015-11-01 16:50:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
map_invalidate_element(vehicle->track_x, vehicle->track_z, mapElement);
|
2016-01-02 18:04:39 +01:00
|
|
|
vehicle_update_block_breaks_open_previous_section(vehicle, mapElement);
|
2015-11-01 15:58:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-21 15:20:52 +01:00
|
|
|
// TODO check if getting the vehicle entry again is necessary
|
2015-12-15 23:32:11 +01:00
|
|
|
rct_ride_type_vehicle* vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
2015-11-21 15:20:52 +01:00
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_8) {
|
2015-11-21 15:20:52 +01:00
|
|
|
vehicle_update_scenery_door(vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (vehicle->var_CD) {
|
|
|
|
default:
|
|
|
|
goto loc_6DB358;
|
|
|
|
case 2:
|
|
|
|
case 3:
|
|
|
|
vehicle->var_CD = 2;
|
|
|
|
goto loc_6DB32A;
|
|
|
|
case 4:
|
|
|
|
vehicle->var_CD = 1;
|
|
|
|
goto loc_6DB358;
|
|
|
|
case 7:
|
|
|
|
vehicle->var_CD = 6;
|
|
|
|
goto loc_6DB358;
|
|
|
|
case 8:
|
|
|
|
vehicle->var_CD = 5;
|
|
|
|
goto loc_6DB358;
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DB32A:
|
|
|
|
{
|
|
|
|
track_begin_end trackBeginEnd;
|
|
|
|
if (!track_block_get_previous(vehicle->track_x, vehicle->track_y, mapElement, &trackBeginEnd)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
return false;
|
2015-11-21 15:20:52 +01:00
|
|
|
}
|
|
|
|
regs.eax = trackBeginEnd.begin_x;
|
|
|
|
regs.ecx = trackBeginEnd.begin_y;
|
|
|
|
regs.edx = trackBeginEnd.begin_z;
|
|
|
|
regs.bl = trackBeginEnd.begin_direction;
|
2015-12-18 21:33:45 +01:00
|
|
|
mapElement = trackBeginEnd.begin_element;
|
2015-11-21 15:20:52 +01:00
|
|
|
}
|
|
|
|
goto loc_6DB41D;
|
|
|
|
|
|
|
|
loc_6DB358:
|
|
|
|
{
|
|
|
|
rct_xy_element xyElement;
|
|
|
|
int z, direction;
|
|
|
|
xyElement.x = vehicle->track_x;
|
|
|
|
xyElement.y = vehicle->track_y;
|
|
|
|
xyElement.element = mapElement;
|
|
|
|
if (!track_block_get_next(&xyElement, &xyElement, &z, &direction)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
return false;
|
2015-11-21 15:20:52 +01:00
|
|
|
}
|
|
|
|
mapElement = xyElement.element;
|
|
|
|
regs.eax = xyElement.x;
|
|
|
|
regs.ecx = xyElement.y;
|
|
|
|
regs.edx = z;
|
|
|
|
regs.bl = direction;
|
|
|
|
}
|
|
|
|
if (mapElement->properties.track.type == 211 ||
|
|
|
|
mapElement->properties.track.type == 212
|
2015-12-13 17:10:30 +01:00
|
|
|
) {
|
2015-11-21 15:20:52 +01:00
|
|
|
if (!vehicle->is_child && vehicle->velocity <= 0x30000) {
|
|
|
|
vehicle->velocity = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-22 13:14:53 +01:00
|
|
|
if (!loc_6DB38B(vehicle, mapElement)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
return false;
|
2015-11-22 13:14:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update VEHICLE_UPDATE_FLAG_11 flag
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_11;
|
2016-01-22 15:38:52 +01:00
|
|
|
int rideType = get_ride(mapElement->properties.track.ride_index)->type;
|
2015-11-22 13:14:53 +01:00
|
|
|
if (RideData4[rideType].flags & RIDE_TYPE_FLAG4_3) {
|
|
|
|
if (mapElement->properties.track.colour & 4) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_11;
|
|
|
|
}
|
|
|
|
}
|
2015-11-21 15:20:52 +01:00
|
|
|
|
|
|
|
loc_6DB41D:
|
2015-11-22 15:55:46 +01:00
|
|
|
vehicle->track_x = regs.ax;
|
|
|
|
vehicle->track_y = regs.cx;
|
|
|
|
vehicle->track_z = regs.dx;
|
|
|
|
|
|
|
|
// TODO check if getting the vehicle entry again is necessary
|
|
|
|
vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if ((vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_14) && vehicle->var_CD < 7) {
|
2015-11-22 15:55:46 +01:00
|
|
|
trackType = mapElement->properties.track.type;
|
|
|
|
if (trackType == TRACK_ELEM_FLAT) {
|
|
|
|
loc_6DB481(vehicle);
|
2015-12-15 23:32:11 +01:00
|
|
|
}
|
|
|
|
else if (ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) {
|
2015-11-22 15:55:46 +01:00
|
|
|
if (track_element_is_station(mapElement)) {
|
|
|
|
loc_6DB481(vehicle);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->var_CD != 0 && vehicle->var_CD < 5) {
|
|
|
|
regs.ax >>= 5;
|
|
|
|
regs.cx >>= 5;
|
|
|
|
regs.ah = regs.cl;
|
|
|
|
regs.dx >>= 3;
|
2016-02-18 21:32:04 +01:00
|
|
|
if (regs.ax != ride->chairlift_bullwheel_location[1].xy || regs.dl != ride->chairlift_bullwheel_z[1]) {
|
|
|
|
if (regs.ax == ride->chairlift_bullwheel_location[0].xy && regs.dl == ride->chairlift_bullwheel_z[0]) {
|
2015-11-22 15:55:46 +01:00
|
|
|
vehicle->var_CD = 4;
|
|
|
|
}
|
2015-12-15 23:32:11 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-11-22 15:55:46 +01:00
|
|
|
vehicle->var_CD = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DB500
|
2015-11-22 15:55:46 +01:00
|
|
|
// Update VEHICLE_UPDATE_FLAG_0
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_0;
|
|
|
|
if (track_element_is_lift_hill(mapElement)) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_0;
|
|
|
|
}
|
|
|
|
|
|
|
|
trackType = mapElement->properties.track.type;
|
|
|
|
if (trackType != TRACK_ELEM_BRAKES) {
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->target_seat_rotation = mapElement->properties.track.colour >> 4;
|
2015-11-22 15:55:46 +01:00
|
|
|
}
|
|
|
|
vehicle->track_direction = regs.bl & 3;
|
|
|
|
vehicle->track_type |= trackType << 2;
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->break_speed = (mapElement->properties.track.sequence >> 4) << 1;
|
2015-11-22 15:55:46 +01:00
|
|
|
if (trackType == TRACK_ELEM_ON_RIDE_PHOTO) {
|
|
|
|
vehicle_trigger_on_ride_photo(vehicle, mapElement);
|
|
|
|
}
|
|
|
|
if (trackType == TRACK_ELEM_ROTATION_CONTROL_TOGGLE) {
|
|
|
|
vehicle->update_flags ^= VEHICLE_UPDATE_FLAG_13;
|
|
|
|
}
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_8) {
|
2015-11-22 15:55:46 +01:00
|
|
|
sub_6DEDE8(vehicle);
|
|
|
|
}
|
2015-12-15 23:32:11 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
2015-12-17 00:01:22 +01:00
|
|
|
* rct2: 0x006DAEB9
|
2015-12-15 23:32:11 +01:00
|
|
|
*/
|
2015-12-17 00:01:22 +01:00
|
|
|
bool vehicle_update_track_motion_forwards(rct_vehicle *vehicle, rct_ride_type_vehicle* vehicleEntry, rct_ride* ride, rct_ride_type* rideEntry) {
|
2015-12-15 23:32:11 +01:00
|
|
|
registers regs = { 0 };
|
|
|
|
loc_6DAEB9:
|
|
|
|
regs.edi = vehicle->track_type;
|
|
|
|
regs.cx = vehicle->track_type >> 2;
|
|
|
|
|
|
|
|
int trackType = vehicle->track_type >> 2;
|
|
|
|
if (trackType == TRACK_ELEM_HEARTLINE_TRANSFER_UP || trackType == TRACK_ELEM_HEARTLINE_TRANSFER_DOWN) {
|
|
|
|
if (vehicle->track_progress == 80) {
|
|
|
|
vehicle->vehicle_type ^= 1;
|
|
|
|
vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
}
|
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0x40000) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -RCT2_GLOBAL(0x00F64E08, sint32) * 8;
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else if (RCT2_GLOBAL(0x00F64E08, sint32) < 0x20000) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = 0x50000;
|
2015-12-15 23:32:11 +01:00
|
|
|
}
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else if (trackType == TRACK_ELEM_BRAKES) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (!(
|
|
|
|
ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN &&
|
|
|
|
ride->breakdown_reason_pending == BREAKDOWN_BRAKES_FAILURE &&
|
|
|
|
ride->mechanic_status == RIDE_MECHANIC_STATUS_4
|
|
|
|
)) {
|
2016-02-18 22:47:24 +01:00
|
|
|
regs.eax = vehicle->break_speed << 16;
|
2015-12-15 23:32:11 +01:00
|
|
|
if (regs.eax < RCT2_GLOBAL(0x00F64E08, sint32)) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -RCT2_GLOBAL(0x00F64E08, sint32) * 16;
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else if (!(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x0F)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E2C, uint8) == 0) {
|
|
|
|
RCT2_GLOBAL(0x00F64E2C, uint8)++;
|
|
|
|
audio_play_sound_at_location(SOUND_51, vehicle->x, vehicle->y, vehicle->z);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((trackType == TRACK_ELEM_FLAT && ride->type == RIDE_TYPE_REVERSE_FREEFALL_COASTER) ||
|
|
|
|
(trackType == TRACK_ELEM_POWERED_LIFT)
|
|
|
|
) {
|
2016-01-11 01:50:03 +01:00
|
|
|
vehicle->acceleration = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8) + 7, uint8) << 16;
|
2015-12-15 23:32:11 +01:00
|
|
|
}
|
|
|
|
if (trackType == TRACK_ELEM_BRAKE_FOR_DROP) {
|
|
|
|
if (!vehicle->is_child) {
|
2016-02-18 22:47:24 +01:00
|
|
|
if (!(vehicle->update_flags & VEHICLE_UPDATE_FLAG_ON_BREAK_FOR_DROP)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (vehicle->track_progress >= 8) {
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = -RCT2_GLOBAL(0x00F64E08, sint32) * 16;
|
2015-12-15 23:32:11 +01:00
|
|
|
if (vehicle->track_progress >= 24) {
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_ON_BREAK_FOR_DROP;
|
|
|
|
vehicle->vertical_drop_countdown = 90;
|
2015-12-15 23:32:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (trackType == TRACK_ELEM_LOG_FLUME_REVERSER) {
|
|
|
|
if (vehicle->track_progress != 16 || vehicle->velocity < 0x40000) {
|
|
|
|
if (vehicle->track_progress == 32) {
|
|
|
|
vehicle->vehicle_type = vehicleEntry->var_58;
|
|
|
|
vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
|
|
|
}
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-12-15 23:32:11 +01:00
|
|
|
vehicle->track_progress += 17;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
regs.ax = vehicle->track_progress + 1;
|
2015-12-17 00:01:22 +01:00
|
|
|
|
2015-12-15 23:32:11 +01:00
|
|
|
const rct_vehicle_info *moveInfo = vehicle_get_move_info(
|
|
|
|
vehicle->var_CD,
|
|
|
|
vehicle->track_type,
|
|
|
|
0
|
|
|
|
);
|
|
|
|
|
|
|
|
// Track Total Progress is in the two bytes before the move info list
|
|
|
|
uint16 trackTotalProgress = *((uint16*)((int)moveInfo - 2));
|
|
|
|
if (regs.ax >= trackTotalProgress) {
|
|
|
|
if (!vehicle_update_track_motion_forwards_get_new_track(vehicle, trackType, ride, rideEntry)) {
|
|
|
|
goto loc_6DB94A;
|
|
|
|
}
|
|
|
|
regs.ax = 0;
|
|
|
|
}
|
2015-11-01 15:58:46 +01:00
|
|
|
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress = regs.ax;
|
2015-11-22 18:50:33 +01:00
|
|
|
vehicle_update_handle_water_splash(vehicle);
|
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DB706
|
2015-12-15 23:32:11 +01:00
|
|
|
moveInfo = vehicle_get_move_info(
|
2015-11-28 18:09:56 +01:00
|
|
|
vehicle->var_CD,
|
|
|
|
vehicle->track_type,
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress
|
2015-12-13 17:10:30 +01:00
|
|
|
);
|
2015-11-28 18:09:56 +01:00
|
|
|
sint16 x = vehicle->track_x + moveInfo->x;
|
|
|
|
sint16 y = vehicle->track_y + moveInfo->y;
|
2015-12-20 21:58:30 +01:00
|
|
|
sint16 z = vehicle->track_z + moveInfo->z + RCT2_GLOBAL(0x0097D21A + (ride->type * 8), sint8);
|
2015-12-17 00:01:22 +01:00
|
|
|
|
2015-12-15 23:32:11 +01:00
|
|
|
trackType = vehicle->track_type >> 2;
|
2015-11-28 18:09:56 +01:00
|
|
|
regs.ebx = 0;
|
|
|
|
if (x != unk_F64E20->x) { regs.ebx |= 1; }
|
|
|
|
if (y != unk_F64E20->y) { regs.ebx |= 2; }
|
|
|
|
if (z != unk_F64E20->z) { regs.ebx |= 4; }
|
|
|
|
if (vehicle->var_CD == 15 &&
|
2015-12-15 23:36:07 +01:00
|
|
|
(trackType == TRACK_ELEM_LEFT_REVERSER ||
|
2015-12-17 00:01:22 +01:00
|
|
|
trackType == TRACK_ELEM_RIGHT_REVERSER) &&
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress >= 30 &&
|
|
|
|
vehicle->track_progress <= 66
|
2015-12-13 17:10:30 +01:00
|
|
|
) {
|
2015-11-28 18:09:56 +01:00
|
|
|
regs.ebx |= 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->var_CD == 16 &&
|
2015-12-15 23:36:07 +01:00
|
|
|
(trackType == TRACK_ELEM_LEFT_REVERSER ||
|
2015-12-17 00:01:22 +01:00
|
|
|
trackType == TRACK_ELEM_RIGHT_REVERSER) &&
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress == 96
|
2015-12-13 17:10:30 +01:00
|
|
|
) {
|
2015-11-28 18:09:56 +01:00
|
|
|
sub_6DB7D6(vehicle);
|
|
|
|
|
|
|
|
const rct_vehicle_info *moveInfo2 = vehicle_get_move_info(
|
|
|
|
vehicle->var_CD,
|
|
|
|
vehicle->track_type,
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress
|
2015-12-13 17:10:30 +01:00
|
|
|
);
|
2015-11-28 18:09:56 +01:00
|
|
|
x = vehicle->x + moveInfo2->x;
|
|
|
|
y = vehicle->y + moveInfo2->y;
|
|
|
|
}
|
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DB8A5
|
2015-12-20 21:58:30 +01:00
|
|
|
regs.ebx = RCT2_ADDRESS(0x009A2930, sint32)[regs.ebx];
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= regs.ebx;
|
2015-11-28 18:49:51 +01:00
|
|
|
unk_F64E20->x = x;
|
|
|
|
unk_F64E20->y = y;
|
|
|
|
unk_F64E20->z = z;
|
|
|
|
vehicle->sprite_direction = moveInfo->direction;
|
|
|
|
vehicle->var_20 = moveInfo->var_08;
|
|
|
|
vehicle->var_1F = moveInfo->var_07;
|
|
|
|
|
|
|
|
regs.ebx = moveInfo->var_07;
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if ((vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_9) && moveInfo->var_07 != 0) {
|
2015-11-28 18:49:51 +01:00
|
|
|
vehicle->var_4A = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->swinging_car_var_0 = 0;
|
2015-11-28 18:49:51 +01:00
|
|
|
vehicle->var_4E = 0;
|
|
|
|
}
|
|
|
|
|
2015-12-15 23:32:11 +01:00
|
|
|
// vehicle == frontVehicle
|
2015-11-28 18:49:51 +01:00
|
|
|
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
2015-11-28 18:49:51 +01:00
|
|
|
regs.bp = vehicle->prev_vehicle_on_ride;
|
2015-12-27 12:46:15 +01:00
|
|
|
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16 *)®s.bp)) {
|
2015-11-28 18:49:51 +01:00
|
|
|
goto loc_6DB967;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DB928
|
2015-12-20 22:36:11 +01:00
|
|
|
if (vehicle->remaining_distance < 0x368A) {
|
2015-12-17 00:01:22 +01:00
|
|
|
return true;
|
2015-11-28 18:49:51 +01:00
|
|
|
}
|
|
|
|
|
2015-12-20 21:58:30 +01:00
|
|
|
regs.ebx = dword_9A2970[regs.ebx];
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration += regs.ebx;
|
2015-11-28 18:49:51 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
goto loc_6DAEB9;
|
|
|
|
|
|
|
|
loc_6DB94A:
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_5;
|
2015-12-20 22:36:11 +01:00
|
|
|
regs.eax = vehicle->remaining_distance + 1;
|
2015-12-20 21:58:30 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) -= regs.eax;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance = 0xFFFFFFFF;
|
2015-11-28 19:11:48 +01:00
|
|
|
regs.ebx = vehicle->var_1F;
|
2015-12-17 00:01:22 +01:00
|
|
|
return false;
|
2015-10-25 20:23:42 +01:00
|
|
|
|
2015-11-28 18:49:51 +01:00
|
|
|
loc_6DB967:
|
2015-12-20 22:36:11 +01:00
|
|
|
regs.eax = vehicle->remaining_distance + 1;
|
2015-12-20 21:58:30 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) -= regs.eax;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= regs.eax;
|
2015-11-28 19:40:44 +01:00
|
|
|
|
|
|
|
// Might need to be bp rather than vehicle, but hopefully not
|
2015-12-18 21:33:45 +01:00
|
|
|
rct_vehicle *head = vehicle_get_head(GET_VEHICLE(regs.bp));
|
2015-11-28 19:40:44 +01:00
|
|
|
|
|
|
|
regs.eax = abs(vehicle->velocity - head->velocity);
|
|
|
|
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_18)) {
|
|
|
|
if (regs.eax > 0xE0000) {
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_6)) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_COLLISION;
|
2015-11-28 19:40:44 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_14) {
|
2015-11-28 19:40:44 +01:00
|
|
|
vehicle->velocity -= vehicle->velocity >> 2;
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-12-15 23:32:11 +01:00
|
|
|
sint32 newHeadVelocity = vehicle->velocity >> 1;
|
2015-11-28 19:40:44 +01:00
|
|
|
vehicle->velocity = head->velocity >> 1;
|
2015-12-15 23:32:11 +01:00
|
|
|
head->velocity = newHeadVelocity;
|
2015-11-28 19:40:44 +01:00
|
|
|
}
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_1;
|
2015-12-17 00:01:22 +01:00
|
|
|
return false;
|
|
|
|
}
|
2015-11-21 15:20:52 +01:00
|
|
|
|
2015-12-17 00:01:22 +01:00
|
|
|
/**
|
2015-12-21 10:19:35 +01:00
|
|
|
*
|
|
|
|
* rct2: 0x006DBAA6
|
|
|
|
*/
|
|
|
|
bool vehicle_update_track_motion_backwards_get_new_track(rct_vehicle *vehicle, uint16 trackType, rct_ride* ride, rct_ride_type* rideEntry, uint16* progress) {
|
2015-12-17 00:39:38 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E36, uint8) = gTrackDefinitions[trackType].vangle_start;
|
|
|
|
RCT2_GLOBAL(0x00F64E37, uint8) = gTrackDefinitions[trackType].bank_start;
|
2015-12-17 00:01:22 +01:00
|
|
|
rct_map_element* mapElement = map_get_track_element_at_of_type_seq(
|
2015-11-28 22:14:34 +01:00
|
|
|
vehicle->track_x,
|
|
|
|
vehicle->track_y,
|
|
|
|
vehicle->track_z >> 3,
|
|
|
|
trackType,
|
|
|
|
0
|
2015-12-13 17:10:30 +01:00
|
|
|
);
|
2015-11-28 22:14:34 +01:00
|
|
|
|
2016-01-03 12:10:02 +01:00
|
|
|
bool nextTileBackwards = true;
|
|
|
|
int direction;
|
|
|
|
//loc_6DBB08:;
|
2015-12-17 00:01:22 +01:00
|
|
|
sint16 x = vehicle->track_x;
|
|
|
|
sint16 y = vehicle->track_y;
|
|
|
|
sint16 z = 0;
|
2016-01-03 12:10:02 +01:00
|
|
|
|
2015-11-28 22:14:34 +01:00
|
|
|
switch (vehicle->var_CD) {
|
|
|
|
case 3:
|
|
|
|
vehicle->var_CD = 1;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
vehicle->var_CD = 5;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
vehicle->var_CD = 6;
|
|
|
|
break;
|
|
|
|
case 2:
|
2016-01-03 12:10:02 +01:00
|
|
|
case 4:
|
2015-11-28 22:14:34 +01:00
|
|
|
vehicle->var_CD = 2;
|
2016-01-03 12:10:02 +01:00
|
|
|
nextTileBackwards = false;
|
|
|
|
break;
|
2015-11-28 22:14:34 +01:00
|
|
|
}
|
|
|
|
|
2016-01-03 12:10:02 +01:00
|
|
|
|
|
|
|
if (nextTileBackwards == true) {
|
|
|
|
//loc_6DBB7E:;
|
2015-11-28 22:42:34 +01:00
|
|
|
track_begin_end trackBeginEnd;
|
2015-12-15 23:32:11 +01:00
|
|
|
if (!track_block_get_previous(x, y, mapElement, &trackBeginEnd)) {
|
2015-12-21 10:19:35 +01:00
|
|
|
return false;
|
2015-11-28 22:42:34 +01:00
|
|
|
}
|
|
|
|
mapElement = trackBeginEnd.begin_element;
|
|
|
|
|
|
|
|
trackType = mapElement->properties.track.type;
|
2015-12-22 15:21:56 +01:00
|
|
|
if (trackType == TRACK_ELEM_LEFT_REVERSER ||
|
2015-12-21 10:19:35 +01:00
|
|
|
trackType == TRACK_ELEM_RIGHT_REVERSER) {
|
|
|
|
return false;
|
2015-11-28 22:42:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int trackColour = vehicle->update_flags >> 9;
|
2015-12-13 17:10:30 +01:00
|
|
|
int bank = gTrackDefinitions[trackType].bank_end;
|
2015-12-21 10:19:35 +01:00
|
|
|
bank = track_get_actual_bank_2(ride->type, trackColour, bank);
|
2015-11-28 22:42:34 +01:00
|
|
|
int vAngle = gTrackDefinitions[trackType].vangle_end;
|
2015-12-15 23:32:11 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E36, uint8) != vAngle ||
|
|
|
|
RCT2_GLOBAL(0x00F64E37, uint8) != bank
|
2015-12-17 00:01:22 +01:00
|
|
|
) {
|
2015-12-21 10:19:35 +01:00
|
|
|
return false;
|
2015-11-28 22:42:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Update VEHICLE_UPDATE_FLAG_11
|
2015-12-15 23:32:11 +01:00
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_11;
|
2015-11-28 22:42:34 +01:00
|
|
|
if (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_3) {
|
|
|
|
if (mapElement->properties.track.colour & 4) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_11;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
x = trackBeginEnd.begin_x;
|
|
|
|
y = trackBeginEnd.begin_y;
|
|
|
|
z = trackBeginEnd.begin_z;
|
2015-11-29 00:48:41 +01:00
|
|
|
direction = trackBeginEnd.begin_direction;
|
2015-11-28 22:42:34 +01:00
|
|
|
}
|
2016-01-03 12:10:02 +01:00
|
|
|
else {
|
|
|
|
//loc_6DBB4F:;
|
|
|
|
rct_xy_element input;
|
|
|
|
rct_xy_element output;
|
|
|
|
int outputZ;
|
|
|
|
|
|
|
|
input.x = x;
|
|
|
|
input.y = y;
|
|
|
|
input.element = mapElement;
|
2016-02-02 19:52:41 +01:00
|
|
|
if (!track_block_get_next(&input, &output, &outputZ, &direction)) {
|
2016-01-03 12:10:02 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
mapElement = output.element;
|
2016-02-02 19:52:41 +01:00
|
|
|
x = output.x;
|
|
|
|
y = output.y;
|
|
|
|
z = outputZ;
|
2016-01-03 12:10:02 +01:00
|
|
|
}
|
2015-10-25 20:23:42 +01:00
|
|
|
|
2016-01-03 12:10:02 +01:00
|
|
|
//loc_6DBC3B:
|
2015-11-29 00:48:41 +01:00
|
|
|
vehicle->track_x = x;
|
|
|
|
vehicle->track_y = y;
|
|
|
|
vehicle->track_z = z;
|
|
|
|
|
|
|
|
if (vehicle->var_CD != 0 &&
|
|
|
|
vehicle->var_CD < 5
|
2015-12-13 17:10:30 +01:00
|
|
|
) {
|
2015-11-29 00:48:41 +01:00
|
|
|
sint16 xy = (x >> 5) | ((y >> 5) << 8);
|
2016-02-18 21:32:04 +01:00
|
|
|
if (ride->chairlift_bullwheel_location[1].xy == xy &&
|
|
|
|
ride->chairlift_bullwheel_z[1] == (z >> 3)
|
2015-12-13 17:10:30 +01:00
|
|
|
) {
|
2015-11-29 00:48:41 +01:00
|
|
|
vehicle->var_CD = 3;
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else if (
|
2016-02-18 21:32:04 +01:00
|
|
|
ride->chairlift_bullwheel_location[0].xy == xy &&
|
|
|
|
ride->chairlift_bullwheel_z[1] == (z >> 3)
|
2015-12-13 17:10:30 +01:00
|
|
|
) {
|
2015-11-29 00:48:41 +01:00
|
|
|
vehicle->var_CD = 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (track_element_is_lift_hill(mapElement)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
2015-11-29 00:48:41 +01:00
|
|
|
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL) {
|
|
|
|
trackType = mapElement->properties.track.type;
|
2015-12-17 00:39:38 +01:00
|
|
|
if (!(RCT2_ADDRESS(0x0099423C, uint16)[trackType] & 0x20)) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_9;
|
2015-11-29 00:48:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_0;
|
|
|
|
}
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-11-29 00:48:41 +01:00
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_0) {
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_0;
|
|
|
|
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_8;
|
2015-11-29 00:48:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
trackType = mapElement->properties.track.type;
|
|
|
|
if (trackType != TRACK_ELEM_BRAKES) {
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->target_seat_rotation = mapElement->properties.track.colour >> 4;
|
2015-11-29 00:48:41 +01:00
|
|
|
}
|
|
|
|
direction &= 3;
|
|
|
|
vehicle->track_type = trackType << 2;
|
|
|
|
vehicle->track_direction |= direction;
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->break_speed = (mapElement->properties.track.sequence >> 4) << 1;
|
2015-11-29 00:48:41 +01:00
|
|
|
|
2015-12-17 00:01:22 +01:00
|
|
|
const rct_vehicle_info* moveInfo = vehicle_get_move_info(
|
2015-11-29 00:48:41 +01:00
|
|
|
vehicle->var_CD,
|
|
|
|
vehicle->track_type,
|
|
|
|
0
|
2015-12-13 17:10:30 +01:00
|
|
|
);
|
2015-11-29 00:48:41 +01:00
|
|
|
|
|
|
|
// There are two bytes before the move info list
|
2015-12-17 00:01:22 +01:00
|
|
|
uint16 trackTotalProgress = *((uint16*)((int)moveInfo - 2));
|
2015-12-21 10:19:35 +01:00
|
|
|
*progress = trackTotalProgress - 1;
|
2015-12-22 15:21:56 +01:00
|
|
|
return true;
|
2015-12-21 10:19:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DBA33
|
|
|
|
*/
|
|
|
|
bool vehicle_update_track_motion_backwards(rct_vehicle *vehicle, rct_ride_type_vehicle* vehicleEntry, rct_ride* ride, rct_ride_type* rideEntry) {
|
|
|
|
registers regs = { 0 };
|
|
|
|
|
|
|
|
loc_6DBA33:;
|
|
|
|
uint16 trackType = vehicle->track_type >> 2;
|
|
|
|
if (trackType == TRACK_ELEM_FLAT && ride->type == RIDE_TYPE_REVERSE_FREEFALL_COASTER) {
|
|
|
|
sint32 unkVelocity = RCT2_GLOBAL(0x00F64E08, sint32);
|
2016-01-12 18:43:47 +01:00
|
|
|
if (unkVelocity < -524288) {
|
2015-12-21 10:19:35 +01:00
|
|
|
unkVelocity = abs(unkVelocity);
|
|
|
|
vehicle->acceleration = unkVelocity * 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (trackType == TRACK_ELEM_BRAKES) {
|
2016-02-18 22:47:24 +01:00
|
|
|
regs.eax = -(vehicle->break_speed << 16);
|
2016-01-18 20:41:40 +01:00
|
|
|
if (regs.eax > RCT2_GLOBAL(0x00F64E08, sint32)) {
|
|
|
|
regs.eax = RCT2_GLOBAL(0x00F64E08, sint32) * -16;
|
2015-12-21 10:19:35 +01:00
|
|
|
vehicle->acceleration = regs.eax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
regs.ax = vehicle->track_progress - 1;
|
|
|
|
if (regs.ax == -1) {
|
2015-12-22 15:21:56 +01:00
|
|
|
if (!vehicle_update_track_motion_backwards_get_new_track(vehicle, trackType, ride, rideEntry, (uint16 *)®s.ax)) {
|
2015-12-21 10:19:35 +01:00
|
|
|
goto loc_6DBE5E;
|
|
|
|
}
|
|
|
|
}
|
2015-11-28 22:14:34 +01:00
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DBD42
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress = regs.ax;
|
2015-12-21 10:19:35 +01:00
|
|
|
const rct_vehicle_info* moveInfo = vehicle_get_move_info(
|
2015-11-29 01:10:48 +01:00
|
|
|
vehicle->var_CD,
|
|
|
|
vehicle->track_type,
|
2015-12-17 00:39:38 +01:00
|
|
|
vehicle->track_progress
|
2015-12-13 17:10:30 +01:00
|
|
|
);
|
2015-11-29 01:10:48 +01:00
|
|
|
|
2015-12-21 10:19:35 +01:00
|
|
|
sint16 x = vehicle->track_x + moveInfo->x;
|
|
|
|
sint16 y = vehicle->track_y + moveInfo->y;
|
|
|
|
sint16 z = vehicle->track_z + moveInfo->z + RCT2_GLOBAL(0x0097D21A + (ride->type * 8), sint8);
|
2015-12-13 17:10:30 +01:00
|
|
|
|
2015-11-29 01:10:48 +01:00
|
|
|
regs.ebx = 0;
|
2015-12-23 12:57:50 +01:00
|
|
|
if (x != unk_F64E20->x) { regs.ebx |= 1; }
|
|
|
|
if (y != unk_F64E20->y) { regs.ebx |= 2; }
|
|
|
|
if (z != unk_F64E20->z) { regs.ebx |= 4; }
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance += RCT2_ADDRESS(0x009A2930, sint32)[regs.ebx];
|
2015-11-29 01:10:48 +01:00
|
|
|
|
|
|
|
unk_F64E20->x = x;
|
|
|
|
unk_F64E20->y = y;
|
|
|
|
unk_F64E20->z = z;
|
|
|
|
vehicle->sprite_direction = moveInfo->direction;
|
|
|
|
vehicle->var_20 = moveInfo->var_08;
|
|
|
|
regs.ebx = moveInfo->var_07;
|
|
|
|
vehicle->var_1F = regs.bl;
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if ((vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_9) && regs.bl != 0) {
|
2015-11-29 01:10:48 +01:00
|
|
|
vehicle->var_4A = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->swinging_car_var_0 = 0;
|
2015-11-29 01:10:48 +01:00
|
|
|
vehicle->var_4E = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
2015-12-21 23:18:56 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
2015-11-29 01:10:48 +01:00
|
|
|
regs.bp = vehicle->next_vehicle_on_ride;
|
2015-12-27 12:46:15 +01:00
|
|
|
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16*)®s.bp)) {
|
2015-11-29 01:10:48 +01:00
|
|
|
goto loc_6DBE7F;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-28 19:11:48 +01:00
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DBE3F
|
2015-12-20 22:36:11 +01:00
|
|
|
if ((sint32)vehicle->remaining_distance >= 0) {
|
2015-12-17 00:01:22 +01:00
|
|
|
return true;
|
2015-11-28 19:11:48 +01:00
|
|
|
}
|
2015-12-20 21:58:30 +01:00
|
|
|
regs.ebx = dword_9A2970[regs.ebx];
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration += regs.ebx;
|
2015-11-28 19:11:48 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
goto loc_6DBA33;
|
|
|
|
|
2015-11-28 22:14:34 +01:00
|
|
|
loc_6DBE5E:
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_5;
|
2015-12-20 22:36:11 +01:00
|
|
|
regs.eax = vehicle->remaining_distance - 0x368A;
|
2015-12-20 21:58:30 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) -= regs.eax;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= regs.eax;
|
2015-11-29 01:10:48 +01:00
|
|
|
regs.ebx = vehicle->var_1F;
|
2015-12-17 00:01:22 +01:00
|
|
|
return false;
|
2015-11-29 01:10:48 +01:00
|
|
|
|
|
|
|
loc_6DBE7F:
|
2015-12-20 22:36:11 +01:00
|
|
|
regs.eax = vehicle->remaining_distance - 0x368A;
|
2015-12-20 21:58:30 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) -= regs.eax;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= regs.eax;
|
2015-11-29 01:24:29 +01:00
|
|
|
|
|
|
|
rct_vehicle *v3 = GET_VEHICLE(regs.bp);
|
|
|
|
rct_vehicle *v4 = RCT2_GLOBAL(0x00F64E04, rct_vehicle*);
|
|
|
|
regs.eax = abs(v4->velocity - v3->velocity);
|
|
|
|
|
|
|
|
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_18)) {
|
|
|
|
if (regs.eax > 0xE0000) {
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_6)) {
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_COLLISION;
|
2015-11-29 01:24:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_14) {
|
2015-11-29 01:24:29 +01:00
|
|
|
vehicle->velocity -= vehicle->velocity >> 2;
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_2;
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-12-21 23:18:56 +01:00
|
|
|
sint32 v3Velocity = v3->velocity;
|
2015-11-29 01:24:29 +01:00
|
|
|
v3->velocity = v4->velocity >> 1;
|
2015-12-21 23:18:56 +01:00
|
|
|
v4->velocity = v3Velocity >> 1;
|
2015-12-13 03:06:39 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_2;
|
2015-11-29 01:24:29 +01:00
|
|
|
}
|
2015-12-13 17:10:30 +01:00
|
|
|
|
2015-12-17 00:01:22 +01:00
|
|
|
return false;
|
|
|
|
}
|
2015-11-28 22:14:34 +01:00
|
|
|
|
2015-12-17 00:01:22 +01:00
|
|
|
/**
|
2016-01-14 19:25:41 +01:00
|
|
|
* rct2: 0x006DC3A7
|
|
|
|
*
|
2015-12-17 00:01:22 +01:00
|
|
|
*
|
|
|
|
*/
|
2016-01-14 19:25:41 +01:00
|
|
|
int vehicle_update_track_motion_mini_golf(rct_vehicle *vehicle, int* outStation) {
|
2015-12-17 00:01:22 +01:00
|
|
|
registers regs = { 0 };
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
|
|
|
rct_ride_type *rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-12-17 00:01:22 +01:00
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-17 00:01:22 +01:00
|
|
|
rct_map_element *mapElement = NULL;
|
2015-11-29 12:54:13 +01:00
|
|
|
|
2015-12-17 00:01:22 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E04, rct_vehicle*) = vehicle;
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) = 0;
|
2016-01-14 19:25:41 +01:00
|
|
|
vehicle->velocity += vehicle->acceleration;
|
|
|
|
RCT2_GLOBAL(0x00F64E08, sint32) = vehicle->velocity;
|
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) = (vehicle->velocity >> 10) * 42;
|
2015-12-17 00:01:22 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
|
|
|
vehicle = vehicle_get_tail(vehicle);
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x00F64E00, rct_vehicle*) = vehicle;
|
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
loc_6DC40E:
|
|
|
|
regs.ebx = vehicle->var_1F;
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32) = 1;
|
|
|
|
vehicle->acceleration = dword_9A2970[vehicle->var_1F];
|
|
|
|
vehicle->remaining_distance = RCT2_GLOBAL(0x00F64E0C, sint32) + vehicle->remaining_distance;
|
|
|
|
if ((sint32)vehicle->remaining_distance < 0) {
|
|
|
|
goto loc_6DCA7A;
|
|
|
|
}
|
|
|
|
if ((sint32)vehicle->remaining_distance < 0x368A) {
|
|
|
|
goto loc_6DCE02;
|
|
|
|
}
|
|
|
|
vehicle->var_B8 &= ~(1 << 1);
|
|
|
|
unk_F64E20->x = vehicle->x;
|
|
|
|
unk_F64E20->y = vehicle->y;
|
|
|
|
unk_F64E20->z = vehicle->z;
|
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
loc_6DC462:
|
|
|
|
if (vehicle->var_D3 == 0) {
|
|
|
|
goto loc_6DC476;
|
|
|
|
}
|
|
|
|
vehicle->var_D3--;
|
|
|
|
goto loc_6DC985;
|
2015-12-17 00:01:22 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
loc_6DC476:
|
2016-02-18 22:47:24 +01:00
|
|
|
if (vehicle->mini_golf_flags & (1 << 2)) {
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.edi = RCT2_ADDRESS(0x008B8F74, uint32)[vehicle->var_D4];
|
|
|
|
regs.al = vehicle->var_C5 + 1;
|
|
|
|
if ((uint8)regs.al < ((uint8*)regs.edi)[-1]) {
|
|
|
|
vehicle->var_C5 = regs.al;
|
|
|
|
goto loc_6DC985;
|
2015-11-29 12:54:13 +01:00
|
|
|
}
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->mini_golf_flags &= ~(1 << 2);
|
2016-01-14 19:25:41 +01:00
|
|
|
}
|
2015-12-17 00:01:22 +01:00
|
|
|
|
2016-02-18 22:47:24 +01:00
|
|
|
if (vehicle->mini_golf_flags & (1 << 0)) {
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.di = vehicle->is_child ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride;
|
|
|
|
rct_vehicle *vEDI = GET_VEHICLE(regs.di);
|
2016-02-18 22:47:24 +01:00
|
|
|
if (!(vEDI->mini_golf_flags & (1 << 0)) || (vEDI->mini_golf_flags & (1 << 2))) {
|
2016-01-14 19:25:41 +01:00
|
|
|
goto loc_6DC985;
|
|
|
|
}
|
|
|
|
if (vEDI->var_D3 != 0) {
|
|
|
|
goto loc_6DC985;
|
|
|
|
}
|
2016-02-18 22:47:24 +01:00
|
|
|
vEDI->mini_golf_flags &= ~(1 << 0);
|
|
|
|
vehicle->mini_golf_flags &= ~(1 << 0);
|
2016-01-14 19:25:41 +01:00
|
|
|
}
|
2015-12-17 00:01:22 +01:00
|
|
|
|
2016-02-18 22:47:24 +01:00
|
|
|
if (vehicle->mini_golf_flags & (1 << 1)) {
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.di = vehicle->is_child ? vehicle->prev_vehicle_on_ride : vehicle->next_vehicle_on_ride;
|
|
|
|
rct_vehicle *vEDI = GET_VEHICLE(regs.di);
|
2016-02-18 22:47:24 +01:00
|
|
|
if (!(vEDI->mini_golf_flags & (1 << 1)) || (vEDI->mini_golf_flags & (1 << 2))) {
|
2016-01-14 19:25:41 +01:00
|
|
|
goto loc_6DC985;
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
if (vEDI->var_D3 != 0) {
|
|
|
|
goto loc_6DC985;
|
2015-12-17 00:01:22 +01:00
|
|
|
}
|
2016-02-18 22:47:24 +01:00
|
|
|
vEDI->mini_golf_flags &= ~(1 << 1);
|
|
|
|
vehicle->mini_golf_flags &= ~(1 << 1);
|
2016-01-14 19:25:41 +01:00
|
|
|
}
|
|
|
|
|
2016-02-18 22:47:24 +01:00
|
|
|
if (vehicle->mini_golf_flags & (1 << 3)) {
|
2016-01-14 19:25:41 +01:00
|
|
|
rct_vehicle *vEDI = vehicle;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
vEDI = GET_VEHICLE(vEDI->prev_vehicle_on_ride);
|
|
|
|
if (vEDI == vehicle) {
|
2015-12-17 00:01:22 +01:00
|
|
|
break;
|
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
if (!vEDI->is_child) continue;
|
2016-02-18 22:47:24 +01:00
|
|
|
if (!(vEDI->mini_golf_flags & (1 << 4))) continue;
|
2016-01-14 19:25:41 +01:00
|
|
|
if (vEDI->track_x != vehicle->track_x) continue;
|
|
|
|
if (vEDI->track_y != vehicle->track_y) continue;
|
|
|
|
if (vEDI->track_z != vehicle->track_z) continue;
|
|
|
|
goto loc_6DC985;
|
2015-12-15 23:59:15 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->mini_golf_flags |= (1 << 4);
|
|
|
|
vehicle->mini_golf_flags &= ~(1 << 3);
|
2015-11-29 12:54:13 +01:00
|
|
|
}
|
2015-11-29 15:07:52 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
// loc_6DC5B8
|
|
|
|
const rct_vehicle_info* moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, 0);
|
2015-11-29 15:07:52 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
// There are two bytes before the move info list
|
|
|
|
{
|
|
|
|
uint16 unk16_v34 = vehicle->track_progress + 1;
|
|
|
|
uint16 unk16 = *((uint16*)((int)moveInfo - 2));
|
|
|
|
if (unk16_v34 < unk16) {
|
|
|
|
regs.ax = unk16_v34;
|
|
|
|
goto loc_6DC743;
|
2015-11-29 15:07:52 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
uint16 trackType = vehicle->track_type >> 2;
|
|
|
|
RCT2_GLOBAL(0x00F64E36, uint8) = gTrackDefinitions[trackType].vangle_end;
|
|
|
|
RCT2_GLOBAL(0x00F64E37, uint8) = gTrackDefinitions[trackType].bank_end;
|
|
|
|
mapElement = map_get_track_element_at_of_type_seq(
|
|
|
|
vehicle->track_x, vehicle->track_y, vehicle->track_z >> 3,
|
|
|
|
trackType, 0
|
|
|
|
);
|
|
|
|
sint16 x, y, z;
|
|
|
|
int direction;
|
|
|
|
{
|
|
|
|
rct_xy_element input, output;
|
|
|
|
int outZ, outDirection;
|
|
|
|
input.x = vehicle->track_x;
|
|
|
|
input.y = vehicle->track_y;
|
|
|
|
input.element = mapElement;
|
|
|
|
if (!track_block_get_next(&input, &output, &outZ, &outDirection)) {
|
|
|
|
goto loc_6DC9BC;
|
|
|
|
}
|
|
|
|
mapElement = output.element;
|
|
|
|
x = output.x;
|
|
|
|
y = output.y;
|
|
|
|
z = outZ;
|
|
|
|
direction = outDirection;
|
2015-11-29 15:07:52 +01:00
|
|
|
}
|
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
if (!loc_6DB38B(vehicle, mapElement)) {
|
|
|
|
goto loc_6DC9BC;
|
2015-11-29 15:07:52 +01:00
|
|
|
}
|
2015-12-13 17:10:30 +01:00
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
int rideType = get_ride(mapElement->properties.track.ride_index)->type;
|
2016-01-14 19:25:41 +01:00
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_11;
|
|
|
|
if (RideData4[rideType].flags & RIDE_TYPE_FLAG4_3) {
|
|
|
|
if (mapElement->properties.track.colour & (1 << 2)) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_11;
|
|
|
|
}
|
2015-12-13 17:10:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->track_x = x;
|
|
|
|
vehicle->track_y = y;
|
|
|
|
vehicle->track_z = z;
|
|
|
|
|
2015-12-13 17:23:24 +01:00
|
|
|
if (vehicle->is_child) {
|
|
|
|
rct_vehicle *prevVehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
|
|
|
regs.al = prevVehicle->var_CD;
|
|
|
|
if (regs.al != 0) {
|
|
|
|
regs.al--;
|
2015-12-13 17:10:30 +01:00
|
|
|
}
|
2015-12-13 17:23:24 +01:00
|
|
|
vehicle->var_CD = regs.al;
|
2015-12-13 17:10:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_0;
|
2015-12-13 17:23:24 +01:00
|
|
|
vehicle->track_type = (mapElement->properties.track.type << 2) | (direction & 3);
|
|
|
|
vehicle->var_CF = (mapElement->properties.track.sequence >> 4) << 1;
|
|
|
|
regs.ax = 0;
|
2015-12-13 17:10:30 +01:00
|
|
|
|
|
|
|
loc_6DC743:
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress = regs.ax;
|
2015-12-13 18:37:23 +01:00
|
|
|
if (vehicle->is_child) {
|
|
|
|
vehicle->var_C5++;
|
|
|
|
if (vehicle->var_C5 >= 6) {
|
|
|
|
vehicle->var_C5 = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
2015-12-15 19:26:44 +01:00
|
|
|
moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, vehicle->track_progress);
|
2015-12-13 18:37:23 +01:00
|
|
|
if (moveInfo->x != (uint16)0x8000) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (moveInfo->y) {
|
|
|
|
case 0: // loc_6DC7B4
|
|
|
|
if (vehicle->is_child) {
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->mini_golf_flags |= (1 << 3);
|
2016-01-14 19:25:41 +01:00
|
|
|
}
|
|
|
|
else {
|
2015-12-13 18:37:23 +01:00
|
|
|
uint16 rand16 = scenario_rand() & 0xFFFF;
|
|
|
|
regs.bl = 14;
|
|
|
|
if (rand16 <= 0xA000) {
|
|
|
|
regs.bl = 12;
|
|
|
|
if (rand16 <= 0x900) {
|
|
|
|
regs.bl = 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vehicle->var_CD = regs.bl;
|
|
|
|
}
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress++;
|
2015-12-13 18:37:23 +01:00
|
|
|
break;
|
|
|
|
case 1: // loc_6DC7ED
|
2016-01-10 10:24:56 +01:00
|
|
|
vehicle->var_D3 = (uint8)moveInfo->z;
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress++;
|
2015-12-13 18:37:23 +01:00
|
|
|
break;
|
|
|
|
case 2: // loc_6DC800
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->mini_golf_flags |= (1 << 0);
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress++;
|
2015-12-13 18:37:23 +01:00
|
|
|
break;
|
|
|
|
case 3: // loc_6DC810
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->mini_golf_flags |= (1 << 1);
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress++;
|
2015-12-13 18:37:23 +01:00
|
|
|
break;
|
|
|
|
case 4: // loc_6DC820
|
2015-12-13 21:32:29 +01:00
|
|
|
z = moveInfo->z;
|
|
|
|
if (z == 2) {
|
2015-12-13 18:37:23 +01:00
|
|
|
rct_peep *peep = GET_PEEP(vehicle->peep[0]);
|
|
|
|
if (peep->id & 7) {
|
2015-12-13 21:32:29 +01:00
|
|
|
z = 7;
|
2015-12-13 18:37:23 +01:00
|
|
|
}
|
|
|
|
}
|
2015-12-18 21:33:45 +01:00
|
|
|
if (z == 6) {
|
2015-12-13 18:37:23 +01:00
|
|
|
rct_peep *peep = GET_PEEP(vehicle->peep[0]);
|
|
|
|
if (peep->id & 7) {
|
2015-12-13 21:32:29 +01:00
|
|
|
z = 8;
|
2015-12-13 18:37:23 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-10 10:24:56 +01:00
|
|
|
vehicle->var_D4 = (uint8)z;
|
2015-12-13 18:37:23 +01:00
|
|
|
vehicle->var_C5 = 0;
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress++;
|
2015-12-13 18:37:23 +01:00
|
|
|
break;
|
|
|
|
case 5: // loc_6DC87A
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->mini_golf_flags |= (1 << 2);
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress++;
|
2015-12-13 18:37:23 +01:00
|
|
|
break;
|
|
|
|
case 6: // loc_6DC88A
|
2016-02-18 22:47:24 +01:00
|
|
|
vehicle->mini_golf_flags &= ~(1 << 4);
|
|
|
|
vehicle->mini_golf_flags |= (1 << 5);
|
2015-12-15 19:26:44 +01:00
|
|
|
vehicle->track_progress++;
|
2015-12-13 18:37:23 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
log_error("Invalid move info...");
|
|
|
|
assert(false);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-10 10:24:56 +01:00
|
|
|
// loc_6DC8A1
|
2015-12-13 21:32:29 +01:00
|
|
|
x = vehicle->track_x + moveInfo->x;
|
|
|
|
y = vehicle->track_y + moveInfo->y;
|
2015-12-20 21:58:30 +01:00
|
|
|
z = vehicle->track_z + moveInfo->z + RCT2_GLOBAL(0x0097D21A + (ride->type * 8), sint8);
|
2015-12-13 21:32:29 +01:00
|
|
|
|
|
|
|
// Investigate redundant code
|
|
|
|
regs.ebx = 0;
|
|
|
|
if (regs.ax != unk_F64E20->x) {
|
|
|
|
regs.ebx |= 1;
|
|
|
|
}
|
|
|
|
if (regs.cx == unk_F64E20->y) {
|
|
|
|
regs.ebx |= 2;
|
|
|
|
}
|
|
|
|
if (regs.dx == unk_F64E20->z) {
|
|
|
|
regs.ebx |= 4;
|
|
|
|
}
|
|
|
|
regs.ebx = 0x368A;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= regs.ebx;
|
|
|
|
if ((sint32)vehicle->remaining_distance < 0) {
|
|
|
|
vehicle->remaining_distance = 0;
|
2015-12-13 21:32:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
unk_F64E20->x = x;
|
|
|
|
unk_F64E20->y = y;
|
|
|
|
unk_F64E20->z = z;
|
|
|
|
vehicle->sprite_direction = moveInfo->direction;
|
|
|
|
vehicle->var_20 = moveInfo->var_08;
|
|
|
|
vehicle->var_1F = moveInfo->var_07;
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (rideEntry->vehicles[0].flags_b & VEHICLE_ENTRY_FLAG_B_9) {
|
2015-12-13 21:32:29 +01:00
|
|
|
if (vehicle->var_1F != 0) {
|
|
|
|
vehicle->var_4A = 0;
|
2016-01-04 10:36:29 +01:00
|
|
|
vehicle->swinging_car_var_0 = 0;
|
2015-12-13 21:32:29 +01:00
|
|
|
vehicle->var_4E = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
2015-12-15 23:32:11 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
2015-12-18 21:33:45 +01:00
|
|
|
regs.bp = vehicle->var_44;
|
2015-12-27 12:46:15 +01:00
|
|
|
vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16*)®s.bp);
|
2015-12-13 21:32:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
goto loc_6DC99A;
|
2015-12-13 03:59:42 +01:00
|
|
|
|
|
|
|
loc_6DC985:
|
2015-12-13 21:32:29 +01:00
|
|
|
regs.ebx = 0;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= 0x368A;
|
|
|
|
if ((sint32)vehicle->remaining_distance < 0) {
|
|
|
|
vehicle->remaining_distance = 0;
|
2015-12-13 21:32:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DC99A:
|
2015-12-20 22:36:11 +01:00
|
|
|
if ((sint32)vehicle->remaining_distance < 0x368A) {
|
2015-12-13 21:32:29 +01:00
|
|
|
goto loc_6DCDE4;
|
|
|
|
}
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = dword_9A2970[vehicle->var_1F];
|
2015-12-13 21:32:29 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
goto loc_6DC462;
|
2015-12-13 03:59:42 +01:00
|
|
|
|
2015-12-13 17:10:30 +01:00
|
|
|
loc_6DC9BC:
|
2015-12-13 21:41:57 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= 0x20;
|
2015-12-20 22:36:11 +01:00
|
|
|
regs.eax = vehicle->remaining_distance + 1;
|
2015-12-20 21:58:30 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) -= regs.eax;
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->remaining_distance -= regs.eax;
|
2015-12-13 21:41:57 +01:00
|
|
|
regs.ebx = vehicle->var_1F;
|
|
|
|
goto loc_6DCD2B;
|
|
|
|
|
|
|
|
/////////////////////////////////////////
|
|
|
|
// Dead code: 0x006DC9D9 to 0x006DCA79 //
|
|
|
|
/////////////////////////////////////////
|
2015-12-13 17:10:30 +01:00
|
|
|
|
2015-12-13 03:59:42 +01:00
|
|
|
loc_6DCA7A:
|
2015-12-13 22:29:03 +01:00
|
|
|
vehicle->var_B8 &= ~(1 << 1);
|
|
|
|
unk_F64E20->x = vehicle->x;
|
|
|
|
unk_F64E20->y = vehicle->y;
|
|
|
|
unk_F64E20->z = vehicle->z;
|
2015-12-20 13:30:10 +01:00
|
|
|
vehicle_invalidate(vehicle);
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
loc_6DCA9A:
|
|
|
|
regs.ax = vehicle->track_progress - 1;
|
|
|
|
if (regs.ax != (short)0xFFFF) {
|
|
|
|
goto loc_6DCC2C;
|
|
|
|
}
|
|
|
|
|
|
|
|
trackType = vehicle->track_type >> 2;
|
|
|
|
RCT2_GLOBAL(0x00F64E36, uint8) = gTrackDefinitions[trackType].vangle_end;
|
|
|
|
RCT2_GLOBAL(0x00F64E37, uint8) = gTrackDefinitions[trackType].bank_end;
|
|
|
|
mapElement = map_get_track_element_at_of_type_seq(
|
|
|
|
vehicle->track_x, vehicle->track_y, vehicle->track_z >> 3,
|
|
|
|
trackType, 0
|
|
|
|
);
|
|
|
|
{
|
|
|
|
track_begin_end trackBeginEnd;
|
|
|
|
if (!track_block_get_previous(vehicle->track_x, vehicle->track_y, mapElement, &trackBeginEnd)) {
|
|
|
|
goto loc_6DC9BC;
|
|
|
|
}
|
|
|
|
x = trackBeginEnd.begin_x;
|
|
|
|
y = trackBeginEnd.begin_y;
|
|
|
|
z = trackBeginEnd.begin_z;
|
|
|
|
direction = trackBeginEnd.begin_direction;
|
|
|
|
mapElement = trackBeginEnd.begin_element;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!loc_6DB38B(vehicle, mapElement)) {
|
|
|
|
goto loc_6DCD4A;
|
|
|
|
}
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rideType = get_ride(mapElement->properties.track.ride_index)->type;
|
2016-01-14 19:25:41 +01:00
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_11;
|
|
|
|
if (RideData4[rideType].flags & RIDE_TYPE_FLAG4_3) {
|
|
|
|
if (mapElement->properties.track.colour & (1 << 2)) {
|
|
|
|
vehicle->update_flags |= VEHICLE_UPDATE_FLAG_11;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->track_x = x;
|
|
|
|
vehicle->track_y = y;
|
|
|
|
vehicle->track_z = z;
|
|
|
|
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_0) {
|
|
|
|
vehicle->update_flags &= ~VEHICLE_UPDATE_FLAG_0;
|
|
|
|
if (vehicle->next_vehicle_on_train == SPRITE_INDEX_NULL) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle->track_type = (mapElement->properties.track.type << 2) | (direction & 3);
|
|
|
|
vehicle->var_CF = (mapElement->properties.track.colour >> 4) << 1;
|
|
|
|
|
|
|
|
moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, 0);
|
|
|
|
|
|
|
|
// There are two bytes before the move info list
|
|
|
|
regs.ax = *((uint16*)((int)moveInfo - 2)) - 1;
|
|
|
|
|
|
|
|
loc_6DCC2C:
|
|
|
|
vehicle->track_progress = regs.ax;
|
|
|
|
|
|
|
|
moveInfo = vehicle_get_move_info(vehicle->var_CD, vehicle->track_type, vehicle->track_progress);
|
|
|
|
x = vehicle->track_x + moveInfo->x;
|
|
|
|
y = vehicle->track_y + moveInfo->y;
|
|
|
|
z = vehicle->track_z + moveInfo->z + RCT2_GLOBAL(0x0097D21A + (ride->type * 8), sint8);
|
|
|
|
|
|
|
|
// Investigate redundant code
|
|
|
|
regs.ebx = 0;
|
|
|
|
if (regs.ax != unk_F64E20->x) {
|
|
|
|
regs.ebx |= 1;
|
|
|
|
}
|
|
|
|
if (regs.cx == unk_F64E20->y) {
|
|
|
|
regs.ebx |= 2;
|
|
|
|
}
|
|
|
|
if (regs.dx == unk_F64E20->z) {
|
|
|
|
regs.ebx |= 4;
|
|
|
|
}
|
|
|
|
regs.ebx = 0x368A;
|
|
|
|
vehicle->remaining_distance -= regs.ebx;
|
|
|
|
if ((sint32)vehicle->remaining_distance < 0) {
|
|
|
|
vehicle->remaining_distance = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unk_F64E20->x = x;
|
|
|
|
unk_F64E20->y = y;
|
|
|
|
unk_F64E20->z = z;
|
|
|
|
vehicle->sprite_direction = moveInfo->direction;
|
|
|
|
vehicle->var_20 = moveInfo->var_08;
|
|
|
|
vehicle->var_1F = moveInfo->var_07;
|
|
|
|
|
|
|
|
if (rideEntry->vehicles[0].flags_b & VEHICLE_ENTRY_FLAG_B_9) {
|
|
|
|
if (vehicle->var_1F != 0) {
|
|
|
|
vehicle->var_4A = 0;
|
|
|
|
vehicle->swinging_car_var_0 = 0;
|
|
|
|
vehicle->var_4E = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle == RCT2_GLOBAL(0x00F64E00, rct_vehicle*)) {
|
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
|
|
|
regs.bp = vehicle->var_44;
|
|
|
|
if (vehicle_update_motion_collision_detection(vehicle, x, y, z, (uint16*)®s.bp)) {
|
|
|
|
goto loc_6DCD6B;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DCD2B:
|
|
|
|
if (vehicle->remaining_distance >= 0) {
|
|
|
|
goto loc_6DCDE4;
|
|
|
|
}
|
|
|
|
vehicle->acceleration += dword_9A2970[vehicle->var_1F];
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
goto loc_6DCA9A;
|
|
|
|
|
|
|
|
loc_6DCD4A:
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_5;
|
|
|
|
regs.eax = vehicle->remaining_distance - 0x368A;
|
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) -= regs.eax;
|
|
|
|
vehicle->remaining_distance -= regs.eax;
|
|
|
|
regs.ebx = vehicle->var_1F;
|
|
|
|
goto loc_6DC99A;
|
|
|
|
|
|
|
|
loc_6DCD6B:
|
|
|
|
regs.eax = vehicle->remaining_distance - 0x368A;
|
|
|
|
RCT2_GLOBAL(0x00F64E0C, sint32) -= regs.eax;
|
|
|
|
vehicle->remaining_distance -= regs.eax;
|
|
|
|
rct_vehicle *vEBP = GET_VEHICLE(regs.bp);
|
|
|
|
rct_vehicle *vEDI = RCT2_GLOBAL(0x00F64E04, rct_vehicle *);
|
|
|
|
regs.eax = abs(vEDI->velocity - vEBP->velocity);
|
|
|
|
if (regs.eax > 0xE0000) {
|
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_6)) {
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_COLLISION;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vEDI->velocity = vEBP->velocity >> 1;
|
|
|
|
vEBP->velocity = vEDI->velocity >> 1;
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_2;
|
|
|
|
goto loc_6DC99A;
|
|
|
|
|
|
|
|
loc_6DCDE4:
|
|
|
|
sprite_move(unk_F64E20->x, unk_F64E20->y, unk_F64E20->z, (rct_sprite*)vehicle);
|
|
|
|
vehicle_invalidate(vehicle);
|
|
|
|
|
|
|
|
loc_6DCE02:
|
|
|
|
vehicle->acceleration /= RCT2_GLOBAL(0x00F64E10, uint32);
|
|
|
|
if (vehicle->var_CD == 2) {
|
|
|
|
goto loc_6DCEB2;
|
|
|
|
}
|
|
|
|
trackType = vehicle->track_type >> 2;
|
|
|
|
if (!(RCT2_GLOBAL(0x0099BA64 + (trackType * 16), uint32) & 0x10)) {
|
|
|
|
goto loc_6DCEB2;
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_3;
|
|
|
|
if (trackType != TRACK_ELEM_END_STATION) {
|
|
|
|
goto loc_6DCEB2;
|
|
|
|
}
|
|
|
|
if (vehicle != RCT2_GLOBAL(0x00F64E04, rct_vehicle*)) {
|
|
|
|
goto loc_6DCEB2;
|
|
|
|
}
|
|
|
|
regs.ax = vehicle->track_progress;
|
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
|
|
|
goto loc_6DCE62;
|
|
|
|
}
|
|
|
|
regs.cx = 8;
|
|
|
|
if (regs.ax > regs.cx) {
|
|
|
|
goto loc_6DCE68;
|
|
|
|
}
|
|
|
|
goto loc_6DCEB2;
|
|
|
|
|
|
|
|
loc_6DCE62:
|
|
|
|
if (regs.ax > 11) {
|
|
|
|
goto loc_6DCEB2;
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DCE68:
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_AT_STATION;
|
|
|
|
regs.al = vehicle->track_x >> 5;
|
|
|
|
regs.ah = vehicle->track_y >> 5;
|
|
|
|
regs.dl = vehicle->track_z >> 3;
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
if ((uint16)regs.ax != ride->station_starts[i]) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ((uint16)regs.dl != ride->station_heights[i]) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
RCT2_GLOBAL(0x00F64E1C, uint32) = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DCEB2:
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_0) {
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_ON_LIFT_HILL;
|
|
|
|
}
|
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
|
|
|
regs.si = vehicle->next_vehicle_on_train;
|
|
|
|
if ((uint16)regs.si == SPRITE_INDEX_NULL) {
|
|
|
|
goto loc_6DCEFF;
|
|
|
|
}
|
|
|
|
vehicle = GET_VEHICLE((uint16)regs.si);
|
|
|
|
goto loc_6DC40E;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle == RCT2_GLOBAL(0x00F64E04, rct_vehicle*)) {
|
|
|
|
goto loc_6DCEFF;
|
|
|
|
}
|
|
|
|
vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_ride);
|
|
|
|
goto loc_6DC40E;
|
|
|
|
|
|
|
|
loc_6DCEFF:
|
|
|
|
vehicle = RCT2_GLOBAL(0x00F64E04, rct_vehicle*);
|
|
|
|
regs.eax = 0;
|
|
|
|
regs.ebp = 0;
|
|
|
|
regs.dx = 0;
|
|
|
|
regs.ebx = 0;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
regs.ebx++;
|
|
|
|
regs.dx |= vehicle->update_flags;
|
|
|
|
regs.bp += vehicle->friction;
|
|
|
|
regs.eax += vehicle->acceleration;
|
|
|
|
regs.si = vehicle->next_vehicle_on_train;
|
|
|
|
if ((uint16)regs.si == SPRITE_INDEX_NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
vehicle = GET_VEHICLE((uint16)regs.si);
|
|
|
|
}
|
|
|
|
|
|
|
|
vehicle = RCT2_GLOBAL(0x00F64E04, rct_vehicle*);
|
|
|
|
regs.eax /= regs.ebx;
|
|
|
|
regs.ecx = (regs.eax * 21) >> 9;
|
|
|
|
regs.eax = vehicle->velocity >> 12;
|
|
|
|
regs.ecx -= regs.eax;
|
|
|
|
regs.ebx = vehicle->velocity;
|
|
|
|
regs.edx = vehicle->velocity >> 8;
|
|
|
|
regs.edx *= regs.edx;
|
|
|
|
if (regs.ebx < 0) {
|
|
|
|
regs.edx = -regs.edx;
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.edx >>= 4;
|
|
|
|
regs.eax = regs.edx / regs.ebp;
|
|
|
|
regs.ecx -= regs.eax;
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3)) {
|
|
|
|
goto loc_6DD069;
|
|
|
|
}
|
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_0) {
|
|
|
|
regs.eax = vehicle->speed * 0x4000;
|
|
|
|
if (regs.eax < vehicle->velocity) {
|
|
|
|
goto loc_6DD069;
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.eax = vehicle->speed;
|
|
|
|
regs.bx = vehicle->track_type >> 2;
|
|
|
|
regs.ebx = regs.eax;
|
|
|
|
regs.eax <<= 14;
|
|
|
|
regs.ebx *= regs.ebp;
|
|
|
|
regs.ebx >>= 2;
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_3) {
|
|
|
|
regs.eax = -regs.eax;
|
|
|
|
}
|
|
|
|
regs.eax -= vehicle->velocity;
|
|
|
|
regs.edx = vehicle->powered_acceleration;
|
|
|
|
regs.edx <<= 1;
|
|
|
|
regs.eax *= regs.edx;
|
|
|
|
regs.eax = regs.eax / regs.ebx;
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_13)) {
|
|
|
|
goto loc_6DD054;
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
if (regs.eax < 0) {
|
|
|
|
regs.eax >>= 4;
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SPINNING) {
|
|
|
|
vehicle->var_B6 = clamp(-0x200, (sint16)vehicle->var_B6, 0x200);
|
|
|
|
}
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
if (vehicle->var_1F != 0) {
|
|
|
|
regs.eax = max(0, regs.eax);
|
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SPINNING) {
|
|
|
|
if (vehicle->var_1F == 2) {
|
|
|
|
vehicle->var_B6 = 0;
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
else {
|
|
|
|
loc_6DD054:
|
|
|
|
regs.ebx = abs(vehicle->velocity);
|
|
|
|
if (regs.ebx > 0x10000) {
|
|
|
|
regs.ecx = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
regs.ecx += regs.eax;
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
loc_6DD069:
|
|
|
|
vehicle->acceleration = regs.ecx;
|
|
|
|
regs.eax = RCT2_GLOBAL(0x00F64E18, uint32);
|
|
|
|
regs.ebx = RCT2_GLOBAL(0x00F64E1C, uint32);
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
if (outStation != NULL) *outStation = regs.ebx;
|
|
|
|
return regs.eax;
|
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* rct2: 0x006DAB4C
|
|
|
|
*/
|
|
|
|
int vehicle_update_track_motion(rct_vehicle *vehicle, int *outStation)
|
|
|
|
{
|
|
|
|
registers regs = { 0 };
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride *ride = get_ride(vehicle->ride);
|
|
|
|
rct_ride_type *rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2016-01-14 19:25:41 +01:00
|
|
|
rct_ride_type_vehicle *vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
rct_map_element *mapElement = NULL;
|
|
|
|
|
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_MINI_GOLF) {
|
|
|
|
return vehicle_update_track_motion_mini_golf(vehicle, outStation);
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
RCT2_GLOBAL(0x00F64E2C, uint8) = 0;
|
|
|
|
RCT2_GLOBAL(0x00F64E04, rct_vehicle*) = vehicle;
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) = 0;
|
|
|
|
RCT2_GLOBAL(0x00F64E1C, uint32) = 0xFFFFFFFF;
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
vehicle_update_track_motion_up_stop_check(vehicle);
|
|
|
|
sub_6DAB4C_chunk_2(vehicle);
|
|
|
|
sub_6DAB4C_chunk_3(vehicle);
|
|
|
|
|
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) < 0) {
|
|
|
|
vehicle = vehicle_get_tail(vehicle);
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
// This will be the front vehicle even when traveling
|
|
|
|
// backwards.
|
|
|
|
RCT2_GLOBAL(0x00F64E00, rct_vehicle*) = vehicle;
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
uint16 spriteId = vehicle->sprite_index;
|
|
|
|
for (rct_vehicle* car = vehicle; spriteId != 0xFFFF; car = GET_VEHICLE(spriteId)) {
|
2016-02-14 20:52:35 +01:00
|
|
|
vehicleEntry = vehicle_get_vehicle_entry(car);
|
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
// Swinging cars
|
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SWINGING) {
|
|
|
|
vehicle_update_swinging_car(car);
|
2015-12-13 22:29:03 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
// Spinning cars
|
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SPINNING) {
|
|
|
|
vehicle_update_spinning_car(car);
|
|
|
|
}
|
|
|
|
// Rider sprites?? animation??
|
|
|
|
if ((vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_7) || (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_8)) {
|
|
|
|
sub_6D63D4(car);
|
|
|
|
}
|
|
|
|
car->acceleration = dword_9A2970[car->var_1F];
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32) = 1;
|
2015-12-13 03:59:42 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.eax = RCT2_GLOBAL(0x00F64E0C, sint32) + car->remaining_distance;
|
|
|
|
car->remaining_distance = regs.eax;
|
2015-12-13 21:41:57 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
car->var_B8 &= ~(1 << 1);
|
|
|
|
unk_F64E20->x = car->x;
|
|
|
|
unk_F64E20->y = car->y;
|
|
|
|
unk_F64E20->z = car->z;
|
|
|
|
invalidate_sprite_2((rct_sprite*)car);
|
2015-12-13 22:29:03 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
while (true) {
|
|
|
|
if (car->remaining_distance < 0) {
|
|
|
|
// Backward loop
|
|
|
|
if (vehicle_update_track_motion_backwards(car, vehicleEntry, ride, rideEntry)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (car->remaining_distance < 0x368A) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
regs.ebx = dword_9A2970[car->var_1F];
|
|
|
|
car->acceleration += regs.ebx;
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (car->remaining_distance < 0x368A) {
|
|
|
|
// Location found
|
|
|
|
goto loc_6DBF3E;
|
|
|
|
}
|
|
|
|
if (vehicle_update_track_motion_forwards(car, vehicleEntry, ride, rideEntry)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (car->remaining_distance >= 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
regs.ebx = dword_9A2970[car->var_1F];
|
|
|
|
car->acceleration = regs.ebx;
|
|
|
|
RCT2_GLOBAL(0x00F64E10, uint32)++;
|
|
|
|
continue;
|
|
|
|
}
|
2015-12-13 23:03:13 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
// loc_6DBF20
|
|
|
|
sprite_move(unk_F64E20->x, unk_F64E20->y, unk_F64E20->z, (rct_sprite*)car);
|
|
|
|
invalidate_sprite_2((rct_sprite*)car);
|
2015-12-13 23:26:57 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
loc_6DBF3E:
|
|
|
|
sub_6DBF3E(car);
|
2015-12-13 23:26:57 +01:00
|
|
|
|
2016-01-14 19:25:41 +01:00
|
|
|
// loc_6DC0F7
|
|
|
|
if (car->update_flags & VEHICLE_UPDATE_FLAG_0) {
|
|
|
|
RCT2_GLOBAL(0x00F64E18, uint32) |= VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_ON_LIFT_HILL;
|
2015-12-13 23:26:57 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
if (RCT2_GLOBAL(0x00F64E08, sint32) >= 0) {
|
|
|
|
spriteId = car->next_vehicle_on_train;
|
2015-12-13 23:26:57 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
else {
|
|
|
|
if (car == RCT2_GLOBAL(0x00F64E04, rct_vehicle*)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
spriteId = car->prev_vehicle_on_ride;
|
2015-12-13 23:26:57 +01:00
|
|
|
}
|
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
// loc_6DC144
|
2015-12-13 23:53:06 +01:00
|
|
|
vehicle = RCT2_GLOBAL(0x00F64E04, rct_vehicle*);
|
2016-02-18 23:24:40 +01:00
|
|
|
|
|
|
|
vehicleEntry = vehicle_get_vehicle_entry(vehicle);
|
2016-01-14 19:25:41 +01:00
|
|
|
//eax
|
|
|
|
sint32 totalAcceleration = 0;
|
|
|
|
//ebp
|
|
|
|
sint32 totalFriction = 0;
|
|
|
|
//Not used
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.dx = 0;
|
2016-01-14 19:25:41 +01:00
|
|
|
//ebx
|
|
|
|
int numVehicles = 0;
|
2015-12-13 23:53:06 +01:00
|
|
|
|
|
|
|
for (;;) {
|
2016-01-14 19:25:41 +01:00
|
|
|
numVehicles++;
|
|
|
|
// Not used?
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.dx |= vehicle->update_flags;
|
2016-01-14 19:25:41 +01:00
|
|
|
totalFriction += vehicle->friction;
|
|
|
|
totalAcceleration += vehicle->acceleration;
|
|
|
|
|
|
|
|
uint16 spriteIndex = vehicle->next_vehicle_on_train;
|
|
|
|
if (spriteIndex == SPRITE_INDEX_NULL) {
|
2015-12-13 23:53:06 +01:00
|
|
|
break;
|
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
vehicle = GET_VEHICLE(spriteIndex);
|
2015-12-13 23:53:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
vehicle = RCT2_GLOBAL(0x00F64E04, rct_vehicle*);
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.eax = (totalAcceleration / numVehicles) * 21;
|
|
|
|
if (regs.eax < 0) {
|
|
|
|
regs.eax += 511;
|
|
|
|
}
|
|
|
|
regs.eax >>= 9;
|
|
|
|
regs.ecx = regs.eax;
|
|
|
|
regs.eax = vehicle->velocity;
|
|
|
|
if (regs.eax < 0) {
|
|
|
|
regs.eax = -regs.eax;
|
|
|
|
regs.eax >>= 12;
|
|
|
|
regs.eax = -regs.eax;
|
|
|
|
} else {
|
|
|
|
regs.eax >>= 12;
|
|
|
|
}
|
|
|
|
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.ecx -= regs.eax;
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.edx = vehicle->velocity;
|
|
|
|
regs.ebx = regs.edx;
|
|
|
|
regs.edx >>= 8;
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.edx *= regs.edx;
|
|
|
|
if (regs.ebx < 0) {
|
|
|
|
regs.edx = -regs.edx;
|
|
|
|
}
|
|
|
|
regs.edx >>= 4;
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.eax = regs.edx;
|
|
|
|
regs.eax = regs.eax / totalFriction;
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.ecx -= regs.eax;
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_3)) {
|
2016-01-14 19:25:41 +01:00
|
|
|
goto loc_6DC2FA;
|
2015-12-13 23:53:06 +01:00
|
|
|
}
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_0) {
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.eax = vehicle->speed * 0x4000;
|
|
|
|
if (regs.eax < vehicle->velocity) {
|
2016-01-14 19:25:41 +01:00
|
|
|
goto loc_6DC2FA;
|
2015-12-13 23:53:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
regs.eax = vehicle->speed;
|
2016-01-14 19:25:41 +01:00
|
|
|
uint16 trackType = vehicle->track_direction >> 2;
|
|
|
|
if (trackType == TRACK_ELEM_LEFT_QUARTER_TURN_1_TILE) {
|
|
|
|
goto loc_6DC22F;
|
|
|
|
}
|
|
|
|
if (trackType != TRACK_ELEM_RIGHT_QUARTER_TURN_1_TILE) {
|
|
|
|
goto loc_6DC23A;
|
|
|
|
}
|
|
|
|
if (vehicle->var_CD == 6) {
|
|
|
|
goto loc_6DC238;
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DC226:
|
|
|
|
regs.ebx = regs.eax >> 2;
|
|
|
|
regs.eax -= regs.ebx;
|
|
|
|
goto loc_6DC23A;
|
|
|
|
|
|
|
|
loc_6DC22F:
|
|
|
|
if (vehicle->var_CD != 5) {
|
|
|
|
goto loc_6DC226;
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DC238:
|
|
|
|
regs.eax >>= 1;
|
|
|
|
|
|
|
|
loc_6DC23A:
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.ebx = regs.eax;
|
|
|
|
regs.eax <<= 14;
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.ebx *= totalFriction;
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.ebx >>= 2;
|
|
|
|
if (vehicle->update_flags & VEHICLE_UPDATE_FLAG_3) {
|
|
|
|
regs.eax = -regs.eax;
|
|
|
|
}
|
|
|
|
regs.eax -= vehicle->velocity;
|
2015-12-20 22:36:11 +01:00
|
|
|
regs.edx = vehicle->powered_acceleration;
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.edx <<= 1;
|
|
|
|
regs.eax *= regs.edx;
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.eax /= regs.ebx;
|
|
|
|
|
|
|
|
if (vehicleEntry->flags_a & VEHICLE_ENTRY_FLAG_A_15) {
|
|
|
|
regs.eax <<= 2;
|
|
|
|
}
|
2015-12-22 15:21:56 +01:00
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_13)) {
|
2016-01-14 19:25:41 +01:00
|
|
|
goto loc_6DC2E3;
|
2015-12-13 23:53:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (regs.eax < 0) {
|
|
|
|
regs.eax >>= 4;
|
|
|
|
}
|
|
|
|
|
2015-12-16 20:12:58 +01:00
|
|
|
if (vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SPINNING) {
|
2016-01-14 19:25:41 +01:00
|
|
|
regs.bx = vehicle->var_B6;
|
|
|
|
if (regs.bx > 512) {
|
|
|
|
regs.bx = 512;
|
|
|
|
}
|
|
|
|
if (regs.bx < -512) {
|
|
|
|
regs.bx = -512;
|
|
|
|
}
|
|
|
|
vehicle->var_B6 = regs.bx;
|
2015-12-13 23:53:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (vehicle->var_1F != 0) {
|
2016-01-14 19:25:41 +01:00
|
|
|
if (regs.eax < 0) {
|
|
|
|
regs.eax = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(vehicleEntry->flags_b & VEHICLE_ENTRY_FLAG_B_SPINNING)) {
|
2015-12-13 23:53:06 +01:00
|
|
|
if (vehicle->var_1F == 2) {
|
|
|
|
vehicle->var_B6 = 0;
|
|
|
|
}
|
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
goto loc_6DC2F6;
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DC2E3:
|
|
|
|
regs.ebx = vehicle->velocity;
|
|
|
|
if (regs.ebx < 0) {
|
|
|
|
regs.ebx = -regs.ebx;
|
2015-12-13 23:53:06 +01:00
|
|
|
}
|
2016-01-14 19:25:41 +01:00
|
|
|
if (regs.ebx <= 0x10000) {
|
|
|
|
regs.ecx = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DC2F6:
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.ecx += regs.eax;
|
2016-01-14 19:25:41 +01:00
|
|
|
goto loc_6DC316;
|
|
|
|
|
|
|
|
loc_6DC2FA:
|
|
|
|
if (regs.ecx <= 0) {
|
|
|
|
if (regs.ecx >= -500) {
|
|
|
|
if (vehicle->velocity <= 0x8000) {
|
|
|
|
regs.ecx += 400;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
loc_6DC316:
|
|
|
|
regs.bx = vehicle->track_type >> 2;
|
|
|
|
if (regs.bx == TRACK_ELEM_WATER_SPLASH) {
|
|
|
|
if (vehicle->track_progress >= 48 &&
|
|
|
|
vehicle->track_progress <= 128
|
|
|
|
) {
|
|
|
|
regs.eax = vehicle->velocity >> 6;
|
|
|
|
regs.ecx -= regs.eax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rideEntry->flags & RIDE_ENTRY_FLAG_9) {
|
|
|
|
if (!vehicle->is_child) {
|
|
|
|
regs.bx = vehicle->track_type >> 2;
|
|
|
|
if (track_element_is_covered(regs.bx)) {
|
|
|
|
if (vehicle->velocity > 0x20000) {
|
|
|
|
regs.eax = vehicle->velocity >> 6;
|
|
|
|
regs.ecx -= regs.eax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-10-25 17:00:21 +01:00
|
|
|
|
2015-12-20 22:36:11 +01:00
|
|
|
vehicle->acceleration = regs.ecx;
|
2016-01-14 19:25:41 +01:00
|
|
|
|
2015-12-13 23:53:06 +01:00
|
|
|
regs.eax = RCT2_GLOBAL(0x00F64E18, uint32);
|
|
|
|
regs.ebx = RCT2_GLOBAL(0x00F64E1C, uint32);
|
2016-01-14 19:25:41 +01:00
|
|
|
if (ride->lifecycle_flags & RIDE_LIFECYCLE_SIX_FLAGS_DEPRECATED) {
|
|
|
|
regs.eax &= ~VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_DERAILED;
|
|
|
|
regs.eax &= ~VEHICLE_UPDATE_MOTION_TRACK_FLAG_VEHICLE_COLLISION;
|
|
|
|
}
|
2015-10-25 22:25:54 +01:00
|
|
|
|
2015-12-15 00:31:00 +01:00
|
|
|
// hook_setreturnregisters(®s);
|
2015-12-15 19:26:44 +01:00
|
|
|
if (outStation != NULL) *outStation = regs.ebx;
|
2015-10-25 22:25:54 +01:00
|
|
|
return regs.eax;
|
2015-10-25 17:00:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
rct_ride_type_vehicle *vehicle_get_vehicle_entry(rct_vehicle *vehicle)
|
|
|
|
{
|
2016-01-22 15:38:52 +01:00
|
|
|
rct_ride_type *rideEntry = get_ride_entry(vehicle->ride_subtype);
|
2015-10-25 17:00:21 +01:00
|
|
|
return &rideEntry->vehicles[vehicle->vehicle_type];
|
|
|
|
}
|
2014-11-12 02:04:50 +01:00
|
|
|
|
|
|
|
int vehicle_get_total_num_peeps(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
uint16 spriteIndex;
|
|
|
|
int numPeeps = 0;
|
|
|
|
for (;;) {
|
|
|
|
numPeeps += vehicle->num_peeps;
|
|
|
|
spriteIndex = vehicle->next_vehicle_on_train;
|
|
|
|
if (spriteIndex == SPRITE_INDEX_NULL)
|
|
|
|
break;
|
|
|
|
|
|
|
|
vehicle = &(g_sprite_list[spriteIndex].vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
return numPeeps;
|
|
|
|
}
|
2014-11-12 02:32:20 +01:00
|
|
|
|
|
|
|
/**
|
2015-12-12 11:21:49 +01:00
|
|
|
*
|
2014-11-12 02:32:20 +01:00
|
|
|
* rct2: 0x006DA1EC
|
|
|
|
*/
|
|
|
|
void vehicle_invalidate_window(rct_vehicle *vehicle)
|
|
|
|
{
|
|
|
|
int viewVehicleIndex;
|
|
|
|
rct_ride *ride;
|
|
|
|
rct_window *w;
|
|
|
|
|
|
|
|
w = window_find_by_number(WC_RIDE, vehicle->ride);
|
|
|
|
if (w == NULL)
|
|
|
|
return;
|
|
|
|
|
2016-01-22 15:38:52 +01:00
|
|
|
ride = get_ride(vehicle->ride);
|
2014-11-12 02:32:20 +01:00
|
|
|
viewVehicleIndex = w->ride.view - 1;
|
|
|
|
if (viewVehicleIndex < 0 || viewVehicleIndex >= ride->num_vehicles)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (vehicle->sprite_index != ride->vehicles[viewVehicleIndex])
|
|
|
|
return;
|
|
|
|
|
|
|
|
window_invalidate(w);
|
2015-10-17 20:30:32 +02:00
|
|
|
}
|