Merge pull request #1065 from duncanspumpkin/track

Track Placement
This commit is contained in:
Ted John 2015-05-14 18:09:36 +01:00
commit 65a58e3177
20 changed files with 2183 additions and 97 deletions

View File

@ -41,6 +41,7 @@
#include "ride/ride.h"
#include "ride/ride_ratings.h"
#include "ride/vehicle.h"
#include "ride/track.h"
#include "scenario.h"
#include "title.h"
#include "tutorial.h"
@ -921,7 +922,7 @@ static uint32 game_do_command_table[58] = {
0,
0,
0,
0x006D13FE,
0,
0,
0x006CDEE4,
0, // 50
@ -984,7 +985,7 @@ static GAME_COMMAND_POINTER* new_game_command_table[58] = {
game_command_remove_large_scenery,
game_command_set_current_loan,
game_command_set_research_funding,
game_command_emptysub,
game_command_place_track,
game_command_start_campaign,
game_command_emptysub,
game_command_place_banner, // 50

View File

@ -71,7 +71,7 @@ enum GAME_COMMAND {
GAME_COMMAND_REMOVE_LARGE_SCENERY,
GAME_COMMAND_SET_CURRENT_LOAN, // 45
GAME_COMMAND_SET_RESEARCH_FUNDING, // 46
GAME_COMMAND_47,
GAME_COMMAND_PLACE_TRACK,
GAME_COMMAND_START_MARKETING_CAMPAIGN, // 48
GAME_COMMAND_49,
GAME_COMMAND_PLACE_BANNER, // New banner? (possibly scenery)

View File

@ -298,6 +298,15 @@ enum {
RCT1_RIDE_TYPE_LEMONADE_STALL
};
enum{
RCT1_TRACK_ELEM_BOOSTER = 100
};
enum{
RCT1_RIDE_MODE_POWERED_LAUNCH = 3,
};
typedef struct{
uint8 type; // 0x00
uint8 vehicle_type; // 0x01

View File

@ -769,10 +769,173 @@ static void ride_remove_peeps(int rideIndex)
ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN;
}
int sub_6C683D(int* x, int* y, int z, int direction, int type, int esi, int edi, int ebp)
/* rct2: 0x006C683D
* ax : x
* bx : direction << 8, type
* cx : y
* dx : z
* si : extra_params
* di : output_element
* bp : flags
*/
int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_params, rct_map_element** output_element, uint16 flags)
{
int ebx = (direction << 8) | type;
return RCT2_CALLFUNC_X(0x006C683D, x, &ebx, y, &z, &esi, &edi, &ebp)&0x100;
//int ebx = (direction << 8) | type;
//return RCT2_CALLFUNC_X(0x006C683D, x, &ebx, y, &z, &esi, &edi, &ebp)&0x100;
rct_map_element* map_element = map_get_first_element_at(*x / 32, *y / 32);
rct_map_element* success_map = NULL;
do{
if (map_element->base_height != *z / 8)
continue;
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK)
continue;
if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
continue;
if (type != map_element->properties.track.type)
continue;
success_map = map_element;
if (!(map_element->properties.track.sequence & 0xF))
break;
}while(!map_element_is_last_for_tile(map_element++));
map_element = success_map;
if (map_element == NULL){
return 1;
}
// Possibly z should be &0xF8
rct_ride* ride = GET_RIDE(map_element->properties.track.ride_index);
rct_preview_track *trackBlock;
if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_SELLS_FOOD){
trackBlock = RCT2_ADDRESS(0x00994A38, rct_preview_track*)[type];
}
else{
trackBlock = RCT2_ADDRESS(0x00994638, rct_preview_track*)[type];
}
int sequence = map_element->properties.track.sequence & 0xF;
uint8 map_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK;
switch (map_direction){
case MAP_ELEMENT_DIRECTION_WEST:
*x -= trackBlock[sequence].x;
*y -= trackBlock[sequence].y;
break;
case MAP_ELEMENT_DIRECTION_NORTH:
*x -= trackBlock[sequence].y;
*y += trackBlock[sequence].x;
break;
case MAP_ELEMENT_DIRECTION_EAST:
*x += trackBlock[sequence].x;
*y += trackBlock[sequence].y;
break;
case MAP_ELEMENT_DIRECTION_SOUTH:
*x += trackBlock[sequence].y;
*y -= trackBlock[sequence].x;
break;
}
*z -= trackBlock[sequence].z;
int start_x = *x, start_y = *y, start_z = *z;
*z += trackBlock[0].z;
for (int i = 0; trackBlock[i].var_00 != 0xFF; ++i){
int cur_x = start_x, cur_y = start_y, cur_z = start_z;
switch (map_direction){
case MAP_ELEMENT_DIRECTION_WEST:
cur_x += trackBlock[i].x;
cur_y += trackBlock[i].y;
break;
case MAP_ELEMENT_DIRECTION_NORTH:
cur_x += trackBlock[i].y;
cur_y -= trackBlock[i].x;
break;
case MAP_ELEMENT_DIRECTION_EAST:
cur_x -= trackBlock[i].x;
cur_y -= trackBlock[i].y;
break;
case MAP_ELEMENT_DIRECTION_SOUTH:
cur_x -= trackBlock[i].y;
cur_y += trackBlock[i].x;
break;
}
cur_z += trackBlock[i].z;
map_invalidate_tile_full(cur_x, cur_y);
map_element = map_get_first_element_at(cur_x / 32, cur_y / 32);
success_map = NULL;
do{
if (map_element->base_height != cur_z / 8)
continue;
if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_TRACK)
continue;
if ((map_element->type & MAP_ELEMENT_DIRECTION_MASK) != direction)
continue;
if ((map_element->properties.track.sequence & 0xF) != trackBlock[i].var_00)
continue;
if (type == map_element->properties.track.type)
{
success_map = map_element;
break;
}
} while (!map_element_is_last_for_tile(map_element++));
if (success_map == NULL){
return 1;
}
if (i == 0 && output_element != NULL)
*output_element = map_element;
if (flags & (1 << 0)){
// Quadrant related ??
map_element->type &= ~(1 << 6);
}
if (flags & (1 << 1)){
// Quadrant related ??
map_element->type |= (1 << 6);
}
if (flags & (1 << 2)){
map_element->properties.track.colour &= 0xFC;
map_element->properties.track.colour |= extra_params & 0xFF;
}
if (flags & (1 << 5)){
map_element->properties.track.colour &= 0x0F;
map_element->properties.track.colour |= (extra_params & 0xFF) << 4;
}
if (flags & (1 << 3)){
map_element->properties.track.colour |= (1 << 3);
}
if (flags & (1 << 4)){
map_element->properties.track.colour &= 0xF7;
}
}
return 0;
}
void sub_6C96C0()
@ -785,11 +948,11 @@ void sub_6C9627()
switch (RCT2_GLOBAL(0x00F440A6, uint8)) {
case 3:
{
int x = RCT2_GLOBAL(0x00F440A8, uint16), y = RCT2_GLOBAL(0x00F440AA, uint16);
int x = RCT2_GLOBAL(0x00F440A8, uint16), y = RCT2_GLOBAL(0x00F440AA, uint16), z = RCT2_GLOBAL(0x00F440AC, uint16);
sub_6C683D(
&x,
&y,
RCT2_GLOBAL(0x00F440AC, uint16),
&z,
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8) & 3,
RCT2_GLOBAL(0x00F440AF, uint8),
0,
@ -969,7 +1132,7 @@ int ride_modify(rct_xy_element *input)
direction = mapElement.element->type & 3;
type = mapElement.element->properties.track.type;
if (sub_6C683D(&x, &y, z, direction, type, 0, 0, 0))
if (sub_6C683D(&x, &y, &z, direction, type, 0, 0, 0))
return 0;
RCT2_GLOBAL(0x00F440A7, uint8) = rideIndex;
@ -2094,8 +2257,8 @@ track_colour ride_get_track_colour(rct_ride *ride, int colourScheme)
vehicle_colour ride_get_vehicle_colour(rct_ride *ride, int vehicleIndex)
{
vehicle_colour result;
result.main = ride->vehicle_colours[vehicleIndex] & 0xFF;
result.additional_1 = ride->vehicle_colours[vehicleIndex] >> 8;
result.main = ride->vehicle_colours[vehicleIndex].body_colour;
result.additional_1 = ride->vehicle_colours[vehicleIndex].trim_colour;
result.additional_2 = ride->vehicle_colours_extended[vehicleIndex];
return result;
}
@ -3709,7 +3872,7 @@ void game_command_demolish_ride(int *eax, int *ebx, int *ecx, int *edx, int *esi
RCT2_CALLPROC_X(0x00696707, 0, 0, 0, ride_id, 0, 0, 0);
*ebx = ride_get_refund_price(ride_id);
RCT2_CALLPROC(0x006CB945);
RCT2_CALLPROC_X(0x006CB945, 0, 0, 0, ride_id, 0, 0, 0);
news_item_disable_news(NEWS_ITEM_RIDE, ride_id);
for(int i = 0; i < MAX_BANNERS; i++){

View File

@ -24,6 +24,7 @@
#include "../common.h"
#include "../peep/peep.h"
#include "../world/map.h"
#include "vehicle.h"
typedef fixed16_2dp ride_rating;
@ -138,7 +139,7 @@ typedef struct {
uint16 pad_002;
uint8 mode; // 0x004
uint8 colour_scheme_type; // 0x005
uint16 vehicle_colours[32]; // 0x006
rct_vehicle_colour vehicle_colours[32]; // 0x006
uint8 pad_046[0x03];
// 0 = closed, 1 = open, 2 = test
uint8 status; // 0x049
@ -753,7 +754,7 @@ void ride_breakdown_add_news_item(int rideIndex);
rct_peep *ride_find_closest_mechanic(rct_ride *ride, int forInspection);
int sub_6CC3FB(int rideIndex);
void sub_6C9627();
int sub_6C683D(int* x, int* y, int z, int direction, int type, int esi, int edi, int ebp);
int sub_6C683D(int* x, int* y, int* z, int direction, int type, uint16 extra_params, rct_map_element** output_element, uint16 flags);
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();

View File

@ -51,18 +51,19 @@ static void loc_6B5BB2();
static void ride_ratings_calculate(rct_ride *ride);
static void ride_ratings_calculate_value(rct_ride *ride);
static int sub_6C6402(rct_map_element *mapElement, int *x, int *y, int *z)
int sub_6C6402(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);
esi = (int)*mapElement;
int result = RCT2_CALLFUNC_X(0x006C6402, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
*x = *((uint16*)&eax);
*y = *((uint16*)&ecx);
*z = *((uint8*)&edx);
return 1;
*mapElement = (rct_map_element*)esi;
return result & (0x100);
}
/**
@ -338,7 +339,7 @@ static void ride_ratings_update_state_5()
x = RCT2_GLOBAL(0x0138B584, uint16);
y = RCT2_GLOBAL(0x0138B586, uint16);
if (!sub_6C6402(mapElement, &x, &y, &z)) {
if (!sub_6C6402(&mapElement, &x, &y, &z)) {
_rideRatingsState = RIDE_RATINGS_STATE_CALCULATE;
return;
}

View File

@ -25,5 +25,6 @@
#include "ride.h"
void ride_ratings_update_all();
int sub_6C6402(rct_map_element **mapElement, int *x, int *y, int *z);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -42,7 +42,7 @@ typedef struct {
uint8 var_00;
sint16 x; // 0x01
sint16 y; // 0x03
uint16 z;
sint16 z;
uint8 pad_07;
uint8 var_08;
uint8 var_09;
@ -57,8 +57,13 @@ typedef struct {
struct {
sint8 x;
sint8 y;
uint8 unk_2;
uint8 type;
union{
uint16 maze_entry;
struct{
uint8 unk_2;
uint8 type;
};
};
};
};
} rct_maze_element;
@ -72,14 +77,22 @@ typedef struct{
/* Track Scenery entry size: 0x16 */
typedef struct{
rct_object_entry scenery_object; // 0x00
uint8 x; // 0x10
uint8 y; // 0x11
uint8 z; // 0x12
sint8 x; // 0x10
sint8 y; // 0x11
sint8 z; // 0x12
uint8 flags; // 0x13 direction quadrant tertiary colour
uint8 primary_colour; // 0x14
uint8 secondary_colour; // 0x15
}rct_track_scenery;
/* Track Entrance entry size: 0x6 */
typedef struct{
sint8 z;
uint8 direction; // 0x01
sint16 x; // 0x02
sint16 y; // 0x04
}rct_track_entrance;
enum{
TRACK_ELEMENT_FLAG_CHAIN_LIFT = (1<<7),
TRACK_ELEMENT_FLAG_INVERTED = (1<<6),
@ -92,12 +105,6 @@ enum{
#define TRACK_PREVIEW_IMAGE_SIZE (370 * 217)
/* size: 0x2 */
typedef struct{
uint8 body_colour;
uint8 trim_colour;
} rct_track_vehicle_colour;
/**
* Track design structure.
* size: 0x4E72B
@ -105,10 +112,20 @@ typedef struct{
typedef struct {
uint8 type; // 0x00
uint8 vehicle_type;
money32 cost; // 0x02
uint8 var_06;
uint8 var_07;
rct_track_vehicle_colour vehicle_colours[32]; // 0x08
union{
// After loading the track this is converted to
// a cost but before its a flags register
money32 cost; // 0x02
uint32 flags; // 0x02
};
union{
// After loading the track this is converted to
// a flags register
uint8 ride_mode; // 0x06
uint8 track_flags; // 0x06
};
uint8 version_and_colour_scheme; // 0x07 0b0000_VVCC
rct_vehicle_colour vehicle_colours[32]; // 0x08
union{
uint8 pad_48;
uint8 track_spine_colour_rct1; // 0x48
@ -121,16 +138,17 @@ typedef struct {
uint8 total_air_time; // 0x4A
uint8 track_support_colour_rct1; // 0x4A
};
uint8 pad_4B;
uint8 depart_flags; // 0x4B
uint8 number_of_trains; // 0x4C
uint8 number_of_cars_per_train; // 0x4D
uint8 pad_4E[2];
uint8 min_waiting_time; // 0x4E
uint8 max_waiting_time; // 0x4F
uint8 var_50;
uint8 max_speed; // 0x51
uint8 average_speed; // 0x52
sint8 max_speed; // 0x51
sint8 average_speed; // 0x52
uint16 ride_length; // 0x53
uint8 max_positive_vertical_g; // 0x55
sint8 max_negitive_vertical_g; // 0x56
sint8 max_negative_vertical_g; // 0x56
uint8 max_lateral_g; // 0x57
union {
uint8 inversions; // 0x58
@ -141,7 +159,7 @@ typedef struct {
uint8 excitement; // 0x5B
uint8 intensity; // 0x5C
uint8 nausea; // 0x5D
uint8 pad_5E[2];
money16 upkeep_cost; // 0x5E
uint8 track_spine_colour[4]; // 0x60
uint8 track_rail_colour[4]; // 0x64
uint8 track_support_colour[4]; // 0x68
@ -150,7 +168,7 @@ typedef struct {
uint8 space_required_x; // 0x80
uint8 space_required_y; // 0x81
uint8 vehicle_additional_colour[32]; // 0x82
uint8 var_A2;
uint8 lift_hill_speed_num_circuits; // 0xA2 0bCCCL_LLLL
} rct_track_td6;
typedef struct{
@ -415,11 +433,13 @@ rct_track_design *temp_track_get_info(char* path, uint8** preview);
rct_track_td6* load_track_design(const char *path);
int track_rename(const char *text);
int track_delete();
void track_mirror();
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);
int sub_6D01B3(uint8 bl, uint8 rideIndex, int x, int y, int z);
int save_track_design(uint8 rideIndex);
int install_track(char* source_path, char* dest_name);
void window_track_list_format_name(char *dst, const char *src, char colour, char quotes);
void game_command_place_track(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* edi, int* ebp);
#endif

View File

@ -23,6 +23,12 @@
#include "../common.h"
/* size: 0x2 */
typedef struct{
uint8 body_colour;
uint8 trim_colour;
} rct_vehicle_colour;
typedef struct {
uint8 sprite_identifier; // 0x00
uint8 var_01;

View File

@ -225,6 +225,43 @@ int sawyercoding_decode_td6(char *src, char *dst, int length)
return decode_chunk_rle(src, dst, length - 4);
}
int sawyercoding_encode_td6(char* src, char* dst, int length){
int output_length = encode_chunk_rle(src, dst, length);
uint32 checksum = 0;
for (int i = 0; i < output_length; i++){
uint8 new_byte = ((checksum & 0xFF) + dst[i]) & 0xFF;
checksum = (checksum & 0xFFFFFF00) + new_byte;
checksum = rol32(checksum, 3);
}
checksum -= 0x1D4C1;
*((uint32*)&dst[output_length]) = checksum;
output_length += 4;
return output_length;
}
/* Based off of rct2: 0x006770C1 */
int sawyercoding_validate_track_checksum(char* src, int length){
uint32 file_checksum = *((uint32*)&src[length - 4]);
uint32 checksum = 0;
for (int i = 0; i < length - 4; i++){
uint8 new_byte = ((checksum & 0xFF) + src[i]) & 0xFF;
checksum = (checksum & 0xFFFFFF00) + new_byte;
checksum = rol32(checksum, 3);
}
if (checksum - 0x1D4C1 == file_checksum)
return 1; // .TD6
else if (checksum - 0x1A67C == file_checksum)
return 1; // .TD4
else if (checksum - 0x1A650 == file_checksum)
return 1; // .TD4
else
return 0;
}
#pragma region Decoding
/**
@ -318,14 +355,14 @@ static int encode_chunk_rle(char *src_buffer, char *dst_buffer, int length)
while (src < end_src - 1){
if ((count && *src == src[1]) || count > 120){
if ((count && *src == src[1]) || count > 125){
*dst++ = count - 1;
for (; count != 0; --count){
*dst++ = *src_norm_start++;
}
}
if (*src == src[1]){
for (; (count < 120) && ((src + count) < end_src); count++){
for (; (count < 125) && ((src + count) < end_src); count++){
if (*src != src[count]) break;
}
*dst++ = 257 - count;

View File

@ -55,6 +55,8 @@ int sawyercoding_decode_sv4(char *src, char *dst, int length);
int sawyercoding_decode_sc4(char *src, char *dst, int length);
int sawyercoding_encode_sv4(char *src, char *dst, int length);
int sawyercoding_decode_td6(char *src, char *dst, int length);
int sawyercoding_encode_td6(char* src, char* dst, int length);
int sawyercoding_validate_track_checksum(char* src, int length);
int sawyercoding_detect_file_type(char *src, int length);

View File

@ -201,7 +201,7 @@ static void window_install_track_select(rct_window *w, int index)
trackDesign = track_get_info(index, NULL);
if (trackDesign == NULL) return;
if (trackDesign->track_td6.var_06 & 4)
if (trackDesign->track_td6.track_flags & 4)
window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1);
window_close(w);
@ -339,7 +339,7 @@ static void window_install_track_paint()
RCT2_GLOBAL(0x00F44153, uint8) = 0;
// Warnings
if (track_td6->var_06 & 1) {
if (track_td6->track_flags & 1) {
RCT2_GLOBAL(0x00F44153, uint8) = 1;
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) == 0) {
// Scenery not available
@ -408,7 +408,7 @@ static void window_install_track_paint()
y += 10;
// Maximum negative verical Gs
gForces = track_td6->max_negitive_vertical_g * 32;
gForces = track_td6->max_negative_vertical_g * 32;
gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y);
y += 10;
@ -417,7 +417,8 @@ static void window_install_track_paint()
gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y);
y += 10;
if (track_td6->var_07 / 4 >= 2) {
// If .TD6
if (track_td6->version_and_colour_scheme / 4 >= 2) {
if (track_td6->total_air_time != 0) {
// Total air time
airTime = track_td6->total_air_time * 25;

View File

@ -322,7 +322,7 @@ void window_construction_mouseup_demolish(rct_window* w){
ecx = RCT2_GLOBAL(0xF440AA, uint16),
edx = RCT2_GLOBAL(0xF440AC, uint16);
sub_6C683D(&eax, &ecx, edx, RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8), RCT2_GLOBAL(0xF440AF, uint8) & 0x3FF, 0, 0, 0);
sub_6C683D(&eax, &ecx, &edx, RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint8), RCT2_GLOBAL(0xF440AF, uint8) & 0x3FF, 0, 0, 0);
}
int ride_id = RCT2_GLOBAL(0xF440A7, uint8);

View File

@ -190,7 +190,7 @@ static void window_track_list_select(rct_window *w, int index)
trackDesign = track_get_info(index, NULL);
if (trackDesign == NULL) return;
if (trackDesign->track_td6.var_06 & 4)
if (trackDesign->track_td6.track_flags & 4)
window_error_open(STR_THIS_DESIGN_WILL_BE_BUILT_WITH_AN_ALTERNATIVE_VEHICLE_TYPE, -1);
window_close(w);
@ -436,13 +436,13 @@ static void window_track_list_paint()
RCT2_GLOBAL(0x00F44153, uint8) = 0;
// Warnings
if ((track_td6->var_06 & 4) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
if ((track_td6->track_flags & 4) && !(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_TRACK_MANAGER)) {
// Vehicle design not available
gfx_draw_string_centred_clipped(dpi, STR_VEHICLE_DESIGN_UNAVAILABLE, NULL, 0, x, y, 368);
y -= 10;
}
if (track_td6->var_06 & 1) {
if (track_td6->track_flags & 1) {
RCT2_GLOBAL(0x00F44153, uint8) = 1;
if (RCT2_GLOBAL(RCT2_ADDRESS_TRACK_DESIGN_SCENERY_TOGGLE, uint8) == 0) {
// Scenery not available
@ -509,7 +509,7 @@ static void window_track_list_paint()
y += 10;
// Maximum negative verical Gs
gForces = track_td6->max_negitive_vertical_g * 32;
gForces = track_td6->max_negative_vertical_g * 32;
gfx_draw_string_left(dpi, STR_MAX_NEGATIVE_VERTICAL_G, &gForces, 0, x, y);
y += 10;
@ -518,7 +518,8 @@ static void window_track_list_paint()
gfx_draw_string_left(dpi, STR_MAX_LATERAL_G, &gForces, 0, x, y);
y += 10;
if (track_td6->var_07 / 4 >= 2) {
// If .TD6
if (track_td6->version_and_colour_scheme / 4 >= 2) {
if (track_td6->total_air_time != 0) {
// Total air time
airTime = track_td6->total_air_time * 25;

View File

@ -308,7 +308,8 @@ static void window_track_place_clear_provisional()
{
if (_window_track_place_last_was_valid) {
sub_6D01B3(
(RCT2_GLOBAL(0x00F440EB, uint8) << 8) | 6,
6,
RCT2_GLOBAL(0x00F440EB, uint8),
_window_track_place_last_valid_x,
_window_track_place_last_valid_y,
_window_track_place_last_valid_z
@ -342,7 +343,7 @@ static int window_track_place_get_base_z(int x, int y)
if (mapElement->properties.surface.terrain & 0x1F)
z = max(z, (mapElement->properties.surface.terrain & 0x1F) << 4);
return z + sub_6D01B3(3, x, y, z);
return z + sub_6D01B3(3, 0, x, y, z);
}
static void window_track_place_attempt_placement(int x, int y, int z, int bl, money32 *cost, uint8 *rideIndex)
@ -354,7 +355,7 @@ static void window_track_place_attempt_placement(int x, int y, int z, int bl, mo
ebx = bl;
ecx = y;
edi = z;
result = game_do_command_p(GAME_COMMAND_47, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
result = game_do_command_p(GAME_COMMAND_PLACE_TRACK, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
if (cost != NULL) *cost = result;
if (rideIndex != NULL) *rideIndex = edi & 0xFF;
@ -427,7 +428,7 @@ static void window_track_place_mouseup()
window_track_place_draw_mini_preview();
break;
case WIDX_MIRROR:
RCT2_CALLPROC_EBPSAFE(0x006D2436);
track_mirror();
RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint16) = (-RCT2_GLOBAL(RCT2_ADDRESS_TRACK_PREVIEW_ROTATION, uint16)) & 3;
window_invalidate(w);
_window_track_place_last_x = 0xFFFF;
@ -477,7 +478,7 @@ static void window_track_place_toolupdate()
// Check if tool map position has changed since last update
if (x == _window_track_place_last_x && y == _window_track_place_last_y) {
sub_6D01B3(0, x, y, 0);
sub_6D01B3(0, 0, x, y, 0);
return;
}
@ -510,7 +511,7 @@ static void window_track_place_toolupdate()
widget_invalidate(w, WIDX_PRICE);
}
sub_6D01B3(0, x, y, z);
sub_6D01B3(0, 0, x, y, z);
}
/**

View File

@ -28,8 +28,7 @@
void sub_673883(int x, int y, int z);
void sub_69A48B(int x, int y, int z);
void sub_6A6C66(int x, int y, rct_map_element *mapElement, int flags);
void sub_6A759F();
enum {
FOOTPATH_CONSTRUCTION_FLAG_ALLOW_DURING_PAUSED = 1 << 3

View File

@ -49,5 +49,7 @@ void footpath_provisional_update();
void footpath_get_coordinates_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
void footpath_bridge_get_info_from_pos(int screenX, int screenY, int *x, int *y, int *direction, rct_map_element **mapElement);
void sub_673883(int x, int y, int z);
void sub_6A6C66(int x, int y, rct_map_element *mapElement, int flags);
void sub_6A759F();
#endif

View File

@ -174,6 +174,22 @@ rct_map_element *map_get_surface_element_at(int x, int y)
return mapElement;
}
rct_map_element* map_get_path_element_at(int x, int y, int z){
rct_map_element *mapElement = map_get_first_element_at(x, y);
uint8 mapFound = 0;
// Find the path element at known z
do {
if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_PATH)
continue;
if (mapElement->base_height != z)
continue;
return mapElement;
} while (!map_element_is_last_for_tile(mapElement++));
return NULL;
}
/**
*
* rct2: 0x0068AB4C

View File

@ -256,6 +256,7 @@ void map_element_set_terrain(rct_map_element *element, int terrain);
void map_element_set_terrain_edge(rct_map_element *element, int terrain);
int map_height_from_slope(int x, int y, int slope);
rct_map_element *map_get_surface_element_at(int x, int y);
rct_map_element* map_get_path_element_at(int x, int y, int z);
int map_element_height(int x, int y);
void sub_68B089();
int map_coord_is_connected(int x, int y, int z, uint8 faceDirection);