1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-17 20:13:07 +01:00

further testing and progress on set_ride_status

This commit is contained in:
IntelOrca
2015-01-29 21:10:34 +00:00
parent fb9f112ea9
commit 0e6a90c5de
5 changed files with 139 additions and 56 deletions

View File

@@ -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
@@ -308,6 +309,28 @@ rct_map_element *sub_6CAF80(int rideIndex, int *outX, int *outY)
/**
*
* rct2: 0x006C60C2
*/
rct_map_element *track_get_next(rct_map_element *mapElement, int *x, int *y, int *z)
{
int eax, ebx, ecx, edx, esi, edi, ebp, result;
eax = *x;
ecx = *y;
esi = (int)mapElement;
result = RCT2_CALLFUNC_X(0x006C60C2, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*x = *((uint16*)&eax);
*y = *((uint16*)&ecx);
*z = *((uint8*)&edx);
mapElement = (rct_map_element*)esi;
if (result & 0x100) return NULL;
return mapElement;
}
/**
*
* Make sure to pass in the x and y of the start track element too.
* rct2: 0x006CB02F
* ax result x
* bx result y
@@ -315,19 +338,44 @@ 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 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, x, y, z;
rct_map_element *trackElement, *nextTrackElement, *loopTrackElement;
rct_ride *ride;
rct_window *w;
if (outX != NULL) *outX = eax & 0xFFFF;
if (outY != NULL) *outY = ecx & 0xFFFF;
return (rct_map_element*)esi;
x = *outX;
y = *outY;
rideIndex = startTrackElement->properties.track.ride_index;
ride = GET_RIDE(rideIndex);
if (ride->type == RIDE_TYPE_MAZE)
return NULL;
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
if (w != NULL && RCT2_GLOBAL(0x00F440A6, uint8) != 0 && RCT2_GLOBAL(0x00F440A7, uint8) == rideIndex)
sub_6C9627();
trackElement = startTrackElement;
loopTrackElement = NULL;
while (1) {
nextTrackElement = track_get_next(trackElement, &x, &y, &z);
if (nextTrackElement == NULL)
return trackElement;
if (!track_is_connected_by_shape(trackElement, nextTrackElement)) {
*outX = x;
*outY = y;
return nextTrackElement;
}
trackElement = nextTrackElement;
if (loopTrackElement == NULL)
loopTrackElement = trackElement;
else if (trackElement == loopTrackElement)
break;
}
return NULL;
}
/**
@@ -858,6 +906,7 @@ int ride_modify_maze(rct_map_element *mapElement, int x, int y)
int ride_modify(rct_map_element *mapElement, int x, int y)
{
int rideIndex, z, direction, type;
rct_map_element *endOfTrackElement;
rct_ride *ride;
rct_window *constructionWindow;
@@ -895,7 +944,9 @@ int ride_modify(rct_map_element *mapElement, int x, int 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);
endOfTrackElement = ride_find_track_gap(mapElement, &outX, &outY);
if (endOfTrackElement != NULL)
mapElement = endOfTrackElement;
}
z = mapElement->base_height * 8;
@@ -2696,7 +2747,7 @@ void ride_music_update_final()
*/
int ride_mode_check_valid_stations(rct_ride *ride)
{
return RCT2_CALLPROC_X(0x006B4CC1, 0, 0, 0, 0, (int)ride, 0, 0) & 0x100;
return (RCT2_CALLPROC_X(0x006B4CC1, 0, 0, 0, 0, (int)ride, 0, 0) & 0x100) == 0;
}
/**
@@ -2705,7 +2756,7 @@ int ride_mode_check_valid_stations(rct_ride *ride)
*/
int ride_check_for_entrance_exit(int rideIndex)
{
return RCT2_CALLPROC_X(0x006B4CC1, 0, 0, 0, rideIndex, 0, 0, 0) & 0x100;
return (RCT2_CALLPROC_X(0x006B5872, 0, 0, 0, rideIndex, 0, 0, 0) & 0x100) == 0;
}
/**
@@ -2835,11 +2886,9 @@ void loc_6B51C0(int rideIndex)
window_scroll_to_location(w, x, y, z);
mapElement = sub_6CAF80(rideIndex, &x, &y);
ride_find_track_gap(mapElement, &x, &y);
w = window_get_main();
rct_viewport *viewport = w->viewport;
mapElement = ride_find_track_gap(mapElement, &x, &y);
ride_modify(mapElement, x, y);
w = window_find_by_class(WC_RIDE_CONSTRUCTION);
if (w != NULL)
window_event_mouse_up_call(w, 29 + entranceOrExit);
@@ -2876,7 +2925,7 @@ rct_map_element *loc_6B4F6B(int rideIndex, int x, int y)
{
rct_map_element *mapElement;
mapElement = map_get_first_element_at(x, y);
mapElement = map_get_first_element_at(x / 32, y / 32);
do {
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_TRACK)
continue;
@@ -2914,11 +2963,13 @@ int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying)
return 0;
if (!ride_check_for_entrance_exit(rideIndex)) {
// TODO check if this is correct
loc_6B51C0(rideIndex);
return 0;
}
if (goingToBeOpen && isApplying) {
// TODO check if this is correct
sub_6B5952(rideIndex);
ride->lifecycle_flags |= RIDE_LIFECYCLE_EVER_BEEN_OPENED;
}
@@ -2932,6 +2983,7 @@ int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying)
}
if (stationIndex == -1) {
// TODO check if this is correct
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 0;
@@ -2943,11 +2995,14 @@ int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying)
return 0;
}
mapElement = loc_6B4F6B(rideIndex, ride->station_starts[i] >> 8, ride->station_starts[i] & 0xFF);
x = (ride->station_starts[i] & 0xFF) * 32;
y = (ride->station_starts[i] >> 8) * 32;
z = ride->station_heights[i] * 8;
mapElement = loc_6B4F6B(rideIndex, x, y);
if (mapElement == NULL)
return 0;
z = ride->station_heights[i] * 8;
if (
ride->type == RIDE_TYPE_AIR_POWERED_VERTICAL_COASTER ||
ride->mode == RIDE_MODE_RACE ||
@@ -2963,6 +3018,8 @@ int ride_is_valid_for_open(int rideIndex, int goingToBeOpen, int isApplying)
}
}
// TODO check if the following is correct
if (
ride->mode == RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED ||
ride->mode == RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED
@@ -3059,23 +3116,20 @@ void game_command_set_ride_status(int *eax, int *ebx, int *ecx, int *edx, int *e
switch (targetStatus) {
case RIDE_STATUS_CLOSED:
if (*ebx & GAME_COMMAND_FLAG_APPLY) {
*ebx = 0;
return;
}
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);
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);
}
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:

View File

@@ -614,6 +614,7 @@ 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 *track_get_next(rct_map_element *mapElement, int *x, int *y, int *z);
rct_map_element *ride_find_track_gap(rct_map_element *startTrackElement, int *outX, int *outY);
void ride_construct_new(ride_list_item listItem);
void ride_construct(int rideIndex);

View File

@@ -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,8 +203,7 @@ 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;
@@ -257,7 +242,7 @@ static void ride_ratings_update_state_2()
x = RCT2_GLOBAL(0x0138B584, uint16);
y = RCT2_GLOBAL(0x0138B586, uint16);
if (!sub_6C60C2(mapElement, &x, &y, &z)) {
if ((mapElement = track_get_next(mapElement, &x, &y, &z)) == NULL) {
_rideRatingsState = RIDE_RATINGS_STATE_4;
return;
}

View File

@@ -29,7 +29,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
@@ -453,4 +456,41 @@ int track_rename(const char *text)
int track_delete()
{
return (RCT2_CALLPROC_X(0x006D3761, 0, 0, 0, 0, 0, 0, 0) & 0x100) != 0;
}
/**
* 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;
}

View File

@@ -22,8 +22,8 @@
#define _TRACK_H_
#include "../common.h"
#include "ride.h"
#include "../object.h"
#include "ride.h"
typedef struct {
uint8 type;
@@ -137,11 +137,14 @@ 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);
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);
#endif