mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-17 12:03:07 +01:00
refactor station update and fix bugs
This commit is contained in:
@@ -711,6 +711,7 @@ static void ride_inspection_update(rct_ride *ride)
|
||||
|
||||
// Inspect the first station that has an exit
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_DUE_INSPECTION;
|
||||
ride->mechanic_status = RIDE_MECHANIC_STATUS_CALLING;
|
||||
ride->inspection_station = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ride->exits[i] != 0xFFFF) {
|
||||
|
||||
@@ -97,7 +97,7 @@ typedef struct {
|
||||
uint16 station_starts[4]; // 0x052
|
||||
uint8 station_heights[4]; // 0x05A
|
||||
uint8 pad_05E[0x4];
|
||||
uint8 var_062[4];
|
||||
uint8 station_depart[4]; // 0x062
|
||||
uint8 pad_066[0x4];
|
||||
uint16 entrances[4]; // 0x06A
|
||||
uint16 exits[4]; // 0x072
|
||||
@@ -114,7 +114,11 @@ typedef struct {
|
||||
uint8 var_0CD;
|
||||
uint8 min_waiting_time; // 0x0CE
|
||||
uint8 max_waiting_time; // 0x0CF
|
||||
uint8 var_0D0;
|
||||
union {
|
||||
uint8 var_0D0;
|
||||
uint8 time_limit; // 0x0D0
|
||||
uint8 num_laps; // 0x0D0
|
||||
};
|
||||
uint8 pad_0D1[0x3];
|
||||
uint8 measurement_index; // 0x0D4
|
||||
uint8 var_0D5;
|
||||
@@ -573,6 +577,9 @@ enum {
|
||||
#define MAX_RIDE_MEASUREMENTS 8
|
||||
#define RIDE_RELIABILITY_UNDEFINED 0xFFFF
|
||||
|
||||
#define STATION_DEPART_FLAG (1 << 7)
|
||||
#define STATION_DEPART_MASK (~STATION_DEPART_FLAG)
|
||||
|
||||
// rct2: 0x009ACFA4
|
||||
rct_ride_type **gRideTypeList;
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
#include "../world/sprite.h"
|
||||
#include "station.h"
|
||||
|
||||
static void ride_update_station_blocksection(rct_ride *ride, int stationIndex, int dl);
|
||||
static void ride_update_station_bumpercar(rct_ride *ride, int stationIndex, int dl);
|
||||
static void ride_update_station_race(rct_ride *ride, int stationIndex, int dl);
|
||||
static void ride_update_station_blocksection(rct_ride *ride, int stationIndex);
|
||||
static void ride_update_station_bumpercar(rct_ride *ride, int stationIndex);
|
||||
static void ride_update_station_normal(rct_ride *ride, int stationIndex);
|
||||
static void ride_update_station_race(rct_ride *ride, int stationIndex);
|
||||
static void ride_race_init_vehicle_speeds(rct_ride *ride);
|
||||
static void ride_invalidate_station_start(rct_ride *ride, int stationIndex, int dl);
|
||||
static void sub_6AC2AF(rct_ride *ride, int stationIndex, int dl);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -36,41 +36,22 @@ static void sub_6AC2AF(rct_ride *ride, int stationIndex, int dl);
|
||||
*/
|
||||
void ride_update_station(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int dl, dh;
|
||||
|
||||
if (ride->station_starts[stationIndex] == 0xFFFF)
|
||||
return;
|
||||
|
||||
dl = 0;
|
||||
switch (ride->mode) {
|
||||
case RIDE_MODE_RACE:
|
||||
ride_update_station_race(ride, stationIndex, dl);
|
||||
ride_update_station_race(ride, stationIndex);
|
||||
break;
|
||||
case RIDE_MODE_BUMPERCAR:
|
||||
ride_update_station_bumpercar(ride, stationIndex, dl);
|
||||
ride_update_station_bumpercar(ride, stationIndex);
|
||||
break;
|
||||
case RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED:
|
||||
case RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED:
|
||||
ride_update_station_blocksection(ride, stationIndex, dl);
|
||||
ride_update_station_blocksection(ride, stationIndex);
|
||||
break;
|
||||
default:
|
||||
if (
|
||||
(ride->lifecycle_flags & (RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED)) &&
|
||||
(ride->status == RIDE_STATUS_CLOSED && ride->num_riders == 0)
|
||||
) {
|
||||
dh = ride->var_062[stationIndex] & 0x7F;
|
||||
if (dh != 0 && dh != 0x7F && !(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 7))
|
||||
ride->var_062[stationIndex]--;
|
||||
} else {
|
||||
dl = 1;
|
||||
dh = ride->var_062[stationIndex] & 0x7F;
|
||||
if (dh != 0) {
|
||||
if (dh != 0x7F && !(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 31))
|
||||
ride->var_062[stationIndex]--;
|
||||
dl = 0;
|
||||
}
|
||||
}
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
ride_update_station_normal(ride, stationIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -79,102 +60,114 @@ void ride_update_station(rct_ride *ride, int stationIndex)
|
||||
*
|
||||
* rct2: 0x006AC0A1
|
||||
*/
|
||||
static void ride_update_station_blocksection(rct_ride *ride, int stationIndex, int dl)
|
||||
static void ride_update_station_blocksection(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
rct_map_element *mapElement;
|
||||
|
||||
mapElement = ride_get_station_start_track_element(ride, stationIndex);
|
||||
|
||||
if ((ride->status == RIDE_STATUS_CLOSED && ride->num_riders == 0) || mapElement->flags & 0x20) {
|
||||
dl = 0;
|
||||
if (ride->var_062[stationIndex] & (1 << 7)) {
|
||||
ride->var_062[stationIndex] &= ~(1 << 7);
|
||||
ride_invalidate_station_start(ride, stationIndex, dl);
|
||||
return;
|
||||
}
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
|
||||
if (mapElement->properties.track.sequence & 0x80) {
|
||||
ride_invalidate_station_start(ride, stationIndex, dl);
|
||||
return;
|
||||
}
|
||||
if ((ride->station_depart[stationIndex] & STATION_DEPART_FLAG) || (mapElement->properties.track.sequence & 0x80))
|
||||
ride_invalidate_station_start(ride, stationIndex, 0);
|
||||
} else {
|
||||
dl = 1;
|
||||
if (!(ride->var_062[stationIndex] & (1 << 7))) {
|
||||
ride->var_062[stationIndex] |= (1 << 7);
|
||||
ride_invalidate_station_start(ride, stationIndex, dl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapElement->properties.track.sequence & 0x80) {
|
||||
ride_invalidate_station_start(ride, stationIndex, dl);
|
||||
return;
|
||||
if (!(ride->station_depart[stationIndex] & STATION_DEPART_FLAG)) {
|
||||
ride->station_depart[stationIndex] |= STATION_DEPART_FLAG;
|
||||
ride_invalidate_station_start(ride, stationIndex, 1);
|
||||
} else if (mapElement->properties.track.sequence & 0x80) {
|
||||
ride_invalidate_station_start(ride, stationIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC12B
|
||||
*/
|
||||
static void ride_update_station_bumpercar(rct_ride *ride, int stationIndex, int dl)
|
||||
static void ride_update_station_bumpercar(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int i, dx, dh;
|
||||
int i, dx, dl, dh;
|
||||
rct_vehicle *vehicle;
|
||||
|
||||
if (
|
||||
ride->status == RIDE_STATUS_CLOSED ||
|
||||
(ride->lifecycle_flags & (RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED))
|
||||
) {
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) {
|
||||
dx = ride->var_0D0 * 32;
|
||||
dx = ride->time_limit * 32;
|
||||
dl = dx & 0xFF;
|
||||
dh = (dx >> 8) & 0xFF;
|
||||
for (i = 0; i < ride->num_vehicles; i++) {
|
||||
vehicle = &(g_sprite_list[ride->vehicles[i]].vehicle);
|
||||
if (dh > vehicle->var_CE)
|
||||
if (vehicle->var_CE < dh || (vehicle->var_CE < dh && vehicle->var_51 > dl))
|
||||
continue;
|
||||
|
||||
if (dh < vehicle->var_CE) {
|
||||
ride->lifecycle_flags &= ~VEHICLE_STATUS_WAITING_TO_DEPART;
|
||||
dh = 0;
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dl > vehicle->var_51)
|
||||
continue;
|
||||
// End match
|
||||
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
|
||||
dl = 1;
|
||||
// Continue match
|
||||
ride->station_depart[stationIndex] |= STATION_DEPART_FLAG;
|
||||
} else {
|
||||
// Check if all vehicles are ready to go
|
||||
for (i = 0; i < ride->num_vehicles; i++) {
|
||||
vehicle = &(g_sprite_list[ride->vehicles[i]].vehicle);
|
||||
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART) {
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ride->lifecycle_flags |= VEHICLE_STATUS_WAITING_TO_DEPART;
|
||||
ride->var_14D = 12;
|
||||
dl = 1;
|
||||
// Begin the match
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
|
||||
ride->station_depart[stationIndex] |= STATION_DEPART_FLAG;
|
||||
ride->var_14D |= 12;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC02C
|
||||
*/
|
||||
static void ride_update_station_normal(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int time;
|
||||
|
||||
time = ride->station_depart[stationIndex] & STATION_DEPART_MASK;
|
||||
if (
|
||||
(ride->lifecycle_flags & (RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED)) &&
|
||||
(ride->status == RIDE_STATUS_CLOSED && ride->num_riders == 0)
|
||||
) {
|
||||
if (time != 0 && time != 127 && !(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 7))
|
||||
time--;
|
||||
|
||||
ride->station_depart[stationIndex] = time;
|
||||
} else {
|
||||
if (time == 0) {
|
||||
ride->station_depart[stationIndex] |= STATION_DEPART_FLAG;
|
||||
} else {
|
||||
if (time != 127 && !(RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 31))
|
||||
time--;
|
||||
|
||||
ride->station_depart[stationIndex] = time;
|
||||
}
|
||||
}
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC1DF
|
||||
*/
|
||||
static void ride_update_station_race(rct_ride *ride, int stationIndex, int dl)
|
||||
static void ride_update_station_race(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int i, dh;
|
||||
int i, numLaps;
|
||||
rct_vehicle *vehicle;
|
||||
rct_peep *peep;
|
||||
|
||||
@@ -182,40 +175,47 @@ static void ride_update_station_race(rct_ride *ride, int stationIndex, int dl)
|
||||
ride->status == RIDE_STATUS_CLOSED ||
|
||||
(ride->lifecycle_flags & (RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED))
|
||||
) {
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(ride->lifecycle_flags & VEHICLE_STATUS_WAITING_TO_DEPART)) {
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) {
|
||||
numLaps = ride->num_laps;
|
||||
for (i = 0; i < ride->num_vehicles; i++) {
|
||||
vehicle = &(g_sprite_list[ride->vehicles[i]].vehicle);
|
||||
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART && vehicle->num_laps >= numLaps) {
|
||||
// Found a winner
|
||||
if (vehicle->var_B3 != 0) {
|
||||
peep = &(g_sprite_list[vehicle->peep].peep);
|
||||
ride->race_winner = peep->sprite_index;
|
||||
ride->var_14D |= 12;
|
||||
}
|
||||
|
||||
// Race is over
|
||||
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Continue racing
|
||||
ride->station_depart[stationIndex] |= STATION_DEPART_FLAG;
|
||||
} else {
|
||||
// Check if all vehicles are ready to go
|
||||
for (i = 0; i < ride->num_vehicles; i++) {
|
||||
vehicle = &(g_sprite_list[ride->vehicles[i]].vehicle);
|
||||
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART && vehicle->status != VEHICLE_STATUS_DEPARTING) {
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Begin the race
|
||||
ride_race_init_vehicle_speeds(ride);
|
||||
ride->lifecycle_flags |= VEHICLE_STATUS_WAITING_TO_DEPART;
|
||||
ride->var_14D = 12;
|
||||
} else {
|
||||
dh = ride->var_0D0;
|
||||
for (i = 0; i < ride->num_vehicles; i++) {
|
||||
vehicle = &(g_sprite_list[ride->vehicles[i]].vehicle);
|
||||
if (vehicle->status != VEHICLE_STATUS_WAITING_TO_DEPART && dh <= vehicle->var_CE) {
|
||||
ride->lifecycle_flags &= ~VEHICLE_STATUS_WAITING_TO_DEPART;
|
||||
if (vehicle->var_B3 != 0) {
|
||||
peep = &(g_sprite_list[vehicle->peep].peep);
|
||||
ride->race_winner = peep->sprite_index;
|
||||
ride->var_14D = 12;
|
||||
}
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
|
||||
ride->station_depart[stationIndex] |= STATION_DEPART_FLAG;
|
||||
ride->var_14D |= 12;
|
||||
}
|
||||
dl = 1;
|
||||
sub_6AC2AF(ride, stationIndex, dl);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,18 +285,6 @@ static void ride_invalidate_station_start(rct_ride *ride, int stationIndex, int
|
||||
map_invalidate_tile(x, y, mapElement->base_height * 8, mapElement->clearance_height * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC2AF
|
||||
*/
|
||||
static void sub_6AC2AF(rct_ride *ride, int stationIndex, int dl)
|
||||
{
|
||||
if (dl != 0)
|
||||
ride->var_062[stationIndex] |= (1 << 7);
|
||||
else
|
||||
ride->var_062[stationIndex] &= ~(1 << 7);
|
||||
}
|
||||
|
||||
rct_map_element *ride_get_station_start_track_element(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int x, y, z;
|
||||
|
||||
@@ -76,7 +76,10 @@ typedef struct {
|
||||
uint8 pad_C3[0x09];
|
||||
uint8 var_CC;
|
||||
uint8 var_CD;
|
||||
uint8 var_CE;
|
||||
union {
|
||||
uint8 var_CE;
|
||||
uint8 num_laps; // 0xCE
|
||||
};
|
||||
uint8 pad_CF[0x07];
|
||||
uint8 var_D6;
|
||||
} rct_vehicle;
|
||||
|
||||
Reference in New Issue
Block a user