mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-10 09:32:29 +01:00
Merge branch 'set-ride-status' into develop
Conflicts: src/ride/track.h
This commit is contained in:
@@ -840,7 +840,7 @@ static uint32 game_do_command_table[58] = {
|
||||
0,
|
||||
0x006B3F0F,
|
||||
0x006B49D9,
|
||||
0x006B4EA6,
|
||||
0,
|
||||
0x006B52D4,
|
||||
0, // 10
|
||||
0x006B5559,
|
||||
@@ -903,7 +903,7 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
|
||||
game_load_or_quit,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_emptysub,
|
||||
game_command_set_ride_status,
|
||||
game_command_emptysub,
|
||||
game_command_set_ride_name, // 10
|
||||
game_command_emptysub,
|
||||
|
||||
@@ -30,7 +30,7 @@ enum GAME_COMMAND {
|
||||
GAME_COMMAND_LOAD_OR_QUIT, // 5
|
||||
GAME_COMMAND_6,
|
||||
GAME_COMMAND_7,
|
||||
GAME_COMMAND_SET_RIDE_OPEN, // 8
|
||||
GAME_COMMAND_SET_RIDE_STATUS, // 8
|
||||
GAME_COMMAND_9,
|
||||
GAME_COMMAND_SET_RIDE_NAME,
|
||||
GAME_COMMAND_11,
|
||||
|
||||
@@ -324,6 +324,7 @@ int viewport_interaction_right_over(int x, int y)
|
||||
*/
|
||||
int viewport_interaction_right_click(int x, int y)
|
||||
{
|
||||
rct_xy_element mapElement;
|
||||
viewport_interaction_info info;
|
||||
|
||||
switch (viewport_interaction_get_item_right(x, y, &info)) {
|
||||
@@ -335,7 +336,10 @@ int viewport_interaction_right_click(int x, int y)
|
||||
ride_construct(info.sprite->vehicle.ride);
|
||||
break;
|
||||
case VIEWPORT_INTERACTION_ITEM_RIDE:
|
||||
ride_modify(info.mapElement, info.x, info.y);
|
||||
mapElement.x = info.x;
|
||||
mapElement.y = info.y;
|
||||
mapElement.element = info.mapElement;
|
||||
ride_modify(&mapElement);
|
||||
break;
|
||||
case VIEWPORT_INTERACTION_ITEM_SCENERY:
|
||||
viewport_interaction_remove_scenery(info.mapElement, info.x, info.y);
|
||||
|
||||
@@ -167,6 +167,10 @@ enum {
|
||||
STR_OVERALL_VIEW = 996,
|
||||
STR_VIEW_SELECTION = 997,
|
||||
|
||||
STR_REQUIRES_A_STATION_PLATFORM = 999,
|
||||
STR_TRACK_IS_NOT_A_COMPLETE_CIRCUIT = 1000,
|
||||
STR_TRACK_UNSUITABLE_FOR_TYPE_OF_TRAIN = 1001,
|
||||
|
||||
STR_CANT_OPEN = 1002,
|
||||
STR_CANT_TEST = 1003,
|
||||
STR_CANT_CLOSE = 1004,
|
||||
@@ -438,6 +442,9 @@ enum {
|
||||
STR_GUESTS = 1463,
|
||||
|
||||
STR_STAFF = 1468,
|
||||
|
||||
STR_RIDE_MUST_START_AND_END_WITH_STATIONS = 1469,
|
||||
STR_STATION_NOT_LONG_ENOUGH = 1470,
|
||||
|
||||
STR_SPEED = 1471,
|
||||
STR_SPEED_TIP = 1472,
|
||||
@@ -503,6 +510,8 @@ enum {
|
||||
STR_RACE_WON_BY_GUEST = 1739,
|
||||
STR_RACE_WON_BY = 1740,
|
||||
|
||||
STR_NOT_YET_CONSTRUCTED = 1741,
|
||||
|
||||
STR_MAX_PEOPLE_ON_RIDE = 1742,
|
||||
STR_MAX_PEOPLE_ON_RIDE_TIP = 1743,
|
||||
|
||||
@@ -1255,6 +1264,10 @@ enum {
|
||||
|
||||
STR_SET_STARTING_POSITIONS_TIP = 3228,
|
||||
|
||||
STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_STATION = 3229,
|
||||
STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_EACH_OTHER = 3230,
|
||||
STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_THE_TOP_OF_THIS_LIFT_HILL = 3231,
|
||||
|
||||
STR_SCENARIO_OPTIONS_FINANCIAL = 3232,
|
||||
STR_SCENARIO_OPTIONS_GUESTS = 3233,
|
||||
STR_SCENARIO_OPTIONS_PARK = 3234,
|
||||
|
||||
756
src/ride/ride.c
756
src/ride/ride.c
@@ -37,6 +37,7 @@
|
||||
#include "../world/sprite.h"
|
||||
#include "ride.h"
|
||||
#include "ride_data.h"
|
||||
#include "track.h"
|
||||
#include "station.h"
|
||||
|
||||
#pragma region Ride classification table
|
||||
@@ -265,13 +266,13 @@ money32 ride_calculate_income_per_hour(rct_ride *ride)
|
||||
* dl ride index
|
||||
* esi result map element
|
||||
*/
|
||||
rct_map_element *sub_6CAF80(int rideIndex, int *outX, int *outY)
|
||||
int sub_6CAF80(int rideIndex, rct_xy_element *output)
|
||||
{
|
||||
map_element_iterator it;
|
||||
rct_map_element *resultMapElement;
|
||||
int foundSpecialTrackPiece;
|
||||
|
||||
resultMapElement = (rct_map_element*)-1;
|
||||
resultMapElement = NULL;
|
||||
foundSpecialTrackPiece = 0;
|
||||
|
||||
map_element_iterator_begin(&it);
|
||||
@@ -283,51 +284,99 @@ rct_map_element *sub_6CAF80(int rideIndex, int *outX, int *outY)
|
||||
|
||||
// Found a track piece for target ride
|
||||
|
||||
// Check if its a ???
|
||||
// Check if its not the station or ??? (but allow end piece of station)
|
||||
int specialTrackPiece = (
|
||||
(it.element->properties.track.type != 2 && it.element->properties.track.type != 3) &&
|
||||
it.element->properties.track.type != 2 &&
|
||||
it.element->properties.track.type != 3 &&
|
||||
(RCT2_ADDRESS(0x0099BA64, uint8)[it.element->properties.track.type * 16] & 0x10)
|
||||
);
|
||||
|
||||
// Set result tile to this track piece if first found track or a ???
|
||||
if (resultMapElement == (rct_map_element*)-1 || specialTrackPiece) {
|
||||
if (resultMapElement == NULL || specialTrackPiece) {
|
||||
resultMapElement = it.element;
|
||||
|
||||
if (outX != NULL) *outX = it.x * 32;
|
||||
if (outY != NULL) *outY = it.y * 32;
|
||||
if (output != NULL) {
|
||||
output->element = resultMapElement;
|
||||
output->x = it.x * 32;
|
||||
output->y = it.y * 32;
|
||||
}
|
||||
}
|
||||
|
||||
if (specialTrackPiece) {
|
||||
foundSpecialTrackPiece = 1;
|
||||
return resultMapElement;
|
||||
return 1;
|
||||
}
|
||||
} while (map_element_iterator_next(&it));
|
||||
|
||||
return resultMapElement;
|
||||
return resultMapElement != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C60C2
|
||||
*/
|
||||
int track_get_next(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp, result;
|
||||
|
||||
eax = input->x;
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006C60C2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = *((uint16*)&eax);
|
||||
output->y = *((uint16*)&ecx);
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Make sure to pass in the x and y of the start track element too.
|
||||
* rct2: 0x006CB02F
|
||||
* ax result x
|
||||
* bx result y
|
||||
* esi input / output map element
|
||||
*/
|
||||
rct_map_element *ride_find_track_gap(rct_map_element *startTrackElement, int *outX, int *outY)
|
||||
int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
esi = (int)startTrackElement;
|
||||
eax = *outX;
|
||||
ebx = 0;
|
||||
ecx = *outY;
|
||||
edx = 0;
|
||||
edi = 0;
|
||||
ebp = 0;
|
||||
RCT2_CALLFUNC_X(0x006CB02F, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
int rideIndex;
|
||||
rct_xy_element trackElement, nextTrackElement;
|
||||
rct_map_element *loopTrackElement;
|
||||
rct_ride *ride;
|
||||
rct_window *w;
|
||||
|
||||
if (outX != NULL) *outX = eax & 0xFFFF;
|
||||
if (outY != NULL) *outY = ecx & 0xFFFF;
|
||||
return (rct_map_element*)esi;
|
||||
trackElement = *input;
|
||||
rideIndex = trackElement.element->properties.track.ride_index;
|
||||
ride = GET_RIDE(rideIndex);
|
||||
|
||||
if (ride->type == RIDE_TYPE_MAZE)
|
||||
return 0;
|
||||
|
||||
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
|
||||
if (w != NULL && RCT2_GLOBAL(0x00F440A6, uint8) != 0 && RCT2_GLOBAL(0x00F440A7, uint8) == rideIndex)
|
||||
sub_6C9627();
|
||||
|
||||
loopTrackElement = NULL;
|
||||
while (1) {
|
||||
if (!track_get_next(&trackElement, &nextTrackElement)) {
|
||||
*output = trackElement;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!track_is_connected_by_shape(trackElement.element, nextTrackElement.element)) {
|
||||
*output = nextTrackElement;
|
||||
return 1;
|
||||
}
|
||||
|
||||
trackElement = nextTrackElement;
|
||||
if (loopTrackElement == NULL)
|
||||
loopTrackElement = trackElement.element;
|
||||
else if (loopTrackElement == trackElement.element)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -855,13 +904,15 @@ int ride_modify_maze(rct_map_element *mapElement, int x, int y)
|
||||
*
|
||||
* rct2: 0x006CC056
|
||||
*/
|
||||
int ride_modify(rct_map_element *mapElement, int x, int y)
|
||||
int ride_modify(rct_xy_element *input)
|
||||
{
|
||||
int rideIndex, z, direction, type;
|
||||
int rideIndex, x, y, z, direction, type;
|
||||
rct_xy_element mapElement, endOfTrackElement;
|
||||
rct_ride *ride;
|
||||
rct_window *constructionWindow;
|
||||
|
||||
rideIndex = mapElement->properties.track.ride_index;
|
||||
mapElement = *input;
|
||||
rideIndex = mapElement.element->properties.track.ride_index;
|
||||
ride = GET_RIDE(rideIndex);
|
||||
|
||||
if (!ride_check_if_construction_allowed(ride))
|
||||
@@ -885,24 +936,27 @@ int ride_modify(rct_map_element *mapElement, int x, int y)
|
||||
ride_remove_peeps(rideIndex);
|
||||
|
||||
// Check if element is a station entrance or exit
|
||||
if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE)
|
||||
return ride_modify_entrance_or_exit(mapElement, x, y);
|
||||
if (map_element_get_type(mapElement.element) == MAP_ELEMENT_TYPE_ENTRANCE)
|
||||
return ride_modify_entrance_or_exit(mapElement.element, mapElement.x, mapElement.y);
|
||||
|
||||
constructionWindow = ride_create_or_find_construction_window(rideIndex);
|
||||
|
||||
if (ride->type == RIDE_TYPE_MAZE)
|
||||
return ride_modify_maze(mapElement, x, y);
|
||||
return ride_modify_maze(mapElement.element, mapElement.x, mapElement.y);
|
||||
|
||||
if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS,uint64)[ride->type] & 0x100) {
|
||||
int outX = x, outY = y;
|
||||
mapElement = ride_find_track_gap(mapElement, &outX, &outY);
|
||||
if (ride_find_track_gap(&mapElement, &endOfTrackElement))
|
||||
mapElement = endOfTrackElement;
|
||||
}
|
||||
|
||||
z = mapElement->base_height * 8;
|
||||
direction = mapElement->type & 3;
|
||||
type = mapElement->properties.track.type;
|
||||
x = mapElement.x;
|
||||
y = mapElement.y;
|
||||
z = mapElement.element->base_height * 8;
|
||||
direction = mapElement.element->type & 3;
|
||||
type = mapElement.element->properties.track.type;
|
||||
|
||||
if (sub_6C683D(&x, &y, z, direction, type, 0, 0, 0)) return 0;
|
||||
if (sub_6C683D(&x, &y, z, direction, type, 0, 0, 0))
|
||||
return 0;
|
||||
|
||||
RCT2_GLOBAL(0x00F440A7, uint8) = rideIndex;
|
||||
RCT2_GLOBAL(0x00F440A6, uint8) = 3;
|
||||
@@ -1924,7 +1978,7 @@ rct_ride_measurement *ride_get_existing_measurement(int rideIndex)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rct_ride_measurement *ride_get_free_measurement()
|
||||
int ride_get_free_measurement()
|
||||
{
|
||||
int i;
|
||||
rct_ride_measurement *measurement;
|
||||
@@ -1932,10 +1986,10 @@ rct_ride_measurement *ride_get_free_measurement()
|
||||
for (i = 0; i < MAX_RIDE_MEASUREMENTS; i++) {
|
||||
measurement = GET_RIDE_MEASUREMENT(i);
|
||||
if (measurement->ride_index == 255)
|
||||
return measurement;
|
||||
return i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1961,8 +2015,8 @@ rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message
|
||||
measurement = ride_get_existing_measurement(rideIndex);
|
||||
if (measurement == NULL) {
|
||||
// Find a free measurement
|
||||
measurement = ride_get_free_measurement();
|
||||
if (measurement == NULL) {
|
||||
i = ride_get_free_measurement();
|
||||
if (i == -1) {
|
||||
// Use last recently used measurement for some other ride
|
||||
lruIndex = 0;
|
||||
lruTicks = 0xFFFFFFFF;
|
||||
@@ -1977,9 +2031,11 @@ rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message
|
||||
|
||||
i = lruIndex;
|
||||
measurement = GET_RIDE_MEASUREMENT(i);
|
||||
ride->measurement_index = 255;
|
||||
GET_RIDE(measurement->ride_index)->measurement_index = 255;
|
||||
} else {
|
||||
measurement = GET_RIDE_MEASUREMENT(i);
|
||||
}
|
||||
|
||||
|
||||
measurement->ride_index = rideIndex;
|
||||
ride->measurement_index = i;
|
||||
measurement->flags = 0;
|
||||
@@ -2690,6 +2746,624 @@ void ride_music_update_final()
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4CC1
|
||||
*/
|
||||
int ride_mode_check_valid_station_numbers(rct_ride *ride)
|
||||
{
|
||||
uint8 no_stations = 0;
|
||||
for (uint8 station_index = 0; station_index < 4; ++station_index){
|
||||
if (ride->station_starts[station_index] != 0xFFFF)no_stations++;
|
||||
}
|
||||
|
||||
switch (ride->mode){
|
||||
case RIDE_MODE_REVERSE_INCLINE_LAUNCHED_SHUTTLE:
|
||||
case RIDE_MODE_POWERED_LAUNCH:
|
||||
case RIDE_MODE_POWERED_LAUNCH_35:
|
||||
case RIDE_MODE_LIM_POWERED_LAUNCH:
|
||||
if (no_stations <= 1) return 1;
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1015;
|
||||
return 0;
|
||||
case RIDE_MODE_SHUTTLE:
|
||||
if (no_stations >= 2) return 1;
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1016;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ride->type == RIDE_TYPE_GO_KARTS || ride->type == RIDE_TYPE_MINI_GOLF){
|
||||
if (no_stations <= 1) return 1;
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1015;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns stationIndex of first station on success
|
||||
* -1 on failure.
|
||||
*/
|
||||
int ride_mode_check_station_present(rct_ride* ride){
|
||||
int stationIndex = -1;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (ride->station_starts[i] != 0xFFFF) {
|
||||
stationIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stationIndex == -1) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_NOT_YET_CONSTRUCTED;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32) & 0x8000)
|
||||
return -1;
|
||||
|
||||
if (ride->type == RIDE_TYPE_MAZE)
|
||||
return -1;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_REQUIRES_A_STATION_PLATFORM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return stationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B5872
|
||||
*/
|
||||
int ride_check_for_entrance_exit(int rideIndex)
|
||||
{
|
||||
rct_ride* ride = GET_RIDE(rideIndex);
|
||||
|
||||
if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & 0x20000) return 1;
|
||||
|
||||
int i;
|
||||
uint8 entrance = 0;
|
||||
uint8 exit = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ride->station_starts[i] == 0xFFFF)
|
||||
continue;
|
||||
|
||||
if (ride->entrances[i] != 0xFFFF) {
|
||||
entrance = 1;
|
||||
}
|
||||
|
||||
if (ride->exits[i] != 0xFFFF) {
|
||||
exit = 1;
|
||||
}
|
||||
|
||||
// If station start and no entrance/exit
|
||||
// Sets same error message as no entrance
|
||||
if (ride->exits[i] == 0xFFFF && ride->entrances[i] == 0xFFFF){
|
||||
entrance = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entrance == 0){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1146;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (exit == 0){
|
||||
RCT2_GLOBAL(0x141E9AC, uint16) = 1147;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B5952
|
||||
*/
|
||||
void sub_6B5952(int rideIndex)
|
||||
{
|
||||
RCT2_CALLPROC_X(0x006B5952, 0, 0, 0, rideIndex, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006D3319
|
||||
*/
|
||||
int ride_check_block_brakes(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
// return RCT2_CALLPROC_X(0x006D3319, x, 0, y, 0, (int)mapElement, 0, 0) & 0x100;
|
||||
|
||||
int rideIndex, type;
|
||||
rct_xy_element trackElement, nextTrackElement;
|
||||
rct_map_element *loopTrackElement;
|
||||
rct_window *w;
|
||||
|
||||
trackElement = *input;
|
||||
rideIndex = trackElement.element->properties.track.ride_index;
|
||||
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
|
||||
if (w != NULL && RCT2_GLOBAL(0x00F440A6, uint8) != 0 && RCT2_GLOBAL(0x00F440A7, uint8) == rideIndex)
|
||||
sub_6C9627();
|
||||
|
||||
loopTrackElement = NULL;
|
||||
while (1) {
|
||||
if (!track_get_next(&trackElement, &nextTrackElement)) {
|
||||
// Not sure why this is the case...
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_STATION;
|
||||
*output = trackElement;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nextTrackElement.element->properties.track.type == 216) {
|
||||
type = trackElement.element->properties.track.type;
|
||||
if (type == 1) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_STATION;
|
||||
*output = nextTrackElement;
|
||||
return 0;
|
||||
}
|
||||
if (type == 216) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_EACH_OTHER;
|
||||
*output = nextTrackElement;
|
||||
return 0;
|
||||
}
|
||||
if ((trackElement.element->type & 0x80) && type != 209 && type != 210) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_BLOCK_BRAKES_CANNOT_BE_USED_DIRECTLY_AFTER_THE_TOP_OF_THIS_LIFT_HILL;
|
||||
*output = nextTrackElement;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
trackElement = nextTrackElement;
|
||||
if (loopTrackElement == NULL)
|
||||
loopTrackElement = trackElement.element;
|
||||
else if (loopTrackElement == trackElement.element)
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CB149
|
||||
*/
|
||||
int ride_check_track_suitability_a(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp, result;
|
||||
|
||||
eax = input->x;
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB149, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CB1D3
|
||||
*/
|
||||
int ride_check_track_suitability_b(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp, result;
|
||||
|
||||
eax = input->x;
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB1D3, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CB25D
|
||||
*/
|
||||
int ride_check_station_length(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp, result;
|
||||
|
||||
// This function has a bug. If the station length is too short and it is
|
||||
// the last station of a ride it will return a pointer to the map_element
|
||||
// where the station piece should go. Instead it should pass the map_element
|
||||
// of the last good station piece. This can cause null pointer dereferences
|
||||
// and cause the map to move to the top left hand corner.
|
||||
eax = input->x;
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB25D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006CB2DA
|
||||
*/
|
||||
int ride_check_start_and_end_is_station(rct_xy_element *input, rct_xy_element *output)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp, result;
|
||||
|
||||
eax = input->x;
|
||||
ecx = input->y;
|
||||
esi = (int)input->element;
|
||||
result = RCT2_CALLFUNC_X(0x006CB2DA, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
output->x = (uint16)eax;
|
||||
output->y = (uint16)ecx;
|
||||
output->element = (rct_map_element*)esi;
|
||||
|
||||
return (result & 0x100) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4D26
|
||||
*/
|
||||
void sub_6B4D26(int rideIndex, rct_xy_element *startElement)
|
||||
{
|
||||
RCT2_CALLPROC_X(0x006B4D26, startElement->x, 0, startElement->y, rideIndex, (int)startElement->element, 0, 0); return;
|
||||
|
||||
rct_xy_element currentElement;
|
||||
rct_ride *ride;
|
||||
int trackType;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
if (ride->type == RIDE_TYPE_BUMPER_BOATS) {
|
||||
|
||||
} else if (ride->type != RIDE_TYPE_MAZE) {
|
||||
|
||||
}
|
||||
|
||||
if (
|
||||
(
|
||||
ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED ||
|
||||
ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED
|
||||
) &&
|
||||
!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)
|
||||
) {
|
||||
// Set flag on track pieces where a train can start
|
||||
currentElement = *startElement;
|
||||
do {
|
||||
trackType = currentElement.element->properties.track.type;
|
||||
switch (trackType) {
|
||||
case 1: // end of station
|
||||
case 123: // cable lift hill
|
||||
case 9: // 25deg up to flat
|
||||
case 63: // 60deg up to flat
|
||||
case 147: // diag 25deg up to flat
|
||||
case 155: // diag 60deg up to flat
|
||||
case 216: // block brakes
|
||||
currentElement.element->flags &= ~(1 << 5);
|
||||
break;
|
||||
}
|
||||
} while (track_get_next(¤tElement, ¤tElement) && currentElement.element != startElement->element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006DD84C
|
||||
*/
|
||||
int sub_6DD84C(rct_ride *ride, int rideIndex, rct_xy_element *element, int isApplying)
|
||||
{
|
||||
return RCT2_CALLPROC_X(0x006DD84C, element->x, isApplying, element->y, rideIndex, (int)ride, (int)element->element, 0) & 0x100;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006DF4D4
|
||||
*/
|
||||
int sub_6DF4D4(rct_ride *ride, rct_xy_element *element, int isApplying)
|
||||
{
|
||||
return RCT2_CALLPROC_X(0x006DF4D4, element->x, isApplying, element->y, 0, (int)ride, (int)element->element, 0) & 0x100;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B51C0
|
||||
*/
|
||||
void loc_6B51C0(int rideIndex)
|
||||
{
|
||||
int i, x, y, z;
|
||||
rct_ride *ride;
|
||||
rct_xy_element trackElement;
|
||||
rct_window *w;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
|
||||
if (RCT2_GLOBAL(0x0141F568, uint8) != RCT2_GLOBAL(0x013CA740, uint8))
|
||||
return;
|
||||
|
||||
w = window_get_main();
|
||||
if (w == NULL)
|
||||
return;
|
||||
|
||||
sint8 entranceOrExit = -1;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (ride->station_starts[i] == 0xFFFF)
|
||||
continue;
|
||||
|
||||
if (ride->entrances[i] == 0xFFFF) {
|
||||
entranceOrExit = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ride->exits[i] == 0xFFFF) {
|
||||
entranceOrExit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entranceOrExit == -1)
|
||||
return;
|
||||
|
||||
if (ride->type != RIDE_TYPE_MAZE) {
|
||||
x = (ride->station_starts[i] & 0xFF) * 32;
|
||||
y = (ride->station_starts[i] >> 8) * 32;
|
||||
z = ride->station_heights[i] * 8;
|
||||
window_scroll_to_location(w, x, y, z);
|
||||
|
||||
sub_6CAF80(rideIndex, &trackElement);
|
||||
ride_find_track_gap(&trackElement, &trackElement);
|
||||
ride_modify(&trackElement);
|
||||
|
||||
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
|
||||
if (w != NULL)
|
||||
window_event_mouse_up_call(w, 29 + entranceOrExit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B528A
|
||||
*/
|
||||
void loc_6B528A(rct_xy_element *trackElement)
|
||||
{
|
||||
rct_ride *ride;
|
||||
rct_window *w;
|
||||
|
||||
ride = GET_RIDE(trackElement->element->properties.track.ride_index);
|
||||
|
||||
if (RCT2_GLOBAL(0x0141F568, uint8) != RCT2_GLOBAL(0x013CA740, uint8))
|
||||
return;
|
||||
|
||||
w = window_get_main();
|
||||
if (w == NULL)
|
||||
return;
|
||||
|
||||
window_scroll_to_location(w, trackElement->x, trackElement->y, trackElement->element->base_height * 8);
|
||||
ride_modify(trackElement);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4F6B
|
||||
*/
|
||||
rct_map_element *loc_6B4F6B(int rideIndex, int x, int y)
|
||||
{
|
||||
rct_map_element *mapElement;
|
||||
|
||||
mapElement = map_get_first_element_at(x / 32, y / 32);
|
||||
do {
|
||||
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK)
|
||||
continue;
|
||||
|
||||
uint32 unk = mapElement->properties.track.type << 4;
|
||||
if (RCT2_GLOBAL(0x00F43484, uint32) & 0x80000) {
|
||||
if (!(RCT2_ADDRESS(0x0099CA64, uint8)[unk] & 0x10))
|
||||
continue;
|
||||
} else {
|
||||
if (!(RCT2_ADDRESS(0x0099BA64, uint8)[unk] & 0x10))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mapElement->properties.track.ride_index == rideIndex)
|
||||
return mapElement;
|
||||
} while (!map_element_is_last_for_tile(mapElement++));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4EEA
|
||||
*/
|
||||
int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying)
|
||||
{
|
||||
int stationIndex;
|
||||
rct_ride *ride;
|
||||
rct_xy_element trackElement, problematicTrackElement;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
|
||||
window_close_by_class(WC_RIDE_CONSTRUCTION);
|
||||
|
||||
stationIndex = ride_mode_check_station_present(ride);
|
||||
if (stationIndex == -1)return 0;
|
||||
|
||||
if (!ride_mode_check_valid_station_numbers(ride))
|
||||
return 0;
|
||||
|
||||
if (!ride_check_for_entrance_exit(rideIndex)) {
|
||||
loc_6B51C0(rideIndex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (goingToBeOpen && isApplying) {
|
||||
sub_6B5952(rideIndex);
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_EVER_BEEN_OPENED;
|
||||
}
|
||||
|
||||
// z = ride->station_heights[i] * 8;
|
||||
trackElement.x = (ride->station_starts[stationIndex] & 0xFF) * 32;
|
||||
trackElement.y = (ride->station_starts[stationIndex] >> 8) * 32;
|
||||
trackElement.element = loc_6B4F6B(rideIndex, trackElement.x, trackElement.y);
|
||||
if (trackElement.element == NULL) {
|
||||
// Maze is strange, station start is 0... investigation required
|
||||
if (ride->type != RIDE_TYPE_MAZE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (
|
||||
ride->type == RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER ||
|
||||
ride->mode == RIDE_MODE_RACE ||
|
||||
ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT ||
|
||||
ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED ||
|
||||
ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED
|
||||
) {
|
||||
if (ride_find_track_gap(&trackElement, &problematicTrackElement)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TRACK_IS_NOT_A_COMPLETE_CIRCUIT;
|
||||
loc_6B528A(&problematicTrackElement);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED ||
|
||||
ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED
|
||||
) {
|
||||
if (!ride_check_block_brakes(&trackElement, &problematicTrackElement)) {
|
||||
loc_6B528A(&problematicTrackElement);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ride->subtype != 255) {
|
||||
rct_ride_type *rideType = GET_RIDE_ENTRY(ride->subtype);
|
||||
if (rideType->var_008 & 2) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TRACK_UNSUITABLE_FOR_TYPE_OF_TRAIN;
|
||||
if (ride_check_track_suitability_a(&trackElement, &problematicTrackElement)) {
|
||||
loc_6B528A(&problematicTrackElement);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (rideType->var_008 & 4) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_TRACK_UNSUITABLE_FOR_TYPE_OF_TRAIN;
|
||||
if (ride_check_track_suitability_b(&trackElement, &problematicTrackElement)) {
|
||||
loc_6B528A(&problematicTrackElement);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ride->mode == RIDE_MODE_STATION_TO_STATION) {
|
||||
if (!ride_find_track_gap(&trackElement, &problematicTrackElement)) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_RIDE_MUST_START_AND_END_WITH_STATIONS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_STATION_NOT_LONG_ENOUGH;
|
||||
if (ride_check_station_length(&trackElement, &problematicTrackElement)) {
|
||||
|
||||
// This is to prevent a bug in the check_station_length function
|
||||
// remove when check_station_length is reveresed and fixed. Prevents
|
||||
// null dereference. Does not prevent moving screen to top left corner.
|
||||
if (map_element_get_type(problematicTrackElement.element) != MAP_ELEMENT_TYPE_TRACK)
|
||||
loc_6B528A(&trackElement);
|
||||
else loc_6B528A(&problematicTrackElement);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = STR_RIDE_MUST_START_AND_END_WITH_STATIONS;
|
||||
if (ride_check_start_and_end_is_station(&trackElement, &problematicTrackElement)) {
|
||||
loc_6B528A(&problematicTrackElement);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (isApplying)
|
||||
sub_6B4D26(rideIndex, &trackElement);
|
||||
|
||||
if (
|
||||
!(RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32) & 0x2000) &&
|
||||
!(ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)
|
||||
) {
|
||||
if (sub_6DD84C(ride, rideIndex, &trackElement, isApplying))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (
|
||||
(RCT2_GLOBAL(0x0097D4F2 + (ride->type * 8), uint32) & 0x400) &&
|
||||
(ride->lifecycle_flags & RIDE_LIFECYCLE_16) &&
|
||||
!(ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT)
|
||||
) {
|
||||
if (sub_6DF4D4(ride, &trackElement, isApplying))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ride_set_status(int rideIndex, int status)
|
||||
{
|
||||
game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, rideIndex | (status << 8), GAME_COMMAND_SET_RIDE_STATUS, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4EA6
|
||||
*/
|
||||
void game_command_set_ride_status(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp)
|
||||
{
|
||||
int rideIndex, targetStatus;
|
||||
rct_ride *ride;
|
||||
|
||||
rideIndex = *edx & 0xFF;
|
||||
targetStatus = (*edx >> 8) & 0xFF;
|
||||
|
||||
RCT2_GLOBAL(0x0141F56C, uint8) = 4;
|
||||
|
||||
ride = GET_RIDE(rideIndex);
|
||||
RCT2_GLOBAL(0x00F43484, uint32) = RCT2_GLOBAL(RCT2_ADDRESS_RIDE_FLAGS + (ride->type * 8), uint32);
|
||||
|
||||
switch (targetStatus) {
|
||||
case RIDE_STATUS_CLOSED:
|
||||
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
|
||||
if (ride->status == targetStatus) {
|
||||
if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) {
|
||||
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED;
|
||||
ride_clear_for_construction(rideIndex);
|
||||
ride_remove_peeps(rideIndex);
|
||||
}
|
||||
}
|
||||
|
||||
ride->status = RIDE_STATUS_CLOSED;
|
||||
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
|
||||
ride->race_winner = 0xFFFF;
|
||||
ride->var_14D |= (1 << 2) | (1 << 3);
|
||||
window_invalidate_by_number(WC_RIDE, rideIndex);
|
||||
}
|
||||
*ebx = 0;
|
||||
return;
|
||||
case RIDE_STATUS_TESTING:
|
||||
case RIDE_STATUS_OPEN:
|
||||
if (ride->status == targetStatus) {
|
||||
*ebx = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ride_is_valid_for_open(rideIndex, targetStatus == RIDE_STATUS_OPEN, *ebx & GAME_COMMAND_FLAG_APPLY)) {
|
||||
*ebx = MONEY32_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
|
||||
ride->race_winner = 0xFFFF;
|
||||
ride->status = targetStatus;
|
||||
ride_get_measurement(rideIndex, NULL);
|
||||
ride->var_14D |= (1 << 2) | (1 << 3);
|
||||
window_invalidate_by_number(WC_RIDE, rideIndex);
|
||||
}
|
||||
*ebx = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ride_set_name(int rideIndex, const char *name)
|
||||
{
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16) = STR_CANT_RENAME_RIDE_ATTRACTION;
|
||||
|
||||
@@ -293,7 +293,7 @@ enum {
|
||||
RIDE_LIFECYCLE_MUSIC = 1 << 13,
|
||||
RIDE_LIFECYCLE_INDESTRUCTIBLE = 1 << 14,
|
||||
RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK = 1 << 15,
|
||||
|
||||
RIDE_LIFECYCLE_16 = 1 << 16,
|
||||
RIDE_LIFECYCLE_CABLE_LIFT = 1 << 17,
|
||||
RIDE_LIFECYCLE_18 = 1 << 18,
|
||||
RIDE_LIFECYCLE_19 = 1 << 19
|
||||
@@ -613,11 +613,12 @@ void ride_update_favourited_stat();
|
||||
void ride_update_all();
|
||||
void ride_check_all_reachable();
|
||||
void ride_update_popularity(rct_ride* ride, uint8 pop_amount);
|
||||
rct_map_element *sub_6CAF80(int rideIndex, int *outX, int *outY);
|
||||
rct_map_element *ride_find_track_gap(rct_map_element *startTrackElement, int *outX, int *outY);
|
||||
int sub_6CAF80(int rideIndex, rct_xy_element *output);
|
||||
int track_get_next(rct_xy_element *input, rct_xy_element *output);
|
||||
int ride_find_track_gap(rct_xy_element *input, rct_xy_element *output);
|
||||
void ride_construct_new(ride_list_item listItem);
|
||||
void ride_construct(int rideIndex);
|
||||
int ride_modify(rct_map_element *trackMapElement, int x, int y);
|
||||
int ride_modify(rct_xy_element *input);
|
||||
void ride_get_status(int rideIndex, int *formatSecondary, int *argument);
|
||||
rct_peep *ride_get_assigned_mechanic(rct_ride *ride);
|
||||
int ride_get_total_length(rct_ride *ride);
|
||||
@@ -638,6 +639,8 @@ void ride_set_map_tooltip(rct_map_element *mapElement);
|
||||
int ride_music_params_update(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId);
|
||||
void ride_music_update_final();
|
||||
|
||||
void ride_set_status(int rideIndex, int status);
|
||||
void game_command_set_ride_status(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
void ride_set_name(int rideIndex, const char *name);
|
||||
void game_command_set_ride_name(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
|
||||
|
||||
@@ -65,20 +65,6 @@ static int sub_6C6402(rct_map_element *mapElement, int *x, int *y, int *z)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int sub_6C60C2(rct_map_element *mapElement, int *x, int *y, int *z)
|
||||
{
|
||||
int eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
|
||||
eax = *x;
|
||||
ecx = *y;
|
||||
esi = (int)mapElement;
|
||||
RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
*x = *((uint16*)&eax);
|
||||
*y = *((uint16*)&ecx);
|
||||
*z = *((uint8*)&edx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B5A2A
|
||||
@@ -217,13 +203,13 @@ static void loc_6B5BB2()
|
||||
*/
|
||||
static void ride_ratings_update_state_2()
|
||||
{
|
||||
// sub_6C6402 returns a carry, CALLFUNC doesn't support this
|
||||
// so have to wait for sub_6C60C2 to be decompiled
|
||||
// TODO test this function
|
||||
RCT2_CALLPROC_EBPSAFE(0x006B5C66);
|
||||
return;
|
||||
|
||||
rct_ride *ride;
|
||||
rct_map_element *mapElement;
|
||||
rct_xy_element trackElement, nextTrackElement;
|
||||
int x, y, z, trackType, entranceIndex;
|
||||
|
||||
ride = GET_RIDE(_rideRatingsCurrentRide);
|
||||
@@ -255,13 +241,18 @@ static void ride_ratings_update_state_2()
|
||||
|
||||
RCT2_CALLPROC_X(0x006B5F9D, 0, 0, 0, 0, (int)mapElement, 0, 0);
|
||||
|
||||
x = RCT2_GLOBAL(0x0138B584, uint16);
|
||||
y = RCT2_GLOBAL(0x0138B586, uint16);
|
||||
if (!sub_6C60C2(mapElement, &x, &y, &z)) {
|
||||
trackElement.x = RCT2_GLOBAL(0x0138B584, uint16);
|
||||
trackElement.y = RCT2_GLOBAL(0x0138B586, uint16);
|
||||
trackElement.element = mapElement;
|
||||
if (!track_get_next(&trackElement, &nextTrackElement)) {
|
||||
_rideRatingsState = RIDE_RATINGS_STATE_4;
|
||||
return;
|
||||
}
|
||||
|
||||
x = nextTrackElement.x;
|
||||
y = nextTrackElement.y;
|
||||
z = nextTrackElement.element->base_height * 8;
|
||||
mapElement = nextTrackElement.element;
|
||||
if (x == RCT2_GLOBAL(0x0138B58A, uint16) && y == RCT2_GLOBAL(0x0138B58C, uint16) && z == RCT2_GLOBAL(0x0138B58E, uint16)) {
|
||||
_rideRatingsState = RIDE_RATINGS_STATE_CALCULATE;
|
||||
return;
|
||||
|
||||
@@ -34,7 +34,10 @@
|
||||
*
|
||||
* rct2: 0x00997C9D
|
||||
*/
|
||||
const rct_trackdefinition gTrackDefinitions[] = {
|
||||
const rct_trackdefinition *gTrackDefinitions = (rct_trackdefinition*)0x00997C9D;
|
||||
|
||||
// TODO This table is incorrect or at least missing 69 elements. There should be 256 in total!
|
||||
const rct_trackdefinition gTrackDefinitions_INCORRECT[] = {
|
||||
// TYPE VANGLE END VANGLE START BANK END BANK START SPECIAL
|
||||
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_FLAT
|
||||
{ TRACK_FLAT, TRACK_NONE, TRACK_NONE, TRACK_BANK_NONE, TRACK_BANK_NONE, TRACK_NONE }, // ELEM_END_STATION
|
||||
@@ -540,10 +543,10 @@ rct_track_td6* load_track_design(const char *path)
|
||||
uint8* track_element = track_elements;
|
||||
while (*track_element != 255) {
|
||||
track_element += 2;
|
||||
}
|
||||
}
|
||||
track_element++;
|
||||
memset(track_element, 255, final_track_element_location - track_element);
|
||||
}
|
||||
}
|
||||
|
||||
// Edit the colours to use the new versions
|
||||
// Unsure why it is 67
|
||||
@@ -1029,7 +1032,7 @@ rct_track_design *track_get_info(int index, uint8** preview)
|
||||
}
|
||||
|
||||
trackDesign = &RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_CACHE, rct_track_design*)[i];
|
||||
|
||||
|
||||
// Copy the track design apart from the preview image
|
||||
memcpy(&trackDesign->track_td6, loaded_track, sizeof(rct_track_td6));
|
||||
// Load in a new preview image, calculate cost variable, calculate var_06
|
||||
@@ -1124,3 +1127,40 @@ int track_delete()
|
||||
window_invalidate(w);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to determine if a connects to b by its bank and angle, not location.
|
||||
*/
|
||||
int track_is_connected_by_shape(rct_map_element *a, rct_map_element *b)
|
||||
{
|
||||
int trackType, aBank, aAngle, bBank, bAngle;
|
||||
rct_ride *ride;
|
||||
|
||||
ride = GET_RIDE(a->properties.track.ride_index);
|
||||
trackType = a->properties.track.type;
|
||||
aBank = gTrackDefinitions[trackType].bank_end;
|
||||
aAngle = gTrackDefinitions[trackType].vangle_end;
|
||||
if (RCT2_GLOBAL(0x0097D4F2 + (ride->type * 8), uint16) & 8) {
|
||||
if (a->properties.track.colour & 4) {
|
||||
if (aBank == TRACK_BANK_NONE)
|
||||
aBank = TRACK_BANK_UPSIDE_DOWN;
|
||||
else if (aBank == TRACK_BANK_UPSIDE_DOWN)
|
||||
aBank = TRACK_BANK_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
ride = GET_RIDE(b->properties.track.ride_index);
|
||||
trackType = b->properties.track.type;
|
||||
bBank = gTrackDefinitions[trackType].bank_start;
|
||||
bAngle = gTrackDefinitions[trackType].vangle_start;
|
||||
if (RCT2_GLOBAL(0x0097D4F2 + (ride->type * 8), uint16) & 8) {
|
||||
if (b->properties.track.colour & 4) {
|
||||
if (bBank == TRACK_BANK_NONE)
|
||||
bBank = TRACK_BANK_UPSIDE_DOWN;
|
||||
else if (bBank == TRACK_BANK_UPSIDE_DOWN)
|
||||
bBank = TRACK_BANK_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
return aBank == bBank && aAngle == bAngle;
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#define _TRACK_H_
|
||||
|
||||
#include "../common.h"
|
||||
#include "ride.h"
|
||||
#include "../object.h"
|
||||
#include "ride.h"
|
||||
|
||||
typedef struct {
|
||||
uint8 type;
|
||||
@@ -204,6 +204,8 @@ enum {
|
||||
TRACK_CORKSCREW_DOWN = 224
|
||||
};
|
||||
|
||||
extern const rct_trackdefinition *gTrackDefinitions;
|
||||
|
||||
void track_load_list(ride_list_item item);
|
||||
int sub_67726A(const char *path);
|
||||
rct_track_design *track_get_info(int index, uint8** preview);
|
||||
@@ -211,6 +213,7 @@ rct_track_td6* load_track_design(const char *path);
|
||||
int track_rename(const char *text);
|
||||
int track_delete();
|
||||
void reset_track_list_cache();
|
||||
int track_is_connected_by_shape(rct_map_element *a, rct_map_element *b);
|
||||
int sub_6D01B3(int bl, int x, int y, int z);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1531,24 +1531,21 @@ static void window_ride_init_viewport(rct_window *w)
|
||||
void window_ride_construct(rct_window *w)
|
||||
{
|
||||
int rideIndex = w->number;
|
||||
rct_xy_element trackElement;
|
||||
|
||||
window_close_by_class(WC_RIDE_CONSTRUCTION);
|
||||
w = window_find_by_number(WC_RIDE, rideIndex);
|
||||
if (w == NULL)
|
||||
return;
|
||||
|
||||
rct_map_element *trackMapElement;
|
||||
int trackX, trackY;
|
||||
|
||||
trackMapElement = sub_6CAF80(rideIndex, &trackX, &trackY);
|
||||
if (trackMapElement == (rct_map_element*)-1) {
|
||||
sub_6CC3FB(rideIndex);
|
||||
} else {
|
||||
trackMapElement = ride_find_track_gap(trackMapElement, &trackX, &trackY);
|
||||
if (sub_6CAF80(rideIndex, &trackElement)) {
|
||||
ride_find_track_gap(&trackElement, &trackElement);
|
||||
|
||||
w = window_get_main();
|
||||
if (w != NULL && ride_modify(trackMapElement, trackX, trackY))
|
||||
window_scroll_to_location(w, trackX, trackY, trackMapElement->base_height * 8);
|
||||
if (w != NULL && ride_modify(&trackElement))
|
||||
window_scroll_to_location(w, trackElement.x, trackElement.y, trackElement.element->base_height * 8);
|
||||
} else {
|
||||
sub_6CC3FB(rideIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1845,9 +1842,9 @@ static void window_ride_main_dropdown()
|
||||
break;
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(0x013CE952 + 6, uint16) = ride->overall_view;
|
||||
RCT2_GLOBAL(0x013CE952 + 6, uint16) = ride->name;
|
||||
RCT2_GLOBAL(0x013CE952 + 8, uint32) = ride->name_arguments;
|
||||
game_do_command(0, 1, 0, w->number | (status << 8), GAME_COMMAND_SET_RIDE_OPEN, 0, 0);
|
||||
ride_set_status(w->number, status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,8 +198,10 @@ rct_window *window_construction_open()
|
||||
return w;
|
||||
}
|
||||
|
||||
void window_construction_close(){
|
||||
void window_construction_close()
|
||||
{
|
||||
rct_window *w;
|
||||
rct_xy_element mapElement;
|
||||
|
||||
window_get_register(w);
|
||||
|
||||
@@ -211,21 +213,18 @@ void window_construction_close(){
|
||||
|
||||
hide_gridlines();
|
||||
|
||||
int x, y;
|
||||
uint8 ride_id = RCT2_GLOBAL(0xF440A7, uint8);
|
||||
rct_map_element* map_element = sub_6CAF80(ride_id, &x, &y);
|
||||
|
||||
if ((int)map_element == -1){
|
||||
uint8 rideIndex = RCT2_GLOBAL(0x00F440A7, uint8);
|
||||
if (!sub_6CAF80(rideIndex, &mapElement)) {
|
||||
int eax = RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = 0;
|
||||
game_do_command(0, 9, 0, ride_id, GAME_COMMAND_7, 0, 0);
|
||||
game_do_command(0, 9, 0, rideIndex, GAME_COMMAND_7, 0, 0);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_PAUSED, uint8) = eax;
|
||||
return;
|
||||
}
|
||||
|
||||
window_ride_main_open(ride_id);
|
||||
window_ride_main_open(rideIndex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -707,7 +707,7 @@ static void window_ride_list_close_all(rct_window *w)
|
||||
RCT2_GLOBAL(0x013CE952 + 6, uint16) = w->scrolls[0].v_top;
|
||||
RCT2_GLOBAL(0x013CE952 + 8, uint32) = w->scrolls[0].v_bottom;
|
||||
|
||||
game_do_command(0, 1, 0, i, GAME_COMMAND_SET_RIDE_OPEN, 0, 0);
|
||||
ride_set_status(i, RIDE_STATUS_CLOSED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -724,6 +724,6 @@ static void window_ride_list_open_all(rct_window *w)
|
||||
RCT2_GLOBAL(0x013CE952 + 6, uint16) = w->scrolls[0].v_top;
|
||||
RCT2_GLOBAL(0x013CE952 + 8, uint32) = w->scrolls[0].v_bottom;
|
||||
|
||||
game_do_command(0, 1, 0, (1 << 8) | i, GAME_COMMAND_SET_RIDE_OPEN, 0, 0);
|
||||
ride_set_status(i, RIDE_STATUS_OPEN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +217,11 @@ typedef struct {
|
||||
sint16 x, y, z;
|
||||
} rct_xyz16;
|
||||
|
||||
typedef struct {
|
||||
int x, y;
|
||||
rct_map_element *element;
|
||||
} rct_xy_element;
|
||||
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
uint16 y;
|
||||
|
||||
Reference in New Issue
Block a user