1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-24 07:14:31 +01:00

implement ride_update_max_vehicles

This commit is contained in:
IntelOrca
2015-06-29 15:13:42 +01:00
parent 380d459dfb
commit 4ada15c972
5 changed files with 181 additions and 30 deletions

View File

@@ -33,7 +33,7 @@ enum GAME_COMMAND {
GAME_COMMAND_6,
GAME_COMMAND_DEMOLISH_RIDE,
GAME_COMMAND_SET_RIDE_STATUS, // 8
GAME_COMMAND_9,
GAME_COMMAND_SET_RIDE_VEHICLES,
GAME_COMMAND_SET_RIDE_NAME,
GAME_COMMAND_SET_RIDE_SETTING,
GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT,

View File

@@ -3363,7 +3363,7 @@ void game_command_set_ride_setting(int *eax, int *ebx, int *ecx, int *edx, int *
}
ride->mode = new_value;
RCT2_CALLPROC_X(0x6DD57D, 0, 0, 0, ride_id, 0, 0, 0);
ride_update_max_vehicles(ride_id);
break;
case 1:
ride->depart_flags = new_value;
@@ -5066,19 +5066,169 @@ void ride_entry_get_train_layout(int rideEntryIndex, int numCarsPerTrain, uint8
for (int i = 0; i < numCarsPerTrain; i++) {
uint8 vehicleType = rideEntry->default_vehicle;
if (i == 0) {
if (rideEntry->front_vehicle != 255)
vehicleType = rideEntry->front_vehicle;
} else if (i == 1) {
if (rideEntry->second_vehicle != 255)
vehicleType = rideEntry->second_vehicle;
} else if (i == 2) {
if (rideEntry->third_vehicle != 255)
vehicleType = rideEntry->third_vehicle;
} else if (i == numCarsPerTrain - 1) {
if (rideEntry->rear_vehicle != 255)
vehicleType = rideEntry->rear_vehicle;
if (i == 0 && rideEntry->front_vehicle != 255) {
vehicleType = rideEntry->front_vehicle;
} else if (i == 1 && rideEntry->second_vehicle != 255) {
vehicleType = rideEntry->second_vehicle;
} else if (i == 2 && rideEntry->third_vehicle != 255) {
vehicleType = rideEntry->third_vehicle;
} else if (i == numCarsPerTrain - 1 && rideEntry->rear_vehicle != 255) {
vehicleType = rideEntry->rear_vehicle;
}
trainLayout[i] = vehicleType;
}
}
int ride_get_smallest_station_length(rct_ride *ride)
{
uint32 result = -1;
for (int i = 0; i < 4; i++) {
if (ride->station_starts[i] != 0xFFFF) {
result = min(result, (uint32)(ride->station_length[i] & 0x0F));
}
}
return (int)result;
}
static int sub_6CB3AA(rct_ride *ride)
{
int eax, ebx, ecx, edx, esi, edi, ebp;
edi = (int)ride;
RCT2_CALLFUNC_X(0x006CB3AA, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
return eax;
}
/**
*
* rct2: 0x006DD57D
*/
void ride_update_max_vehicles(int rideIndex)
{
rct_ride *ride;
rct_ride_type *rideEntry;
rct_ride_type_vehicle *vehicleEntry;
uint8 trainLayout[16], numCarsPerTrain, numVehicles;
int trainLength, maxNumTrains;
ride = GET_RIDE(rideIndex);
if (ride->subtype == 0xFF)
return;
rideEntry = GET_RIDE_ENTRY(ride->subtype);
if (rideEntry->cars_per_flat_ride == 0xFF) {
ride->num_cars_per_train = max(rideEntry->min_cars_in_train, ride->num_cars_per_train);
ride->min_max_cars_per_train = rideEntry->max_cars_in_train | (rideEntry->min_cars_in_train << 4);
// Calculate maximum train length based on smallest station length
int stationLength = ride_get_smallest_station_length(ride);
if (stationLength == -1)
return;
stationLength = (stationLength * 0x44180) - 0x16B2A;
int maxFriction = RCT2_GLOBAL(0x0097D21B + (ride->type * 8), uint8) << 8;
int maxCarsPerTrain = 1;
for (int numCars = rideEntry->max_cars_in_train; numCars > 0; numCars--) {
ride_entry_get_train_layout(ride->subtype, numCars, trainLayout);
trainLength = 0;
int totalFriction = 0;
for (int i = 0; i < numCars; i++) {
vehicleEntry = &rideEntry->vehicles[trainLayout[i]];
trainLength += vehicleEntry->var_04;
totalFriction += vehicleEntry->var_08;
}
if (trainLength <= stationLength && totalFriction <= maxFriction) {
maxCarsPerTrain = numCars;
break;
}
}
maxCarsPerTrain = max(maxCarsPerTrain, rideEntry->min_cars_in_train);
ride->min_max_cars_per_train = maxCarsPerTrain | (rideEntry->min_cars_in_train << 4);
switch (ride->mode) {
case RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED:
case RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED:
maxNumTrains = clamp(1, ride->num_stations + ride->num_block_brakes - 1, 31);
break;
case RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE:
case RIDE_MODE_POWERED_LAUNCH_PASSTROUGH:
case RIDE_MODE_SHUTTLE:
case RIDE_MODE_LIM_POWERED_LAUNCH:
case RIDE_MODE_POWERED_LAUNCH:
maxNumTrains = 1;
break;
default:
// Calculate maximum number of trains
ride_entry_get_train_layout(ride->subtype, maxCarsPerTrain, trainLayout);
trainLength = 0;
for (int i = 0; i < maxCarsPerTrain; i++) {
vehicleEntry = &rideEntry->vehicles[trainLayout[i]];
trainLength += vehicleEntry->var_04;
}
int totalLength = trainLength / 2;
if (maxCarsPerTrain != 1)
totalLength /= 2;
maxNumTrains = 0;
do {
maxNumTrains++;
totalLength += trainLength;
} while (totalLength <= stationLength);
if (
(ride->mode != RIDE_MODE_STATION_TO_STATION && ride->mode != RIDE_MODE_CONTINUOUS_CIRCUIT) ||
!(RCT2_GLOBAL(0x0097D4F2 + (ride->type * 8), uint16) & 0x40)
) {
maxNumTrains = min(maxNumTrains, 31);
} else {
ride_entry_get_train_layout(ride->subtype, maxCarsPerTrain, trainLayout);
vehicleEntry = &rideEntry->vehicles[trainLayout[0]];
int unk = vehicleEntry->var_5C;
int totalSpacing = 0;
for (int i = 0; i < maxCarsPerTrain; i++) {
vehicleEntry = &rideEntry->vehicles[trainLayout[i]];
totalSpacing += vehicleEntry->var_04;
}
totalSpacing >>= 13;
int unk2 = sub_6CB3AA(ride) / 4;
if (unk > 10) {
unk2 = (unk2 * 3) / 4;
}
if (unk > 25) {
unk2 = (unk2 * 3) / 4;
}
if (unk > 40) {
unk2 = (unk2 * 3) / 4;
}
maxNumTrains = 0;
int unk3 = 0;
do {
maxNumTrains++;
unk3 += totalSpacing;
} while (maxNumTrains < 31 && unk3 < unk2);
}
break;
}
ride->max_trains = maxNumTrains;
numCarsPerTrain = min(ride->var_0CB, maxCarsPerTrain);
numVehicles = min(ride->var_0CA, maxNumTrains);
} else {
ride->max_trains = rideEntry->cars_per_flat_ride;
ride->min_max_cars_per_train = rideEntry->max_cars_in_train | (rideEntry->min_cars_in_train << 4);
numCarsPerTrain = rideEntry->max_cars_in_train;
numVehicles = min(ride->var_0CA, rideEntry->cars_per_flat_ride);
}
// Refresh new current num vehicles / num cars per vehicle
if (numVehicles != ride->num_vehicles || numCarsPerTrain != ride->num_cars_per_train) {
ride->num_cars_per_train = numCarsPerTrain;
ride->num_vehicles = numVehicles;
window_invalidate_by_number(WC_RIDE, rideIndex);
}
}

View File

@@ -154,7 +154,7 @@ typedef struct {
uint16 overall_view; // 0x050 00XX = X, XX00 = Y (* 32 + 16)
uint16 station_starts[4]; // 0x052
uint8 station_heights[4]; // 0x05A
uint8 pad_05E[0x4];
uint8 station_length[4]; // 0x05E
uint8 station_depart[4]; // 0x062
uint8 var_066[4];
uint16 entrances[4]; // 0x06A
@@ -168,9 +168,10 @@ typedef struct {
uint8 num_stations; // 0x0C7
uint8 num_vehicles; // 0x0C8
uint8 num_cars_per_train; // 0x0C9
uint8 pad_0CA[0x2];
uint8 var_0CC;
uint8 var_0CD;
uint8 var_0CA;
uint8 var_0CB;
uint8 max_trains; // 0x0CC
uint8 min_max_cars_per_train; // 0x0CD
uint8 min_waiting_time; // 0x0CE
uint8 max_waiting_time; // 0x0CF
union {
@@ -938,5 +939,6 @@ bool ride_are_all_possible_entrances_and_exits_built(rct_ride *ride);
void ride_fix_breakdown(int rideIndex, int reliabilityIncreaseFactor);
void ride_entry_get_train_layout(int rideEntryIndex, int numCarsPerTrain, uint8 *trainLayout);
void ride_update_max_vehicles(int rideIndex);
#endif

View File

@@ -3250,14 +3250,14 @@ void game_command_place_track_design(int* eax, int* ebx, int* ecx, int* edx, int
}
if (entry_index != 0xFF){
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (2 << 8), 0, rideIndex | (entry_index << 8), GAME_COMMAND_9, 0, 0);
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (2 << 8), 0, rideIndex | (entry_index << 8), GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0);
}
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (track_design->ride_mode << 8), 0, rideIndex | (0 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0);
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (0 << 8), 0, rideIndex | (track_design->number_of_trains << 8), GAME_COMMAND_9, 0, 0);
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (0 << 8), 0, rideIndex | (track_design->number_of_trains << 8), GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0);
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (1 << 8), 0, rideIndex | (track_design->number_of_cars_per_train << 8), GAME_COMMAND_9, 0, 0);
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (1 << 8), 0, rideIndex | (track_design->number_of_cars_per_train << 8), GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0);
game_do_command(0, GAME_COMMAND_FLAG_APPLY | (track_design->depart_flags << 8), 0, rideIndex | (1 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0);

View File

@@ -1419,9 +1419,8 @@ static void window_ride_set_page(rct_window *w, int page)
w->frame_no = 0;
w->var_492 = 0;
if (page == WINDOW_RIDE_PAGE_VEHICLE){
// Reload the vehicle settings
RCT2_CALLPROC_X(0x006DD57D, 0, 0, 0, w->number, 0, 0, 0);
if (page == WINDOW_RIDE_PAGE_VEHICLE) {
ride_update_max_vehicles(w->number);
}
if (w->viewport != NULL) {
@@ -2401,7 +2400,7 @@ static void window_ride_vehicle_mousedown(int widgetIndex, rct_window *w, rct_wi
dropdownWidget->bottom - dropdownWidget->top + 1,
w->colours[1],
DROPDOWN_FLAG_STAY_OPEN,
ride->var_0CC,
ride->max_trains,
widget->right - dropdownWidget->left
);
@@ -2414,8 +2413,8 @@ static void window_ride_vehicle_mousedown(int widgetIndex, rct_window *w, rct_wi
gDropdownItemsChecked = (1 << (ride->num_vehicles - 1));
break;
case WIDX_VEHICLE_CARS_PER_TRAIN_DROPDOWN:
minCars = (ride->var_0CD >> 4);
maxCars = (ride->var_0CD & 0x0F);
minCars = (ride->min_max_cars_per_train >> 4);
maxCars = (ride->min_max_cars_per_train & 0x0F);
window_dropdown_show_text_custom_width(
w->x + dropdownWidget->left,
@@ -2466,15 +2465,15 @@ static void window_ride_vehicle_dropdown()
dropdownIndex = (gDropdownItemsArgs[dropdownIndex] >> 16) & 0xFFFF;
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 1018;
game_do_command(0, (2 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_9, 0, 0);
game_do_command(0, (2 << 8) | 1, 0, (dropdownIndex << 8) | w->number, GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0);
break;
case WIDX_VEHICLE_TRAINS_DROPDOWN:
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 1020;
game_do_command(0, (0 << 8) | 1, 0, ((dropdownIndex + 1) << 8) | w->number, GAME_COMMAND_9, 0, 0);
game_do_command(0, (0 << 8) | 1, 0, ((dropdownIndex + 1) << 8) | w->number, GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0);
break;
case WIDX_VEHICLE_CARS_PER_TRAIN_DROPDOWN:
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 1019;
game_do_command(0, (1 << 8) | 1, 0, ((rideEntry->min_cars_in_train + dropdownIndex) << 8) | w->number, GAME_COMMAND_9, 0, 0);
game_do_command(0, (1 << 8) | 1, 0, ((rideEntry->min_cars_in_train + dropdownIndex) << 8) | w->number, GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0);
break;
}
}