mirror of https://github.com/OpenRCT2/OpenRCT2.git
commit
0104042640
|
@ -89,6 +89,7 @@
|
|||
<ClCompile Include="..\src\ride\ride.c" />
|
||||
<ClCompile Include="..\src\ride\ride_data.c" />
|
||||
<ClCompile Include="..\src\ride\ride_ratings.c" />
|
||||
<ClCompile Include="..\src\ride\station.c" />
|
||||
<ClCompile Include="..\src\ride\track.c" />
|
||||
<ClCompile Include="..\src\ride\vehicle.c" />
|
||||
<ClCompile Include="..\src\scenario.c" />
|
||||
|
@ -190,6 +191,7 @@
|
|||
<ClInclude Include="..\src\ride\ride.h" />
|
||||
<ClInclude Include="..\src\ride\ride_data.h" />
|
||||
<ClInclude Include="..\src\ride\ride_ratings.h" />
|
||||
<ClInclude Include="..\src\ride\station.h" />
|
||||
<ClInclude Include="..\src\ride\track.h" />
|
||||
<ClInclude Include="..\src\ride\vehicle.h" />
|
||||
<ClInclude Include="..\src\scenario.h" />
|
||||
|
|
|
@ -381,7 +381,6 @@
|
|||
<ClCompile Include="..\lib\lodepng\lodepng.c" />
|
||||
<ClCompile Include="..\lib\lodepng\lodepng.c" />
|
||||
<ClCompile Include="..\lib\lodepng\lodepng.c" />
|
||||
<ClCompile Include="..\lib\lodepng\lodepng.c" />
|
||||
<ClCompile Include="..\src\drawing\rain.c">
|
||||
<Filter>Source\Drawing</Filter>
|
||||
</ClCompile>
|
||||
|
@ -434,6 +433,10 @@
|
|||
<ClCompile Include="..\src\windows\sign.c">
|
||||
<Filter>Source\Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\lib\libspeex\resample.c;..\lib\lodepng\lodepng.c" />
|
||||
<ClCompile Include="..\src\ride\station.c">
|
||||
<Filter>Source\Ride</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\management\award.h">
|
||||
|
@ -631,5 +634,8 @@
|
|||
<ClInclude Include="..\src\world\banner.h">
|
||||
<Filter>Source\World</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\ride\station.h">
|
||||
<Filter>Source\Ride</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -493,7 +493,7 @@ static void RCT2_CALLPROC_EBPSAFE(int address)
|
|||
/* Returns the flags register
|
||||
*
|
||||
*Flags register is as follows:
|
||||
*0bSZ0A_0P0C_0000_00000
|
||||
*0bSZ0A_0P0C_0000_0000
|
||||
*S = Signed flag
|
||||
*Z = Zero flag
|
||||
*C = Carry flag
|
||||
|
|
|
@ -1836,35 +1836,6 @@ void stop_vehicle_sounds()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update zoom based volume attenuation for ride music and clear music list
|
||||
* rct2: 0x006BC348
|
||||
*/
|
||||
void sub_6BC348()
|
||||
{
|
||||
RCT2_GLOBAL(0x009AF42C, rct_music_info*) = &RCT2_GLOBAL(0x009AF430, rct_music_info);
|
||||
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = (rct_viewport*)-1;
|
||||
rct_window* window = RCT2_GLOBAL(RCT2_ADDRESS_NEW_WINDOW_PTR, rct_window*);
|
||||
while (1) {
|
||||
window--;
|
||||
if (window < RCT2_ADDRESS(RCT2_ADDRESS_WINDOW_LIST, rct_window)) {
|
||||
break;
|
||||
}
|
||||
if (window->viewport && window->viewport->flags & VIEWPORT_FLAG_SOUND_ON) {
|
||||
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = window->viewport;
|
||||
RCT2_GLOBAL(0x00F438A8, rct_window*) = window;
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 0;
|
||||
if (window->viewport->zoom) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 30;
|
||||
if (window->viewport->zoom != 1) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 60;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006BC3AC
|
||||
|
@ -1874,17 +1845,32 @@ void sub_6BC348()
|
|||
* @param x (ax)
|
||||
* @param y (cx)
|
||||
* @param z (dx)
|
||||
* @param bx
|
||||
* @param ebp
|
||||
* @param di
|
||||
* @returns ebp register
|
||||
* @param sampleRate (di)
|
||||
* @param rideIndex (bl)
|
||||
* @param position (ebp)
|
||||
* @param tuneId (bh)
|
||||
* @returns new position (ebp)
|
||||
*/
|
||||
int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint16 bx, uint32 ebp, uint16 di)
|
||||
int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId)
|
||||
{
|
||||
uint8 bl = LOBYTE(bx);
|
||||
uint8 bh = HIBYTE(bx);
|
||||
{
|
||||
int a_eax, a_ebx, a_ecx, a_edx, a_esi, a_edi, a_ebp;
|
||||
|
||||
a_eax = x;
|
||||
a_ebx = (*tuneId << 8) | rideIndex;
|
||||
a_ecx = y;
|
||||
a_edx = z;
|
||||
a_edi = sampleRate;
|
||||
a_ebp = position;
|
||||
RCT2_CALLFUNC_X(0x006BC3AC, &a_eax, &a_ebx, &a_ecx, &a_edx, &a_esi, &a_edi, &a_ebp);
|
||||
|
||||
*tuneId = (a_ebx >> 8) & 0xFF;
|
||||
return a_ebp;
|
||||
}
|
||||
|
||||
// TODO fix / bh needs returning too!
|
||||
if(!(RCT2_GLOBAL(RCT2_ADDRESS_SCREEN_FLAGS, uint8) & SCREEN_FLAGS_SCENARIO_EDITOR) && !RCT2_GLOBAL(0x009AF59C, uint8) && RCT2_GLOBAL(0x00F438A4, rct_viewport*) != (rct_viewport*)-1) {
|
||||
RCT2_GLOBAL(0x009AF47C, uint16) = di;
|
||||
RCT2_GLOBAL(0x009AF47C, uint16) = sampleRate;
|
||||
sint16 v11;
|
||||
sint16 v12;
|
||||
switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)) {
|
||||
|
@ -1988,12 +1974,12 @@ int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint16 bx, uint32 ebp, uint16 di)
|
|||
rct_music_info2* music_info2 = &RCT2_GLOBAL(0x009AF46C, rct_music_info2);
|
||||
int channel = 0;
|
||||
uint32 a1;
|
||||
while (music_info2->id != bl && music_info2->var_1 != bh) {
|
||||
while (music_info2->id != rideIndex && music_info2->var_1 != *tuneId) {
|
||||
music_info2++;
|
||||
channel++;
|
||||
if (channel >= 2) {
|
||||
rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[bh];
|
||||
a1 = ebp + music_info3->var_4;
|
||||
rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[*tuneId];
|
||||
a1 = position + music_info3->var_4;
|
||||
goto label51;
|
||||
}
|
||||
}
|
||||
|
@ -2007,11 +1993,11 @@ int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint16 bx, uint32 ebp, uint16 di)
|
|||
a1 = sub_401B46(channel);
|
||||
RCT2_GLOBAL(0x014241BC, uint32) = 0;
|
||||
label51:
|
||||
if (a1 < RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[bh].var_0) {
|
||||
if (a1 < RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[*tuneId].var_0) {
|
||||
rct_music_info* music_info = RCT2_GLOBAL(0x009AF42C, rct_music_info*);
|
||||
if (music_info < (rct_music_info*)0x009AF46C/*music_info list end*/) {
|
||||
music_info->id = bl;
|
||||
music_info->var_1 = bh;
|
||||
music_info->id = rideIndex;
|
||||
music_info->var_1 = *tuneId;
|
||||
music_info->offset = a1;
|
||||
music_info->volume = v32;
|
||||
music_info->pan = panx;
|
||||
|
@ -2022,16 +2008,16 @@ int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint16 bx, uint32 ebp, uint16 di)
|
|||
} else {
|
||||
uint32 eax;
|
||||
label58:
|
||||
eax = ebp;
|
||||
ebp = bh;
|
||||
rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[bh];
|
||||
eax = position;
|
||||
position = *tuneId;
|
||||
rct_music_info3* music_info3 = &RCT2_GLOBAL(0x009AF1C8, rct_music_info3*)[*tuneId];
|
||||
eax += music_info3->var_4;
|
||||
if (eax < music_info3->var_0) {
|
||||
ebp = eax;
|
||||
position = eax;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ebp;
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -213,8 +213,8 @@ void audio_close();
|
|||
void pause_sounds();
|
||||
void unpause_sounds();
|
||||
void stop_vehicle_sounds();
|
||||
void sub_6BC348();
|
||||
void sub_6BC6D8();
|
||||
int sub_6BC3AC(sint16 x, sint16 y, sint16 z, uint8 rideIndex, uint16 sampleRate, uint32 position, uint8 *tuneId);
|
||||
|
||||
// 0x009AF59C probably does the same job
|
||||
// once it's confirmed and calls in pause_sounds() are reversed, it can be used instead of this
|
||||
|
|
|
@ -1793,3 +1793,38 @@ void sub_6EA73F()
|
|||
RCT2_CALLPROC_X(w->event_handlers[WE_RESIZE], 0, 0, 0, 0, (int)w, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update zoom based volume attenuation for ride music and clear music list.
|
||||
* rct2: 0x006BC348
|
||||
*/
|
||||
void window_update_viewport_ride_music()
|
||||
{
|
||||
rct_viewport *viewport;
|
||||
rct_window *w;
|
||||
|
||||
RCT2_GLOBAL(0x009AF42C, rct_music_info*) = (rct_music_info*)0x009AF430;
|
||||
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = (rct_viewport*)-1;
|
||||
|
||||
for (w = RCT2_LAST_WINDOW; w >= g_window_list; w--) {
|
||||
viewport = w->viewport;
|
||||
if (viewport == NULL || !(viewport->flags & VIEWPORT_FLAG_SOUND_ON))
|
||||
continue;
|
||||
|
||||
RCT2_GLOBAL(0x00F438A4, rct_viewport*) = viewport;
|
||||
RCT2_GLOBAL(0x00F438A8, rct_window*) = w;
|
||||
|
||||
switch (viewport->zoom) {
|
||||
case 0:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 0;
|
||||
break;
|
||||
case 1:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 30;
|
||||
break;
|
||||
default:
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_VOLUME_ADJUST_ZOOM, uint8) = 60;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -463,6 +463,8 @@ void tool_cancel();
|
|||
|
||||
void window_close_construction_windows();
|
||||
|
||||
void window_update_viewport_ride_music();
|
||||
|
||||
// Open window functions
|
||||
void window_main_open();
|
||||
void window_resize_gui(int width, int height);
|
||||
|
|
|
@ -558,11 +558,11 @@ void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argum
|
|||
*argument_2 = 0;
|
||||
break;
|
||||
case PEEP_STATE_ANSWERING:
|
||||
if (peep->pad_2C == 0){
|
||||
if (peep->var_2C == 0){
|
||||
*argument_1 = STR_WALKING;
|
||||
*argument_2 = 0;
|
||||
}
|
||||
else if (peep->pad_2C == 1){
|
||||
else if (peep->var_2C == 1){
|
||||
*argument_1 = STR_ANSWERING_RADIO_CALL;
|
||||
*argument_2 = 0;
|
||||
}
|
||||
|
|
|
@ -304,7 +304,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint8 sprite_identifier; // 0x00
|
||||
uint8 pad_01;
|
||||
uint8 var_01;
|
||||
uint16 var_02; // 0x02
|
||||
uint16 next; // 0x04
|
||||
uint16 previous; // 0x06
|
||||
|
@ -329,7 +329,7 @@ typedef struct {
|
|||
uint16 next_z; // 0x28
|
||||
uint8 var_2A;
|
||||
uint8 state; // 0x2B
|
||||
uint8 pad_2C;
|
||||
uint8 var_2C;
|
||||
uint8 sprite_type; // 0x2D
|
||||
uint8 type; // 0x2E
|
||||
union{
|
||||
|
@ -363,7 +363,7 @@ typedef struct {
|
|||
uint8 photo4_ride_ref; // 0x5E
|
||||
uint8 pad_5F[0x09]; // 0x5C
|
||||
uint8 current_ride; // 0x68
|
||||
uint8 pad_69;
|
||||
uint8 current_ride_station; // 0x69
|
||||
uint8 current_train; // 0x6A
|
||||
uint8 current_car; // 0x6B
|
||||
uint8 current_seat; // 0x6C
|
||||
|
|
|
@ -290,3 +290,34 @@ void sub_6C0C3F()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int staff_is_location_in_patrol_area(rct_peep *peep, int x, int y)
|
||||
{
|
||||
// Patrol quads are stored in a bit map (8 patrol quads per byte)
|
||||
// Each patrol quad is 4x4
|
||||
// Therefore there are in total 64 x 64 patrol quads in the 256 x 256 map
|
||||
int patrolOffset = peep->staff_id * (64 * 64 / 8);
|
||||
int patrolIndex = ((x & 0x1F80) >> 7) | ((y & 0x1F80) >> 1);
|
||||
int mask = 1 << (patrolIndex & 0x1F);
|
||||
int base = patrolIndex >> 5;
|
||||
|
||||
uint32 *patrolBits = (uint32*)(0x013B0E72 + patrolOffset + (base * 4));
|
||||
return (*patrolBits & mask) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C0905
|
||||
*/
|
||||
int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y)
|
||||
{
|
||||
// Check if location is in the park
|
||||
if (!sub_664F72(x, y, mechanic->z))
|
||||
return 0;
|
||||
|
||||
// Check if mechanic has patrol area
|
||||
if (!(RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[mechanic->staff_id] & 2))
|
||||
return 1;
|
||||
|
||||
return staff_is_location_in_patrol_area(mechanic, x, y);
|
||||
}
|
|
@ -22,6 +22,7 @@
|
|||
#define _STAFF_H_
|
||||
|
||||
#include "../common.h"
|
||||
#include "peep.h"
|
||||
|
||||
#define STAFF_MAX_COUNT 0xC8
|
||||
#define STAFF_TYPE_COUNT 0x04
|
||||
|
@ -45,5 +46,6 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx,
|
|||
void update_staff_colour(uint8 staff_type, uint16 color);
|
||||
uint16 hire_new_staff_member(uint8 staff_type);
|
||||
void sub_6C0C3F();
|
||||
int mechanic_is_location_in_patrol(rct_peep *mechanic, int x, int y);
|
||||
|
||||
#endif
|
1402
src/ride/ride.c
1402
src/ride/ride.c
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
union {
|
||||
uint8 var_0D0;
|
||||
uint8 time_limit; // 0x0D0
|
||||
uint8 num_laps; // 0x0D0
|
||||
};
|
||||
uint8 pad_0D1[0x3];
|
||||
uint8 measurement_index; // 0x0D4
|
||||
uint8 var_0D5;
|
||||
|
@ -178,20 +182,26 @@ typedef struct {
|
|||
uint16 var_158;
|
||||
uint8 pad_15A;
|
||||
uint8 num_riders; // 0x15B
|
||||
uint8 var_15C;
|
||||
uint8 music_tune_id; // 0x15C
|
||||
uint8 var_15D;
|
||||
union {
|
||||
uint16 slide_peep; // 0x15E
|
||||
uint16 maze_tiles; // 0x15E
|
||||
};
|
||||
uint8 pad_160[0x16];
|
||||
uint8 var_176;
|
||||
uint8 pad_177[0x9];
|
||||
sint16 build_date; // 0x180
|
||||
money16 upkeep_cost; // 0x182
|
||||
uint16 race_winner; // 0x184
|
||||
uint8 pad_186[0x06];
|
||||
uint8 var_18C;
|
||||
uint8 pad_186[0x02];
|
||||
uint32 music_position; // 0x188
|
||||
uint8 breakdown_reason_pending; // 0x18C
|
||||
uint8 mechanic_status; // 0x18D
|
||||
uint16 mechanic; // 0x18E
|
||||
uint8 pad_190[0x03];
|
||||
uint8 inspection_station; // 0x190
|
||||
uint8 broken_vehicle; // 0x191
|
||||
uint8 broken_car; // 0x192
|
||||
uint8 breakdown_reason; // 0x193
|
||||
money16 price_secondary; // 0x194
|
||||
uint16 var_196;
|
||||
|
@ -200,9 +210,18 @@ typedef struct {
|
|||
uint8 var_199;
|
||||
uint8 inspection_interval; // 0x19A
|
||||
uint8 last_inspection; // 0x19B
|
||||
uint8 pad_19C[0x8];
|
||||
uint8 var_19C;
|
||||
uint8 var_19D;
|
||||
uint8 var_19E;
|
||||
uint8 var_19F;
|
||||
uint8 var_1A0;
|
||||
uint8 var_1A1;
|
||||
uint8 var_1A2;
|
||||
uint8 var_1A3;
|
||||
uint32 var_1A4;
|
||||
uint8 pad_1A8[6];
|
||||
uint8 pad_1A8[4];
|
||||
uint8 var_1AC;
|
||||
uint8 var_1AD;
|
||||
uint8 var_1AE;
|
||||
uint8 connected_message_throttle; // 0x1AF
|
||||
money32 income_per_hour; // 0x1B0
|
||||
|
@ -261,8 +280,9 @@ enum {
|
|||
RIDE_LIFECYCLE_NO_RAW_STATS = 1 << 3,
|
||||
RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING = 1 << 4,
|
||||
RIDE_LIFECYCLE_ON_RIDE_PHOTO = 1 << 5,
|
||||
|
||||
RIDE_LIFECYCLE_BREAKDOWN_PENDING = 1 << 6,
|
||||
RIDE_LIFECYCLE_BROKEN_DOWN = 1 << 7,
|
||||
RIDE_LIFECYCLE_DUE_INSPECTION = 1 << 8,
|
||||
|
||||
RIDE_LIFECYCLE_CRASHED = 1 << 10,
|
||||
RIDE_LIFECYCLE_11 = 1 << 11,
|
||||
|
@ -480,9 +500,11 @@ enum {
|
|||
};
|
||||
|
||||
enum {
|
||||
RIDE_MECHANIC_STATUS_CALLING = 1,
|
||||
RIDE_MECHANIC_STATUS_HEADING = 2,
|
||||
RIDE_MECHANIC_STATUS_FIXING = 3,
|
||||
RIDE_MECHANIC_STATUS_UNDEFINED,
|
||||
RIDE_MECHANIC_STATUS_CALLING,
|
||||
RIDE_MECHANIC_STATUS_HEADING,
|
||||
RIDE_MECHANIC_STATUS_FIXING,
|
||||
RIDE_MECHANIC_STATUS_4
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -522,6 +544,16 @@ enum {
|
|||
RIDE_ENTRANCE_STYLE_SPACE
|
||||
};
|
||||
|
||||
enum {
|
||||
RIDE_INSPECTION_EVERY_10_MINUTES,
|
||||
RIDE_INSPECTION_EVERY_20_MINUTES,
|
||||
RIDE_INSPECTION_EVERY_30_MINUTES,
|
||||
RIDE_INSPECTION_EVERY_45_MINUTES,
|
||||
RIDE_INSPECTION_EVERY_HOUR,
|
||||
RIDE_INSPECTION_EVERY_2_HOURS,
|
||||
RIDE_INSPECTION_NEVER
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8 main;
|
||||
uint8 additional;
|
||||
|
@ -545,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;
|
||||
|
||||
|
@ -587,5 +622,6 @@ rct_ride_type *ride_get_entry(rct_ride *ride);
|
|||
uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType);
|
||||
void ride_measurements_update();
|
||||
rct_ride_measurement *ride_get_measurement(int rideIndex, rct_string_id *message);
|
||||
void ride_breakdown_add_news_item(int rideIndex);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -772,3 +772,97 @@ const uint8 RideAvailableModes[] = {
|
|||
RIDE_MODE_CONTINUOUS_CIRCUIT, RIDE_MODE_CONTINUOUS_CIRCUIT_BLOCK_SECTIONED, 0xFF, // 59 LIM Launched Roller Coaster
|
||||
RIDE_MODE_POWERED_LAUNCH_35, RIDE_MODE_POWERED_LAUNCH_BLOCK_SECTIONED, 0xFF // 60 (none)
|
||||
};
|
||||
|
||||
const uint8 RideAvailableBreakdowns[] = {
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 00 Spiral Roller coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 01 Stand Up Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 02 Suspended Swinging
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 03 Inverted
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 04 Steel Mini Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 05 Mini Railroad
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 06 Monorail
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 07 Mini Suspended Coaster
|
||||
(1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 08 Bumper Boats
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 09 Wooden Wild Mine/Mouse
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 0A Steeplechase/Motorbike/Soap Box Derby
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 0B Car Ride
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 0C Launched Freefall
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 0D Bobsleigh Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 0E Observation Tower
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 0F Looping Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 10 Dinghy Slide
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 11 Mine Train Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 12 Chairlift
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 13 Corkscrew Roller Coaster
|
||||
0, // 14 Maze
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 15 Spiral Slide
|
||||
(1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 16 Go Karts
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 17 Log Flume
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 18 River Rapids
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 19 Bumper Cars
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 1A Pirate Ship
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 1B Swinging Inverter Ship
|
||||
0, // 1C Food Stall
|
||||
0, // 1D (none)
|
||||
0, // 1E Drink Stall
|
||||
0, // 1F (none)
|
||||
0, // 20 Shop (all types)
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 21 Merry Go Round
|
||||
0, // 22 Balloon Stall (maybe)
|
||||
0, // 23 Information Kiosk
|
||||
0, // 24 Bathroom
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 25 Ferris Wheel
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 26 Motion Simulator
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 27 3D Cinema
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 28 Gravitron
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 29 Space Rings
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 2A Reverse Freefall Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN), // 2B Elevator
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 2C Vertical Drop Roller Coaster
|
||||
0, // 2D ATM
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 2E Twist
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 2F Haunted House
|
||||
0, // 30 First Aid
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 31 Circus Show
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 32 Ghost Train
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 33 Twister Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 34 Wooden Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 35 Side-Friction Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 36 Wild Mouse
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 37 Multi Dimension Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 38 (none)
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 39 Flying Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 3A (none)
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 3B Virginia Reel
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_CONTROL_FAILURE), // 3C Splash Boats
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 3D Mini Helicopters
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 3E Lay-down Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_DOORS_STUCK_CLOSED) | (1 << BREAKDOWN_DOORS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 3F Suspended Monorail
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 40 (none)
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 41 Reverser Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 42 Heartline Twister Roller Coaster
|
||||
0, // 43 Mini Golf
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 44 Giga Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 45 Roto-Drop
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 46 Flying Saucers
|
||||
0, // 47 Crooked House
|
||||
(1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 48 Monorail Cycles
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 49 Compact Inverted Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 4A Water Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 4B Air Powered Vertical Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 4C Inverted Hairpin Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 4D Magic Carpet
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 4E Submarine Ride
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 4F River Rafts
|
||||
0, // 50 (none)
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT), // 51 Enterprise
|
||||
0, // 52 (none)
|
||||
0, // 53 (none)
|
||||
0, // 54 (none)
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 55 (none)
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 56 Inverted Impulse Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 57 Mini Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION), // 58 Mine Ride
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE), // 59 LIM Launched Roller Coaster
|
||||
(1 << BREAKDOWN_SAFETY_CUT_OUT) | (1 << BREAKDOWN_RESTRAINTS_STUCK_CLOSED) | (1 << BREAKDOWN_RESTRAINTS_STUCK_OPEN) | (1 << BREAKDOWN_VEHICLE_MALFUNCTION) | (1 << BREAKDOWN_BRAKES_FAILURE) // 60 (none)
|
||||
};
|
|
@ -41,5 +41,6 @@ extern const uint8 rideUnknownData3[0x60];
|
|||
|
||||
extern const rct_ride_name_convention RideNameConvention[96];
|
||||
extern const uint8 RideAvailableModes[];
|
||||
extern const uint8 RideAvailableBreakdowns[];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,309 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../addresses.h"
|
||||
#include "../scenario.h"
|
||||
#include "../world/sprite.h"
|
||||
#include "station.h"
|
||||
|
||||
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);
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006ABFFB
|
||||
*/
|
||||
void ride_update_station(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
if (ride->station_starts[stationIndex] == 0xFFFF)
|
||||
return;
|
||||
|
||||
switch (ride->mode) {
|
||||
case RIDE_MODE_RACE:
|
||||
ride_update_station_race(ride, stationIndex);
|
||||
break;
|
||||
case RIDE_MODE_BUMPERCAR:
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
ride_update_station_normal(ride, stationIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC0A1
|
||||
*/
|
||||
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) {
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
|
||||
if ((ride->station_depart[stationIndex] & STATION_DEPART_FLAG) || (mapElement->properties.track.sequence & 0x80))
|
||||
ride_invalidate_station_start(ride, stationIndex, 0);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC12B
|
||||
*/
|
||||
static void ride_update_station_bumpercar(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int i, dx, dl, dh;
|
||||
rct_vehicle *vehicle;
|
||||
|
||||
if (
|
||||
ride->status == RIDE_STATUS_CLOSED ||
|
||||
(ride->lifecycle_flags & (RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED))
|
||||
) {
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) {
|
||||
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 (vehicle->var_CE < dh || (vehicle->var_CE < dh && vehicle->var_51 > dl))
|
||||
continue;
|
||||
|
||||
// End match
|
||||
ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC1DF
|
||||
*/
|
||||
static void ride_update_station_race(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int i, numLaps;
|
||||
rct_vehicle *vehicle;
|
||||
rct_peep *peep;
|
||||
|
||||
if (
|
||||
ride->status == RIDE_STATUS_CLOSED ||
|
||||
(ride->lifecycle_flags & (RIDE_LIFECYCLE_BROKEN_DOWN | RIDE_LIFECYCLE_CRASHED))
|
||||
) {
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
ride->station_depart[stationIndex] &= ~STATION_DEPART_FLAG;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Begin the race
|
||||
ride_race_init_vehicle_speeds(ride);
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING;
|
||||
ride->station_depart[stationIndex] |= STATION_DEPART_FLAG;
|
||||
ride->var_14D |= 12;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC988
|
||||
* set the speed of the go kart type vehicle at the start to a random value or alter if peep name is an easter egg
|
||||
* @param ride (esi)
|
||||
*/
|
||||
static void ride_race_init_vehicle_speeds(rct_ride *ride)
|
||||
{
|
||||
rct_ride_type *rideEntry;
|
||||
rct_vehicle *vehicle;
|
||||
uint8 *unk;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ride->num_vehicles; i++) {
|
||||
vehicle = &g_sprite_list[ride->vehicles[i]].vehicle;
|
||||
vehicle->var_48 &= ~(1 << 6);
|
||||
|
||||
rideEntry = GET_RIDE_ENTRY(vehicle->var_D6);
|
||||
unk = (uint8*)((int)rideEntry + (vehicle->var_31 * 0x65));
|
||||
|
||||
vehicle->speed = (scenario_rand() & 16) - 8 + RCT2_GLOBAL(unk + 0x76, uint8);
|
||||
|
||||
if (vehicle->var_B3) {
|
||||
rct_peep *peep = &g_sprite_list[vehicle->peep].peep;
|
||||
|
||||
switch (peep_get_easteregg_name_id(peep)) {
|
||||
case EASTEREGG_PEEP_NAME_MICHAEL_SCHUMACHER:
|
||||
vehicle->speed += 35;
|
||||
break;
|
||||
case EASTEREGG_PEEP_NAME_JACQUES_VILLENEUVE:
|
||||
vehicle->speed += 25;
|
||||
break;
|
||||
case EASTEREGG_PEEP_NAME_DAMON_HILL:
|
||||
vehicle->speed += 55;
|
||||
break;
|
||||
case EASTEREGG_PEEP_NAME_CHRIS_SAWYER:
|
||||
vehicle->speed += 14;
|
||||
break;
|
||||
case EASTEREGG_PEEP_NAME_MR_BEAN:
|
||||
vehicle->speed = 9;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006AC2C7
|
||||
*/
|
||||
static void ride_invalidate_station_start(rct_ride *ride, int stationIndex, int dl)
|
||||
{
|
||||
int x, y;
|
||||
rct_map_element *mapElement;
|
||||
|
||||
x = (ride->station_starts[stationIndex] & 0xFF) * 32;
|
||||
y = (ride->station_starts[stationIndex] >> 8) * 32;
|
||||
mapElement = ride_get_station_start_track_element(ride, stationIndex);
|
||||
|
||||
mapElement->properties.track.sequence &= 0x7F;
|
||||
if (dl != 0)
|
||||
mapElement->properties.track.sequence |= 0x80;
|
||||
|
||||
// Invalidate map tile
|
||||
map_invalidate_tile(x, y, mapElement->base_height * 8, mapElement->clearance_height * 8);
|
||||
}
|
||||
|
||||
rct_map_element *ride_get_station_start_track_element(rct_ride *ride, int stationIndex)
|
||||
{
|
||||
int x, y, z;
|
||||
rct_map_element *mapElement;
|
||||
|
||||
x = ride->station_starts[stationIndex] & 0xFF;
|
||||
y = ride->station_starts[stationIndex] >> 8;
|
||||
z = ride->station_heights[stationIndex];
|
||||
|
||||
// Get first element of the tile
|
||||
mapElement = TILE_MAP_ELEMENT_POINTER(y * 256 + x);
|
||||
|
||||
// Find the station track element
|
||||
do {
|
||||
if ((mapElement->type & MAP_ELEMENT_TYPE_MASK) == MAP_ELEMENT_TYPE_TRACK && z == mapElement->base_height)
|
||||
return mapElement;
|
||||
|
||||
mapElement++;
|
||||
} while (!((mapElement - 1)->flags & MAP_ELEMENT_FLAG_LAST_TILE));
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _RIDE_STATION_H_
|
||||
#define _RIDE_STATION_H_
|
||||
|
||||
#include "../common.h"
|
||||
#include "../world/map.h"
|
||||
#include "ride.h"
|
||||
|
||||
void ride_update_station(rct_ride *ride, int stationIndex);
|
||||
rct_map_element *ride_get_station_start_track_element(rct_ride *ride, int stationIndex);
|
||||
|
||||
#endif
|
|
@ -76,7 +76,10 @@ typedef struct {
|
|||
uint8 pad_C3[0x09];
|
||||
uint8 var_CC;
|
||||
uint8 var_CD;
|
||||
union {
|
||||
uint8 var_CE;
|
||||
uint8 num_laps; // 0xCE
|
||||
};
|
||||
uint8 pad_CF[0x07];
|
||||
uint8 var_D6;
|
||||
} rct_vehicle;
|
||||
|
|
|
@ -642,7 +642,7 @@ void scenario_update()
|
|||
*
|
||||
* rct2: 0x006E37D2
|
||||
*/
|
||||
int scenario_rand()
|
||||
unsigned int scenario_rand()
|
||||
{
|
||||
int eax = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32) += ror32(RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_1, uint32) ^ 0x1234567F, 7);
|
||||
|
|
|
@ -407,6 +407,6 @@ int scenario_load(const char *path);
|
|||
int scenario_load_and_play(const rct_scenario_basic *scenario);
|
||||
int scenario_load_and_play_from_path(const char *path);
|
||||
void scenario_update();
|
||||
int scenario_rand();
|
||||
unsigned int scenario_rand();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,3 +52,14 @@ long fsize(FILE *fp)
|
|||
|
||||
return size;
|
||||
}
|
||||
|
||||
int bitscanforward(int source)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
if (source & (1 << i))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -29,4 +29,6 @@ int mph_to_kmph(int mph);
|
|||
|
||||
long fsize(FILE *fp);
|
||||
|
||||
int bitscanforward(int source);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -627,7 +627,7 @@ void window_guest_overview_mouse_up(){
|
|||
RCT2_CALLPROC_X(0x0069E9D3, 0x8000, 0, peep->y, peep->z, (int)peep, 0, 0);
|
||||
RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
peep->state = 9;
|
||||
peep->pad_2C = 0;
|
||||
peep->var_2C = 0;
|
||||
RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0);
|
||||
break;
|
||||
case WIDX_RENAME:
|
||||
|
@ -1204,7 +1204,7 @@ void window_guest_overview_tool_down(){
|
|||
|
||||
int dest_z = ((uint8*)edx)[2] * 8 + 16;
|
||||
|
||||
if (sub_664F72(tile_x, tile_y, dest_z)){
|
||||
if (!sub_664F72(tile_x, tile_y, dest_z)){
|
||||
window_error_open(0x785,-1);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1124,7 +1124,7 @@ void window_staff_overview_tool_down(){
|
|||
|
||||
int dest_z = ((uint8*)edx)[2] * 8 + 16;
|
||||
|
||||
if (sub_664F72(tile_x, tile_y, dest_z)){
|
||||
if (!sub_664F72(tile_x, tile_y, dest_z)){
|
||||
window_error_open(0x785, -1);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -437,27 +437,56 @@ static void sub_6A87BB(int x, int y)
|
|||
RCT2_CALLPROC_X(0x006A87BB, x, 0, y, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* rct2: 0x664F72 */
|
||||
int sub_664F72(int x, int y, int z){
|
||||
if (x > 0x1FFF || y > 0x1FFF){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0x6C1;
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00664F72
|
||||
*/
|
||||
int sub_664F72(int x, int y, int z)
|
||||
{
|
||||
rct_map_element *mapElement;
|
||||
|
||||
if (x < (256 * 32) && y < (256 * 32)) {
|
||||
mapElement = map_get_surface_element_at(x / 32, y / 32);
|
||||
if (mapElement->properties.surface.ownership & 0x20)
|
||||
return 1;
|
||||
|
||||
if (mapElement->properties.surface.ownership & 0x10) {
|
||||
z /= 8;
|
||||
if (z < mapElement->base_height || z - 2 > mapElement->base_height)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 1729;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x00664F2C
|
||||
*/
|
||||
int map_is_location_in_park(int x, int y)
|
||||
{
|
||||
rct_map_element *mapElement;
|
||||
|
||||
if (x < (256 * 32) && y < (256 * 32)) {
|
||||
mapElement = map_get_surface_element_at(x / 32, y / 32);
|
||||
if (mapElement->properties.surface.ownership & 0x20)
|
||||
return 1;
|
||||
}
|
||||
|
||||
rct_map_element* map_element = map_get_surface_element_at(x / 32, y / 32);
|
||||
if (map_element->properties.surface.ownership & 0x20) return 0;
|
||||
if (!(map_element->properties.surface.ownership & 0x10)){
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0x6C1;
|
||||
return 1;
|
||||
}
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 1729;
|
||||
return 0;
|
||||
}
|
||||
|
||||
z >>= 3;
|
||||
if ((z & 0xFF) < map_element->base_height)return 0;
|
||||
z = (z & 0xFF) - 2;
|
||||
if (z > map_element->base_height)return 0;
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 0x6C1;
|
||||
return 1;
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006ECB60
|
||||
* NOTE: x, y and z are in pixels, not tile units
|
||||
*/
|
||||
void map_invalidate_tile(int x, int y, int zLow, int zHigh)
|
||||
{
|
||||
RCT2_CALLPROC_X(0x006ECB60, x, 0, y, 0, zHigh, zLow, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -206,6 +206,8 @@ int map_coord_is_connected(uint16 coordinate, uint8 height, uint8 face_direction
|
|||
void map_invalidate_animations();
|
||||
void sub_6A876D();
|
||||
int sub_664F72(int x, int y, int z);
|
||||
int map_is_location_in_park(int x, int y);
|
||||
void map_invalidate_tile(int x, int y, int zLow, int zHigh);
|
||||
|
||||
void fountain_update_all();
|
||||
|
||||
|
|
|
@ -508,7 +508,7 @@ static rct_peep *park_generate_new_guest_due_to_campaign(int campaign)
|
|||
static void park_generate_new_guests()
|
||||
{
|
||||
// Generate a new guest for some probability
|
||||
if ((scenario_rand() & 0xFFFF) < _guestGenerationProbability) {
|
||||
if ((int)(scenario_rand() & 0xFFFF) < _guestGenerationProbability) {
|
||||
int difficultGeneration = (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_DIFFICULT_GUEST_GENERATION) != 0;
|
||||
if (!difficultGeneration || _suggestedGuestMaximum + 150 >= RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16))
|
||||
park_generate_new_guest();
|
||||
|
@ -519,7 +519,7 @@ static void park_generate_new_guests()
|
|||
for (campaign = 0; campaign < ADVERTISING_CAMPAIGN_COUNT; campaign++) {
|
||||
if (RCT2_ADDRESS(0x01358102, uint8)[campaign] != 0) {
|
||||
// Random chance of guest generation
|
||||
if ((scenario_rand() & 0xFFFF) < marketing_get_campaign_guest_generation_probability(campaign))
|
||||
if ((int)(scenario_rand() & 0xFFFF) < marketing_get_campaign_guest_generation_probability(campaign))
|
||||
park_generate_new_guest_due_to_campaign(campaign);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue