diff --git a/src/interface/viewport.c b/src/interface/viewport.c index c7f2adb167..2ee03af13f 100644 --- a/src/interface/viewport.c +++ b/src/interface/viewport.c @@ -751,20 +751,55 @@ void sub_688485(){ } -int sub_0x686806(rct_sprite* sprite, int eax, int ecx, int edx){ +int sub_0x686806(rct_sprite* sprite, int eax, int image_id, int ecx, int edx){ int ebp = (eax >> 8) & 0xFF; edx <<= 16; ebp += RCT2_GLOBAL(0x9DEA56, uint16); RCT2_GLOBAL(0xF1AD28, uint32) = 0; RCT2_GLOBAL(0xF1AD2C, uint32) = 0; edx = (edx >> 16) | (ebp << 16); - ebp = RCT2_GLOBAL(0xEE7888, uint32); - if ((uint32)ebp >= RCT2_GLOBAL(0xEE7880, uint32)) return 1; - //686840 not finished + + //Not a paint struct but something similar + paint_struct* ps = RCT2_GLOBAL(0xEE7888, paint_struct*); + + if ((uint32)ps >= RCT2_GLOBAL(0xEE7880, uint32)) return 1; + + ps->image_id = image_id; + + rct_g1_element *g1Element = &RCT2_ADDRESS(RCT2_ADDRESS_G1_ELEMENTS, rct_g1_element)[image_id & 0x7FFFF]; + + eax = (eax & 0xFF) + RCT2_GLOBAL(0x9DE568, uint16); + ecx = (ecx & 0xFF) + RCT2_GLOBAL(0x9DE56C, uint16); + + int x = ecx - eax; + int y = (ecx + eax) / 2 - (edx & 0xFFFF); + + ps->x = x; + ps->y = y; + + int left = x + g1Element->x_offset; + int bottom = y + g1Element->y_offset; + + int right = left + g1Element->width; + int top = bottom + g1Element->height; + + RCT2_GLOBAL(0xF1AD1C, uint16) = left; + RCT2_GLOBAL(0xF1AD1E, uint16) = bottom; + + rct_drawpixelinfo* dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); + + if (right <= dpi->x)return 1; + if (top <= dpi->y)return 1; + if (left > dpi->x + dpi->width) return 1; + if (bottom > dpi->y + dpi->height) return 1; + + RCT2_GLOBAL(0x9DE568, uint16); + //686918 not finished return 0; } + /** * Litter Paint Setup?? * rct2: 0x006736FC @@ -829,8 +864,8 @@ void sub_0x69E8B0(uint32 eax, uint32 ecx){ eax = (eax & 0x1FE0) << 3 | (ecx >> 5); int sprite_idx = RCT2_ADDRESS(0xF1EF60, uint16)[eax]; if (sprite_idx == SPRITE_INDEX_NULL) return; - - for (rct_sprite* spr = &g_sprite_list[sprite_idx]; sprite_idx != SPRITE_INDEX_NULL; sprite_idx = spr->unknown.var_02){ + + for (rct_sprite* spr = &g_sprite_list[sprite_idx]; sprite_idx != SPRITE_INDEX_NULL; sprite_idx = spr->unknown.next_in_quadrant){ spr = &g_sprite_list[sprite_idx]; dpi = RCT2_GLOBAL(0x140E9A8, rct_drawpixelinfo*); diff --git a/src/interface/viewport_interaction.c b/src/interface/viewport_interaction.c index 86ecbe17b1..0df24f497f 100644 --- a/src/interface/viewport_interaction.c +++ b/src/interface/viewport_interaction.c @@ -67,7 +67,7 @@ int viewport_interaction_get_item_left(int x, int y, viewport_interaction_info * switch (sprite->unknown.sprite_identifier) { case SPRITE_IDENTIFIER_VEHICLE: vehicle = &(sprite->vehicle); - if (vehicle->var_D6 != 255) + if (vehicle->ride_subtype != 255) vehicle_set_map_toolbar(vehicle); else info->type = VIEWPORT_INTERACTION_ITEM_NONE; diff --git a/src/object.c b/src/object.c index eaae1f0860..96d46ed858 100644 --- a/src/object.c +++ b/src/object.c @@ -644,7 +644,7 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp no_positions = *((uint16*)peep_loading_positions); peep_loading_positions += 2; } - rideVehicleEntry->var_61 = (uint32)peep_loading_positions; + rideVehicleEntry->peep_loading_positions = peep_loading_positions; peep_loading_positions += no_positions; } } @@ -718,7 +718,7 @@ int paint_ride_entry(int flags, int ebx, int ecx, int edx, rct_drawpixelinfo* dp } rideVehicleEntry->var_02 = 0; rideVehicleEntry->var_03 = 0; - rideVehicleEntry->var_61 = 0; + rideVehicleEntry->peep_loading_positions = 0; } ride_type->var_1AE = 0; diff --git a/src/peep/peep.c b/src/peep/peep.c index 71fd8f08a1..555e04e25d 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -29,6 +29,7 @@ #include "../sprites.h" #include "../world/sprite.h" #include "../world/scenery.h" +#include "../management/marketing.h" #include "peep.h" #include "staff.h" @@ -147,15 +148,15 @@ void sub_693B58(rct_peep* peep){ else{ ebx = RCT2_ADDRESS(0x981D8F, uint8)[peep->action]; } - if (ebx == peep->var_6E)return; + if (ebx == peep->action_sprite_type)return; invalidate_sprite((rct_sprite*)peep); - peep->var_6E = ebx; + peep->action_sprite_type = ebx; uint8* edx = RCT2_ADDRESS(0x98270C, uint8*)[peep->sprite_type * 2]; - peep->var_14 = edx[ebx * 4]; - peep->var_09 = edx[ebx * 4 + 1]; - peep->var_15 = edx[ebx * 4 + 2]; + peep->sprite_width = edx[ebx * 4]; + peep->sprite_height_negative = edx[ebx * 4 + 1]; + peep->sprite_height_positive = edx[ebx * 4 + 2]; // This is pointless as nothing will have changed. invalidate_sprite((rct_sprite*)peep); } @@ -243,13 +244,13 @@ void peep_check_cant_find_exit(rct_peep* peep){ } /* rct2: 0x6939EB - * Possibly peep update action frame. * Also used to move peeps to the correct position to - * start an action. Returns 0 if the correct destination - * has not yet been reached. + * start an action. Returns 1 if the correct destination + * has not yet been reached. xy_distance is how close the + * peep is to the target. */ -int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ - RCT2_GLOBAL(0xF1AEF0, uint8) = peep->var_70; +int peep_update_action(sint16* x, sint16* y, sint16* xy_distance, rct_peep* peep){ + RCT2_GLOBAL(0xF1AEF0, uint8) = peep->action_sprite_image_offset; if (peep->action == 0xFE){ peep->action = 0xFF; } @@ -259,9 +260,11 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ int x_delta = abs(*x); int y_delta = abs(*y); - + + *xy_distance = x_delta + y_delta; + if (peep->action >= 0xFE){ - if (x_delta + y_delta <= peep->destination_tolerence){ + if (*xy_distance <= peep->destination_tolerence){ return 0; } int direction = 0; @@ -280,25 +283,24 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ peep->sprite_direction = direction; *x = peep->x + RCT2_ADDRESS(0x981D7C, uint16)[direction / 4]; *y = peep->y + RCT2_ADDRESS(0x981D7E, uint16)[direction / 4]; - int ebx = peep->var_E0 + 1; + peep->no_action_frame_no++; uint32* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2]; - uint8* _edi = (uint8*)(edi[peep->var_6E * 2 + 1]); - if (ebx >= *_edi){ - ebx = 0; + uint8* _edi = (uint8*)(edi[peep->action_sprite_type * 2 + 1]); + if (peep->no_action_frame_no >= *_edi){ + peep->no_action_frame_no = 0; } - peep->var_E0 = ebx; - peep->var_70 = _edi[ebx + 1]; + peep->action_sprite_image_offset = _edi[peep->no_action_frame_no + 1]; return 1; } int* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2]; - uint8* _edi = (uint8*)(edi[peep->var_6E * 2 + 1]); + uint8* _edi = (uint8*)(edi[peep->action_sprite_type * 2 + 1]); peep->action_frame++; int ebx = _edi[peep->action_frame + 1]; // If last frame of action if (ebx == 0xFF){ - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; peep->action = 0xFF; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -306,7 +308,7 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ *y = peep->y; return 1; } - peep->var_70 = ebx; + peep->action_sprite_image_offset = ebx; // If not throwing up and not at the frame where sick appears. if (peep->action != PEEP_ACTION_THROW_UP || peep->action_frame != 15){ @@ -339,6 +341,7 @@ int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ *y = peep->y; return 1; } + /** * rct2: 0x0069A409 * Decreases rider count if on/entering a ride. @@ -353,6 +356,171 @@ void peep_decrement_num_riders(rct_peep* peep){ } } +/* Part of 0x0069B8CC rct2:0x0069BC31 */ +void set_sprite_type(rct_peep* peep, uint8 type){ + if (peep->sprite_type == type)return; + + peep->sprite_type = type; + peep->action_sprite_image_offset = 0; + peep->no_action_frame_no = 0; + + if (peep->action >= PEEP_ACTION_NONE_1) + peep->action = PEEP_ACTION_NONE_2; + + peep->flags &= ~PEEP_FLAGS_SLOW_WALK; + if (RCT2_ADDRESS(0x00982134, uint8)[type] & 1){ + peep->flags |= PEEP_FLAGS_SLOW_WALK; + } + + peep->action_sprite_type = 0xFF; + sub_693B58(peep); + + if (peep->state == PEEP_STATE_SITTING){ + peep->action = PEEP_ACTION_NONE_1; + peep->var_6F = 7; + RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0); + } + if (peep->state == PEEP_STATE_WATCHING){ + peep->action = PEEP_ACTION_NONE_1; + peep->var_6F = 2; + RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0); + } +} + +typedef struct{ + uint8 type; // 0 for standard, 1 for extra + uint32 item; // And this with the relevant flags + uint8 sprite_type; +} item_pref; + +item_pref item_order_preference[] = { + { 0, PEEP_ITEM_ICE_CREAM, 15 }, + { 0, PEEP_ITEM_FRIES, 16}, + { 0, PEEP_ITEM_PIZZA, 22 }, + { 0, PEEP_ITEM_BURGER, 17 }, + { 0, PEEP_ITEM_DRINK, 18 }, + { 0, PEEP_ITEM_COFFEE, 35 }, + { 0, PEEP_ITEM_CHICKEN, 34 }, + { 0, PEEP_ITEM_LEMONADE, 37 }, + { 0, PEEP_ITEM_COTTON_CANDY, 20 }, + { 0, PEEP_ITEM_POPCORN, 22 }, + { 0, PEEP_ITEM_HOT_DOG, 31 }, + { 0, PEEP_ITEM_TENTACLE, 32 }, + { 0, PEEP_ITEM_CANDY_APPLE, 33 }, + { 0, PEEP_ITEM_DONUT, 34 }, + { 1, PEEP_ITEM_PRETZEL, 39 }, + { 1, PEEP_ITEM_COOKIE, 39 }, + { 1, PEEP_ITEM_CHOCOLATE, 35 }, + { 1, PEEP_ITEM_ICED_TEA, 35 }, + { 1, PEEP_ITEM_FUNNEL_CAKE, 43 }, + { 1, PEEP_ITEM_BEEF_NOODLES, 44 }, + { 1, PEEP_ITEM_FRIED_RICE_NOODLES, 44 }, + { 1, PEEP_ITEM_WONTON_SOUP, 46 }, + { 1, PEEP_ITEM_MEATBALL_SOUP, 46 }, + { 1, PEEP_ITEM_FRUIT_JUICE, 43 }, + { 1, PEEP_ITEM_SOYBEAN_MILK, 41 }, + { 1, PEEP_ITEM_SU_JONGKWA, 41 }, + { 1, PEEP_ITEM_SUB_SANDWICH, 47 }, + { 1, PEEP_ITEM_ROAST_SAUSAGE, 45 }, + { 0, PEEP_ITEM_BALLOON, 19 }, + { 0, PEEP_ITEM_HAT, 30}, + { 1, PEEP_ITEM_SUNGLASSES, 40}, + { 0xFF, 0xFFFFFFFF, 0xFF} +}; + +/* rct2: 0x0069B8CC */ +void peep_update_sprite_type(rct_peep* peep){ + if (peep->sprite_type == 19 && + (scenario_rand() & 0xFFFF) <= 327){ + uint8 bl = 0; + + if ((scenario_rand() & 0xFFFF) <= 13107 && + peep->x != SPRITE_LOCATION_NULL){ + + bl = 1; + sound_play_panned(SOUND_BALLOON_POP, 0x8001, peep->x, peep->y, peep->z); + } + + if (peep->x != SPRITE_LOCATION_NULL){ + create_balloon(peep->x, peep->y, peep->z + 9, peep->balloon_colour, bl); + } + + peep->item_standard_flags &= ~PEEP_ITEM_BALLOON; + + peep->var_45 |= (1 << 3); + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_RAIN_LEVEL, uint8) != 0 && + peep->item_standard_flags & PEEP_ITEM_UMBRELLA && + peep->x != SPRITE_LOCATION_NULL){ + int x = peep->x & 0xFFE0; + int y = peep->y & 0xFFE0; + + if (x < 0x1FFF && y < 0x1FFF){ + rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); + while (1) { + if ((peep->z / 32) < map_element->base_height)break; + + if (map_element_is_last_for_tile(map_element)){ + set_sprite_type(peep, 21); + return; + } + map_element++; + } + } + } + + for (item_pref* item_pref = item_order_preference; item_pref->type != 0xFF; item_pref++){ + if (item_pref->type == 0){ + if (peep->item_standard_flags & item_pref->item){ + set_sprite_type(peep, item_pref->sprite_type); + return; + } + } + else{ + if (peep->item_extra_flags & item_pref->item){ + set_sprite_type(peep, item_pref->sprite_type); + return; + } + } + } + + if (peep->state == PEEP_STATE_WATCHING && + peep->standing_flags & (1<<1)){ + set_sprite_type(peep, 38); + return; + } + + if (peep->nausea > 170){ + set_sprite_type(peep, 28); + return; + } + + if (peep->nausea > 140){ + set_sprite_type(peep, 27); + return; + } + + if (peep->energy <= 64 && + peep->happiness < 128){ + set_sprite_type(peep, 26); + return; + } + + if (peep->energy <= 80 && + peep->happiness < 128){ + set_sprite_type(peep, 25); + return; + } + + if (peep->bathroom > 220){ + set_sprite_type(peep, 29); + return; + } + + set_sprite_type(peep, 0); +} + /** * rct2: 0x0069A42F * Call after changing a peeps state to insure that @@ -385,6 +553,36 @@ void peep_window_state_update(rct_peep* peep){ } } +/* rct2: 0x0069A535*/ +void peep_sprite_remove(rct_peep* peep){ + //RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0); + //return; + + RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0); + invalidate_sprite((rct_sprite*)peep); + + window_close_by_number(WC_PEEP, peep->sprite_index); + + window_close_by_number(WC_FIRE_PROMPT, peep->sprite_identifier); + + if (peep->type == PEEP_TYPE_GUEST){ + window_invalidate_by_class(WC_GUEST_LIST); + + RCT2_CALLPROC_X(0x0066E407, 2, 0, peep->sprite_index, 0, 0, 0, 0); + } + else{ + window_invalidate_by_class(WC_STAFF_LIST); + + RCT2_ADDRESS(RCT2_ADDRESS_STAFF_MODE_ARRAY, uint8)[peep->staff_id] = 0; + peep->type = 0xFF; + sub_6C0C3F(); + peep->type = PEEP_TYPE_STAFF; + + RCT2_CALLPROC_X(0x0066E407, 3, 0, peep->sprite_index, 0, 0, 0, 0); + } + sprite_remove((rct_sprite*)peep); +} + /** New function removes peep from * park existance. Works with staff. */ @@ -398,7 +596,7 @@ void peep_remove(rct_peep* peep){ RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--; } } - RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0); + peep_sprite_remove(peep); } /** @@ -408,8 +606,9 @@ void peep_remove(rct_peep* peep){ void peep_update_falling(rct_peep* peep){ if (peep->action == PEEP_ACTION_DROWNING){ // Check to see if we are ready to drown. - sint16 x, y; - sub_6939EB(&x, &y, peep); + sint16 x, y, xy_distance; + + peep_update_action(&x, &y, &xy_distance, peep); //RCT2_CALLPROC_X(0x6939EB, 0, 0, 0, 0, (int)peep, 0, 0); if (peep->action == PEEP_ACTION_DROWNING) return; if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x80000)){ @@ -456,9 +655,9 @@ void peep_update_falling(rct_peep* peep){ peep->item_standard_flags &= ~PEEP_ITEM_BALLOON; if (peep->sprite_type == 19 && peep->x != 0x8000){ - create_balloon(peep->x, peep->y, height, peep->balloon_colour); + create_balloon(peep->x, peep->y, height, peep->balloon_colour, 0); peep->var_45 |= (1 << 3); - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); } } @@ -466,7 +665,7 @@ void peep_update_falling(rct_peep* peep){ peep->action = PEEP_ACTION_DROWNING; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -566,8 +765,8 @@ void peep_update_sitting(rct_peep* peep){ } else if (peep->sub_state == 1){ if (peep->action < 0xFE){ - sint16 x, y; - sub_6939EB(&x, &y, peep); + sint16 x, y, xy_distance; + peep_update_action(&x, &y, &xy_distance, peep); //RCT2_CALLPROC_X(0x6939EB, 0, 0, 0, 0, (int)peep, 0, 0); if (peep->action != 0xFF) return; @@ -601,7 +800,7 @@ void peep_update_sitting(rct_peep* peep){ } peep->action = PEEP_ACTION_SITTING_EAT_FOOD; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); return; @@ -626,17 +825,1783 @@ void peep_update_sitting(rct_peep* peep){ peep->action = PEEP_ACTION_SITTING_CHECK_WATCH; } peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); return; } } +/* rct2: 0x006966A9 */ +static void remove_peep_from_queue(rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + uint8 cur_station = peep->current_ride_station; + ride->queue_length[cur_station]--; + if (peep->sprite_index == ride->first_peep_in_queue[cur_station]) + { + ride->first_peep_in_queue[cur_station] = peep->next_in_queue; + return; + } + + for (rct_peep* other_peep = GET_PEEP(ride->first_peep_in_queue[cur_station]);; + other_peep = GET_PEEP(other_peep->next_in_queue)){ + if (peep->sprite_index == other_peep->next_in_queue){ + other_peep->next_in_queue = peep->next_in_queue; + return; + } + } +} + +/* rct2: 0x00691C6E */ +static rct_vehicle* peep_choose_car_from_ride(rct_peep* peep, rct_ride* ride, uint8* car_array, uint8 car_array_size){ + uint8 chosen_car = scenario_rand(); + if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_HAS_G_FORCES + && ((chosen_car & 0xC) != 0xC)){ + chosen_car = (scenario_rand() & 1) ? 0 : car_array_size - 1; + } + else{ + chosen_car = (chosen_car * (uint16)car_array_size) >> 8; + } + + peep->current_car = car_array[chosen_car]; + + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + + for (int i = peep->current_car; i > 0; --i){ + vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train); + } + + return vehicle; +} + +/* rct2: 0x00691CD1 */ +static void peep_choose_seat_from_car(rct_peep* peep, rct_ride* ride, rct_vehicle* vehicle){ + uint8 chosen_seat = vehicle->next_free_seat; + + if (ride->mode == RIDE_MODE_FORWARD_ROTATION || + ride->mode == RIDE_MODE_BACKWARD_ROTATION){ + + chosen_seat = (((~vehicle->var_1F + 1) >> 3) & 0xF) * 2; + if (vehicle->next_free_seat & 1){ + chosen_seat++; + } + } + peep->current_seat = chosen_seat; + vehicle->next_free_seat++; + + vehicle->peep[peep->current_seat] = peep->sprite_index; + vehicle->peep_tshirt_colours[peep->current_seat] = peep->tshirt_colour; +} + +/* rct2: 0x00691D27 */ +static void peep_go_to_ride_entrance(rct_peep* peep, rct_ride* ride){ + int x = ride->entrances[peep->current_ride_station] & 0xFF; + int y = ride->entrances[peep->current_ride_station] >> 8; + int z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + x *= 32; + y *= 32; + x += 16; + y += 16; + + sint16 x_shift = RCT2_ADDRESS(0x00981D6C, sint16)[direction * 2]; + sint16 y_shift = RCT2_ADDRESS(0x00981D6E, sint16)[direction * 2]; + + uint8 shift_multiplier = 21; + rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype); + if (ride_type->vehicles[ride_type->var_014].var_12 & (1 << 3) || + ride_type->vehicles[ride_type->var_014].var_14 & 0x5000){ + shift_multiplier = 32; + } + + x_shift *= shift_multiplier; + y_shift *= shift_multiplier; + + x += x_shift; + y += y_shift; + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 2; + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_ENTERING_RIDE; + peep->sub_state = 1; + peep_window_state_update(peep); + + peep->var_AC = 0; + peep->var_E2 = 0; + + remove_peep_from_queue(peep); +} + +/* rct2: 0x00691A3B */ +static void peep_update_ride_sub_state_0(rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (peep->destination_tolerence != 0){ + invalidate_sprite((rct_sprite*)peep); + + sint16 x, y, xy_distance; + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + sint16 z = peep->z; + if (xy_distance < 16){ + z = ride->station_heights[peep->current_ride_station] * 8 + 2; + } + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + } + else{ + peep->destination_tolerence = 0; + peep->sprite_direction ^= (1 << 4); + } + } + + uint8 car_array_size = 0xFF; + uint8* car_array = RCT2_ADDRESS(0xF1AD78, uint8); + + if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_13){ + if (ride->num_riders >= ride->var_0D0) + return; + } + else{ + uint8 chosen_train; + + if (ride->mode == RIDE_MODE_BUMPERCAR || ride->mode == RIDE_MODE_RACE){ + if (ride->lifecycle_flags & RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING) + return; + + for (int i = 0; i < ride->num_vehicles; ++i){ + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[i]); + + if (vehicle->next_free_seat >= vehicle->num_seats) + continue; + + if (vehicle->status != VEHICLE_STATUS_WAITING_FOR_PASSENGERS) + continue; + chosen_train = i; + break; + } + } + else{ + chosen_train = ride->var_066[peep->current_ride_station]; + } + if (chosen_train == 0xFF){ + return; + } + + peep->current_train = chosen_train; + uint8* car_array_pointer = car_array; + + int i = 0; + + uint16 vehicle_id = ride->vehicles[chosen_train]; + rct_vehicle* vehicle = GET_VEHICLE(vehicle_id); + + for (; vehicle_id != 0xFFFF; + vehicle_id = vehicle->next_vehicle_on_train, + i++){ + vehicle = GET_VEHICLE(vehicle_id); + + uint8 num_seats = vehicle->num_seats; + if (vehicle_is_used_in_pairs(vehicle)){ + num_seats &= VEHICLE_SEAT_NUM_MASK; + if (vehicle->next_free_seat & 1){ + peep->current_car = i; + peep_choose_seat_from_car(peep, ride, vehicle); + peep_go_to_ride_entrance(peep, ride); + return; + } + } + if (num_seats == vehicle->next_free_seat) + continue; + + if (ride->mode == RIDE_MODE_FORWARD_ROTATION || + ride->mode == RIDE_MODE_BACKWARD_ROTATION) + { + uint8 position = (((~vehicle->var_1F + 1) >> 3) & 0xF) * 2; + if (vehicle->peep[position] != 0xFFFF) + continue; + } + + *car_array_pointer++ = i; + } + + car_array_size = car_array_pointer - car_array; + + if (car_array_size == 0)return; + } + + if (ride->status != RIDE_STATUS_OPEN || + ride->var_1CA != 0){ + if (peep->destination_tolerence == 0){ + remove_peep_from_queue(peep); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + } + return; + } + + if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + return; + + if (ride->price != 0){ + if (!(peep->item_standard_flags & PEEP_ITEM_VOUCHER) || + !(peep->voucher_type == VOUCHER_TYPE_RIDE_FREE) || + !(peep->voucher_arguments == peep->current_ride)){ + + if (peep->cash_in_pocket <= 0){ + peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_SPENT_MONEY, 0xFF); + if (peep->destination_tolerence == 0){ + remove_peep_from_queue(peep); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + } + return; + } + + if (ride->price > peep->cash_in_pocket){ + peep_insert_new_thought(peep, 0, peep->current_ride); + if (peep->destination_tolerence == 0){ + remove_peep_from_queue(peep); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + } + return; + } + + uint16 value = ride->value; + if (value != RIDE_VALUE_UNDEFINED){ + if (value * 2 < ride->price){ + peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_BAD_VALUE, peep->current_ride); + if (peep->destination_tolerence == 0){ + remove_peep_from_queue(peep); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + } + return; + } + } + } + } + + if (!(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_13)){ + rct_vehicle* vehicle = peep_choose_car_from_ride(peep, ride, car_array, car_array_size); + peep_choose_seat_from_car(peep, ride, vehicle); + } + peep_go_to_ride_entrance(peep, ride); +} + +/* rct2: 0x006921D3 */ +void peep_update_ride_sub_state_1(rct_peep* peep){ + sint16 x, y, xy_distance; + + rct_ride* ride = GET_RIDE(peep->current_ride); + rct_ride_type* ride_entry = gRideTypeList[ride->subtype]; + + if (peep_update_action(&x, &y, &xy_distance, peep)) + { + uint8 vehicle = ride_entry->var_014; + + if (ride_entry->vehicles[vehicle].var_12 & (1 << 3) || + ride_entry->vehicles[vehicle].var_14 & ((1 << 14) | (1<<12))) + RCT2_GLOBAL(0xF1AECA, uint16) = 0x1C; + else + RCT2_GLOBAL(0xF1AECA, uint16) = 0x10; + + if (peep->sub_state == 1 && + xy_distance < RCT2_GLOBAL(0xF1AECA, uint16)) + peep->sub_state = 2; + + invalidate_sprite((rct_sprite*)peep); + + sint16 z = ride->station_heights[peep->current_ride_station] * 8; + + RCT2_GLOBAL(0xF1AECA, uint16) += 4; + + if (xy_distance < RCT2_GLOBAL(0xF1AECA, uint16)){ + z += RCT2_ADDRESS(0x0097D21C, uint8)[ride->type * 8]; + } + + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] &RIDE_TYPE_FLAG_13) + { + sint16 x, y, z; + x = ride->entrances[peep->current_ride_station] & 0xFF; + y = ride->entrances[peep->current_ride_station] >> 8; + z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 direction_entrance = (map_element->type & MAP_ELEMENT_DIRECTION_MASK); + + if (ride->type == RIDE_TYPE_MAZE){ + peep->maze_last_edge = direction_entrance + 1; + x *= 32; + y *= 32; + + x += RCT2_ADDRESS(0x993CCC, sint16)[direction_entrance * 2]; + y += RCT2_ADDRESS(0x993CCE, sint16)[direction_entrance * 2]; + + uint8 direction = direction_entrance * 4 + 11; + if (scenario_rand() & 0x40){ + direction += 4; + peep->maze_last_edge += 2; + } + + direction &= 0xF; + peep->var_37 = direction; + peep->maze_last_edge &= 3; + + x += RCT2_GLOBAL(0x981FD1 + direction, sint16); + y += RCT2_GLOBAL(0x981FD3 + direction, sint16); + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 3; + + ride->var_120++; + RCT2_CALLPROC_X(0x00695444, 0, 0, 0, peep->current_ride, (int)peep, 0, 0); + peep->sub_state = 17; + return; + } + + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + map_element = ride_get_station_start_track_element(ride, peep->current_ride_station); + + uint8 direction_track = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + peep->var_37 = (direction_entrance << 2) | (direction_track << 4); + + x *= 32; + y *= 32; + + sint8* edx = peep->var_37 * 2 + RCT2_ADDRESS(0x97E1BC, sint8*)[ride->type]; + + x += edx[0]; + y += edx[1]; + + peep->destination_x = x; + peep->destination_y = y; + peep->current_car = 0; + + ride->var_120++; + RCT2_CALLPROC_X(0x00695444, 0, 0, 0, peep->current_ride, (int)peep, 0, 0); + peep->sub_state = 14; + return; + } + + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + for (int i = peep->current_car; i != 0; --i){ + vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train); + } + + ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype); + rct_ride_type_vehicle* vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type]; + + if (vehicle_type->var_14 & (1 << 10)){ + sint16 x, y, z; + x = ride->entrances[peep->current_ride_station] & 0xFF; + y = ride->entrances[peep->current_ride_station] >> 8; + z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 direction_entrance = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + map_element = ride_get_station_start_track_element(ride, peep->current_ride_station); + + uint8 direction_track = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype); + vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type]; + + uint8 cl = peep->current_seat; + uint8 ch = peep->current_seat & 0xF8; + + if (ride->type != RIDE_TYPE_ENTERPRISE) + direction_track *= 2; + + if (*vehicle_type->peep_loading_positions == 0){ + direction_track /= 2; + cl = 0; + ch = 0; + } + cl += direction_track; + cl &= 0x7; + cl += ch; + peep->var_37 = (direction_entrance | cl * 4) * 4; + + x *= 32; + y *= 32; + x += 16; + y += 16; + + if (ride->type == RIDE_TYPE_ENTERPRISE) + { + x = vehicle->x; + y = vehicle->y; + } + + x += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 1]; + y += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 2]; + + peep->destination_x = x; + peep->destination_y = y; + peep->sub_state = 12; + return; + } + + if (vehicle_type->var_14 & (1 << 15)){ + peep->destination_x = vehicle->x; + peep->destination_y = vehicle->y; + peep->destination_tolerence = 15; + peep->sub_state = 4; + return; + } + + uint8 load_position = vehicle_type->peep_loading_positions[peep->current_seat]; + + switch (vehicle->sprite_direction / 8){ + case 0: + peep->destination_x = vehicle->x - load_position; + break; + case 1: + peep->destination_y = vehicle->y + load_position; + break; + case 2: + peep->destination_x = vehicle->x + load_position; + break; + case 3: + peep->destination_y = vehicle->y - load_position; + break; + } + + peep->sub_state = 4; + return; +} + +/* rct2: 0x0069321D */ +static void peep_go_to_ride_exit(rct_peep* peep, rct_ride* ride, sint16 x, sint16 y, sint16 z, uint8 exit_direction){ + z += RCT2_ADDRESS(0x0097D21C, uint8)[ride->type * 8]; + + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + + x = ride->exits[peep->current_ride_station] & 0xFF; + y = ride->exits[peep->current_ride_station] >> 8; + x *= 32; + y *= 32; + x += 16; + y += 16; + + sint16 x_shift = RCT2_ADDRESS(0x00981D6C, sint16)[exit_direction * 2]; + sint16 y_shift = RCT2_ADDRESS(0x00981D6E, sint16)[exit_direction * 2]; + + sint16 shift_multiplier = 20; + + rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype); + rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->var_014]; + if (vehicle_entry->var_12 & (1 << 3) || + vehicle_entry->var_14 & 0x5000){ + shift_multiplier = 32; + } + + x_shift *= shift_multiplier; + y_shift *= shift_multiplier; + + x -= x_shift; + y -= y_shift; + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 2; + + peep->sprite_direction = exit_direction * 8; + peep->sub_state = 8; + return; +} + +/* rct2: 0x006920B4 */ +static void peep_update_ride_sub_state_2_enter_ride(rct_peep* peep, rct_ride* ride){ + if (ride->price != 0){ + if ((peep->item_standard_flags & PEEP_ITEM_VOUCHER) && + (peep->voucher_type == VOUCHER_TYPE_RIDE_FREE) && + (peep->voucher_arguments == peep->current_ride)){ + + peep->item_standard_flags &= ~PEEP_ITEM_VOUCHER; + peep->var_45 |= (1 << 3); + } + else{ + ride->total_profit += ride->price; + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_INCOME; + RCT2_GLOBAL(0x0141F56C, uint8) = 20; + RCT2_GLOBAL(0xF1AEC0, uint32) = 230; + + RCT2_CALLPROC_X(0x0069926C, 0, ride->price, 0, 0, (int)peep, 0, 0); + } + } + + peep->sub_state++; + uint8 queue_time = peep->days_in_queue; + if (queue_time < 253)queue_time += 3; + + queue_time /= 2; + if (queue_time != ride->queue_time[peep->current_ride_station]){ + ride->queue_time[peep->current_ride_station] = queue_time; + window_invalidate_by_number(WC_RIDE, peep->current_ride); + } + + if (peep->flags & PEEP_FLAGS_TRACKING){ + RCT2_GLOBAL(0x13CE952, uint16) = peep->name_string_idx; + RCT2_GLOBAL(0x13CE954, uint32) = peep->id; + RCT2_GLOBAL(0x13CE958, uint16) = ride->name; + RCT2_GLOBAL(0x13CE95A, uint32) = ride->name_arguments; + + rct_string_id msg_string; + if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_IN_RIDE) + msg_string = 1932; + else + msg_string = 1933; + + news_item_add_to_queue(NEWS_ITEM_PEEP_ON_RIDE, msg_string, peep->sprite_index); + } + + if (ride->type == RIDE_TYPE_SPIRAL_SLIDE){ + sub_693BE5(peep, 1); + } + + peep_update_ride_sub_state_1(peep); +} + +/* rct2: 0x00691FD4 */ +static void peep_update_ride_sub_state_2_rejoin_queue(rct_peep* peep, rct_ride* ride){ + sint16 x, y, z; + x = ride->entrances[peep->current_ride_station] & 0xFF; + y = ride->entrances[peep->current_ride_station] >> 8; + z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 direction_entrance = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + x *= 32; + y *= 32; + x += 16 - RCT2_ADDRESS(0x981D6C, sint16)[direction_entrance * 2] * 20; + y += 16 - RCT2_ADDRESS(0x981D6E, sint16)[direction_entrance * 2] * 20; + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 2; + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_QUEUING_FRONT; + peep->sub_state = 0; + peep_window_state_update(peep); + + peep->next_in_queue = 0xFFFF; + + ride->queue_length[peep->current_ride_station]++; + + uint16 current_first = ride->first_peep_in_queue[peep->current_ride_station]; + if (current_first == 0xFFFF){ + ride->first_peep_in_queue[peep->current_ride_station] = peep->sprite_index; + return; + } + + rct_peep* queue_peep; + for (queue_peep = GET_PEEP(current_first); + queue_peep->next_in_queue != 0xFFFF; + queue_peep = GET_PEEP(queue_peep->next_in_queue)); + + queue_peep->next_in_queue = peep->sprite_index; +} +/* rct2: 0x00691E42 + * Note: Before this was the entry + * point for sub state 1 and 3. The + * check has been removed that would + * branch it out to 1 and 3. Now uses + * separate functions. + */ +static void peep_update_ride_sub_state_2(rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_13){ + if (ride->status != RIDE_STATUS_OPEN || + ride->var_1CA != 0 || + (++peep->var_AC) == 0){ + + peep_update_ride_sub_state_2_rejoin_queue(peep, ride); + return; + } + + peep_update_ride_sub_state_2_enter_ride(peep, ride); + return; + } + + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + for (int i = peep->current_car; i != 0; --i){ + vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train); + } + + rct_ride_type* ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype); + + if (ride_entry->vehicles[0].var_12 & (1 << 3)){ + vehicle->var_D5 &= ~(1 << 5); + + + for (int i = 0; i < ride->num_vehicles; ++i){ + if (ride->vehicles[i] == 0xFFFF) + continue; + + rct_vehicle* train = GET_VEHICLE(ride->vehicles[i]); + rct_vehicle* second_vehicle = GET_VEHICLE(train->next_vehicle_on_train); + + if (second_vehicle->num_peeps == 0) + continue; + + if (second_vehicle->var_D5 & (1 << 5)) + continue; + + return; + } + } + + if (!vehicle_is_used_in_pairs(vehicle)){ + peep_update_ride_sub_state_2_enter_ride(peep, ride); + return; + } + + if (ride->mode == RIDE_MODE_FORWARD_ROTATION || + ride->mode == RIDE_MODE_BACKWARD_ROTATION){ + if (peep->current_seat & 1 || + !(vehicle->next_free_seat & 1)){ + peep_update_ride_sub_state_2_enter_ride(peep, ride); + return; + } + } + else{ + uint8 current_seat = (peep->current_seat & 0xFE) + 1; + if (current_seat < vehicle->next_free_seat) + { + peep_update_ride_sub_state_2_enter_ride(peep, ride); + return; + } + } + + if (ride->status == RIDE_STATUS_OPEN && + ++peep->var_AC != 0 && + !(GET_VEHICLE(ride->vehicles[peep->current_train]))->var_48 & (1 << 4)) + return; + + if (ride->mode != RIDE_MODE_FORWARD_ROTATION && + ride->mode != RIDE_MODE_BACKWARD_ROTATION){ + if (vehicle->next_free_seat - 1 != peep->current_seat) + return; + } + + vehicle->next_free_seat--; + vehicle->peep[peep->current_seat] = 0xFFFF; + + peep_update_ride_sub_state_2_rejoin_queue(peep, ride); +} + +static void peep_update_ride_sub_state_5(rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + for (int i = peep->current_car; i != 0; --i){ + vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train); + } + + if (ride->mode != RIDE_MODE_FORWARD_ROTATION && + ride->mode != RIDE_MODE_BACKWARD_ROTATION){ + if (peep->current_seat != vehicle->num_peeps) + return; + } + + if (vehicle_is_used_in_pairs(vehicle)){ + rct_peep* seated_peep = GET_PEEP(vehicle->peep[peep->current_seat ^ 1]); + if (seated_peep->sub_state != 5) + return; + + vehicle->num_peeps++; + ride->var_120++; + + vehicle->var_46 += seated_peep->var_41; + invalidate_sprite((rct_sprite*)seated_peep); + sprite_move(0x8000, 0, 0, (rct_sprite*)seated_peep); + + peep_decrement_num_riders(seated_peep); + seated_peep->state = PEEP_STATE_ON_RIDE; + peep_window_state_update(seated_peep); + seated_peep->var_E2 = 0; + seated_peep->sub_state = 6; + RCT2_CALLPROC_X(0x00695444, 0, 0, 0, seated_peep->current_ride, (int)seated_peep, 0, 0); + } + + vehicle->num_peeps++; + ride->var_120++; + + vehicle->var_46 += peep->var_41; + invalidate_sprite((rct_sprite*)vehicle); + + invalidate_sprite((rct_sprite*)peep); + sprite_move(0x8000, 0, 0, (rct_sprite*)peep); + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_ON_RIDE; + peep_window_state_update(peep); + + peep->var_E2 = 0; + peep->sub_state = 6; + + RCT2_CALLPROC_X(0x00695444, 0, 0, 0, peep->current_ride, (int)peep, 0, 0); +} + +/* rct2: 0x00693028*/ +static void peep_update_ride_sub_state_7(rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + uint8 ride_station = vehicle->current_station; + + for (int i = peep->current_car; i != 0; --i){ + vehicle = GET_VEHICLE(vehicle->next_vehicle_on_train); + } + + // Unsure why backward rotation is missing. + if (ride->mode != RIDE_MODE_FORWARD_ROTATION){ + if (vehicle->num_peeps - 1 != peep->current_seat) + return; + } + + peep->action_sprite_image_offset++; + if (peep->action_sprite_image_offset & 3) + return; + + peep->action_sprite_image_offset = 0; + + vehicle->num_peeps--; + vehicle->var_46 -= peep->var_41; + invalidate_sprite((rct_sprite*)vehicle); + + peep->current_ride_station = ride_station; + + rct_ride_type* ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype); + rct_ride_type_vehicle* vehicle_entry = &ride_entry->vehicles[vehicle->vehicle_type]; + + if (!(vehicle_entry->var_14 & (1 << 10))){ + sint16 x, y, z; + x = ride->exits[peep->current_ride_station] & 0xFF; + y = ride->exits[peep->current_ride_station] >> 8; + z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 exit_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + exit_direction ^= (1 << 1); + + if (!(RCT2_ADDRESS(RCT2_ADDRESS_RIDE_FLAGS, uint32)[ride->type * 2] & RIDE_TYPE_FLAG_16)){ + + for (; vehicle->var_01 != 0; vehicle = GET_VEHICLE(vehicle->prev_vehicle_on_train)){ + uint16 eax = vehicle->var_36 / 4; + if (eax == 0 || eax > 3) + continue; + + rct_map_element* inner_map = map_get_first_element_at(vehicle->var_38 / 32, vehicle->var_3A / 32); + for (;; inner_map++){ + if (map_element_get_type(inner_map) != MAP_ELEMENT_TYPE_TRACK) + continue; + if (inner_map->base_height == vehicle->var_3C / 8) + break; + } + + uint8 al = (inner_map->properties.track.sequence & 0x70) >> 4; + if (al == peep->current_ride_station) + break; + } + + ride_entry = GET_RIDE_ENTRY(ride->subtype); + vehicle_entry = &ride_entry->vehicles[ride_entry->var_014]; + + uint8 shift_multiplier = 12; + if (vehicle_entry->var_14 & (1 << 14)){ + shift_multiplier = 9; + } + + uint8 direction = exit_direction; + if (vehicle_entry->var_14 & ((1 << 14) | (1 << 12))){ + direction = ((vehicle->sprite_direction + 3) / 8) + 1; + direction &= 3; + + if (vehicle->var_CD == 6) + direction ^= (1 << 1); + } + + sint16 x_shift = RCT2_ADDRESS(0x00981D6C, sint16)[direction * 2]; + sint16 y_shift = RCT2_ADDRESS(0x00981D6E, sint16)[direction * 2]; + + x = vehicle->x + x_shift * shift_multiplier; + y = vehicle->y + y_shift * shift_multiplier; + z *= 8; + + peep_go_to_ride_exit(peep, ride, x, y, z, exit_direction); + return; + } + + x = vehicle->x + RCT2_ADDRESS(0x00981D6C, sint16)[exit_direction * 2] * 12; + y = vehicle->y + RCT2_ADDRESS(0x00981D6E, sint16)[exit_direction * 2] * 12; + + uint8 load_position = vehicle_entry->peep_loading_positions[peep->current_seat]; + + switch (vehicle->sprite_direction / 8){ + case 0: + x -= load_position; + break; + case 1: + y += load_position; + break; + case 2: + x += load_position; + break; + case 3: + y -= load_position; + break; + } + + z = ride->station_heights[peep->current_ride_station] * 8; + + peep_go_to_ride_exit(peep, ride, x, y, z, exit_direction); + return; + } + + sint16 x, y, z; + x = ride->exits[peep->current_ride_station] & 0xFF; + y = ride->exits[peep->current_ride_station] >> 8; + z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 exit_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + map_element = ride_get_station_start_track_element(ride, peep->current_ride_station); + + uint8 station_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + + ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype); + rct_ride_type_vehicle* vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type]; + + uint8 cl = peep->current_seat; + uint8 ch = peep->current_seat & 0xF8; + + if (ride->type != RIDE_TYPE_ENTERPRISE) + station_direction *= 2; + + if (*vehicle_type->peep_loading_positions == 0){ + station_direction /= 2; + cl = 0; + ch = 0; + } + cl += station_direction; + cl &= 0x7; + cl += ch; + peep->var_37 = ((exit_direction | cl * 4) * 4) | 1; + + x *= 32; + y *= 32; + x += 16; + y += 16; + + if (ride->type == RIDE_TYPE_ENTERPRISE) + { + x = vehicle->x; + y = vehicle->y; + } + + sint16 exit_x = x + ((sint8*)vehicle_type->peep_loading_positions)[(peep->var_37 + 1) * 2 + 1]; + sint16 exit_y = y + ((sint8*)vehicle_type->peep_loading_positions)[(peep->var_37 + 1) * 2 + 2]; + + z *= 8; + z += RCT2_ADDRESS(0x0097D21C, uint8)[ride->type * 8]; + + if (ride->type == RIDE_TYPE_MOTION_SIMULATOR) + z += 15; + + sprite_move(exit_x, exit_y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + + x += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 1]; + y += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 2]; + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 2; + peep->sub_state = 13; +} + +/* rct2: 0x0069376A */ +static void peep_update_ride_prepare_for_state_9(rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + sint16 x = ride->exits[peep->current_ride_station] & 0xFF; + sint16 y = ride->exits[peep->current_ride_station] >> 8; + sint16 z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 exit_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + x *= 32; + y *= 32; + x += 16; + y += 16; + + sint16 x_shift = RCT2_ADDRESS(0x00981D6C, sint16)[exit_direction * 2]; + sint16 y_shift = RCT2_ADDRESS(0x00981D6E, sint16)[exit_direction * 2]; + + sint16 shift_multiplier = 20; + + rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype); + rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->var_014]; + if (vehicle_entry->var_14 & 0x5000){ + shift_multiplier = 32; + } + + x_shift *= shift_multiplier; + y_shift *= shift_multiplier; + + x -= x_shift; + y -= y_shift; + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 2; + peep->sub_state = 9; +} + +/* rct2: 0x0069374F */ +static void peep_update_ride_sub_state_8(rct_peep* peep){ + sint16 x, y, xy_distance; + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + peep_update_ride_prepare_for_state_9(peep); +} + +/* rct2: 0x0069382E */ +static void peep_update_ride_sub_state_9(rct_peep* peep){ + sint16 x, y, xy_distance; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + + if (xy_distance >= 16){ + sint16 z = ride->station_heights[peep->current_ride_station] * 8; + + z += RCT2_ADDRESS(0x97D21C, uint8)[ride->type * 8]; + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + sub_693BE5(peep, 0); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + } + + if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_RIDE_PHOTO){ + uint8 secondaryItem = RCT2_ADDRESS(0x0097D7CB, uint8)[ride->type * 4]; + if (!(RCT2_CALLPROC_X(0x0069AF1E, secondaryItem | (peep->current_ride << 8), 0, ride->price_secondary, 0, (int)peep, 0, 0) & 0x100)){ + ride->no_secondary_items_sold++; + } + } + peep->sub_state = 18; +} + +/* rct2: 0x006926AD */ +static void peep_update_ride_sub_state_12(rct_peep* peep){ + sint16 x, y, xy_distance; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + sint16 z; + if (ride->type == RIDE_TYPE_MOTION_SIMULATOR){ + z = ride->station_heights[peep->current_ride_station] * 8 + 2; + + if ((peep->var_37 & 3) == 2){ + xy_distance -= 12; + if (xy_distance < 0) + xy_distance = 0; + + if (xy_distance <= 15){ + z += 15 - xy_distance; + } + } + } + else{ + z = peep->z; + } + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + if ((peep->var_37 & 3) == 2){ + peep->sub_state = 5; + return; + } + + peep->var_37++; + + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + x *= 32; + y *= 32; + x += 16; + y += 16; + + if (ride->type == RIDE_TYPE_ENTERPRISE){ + x = vehicle->x; + y = vehicle->y; + } + + rct_ride_type* ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype); + rct_ride_type_vehicle* vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type]; + + x += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 1]; + y += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 2]; + + peep->destination_x = x; + peep->destination_y = y; +} + +/* rct2: 0x0069357D */ +static void peep_udpate_ride_sub_state_13(rct_peep* peep){ + sint16 x, y, xy_distance; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + sint16 z; + if (ride->type == RIDE_TYPE_MOTION_SIMULATOR){ + z = ride->station_heights[peep->current_ride_station] * 8 + 2; + + if ((peep->var_37 & 3) == 1){ + + if (xy_distance > 15) + xy_distance = 15; + + z += xy_distance; + } + } + else{ + z = peep->z; + } + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + if ((peep->var_37 & 3) != 0){ + if ((peep->var_37 & 3) == 3){ + peep_update_ride_prepare_for_state_9(peep); + return; + } + + peep->var_37--; + rct_vehicle* vehicle = GET_VEHICLE(ride->vehicles[peep->current_train]); + + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + x *= 32; + y *= 32; + x += 16; + y += 16; + + if (ride->type == RIDE_TYPE_ENTERPRISE){ + x = vehicle->x; + y = vehicle->y; + } + + rct_ride_type* ride_entry = GET_RIDE_ENTRY(vehicle->ride_subtype); + rct_ride_type_vehicle* vehicle_type = &ride_entry->vehicles[vehicle->vehicle_type]; + + x += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 1]; + y += ((sint8*)vehicle_type->peep_loading_positions)[peep->var_37 * 2 + 2]; + + peep->destination_x = x; + peep->destination_y = y; + } + + peep->var_37 |= 3; + + x = ride->exits[peep->current_ride_station] & 0xFF; + y = ride->exits[peep->current_ride_station] >> 8; + sint16 z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 exit_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + exit_direction ^= (1 << 1); + + x *= 32; + y *= 32; + x += 16; + y += 16; + + sint16 x_shift = RCT2_ADDRESS(0x00981D6C, sint16)[exit_direction * 2]; + sint16 y_shift = RCT2_ADDRESS(0x00981D6E, sint16)[exit_direction * 2]; + + sint16 shift_multiplier = 20; + + rct_ride_type* ride_type = GET_RIDE_ENTRY(ride->subtype); + rct_ride_type_vehicle* vehicle_entry = &ride_type->vehicles[ride_type->var_014]; + if (vehicle_entry->var_14 & 0x5000){ + shift_multiplier = 32; + } + + x_shift *= shift_multiplier; + y_shift *= shift_multiplier; + + x -= x_shift; + y -= y_shift; + + peep->destination_x = x; + peep->destination_y = y; +} + +/* rct2: 0x006927B3 */ +static void peep_update_ride_sub_state_14(rct_peep* peep){ + sint16 x, y, xy_distance; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + if ((peep->var_37 & 3) == 3){ + peep->sub_state = 15; + peep->destination_x = 0; + peep->destination_y = 0; + peep->var_37 = (peep->var_37 / 4) & 0xC; + sprite_move(0x8000, y, peep->z, (rct_sprite*)peep); + return; + } + else if ((peep->var_37 & 3) == 2){ + uint8 last_ride = 0; + if (ride->status != RIDE_STATUS_OPEN) + last_ride = 1; + else if (peep->current_car++ != 0){ + if (ride->mode == RIDE_MODE_SINGLE_RIDE_PER_ADMISSION) + last_ride = 1; + if ((uint8)(peep->current_car - 1) > (scenario_rand() & 0xF)) + last_ride = 1; + } + + if (last_ride){ + x = ride->exits[peep->current_ride_station] & 0xFF; + y = ride->exits[peep->current_ride_station] >> 8; + sint16 z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 exit_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + + peep->var_37 = (exit_direction * 4) | (peep->var_37 & 0x30) | 1; + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + x *= 32; + y *= 32; + sint8* edx = peep->var_37 * 2 + RCT2_ADDRESS(0x97E1BC, sint8*)[ride->type]; + + x += edx[0]; + y += edx[1]; + + peep->destination_x = x; + peep->destination_y = y; + peep->sub_state = 16; + return; + } + } + peep->var_37++; + + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + x *= 32; + y *= 32; + sint8* edx = peep->var_37 * 2 + RCT2_ADDRESS(0x97E1BC, sint8*)[ride->type]; + + x += edx[0]; + y += edx[1]; + + peep->destination_x = x; + peep->destination_y = y; +} + +/* rct2: 0x00692D83 */ +static void peep_update_ride_sub_state_15(rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (ride->type != RIDE_TYPE_SPIRAL_SLIDE) + return; + + if ((peep->var_37 & 3) == 0){ + switch (peep->destination_x){ + case 0: + peep->destination_y++; + if (peep->destination_y >= 30) + peep->destination_x++; + return; + case 1: + if (ride->var_15D != 0) + return; + + ride->var_15D++; + ride->slide_peep = peep->sprite_index; + ride->slide_peep_t_shirt_colour = peep->tshirt_colour; + ride->var_176 = 0; + peep->destination_x++; + return; + case 2: + return; + case 3: + { + sint16 x = ride->station_starts[peep->current_ride_station] & 0xFF; + sint16 y = ride->station_starts[peep->current_ride_station] >> 8; + + x *= 32; + y *= 32; + + uint8 direction = (peep->var_37 / 4) & 3; + sint16 dest_x = x + RCT2_ADDRESS(0x981F1C, sint16)[direction * 2]; + sint16 dest_y = y + RCT2_ADDRESS(0x981F1E, sint16)[direction * 2]; + + peep->destination_x = dest_x; + peep->destination_y = dest_y; + + x += RCT2_ADDRESS(0x981F0C, sint16)[direction * 2]; + y += RCT2_ADDRESS(0x981F0E, sint16)[direction * 2]; + + sprite_move(x, y, peep->z, (rct_sprite*)peep); + + peep->sprite_direction = (peep->var_37 & 0xC) * 2; + + invalidate_sprite((rct_sprite*)peep); + + peep->var_37++; + return; + } + default: + return; + } + } + + sint16 x, y, xy_distance; + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + peep->var_37 = (peep->var_37 * 4 & 0x30) + 2; + + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + x *= 32; + y *= 32; + sint8* edx = peep->var_37 * 2 + RCT2_ADDRESS(0x97E1BC, sint8*)[ride->type]; + + x += edx[0]; + y += edx[1]; + + peep->destination_x = x; + peep->destination_y = y; + peep->sub_state = 14; +} + +/* rct2: 0x00692C6B */ +static void peep_update_ride_sub_state_16(rct_peep* peep){ + sint16 x, y, xy_distance; + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + rct_ride* ride = GET_RIDE(peep->current_ride); + + if ((peep->var_37 & 0x3) != 0){ + if ((peep->var_37 & 0x3) == 3){ + peep_update_ride_prepare_for_state_9(peep); + return; + } + + peep->var_37--; + x = ride->station_starts[peep->current_ride_station] & 0xFF; + y = ride->station_starts[peep->current_ride_station] >> 8; + + x *= 32; + y *= 32; + sint8* edx = peep->var_37 * 2 + RCT2_ADDRESS(0x97E1BC, sint8*)[ride->type]; + + x += edx[0]; + y += edx[1]; + + peep->destination_x = x; + peep->destination_y = y; + return; + } + + peep->var_37 |= 3; + + x = ride->exits[peep->current_ride_station] & 0xFF; + y = ride->exits[peep->current_ride_station] >> 8; + sint16 z = ride->station_heights[peep->current_ride_station]; + + rct_map_element* map_element = ride_get_station_exit_element(ride, x, y, z); + + uint8 exit_direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + exit_direction ^= (1 << 1); + + x *= 32; + y *= 32; + x += 16; + y += 16; + + sint16 x_shift = RCT2_ADDRESS(0x00981D6C, sint16)[exit_direction * 2]; + sint16 y_shift = RCT2_ADDRESS(0x00981D6E, sint16)[exit_direction * 2]; + + sint16 shift_multiplier = 20; + + x_shift *= shift_multiplier; + y_shift *= shift_multiplier; + + x -= x_shift; + y -= y_shift; + + peep->destination_x = x; + peep->destination_y = y; +} + +/* rct2: 0x00692A83 */ +static void peep_update_ride_sub_state_17(rct_peep* peep){ + sint16 x, y, xy_distance; + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + rct_ride* ride = GET_RIDE(peep->current_ride); + if (peep->var_37 == 16){ + peep_update_ride_prepare_for_state_9(peep); + return; + } + + if (peep->action >= PEEP_ACTION_NONE_1){ + if (peep->energy > 64 && + (scenario_rand() & 0xFFFF) <= 2427){ + + peep->action = PEEP_ACTION_JUMP; + peep->action_frame = 0; + peep->action_sprite_image_offset = 0; + sub_693B58(peep); + invalidate_sprite((rct_sprite*)peep); + } + } + + x = peep->destination_x & 0xFFE0; + y = peep->destination_y & 0xFFE0; + sint16 z = ride->station_heights[0]; + + // Find the station track element + rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32); + do { + if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK && z == mapElement->base_height) + break; + + } while (!map_element_is_last_for_tile(mapElement++)); + + uint16 maze_entry = mapElement->properties.track.maze_entry; + uint16 open_hedges = 0; + uint8 var_37 = peep->var_37; + + if (maze_entry & (1 << RCT2_ADDRESS(0x981FF4, uint8)[var_37])){ + open_hedges = 1; + } + open_hedges <<= 1; + if (maze_entry & (1 << RCT2_ADDRESS(0x981FF3, uint8)[var_37])){ + open_hedges |= 1; + } + open_hedges <<= 1; + if (maze_entry & (1 << RCT2_ADDRESS(0x981FF2, uint8)[var_37])){ + open_hedges |= 1; + } + open_hedges <<= 1; + if (maze_entry & (1 << RCT2_ADDRESS(0x981FF1, uint8)[var_37])){ + open_hedges |= 1; + } + + open_hedges ^= 0xF; + if (open_hedges == 0) + return; + + uint8 maze_last_edge = peep->maze_last_edge ^ (1 << 1); + open_hedges &= ~(1 << maze_last_edge); + if (open_hedges == 0) + open_hedges |= (1 << maze_last_edge); + + uint8 chosen_edge = scenario_rand() & 0x3; + while (!(open_hedges & (1 << chosen_edge))){ + chosen_edge = (chosen_edge + 1) & 3; + } + + x = RCT2_ADDRESS(0x993CCC, sint16)[chosen_edge * 2] / 2; + y = RCT2_ADDRESS(0x993CCE, sint16)[chosen_edge * 2] / 2; + + x += peep->destination_x; + y += peep->destination_y; + + uint8 type = 0; + + mapElement = map_get_first_element_at(x / 32, y / 32); + do { + if (z != mapElement->base_height) + continue; + + if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_TRACK){ + type = 1; + break; + } + + if (map_element_get_type(mapElement) == MAP_ELEMENT_TYPE_ENTRANCE && + mapElement->properties.entrance.type == ENTRANCE_TYPE_RIDE_EXIT){ + type = 2; + break; + } + } while (!map_element_is_last_for_tile(mapElement++)); + + switch (type){ + case 0: + peep->maze_last_edge++; + peep->maze_last_edge &= 3; + return; + case 1: + peep->destination_x = x; + peep->destination_y = y; + + peep->var_37 = RCT2_ADDRESS(0x981FE1, uint8)[peep->var_37 + chosen_edge]; + peep->maze_last_edge = chosen_edge; + break; + case 2: + x = peep->destination_x; + y = peep->destination_y; + if (chosen_edge & 1){ + x &= 0xFFE0; + x += 16; + } + else{ + y &= 0xFFE0; + y += 16; + } + peep->destination_x = x; + peep->destination_y = y; + peep->var_37 = 16; + peep->maze_last_edge = chosen_edge; + break; + } + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } +} + +/* rct2: 0x006938D2 */ +static void peep_update_ride_sub_state_18(rct_peep* peep){ + sint16 x, y, xy_distance; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, ride->station_heights[peep->current_ride_station] * 8, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + RCT2_CALLPROC_X(0x00695444, 0, 0, 0, peep->current_ride | (1 << 8), (int)peep, 0, 0); + + if (peep->flags & PEEP_FLAGS_TRACKING){ + RCT2_GLOBAL(0x13CE952, uint16) = peep->name_string_idx; + RCT2_GLOBAL(0x13CE954, uint32) = peep->id; + RCT2_GLOBAL(0x13CE958, uint16) = ride->name; + RCT2_GLOBAL(0x13CE95A, uint32) = ride->name_arguments; + + news_item_add_to_queue(NEWS_ITEM_PEEP_ON_RIDE, 1934, peep->sprite_index); + } + + peep->var_79 = 0xFF; + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + + x = peep->x & 0xFFE0; + y = peep->y & 0xFFE0; + + // Find the station track element + rct_map_element* mapElement = map_get_first_element_at(x / 32, y / 32); + do { + if (map_element_get_type(mapElement) != MAP_ELEMENT_TYPE_PATH) + continue; + + sint16 z = map_height_from_slope(peep->x, peep->y, mapElement->properties.path.type); + z += mapElement->base_height * 8; + + sint16 z_diff = peep->z - z; + if (z_diff > 0 || z_diff < -16) + continue; + + sprite_move(peep->x, peep->y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } while (!map_element_is_last_for_tile(mapElement++)); +} + +/* rct2: 0x0069299C */ +static void peep_update_ride_sub_state_19(rct_peep* peep){ + sint16 x, y, xy_distance; + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + return; + } + + peep->sub_state++; +} + +/* rct2: 0x006929BB */ +static void peep_update_ride_sub_state_20(rct_peep* peep){ + sint16 x, y; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (ride->type == RIDE_TYPE_FIRST_AID){ + if (peep->nausea <= 35){ + peep->sub_state++; + + x = peep->next_x + 16; + y = peep->next_y + 16; + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 3; + peep->happiness_growth_rate = min(peep->happiness_growth_rate + 30, 0xFF); + peep->happiness = peep->happiness_growth_rate; + } + else{ + peep->nausea--; + peep->nausea_growth_rate = peep->nausea; + } + return; + } + + if (peep->bathroom != 0){ + peep->bathroom--; + return; + } + + sound_play_panned(SOUND_TOILET_FLUSH, 0x8001, peep->x, peep->y, peep->z); + + peep->sub_state++; + + x = peep->next_x + 16; + y = peep->next_y + 16; + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 3; + + peep->happiness_growth_rate = min(peep->happiness_growth_rate + 30, 0xFF); + peep->happiness = peep->happiness_growth_rate; + + peep_stop_purchase_thought(peep, ride->type); +} + +/* rct2: 0x00692935 */ +static void peep_update_ride_sub_state_21(rct_peep* peep){ + sint16 x, y, xy_distance; + + if (peep_update_action(&x, &y, &xy_distance, peep)){ + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + + x = peep->x & 0xFFE0; + y = peep->y & 0xFFE0; + if (x != peep->next_x) + return; + if (y != peep->next_y) + return; + } + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_WALKING; + peep_window_state_update(peep); + + rct_ride* ride = GET_RIDE(peep->current_ride); + ride->total_customers++; + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_CUSTOMER; + + RCT2_CALLPROC_X(0x0069A3A2, 0, peep->happiness / 64, 0, 0, 0, peep->current_ride * sizeof(rct_ride), 0); +} + /* rct2: 0x691A30 - * Also used by entering_ride and queueing_front */ -static void peep_update_leaving_ride(rct_peep* peep){ - RCT2_CALLPROC_X(RCT2_ADDRESS(0x9820DC, int)[peep->sub_state], 0, 0, 0, 0, (int)peep, 0, 0); + * Used by entering_ride and queueing_front */ +static void peep_update_ride(rct_peep* peep){ + switch (peep->sub_state){ + case 0: + peep_update_ride_sub_state_0(peep); + break; + case 1: + peep_update_ride_sub_state_1(peep); + break; + case 2: + peep_update_ride_sub_state_2(peep); + break; + case 3: + peep_update_ride_sub_state_1(peep); + break; + case 4: + { + sint16 x, y, xy_distance; + if (!peep_update_action(&x, &y, &xy_distance, peep)) + { + peep->sub_state = 5; + break; + } + + invalidate_sprite((rct_sprite*)peep); + sprite_move(x, y, peep->z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + break; + } + case 5: + peep_update_ride_sub_state_5(peep); + break; + case 6: + // No action, on ride. + break; + case 7: + peep_update_ride_sub_state_7(peep); + break; + case 8: + peep_update_ride_sub_state_8(peep); + break; + case 9: + peep_update_ride_sub_state_9(peep); + break; + case 10: + case 11: + assert(false); + break; + case 12: + peep_update_ride_sub_state_12(peep); + break; + case 13: + peep_udpate_ride_sub_state_13(peep); + break; + case 14: + peep_update_ride_sub_state_14(peep); + break; + case 15: + peep_update_ride_sub_state_15(peep); + break; + case 16: + peep_update_ride_sub_state_16(peep); + break; + case 17: + peep_update_ride_sub_state_17(peep); + break; + case 18: + peep_update_ride_sub_state_18(peep); + break; + case 19: + peep_update_ride_sub_state_19(peep); + break; + case 20: + peep_update_ride_sub_state_20(peep); + break; + case 21: + peep_update_ride_sub_state_21(peep); + break; + default: + RCT2_CALLPROC_X(RCT2_ADDRESS(0x9820DC, int)[peep->sub_state], 0, 0, 0, 0, (int)peep, 0, 0); + } +} + +/* rct2: 0x006C0E8B + * Also used by inspecting. + */ +static void peep_update_fixing(int steps, rct_peep* peep){ + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (ride->type == RIDE_TYPE_NULL) + { + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + + RCT2_CALLPROC_X(RCT2_ADDRESS(0x006C0EB0, uint32)[peep->sub_state], steps, 0, 0, 0, (int)peep, (int)ride, 0); } /** @@ -644,20 +2609,20 @@ static void peep_update_leaving_ride(rct_peep* peep){ */ static void peep_update_queuing(rct_peep* peep){ if (!sub_68F3AE(peep)){ - RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); + remove_peep_from_queue(peep); return; } rct_ride* ride = GET_RIDE(peep->current_ride); if (ride->status == RIDE_STATUS_CLOSED || ride->status == RIDE_STATUS_TESTING){ - RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); + remove_peep_from_queue(peep); peep_decrement_num_riders(peep); peep->state = PEEP_STATE_1; peep_window_state_update(peep); return; } - if (peep->sub_state != 0xA){ - if (peep->var_74 == 0xFFFF){ + if (peep->sub_state != 10){ + if (peep->next_in_queue == 0xFFFF){ //Happens every time peep goes onto ride. peep->destination_tolerence = 0; peep_decrement_num_riders(peep); @@ -669,7 +2634,7 @@ static void peep_update_queuing(rct_peep* peep){ //Give up queueing for the ride peep->sprite_direction ^= (1 << 4); invalidate_sprite((rct_sprite*)peep); - RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); + remove_peep_from_queue(peep); peep_decrement_num_riders(peep); peep->state = PEEP_STATE_1; peep_window_state_update(peep); @@ -679,22 +2644,22 @@ static void peep_update_queuing(rct_peep* peep){ RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); if (peep->action < 0xFE)return; if (peep->sprite_type == 0){ - if (peep->var_7A >= 2000 && (0xFFFF & scenario_rand()) <= 119){ + if (peep->time_in_queue >= 2000 && (0xFFFF & scenario_rand()) <= 119){ // Eat Food/Look at watch peep->action = PEEP_ACTION_EAT_FOOD; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); } - if (peep->var_7A >= 3500 && (0xFFFF & scenario_rand()) <= 93) + if (peep->time_in_queue >= 3500 && (0xFFFF & scenario_rand()) <= 93) { //Create the ive been waiting in line ages thought peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_QUEUING_AGES, peep->current_ride); } } else{ - if (!(peep->var_7A & 0x3F) && peep->action == 0xFE && peep->var_6F == 2){ + if (!(peep->time_in_queue & 0x3F) && peep->action == 0xFE && peep->var_6F == 2){ switch (peep->sprite_type){ case 0xF: case 0x10: @@ -721,20 +2686,20 @@ static void peep_update_queuing(rct_peep* peep){ // Eat food/Look at watch peep->action = PEEP_ACTION_EAT_FOOD; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); break; } } } - if (peep->var_7A < 4300) return; + if (peep->time_in_queue < 4300) return; if (peep->happiness <= 65 && (0xFFFF & scenario_rand()) < 2184){ //Give up queueing for the ride peep->sprite_direction ^= (1 << 4); invalidate_sprite((rct_sprite*)peep); - RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); + remove_peep_from_queue(peep); peep_decrement_num_riders(peep); peep->state = PEEP_STATE_1; peep_window_state_update(peep); @@ -748,8 +2713,8 @@ static void peep_update_mowing(rct_peep* peep){ invalidate_sprite((rct_sprite*)peep); while (1){ - sint16 x = 0, y = 0; - if (sub_6939EB(&x, &y, peep)){ + sint16 x = 0, y = 0, xy_distance; + if (peep_update_action(&x, &y, &xy_distance, peep)){ int eax = x, ebx, ecx = y, z, ebp, edi; RCT2_CALLFUNC_X(0x662783, &eax, &ebx, &ecx, &z, (int*)&peep, &edi, &ebp); @@ -801,7 +2766,7 @@ static void peep_update_watering(rct_peep* peep){ peep->sprite_direction = (peep->var_37 & 3) << 3; peep->action = PEEP_ACTION_STAFF_WATERING; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -809,8 +2774,8 @@ static void peep_update_watering(rct_peep* peep){ } else if (peep->sub_state == 1){ if (peep->action != PEEP_ACTION_NONE_2){ - sint16 x, y; - sub_6939EB(&x, &y, peep); + sint16 x, y, xy_distance; + peep_update_action(&x, &y, &xy_distance, peep); return; } @@ -853,7 +2818,7 @@ static void peep_update_emptying_bin(rct_peep* peep){ peep->sprite_direction = (peep->var_37 & 3) << 3; peep->action = PEEP_ACTION_STAFF_EMPTY_BIN; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -866,8 +2831,8 @@ static void peep_update_emptying_bin(rct_peep* peep){ return; } - sint16 x = 0, y = 0; - sub_6939EB(&x, &y, peep); + sint16 x = 0, y = 0, xy_distance; + peep_update_action(&x, &y, &xy_distance, peep); if (peep->action_frame != 11)return; @@ -921,8 +2886,8 @@ static void peep_update_sweeping(rct_peep* peep){ peep->staff_litter_swept++; peep->var_45 |= (1 << 4); } - sint16 x = 0, y = 0; - if (sub_6939EB(&x, &y, peep)){ + sint16 x = 0, y = 0, xy_distance; + if (peep_update_action(&x, &y, &xy_distance, peep)){ int eax = x, ebx, ecx = y, z, ebp, edi; RCT2_CALLFUNC_X(0x694921, &eax, &ebx, &ecx, &z, (int*)&peep, &edi, &ebp); @@ -937,7 +2902,7 @@ static void peep_update_sweeping(rct_peep* peep){ if (peep->var_37 != 2){ peep->action = PEEP_ACTION_STAFF_SWEEP; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); return; @@ -981,12 +2946,12 @@ static void peep_update_leaving_park(rct_peep* peep){ if (peep->var_37 != 0){ RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 2))return; - RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0); + peep_sprite_remove(peep); return; } - sint16 x = 0, y = 0; - if (sub_6939EB(&x, &y, peep)){ + sint16 x = 0, y = 0, xy_distance; + if (peep_update_action(&x, &y, &xy_distance, peep)){ invalidate_sprite((rct_sprite*)peep); sprite_move(x, y, peep->z, (rct_sprite*)peep); invalidate_sprite((rct_sprite*)peep); @@ -1003,7 +2968,7 @@ static void peep_update_leaving_park(rct_peep* peep){ RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 2))return; - RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0); + peep_sprite_remove(peep); } /* rct2: 0x6916D6 */ @@ -1028,13 +2993,13 @@ static void peep_update_watching(rct_peep* peep){ peep->sub_state++; peep->time_to_stand = clamp(0, ((129 - peep->energy) * 16 + 50) / 2, 255); - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); } else if (peep->sub_state == 1){ if (peep->action < 0xFE){ //6917F6 - sint16 x = 0, y = 0; - sub_6939EB(&x, &y, peep); + sint16 x = 0, y = 0, xy_distance; + peep_update_action(&x, &y, &xy_distance, peep); if (peep->action != 0xFF)return; peep->action = 0xFE; @@ -1044,7 +3009,7 @@ static void peep_update_watching(rct_peep* peep){ if ((scenario_rand() & 0xFFFF) <= 1310){ peep->action = PEEP_ACTION_EAT_FOOD; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); return; @@ -1054,7 +3019,7 @@ static void peep_update_watching(rct_peep* peep){ if ((scenario_rand() & 0xFFFF) <= 655){ peep->action = PEEP_ACTION_TAKE_PHOTO; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); return; @@ -1064,7 +3029,7 @@ static void peep_update_watching(rct_peep* peep){ if ((scenario_rand() & 0xFFFF) <= 655){ peep->action = PEEP_ACTION_WAVE; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); return; @@ -1081,7 +3046,7 @@ static void peep_update_watching(rct_peep* peep){ peep_decrement_num_riders(peep); peep->state = PEEP_STATE_WALKING; peep_window_state_update(peep); - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); // Send peep to the center of current tile. peep->destination_x = (peep->x & 0xFFE0) + 16; peep->destination_y = (peep->y & 0xFFE0) + 16; @@ -1098,12 +3063,12 @@ static void peep_update_entering_park(rct_peep* peep){ RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); if ((RCT2_GLOBAL(0xF1EE18, uint16) & 2)){ RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--; - RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0); + peep_sprite_remove(peep); } return; } - sint16 x = 0, y = 0; - if (sub_6939EB(&x, &y, peep)){ + sint16 x = 0, y = 0, xy_distance; + if (peep_update_action(&x, &y, &xy_distance, peep)){ invalidate_sprite((rct_sprite*)peep); sprite_move(x, y, peep->z, (rct_sprite*)peep); invalidate_sprite((rct_sprite*)peep); @@ -1157,7 +3122,7 @@ static int peep_update_walking_find_bench(rct_peep* peep){ uint16 sprite_id = RCT2_ADDRESS(0xF1EF60, uint16)[((peep->x & 0x1FE0) << 3) | (peep->y >> 5)]; uint8 free_edge = 3; - for (rct_sprite* sprite; sprite_id != SPRITE_INDEX_NULL; sprite_id = sprite->unknown.var_02){ + for (rct_sprite* sprite; sprite_id != SPRITE_INDEX_NULL; sprite_id = sprite->unknown.next_in_quadrant){ sprite = &g_sprite_list[sprite_id]; if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP)continue; @@ -1349,8 +3314,8 @@ static void peep_update_buying(rct_peep* peep) if (peep->sub_state == 1){ if (peep->action != 0xFF){ - sint16 x, y; - sub_6939EB(&x, &y, peep); + sint16 x, y, xy_distance; + peep_update_action(&x, &y, &xy_distance, peep); return; } @@ -1384,7 +3349,7 @@ static void peep_update_buying(rct_peep* peep) else{ peep->action = PEEP_ACTION_WITHDRAW_MONEY; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -1443,8 +3408,8 @@ static void peep_update_using_bin(rct_peep* peep){ else if (peep->sub_state == 1){ if (peep->action != PEEP_ACTION_NONE_2){ - sint16 x, y; - sub_6939EB(&x, &y, peep); + sint16 x, y, xy_distance; + peep_update_action(&x, &y, &xy_distance, peep); return; } @@ -1502,7 +3467,7 @@ static void peep_update_using_bin(rct_peep* peep){ if (scenario_rand() & 7) rubbish_in_bin--; peep->item_standard_flags &= ~(1 << cur_container); peep->var_45 |= 8; - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); continue; } uint8 bp = RCT2_ADDRESS(0x97EFCC, uint8)[cur_container]; @@ -1515,7 +3480,7 @@ static void peep_update_using_bin(rct_peep* peep){ peep->item_standard_flags &= ~(1 << cur_container); peep->var_45 |= 8; - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); } // Original bug: This would clear any rubbish placed by the previous function @@ -1533,7 +3498,7 @@ static void peep_update_using_bin(rct_peep* peep){ peep->item_extra_flags &= ~(1 << cur_container); peep->var_45 |= 8; - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); continue; } uint8 bp = RCT2_ADDRESS(0x97EFE8, uint8)[cur_container]; @@ -1546,7 +3511,7 @@ static void peep_update_using_bin(rct_peep* peep){ peep->item_extra_flags &= ~(1 << cur_container); peep->var_45 |= 8; - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); } // Place new amount in bin by first clearing the value @@ -1559,6 +3524,446 @@ static void peep_update_using_bin(rct_peep* peep){ } } +/* rct2: 0x006C16D7 */ +static void peep_update_heading_to_inspect(rct_peep* peep){ + //RCT2_CALLPROC_X(0x006C16D7, 0, 0, 0, 0, (int)peep, 0, 0); + //return; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (ride->type == RIDE_TYPE_NULL){ + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + + if (ride->exits[peep->current_ride_station] == 0xFFFF){ + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_DUE_INSPECTION; + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + + if (ride->mechanic_status != RIDE_MECHANIC_STATUS_HEADING || + !(ride->lifecycle_flags & RIDE_LIFECYCLE_DUE_INSPECTION)){ + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + + if (peep->sub_state == 0){ + peep->var_74 = 0; + RCT2_CALLPROC_X(0x0069A98C, 0, 0, 0, 0, (int)peep, 0, 0); + peep->sub_state = 2; + } + + if (peep->sub_state <= 3){ + peep->var_74++; + if (peep->var_74 > 2500){ + if (ride->lifecycle_flags & RIDE_LIFECYCLE_DUE_INSPECTION&& + ride->mechanic_status == RIDE_MECHANIC_STATUS_HEADING){ + ride->mechanic_status = RIDE_MECHANIC_STATUS_CALLING; + } + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + + if (!sub_68F3AE(peep))return; + + RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); + + if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 0xC))return; + + rct_map_element* map_element = RCT2_GLOBAL(0x00F1EE1A, rct_map_element*); + + if (peep->current_ride != + map_element->properties.entrance.ride_index) + return; + + uint8 exit_index = ((map_element->properties.entrance.index & 0x70) >> 4); + + if (peep->current_ride_station != exit_index) + return; + + if (RCT2_GLOBAL(0xF1EE18, uint16)&(1 << 3)){ + if (ride->exits[exit_index] != 0xFFFF)return; + } + + uint8 direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + peep->var_78 = direction; + + int x = peep->next_x + 16 + RCT2_ADDRESS(0x00981D6C, sint16)[direction * 2] * 53; + int y = peep->next_y + 16 + RCT2_ADDRESS(0x00981D6E, sint16)[direction * 2] * 53; + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 2; + peep->sprite_direction = direction << 3; + + peep->z = map_element->base_height * 4; + peep->sub_state = 4; + // Falls through into sub_state 4 + } + + invalidate_sprite((rct_sprite*)peep); + + sint16 delta_y = abs(peep->y - peep->destination_y); + + sint16 x, y, xy_distance; + if (!peep_update_action(&x, &y, &xy_distance, peep)){ + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_INSPECTING; + peep->sub_state = 0; + peep_window_state_update(peep); + return; + } + + int z = ride->station_heights[peep->current_ride_station] * 8; + + if (delta_y < 20){ + z += RCT2_ADDRESS(0x0097D21C, uint8)[ride->type * 8]; + } + + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); +} + +/* rct2: 0x006C0CB8 */ +static void peep_update_answering(rct_peep* peep){ + //RCT2_CALLPROC_X(0x006C0CB8, 0, 0, 0, 0, (int)peep, 0, 0); + //return; + rct_ride* ride = GET_RIDE(peep->current_ride); + + if (ride->type == RIDE_TYPE_NULL || + ride->mechanic_status != RIDE_MECHANIC_STATUS_HEADING){ + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + + if (peep->sub_state == 0){ + peep->action = PEEP_ACTION_STAFF_ANSWER_CALL; + peep->action_frame = 0; + peep->action_sprite_image_offset = 0; + + sub_693B58(peep); + invalidate_sprite((rct_sprite*)peep); + + peep->sub_state = 1; + peep_window_state_update(peep); + return; + } + else if (peep->sub_state == 1){ + if (peep->action == PEEP_ACTION_NONE_2){ + peep->sub_state = 2; + peep_window_state_update(peep); + peep->var_74 = 0; + RCT2_CALLPROC_X(0x0069A98C, 0, 0, 0, 0, (int)peep, 0, 0); + return; + } + sint16 x, y, xy_distance; + peep_update_action(&x, &y, &xy_distance, peep); + return; + } + else if (peep->sub_state <= 3){ + peep->var_74++; + if (peep->var_74 > 2500){ + if (ride->mechanic_status == RIDE_MECHANIC_STATUS_HEADING){ + ride->mechanic_status = RIDE_MECHANIC_STATUS_CALLING; + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAINTENANCE; + } + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + + if (!sub_68F3AE(peep))return; + + RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); + + if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 0xC))return; + + rct_map_element* map_element = RCT2_GLOBAL(0x00F1EE1A, rct_map_element*); + + if (peep->current_ride != + map_element->properties.entrance.ride_index) + return; + + uint8 exit_index = ((map_element->properties.entrance.index & 0x70) >> 4); + + if (peep->current_ride_station != exit_index) + return; + + if (RCT2_GLOBAL(0xF1EE18, uint16)&(1 << 3)){ + if (ride->exits[exit_index] != 0xFFFF)return; + } + + uint8 direction = map_element->type & MAP_ELEMENT_DIRECTION_MASK; + peep->var_78 = direction; + + int x = peep->next_x + 16 + RCT2_ADDRESS(0x00981D6C, sint16)[direction * 2] * 53; + int y = peep->next_y + 16 + RCT2_ADDRESS(0x00981D6E, sint16)[direction * 2] * 53; + + peep->destination_x = x; + peep->destination_y = y; + peep->destination_tolerence = 2; + peep->sprite_direction = direction << 3; + + peep->z = map_element->base_height * 4; + peep->sub_state = 4; + // Falls through into sub_state 4 + } + + invalidate_sprite((rct_sprite*)peep); + + sint16 delta_y = abs(peep->y - peep->destination_y); + + sint16 x, y, xy_distance; + if (!peep_update_action(&x, &y, &xy_distance, peep)){ + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FIXING; + peep->sub_state = 0; + peep_window_state_update(peep); + return; + } + + int z = ride->station_heights[peep->current_ride_station] * 8; + + if (delta_y < 20){ + z += RCT2_ADDRESS(0x0097D21C, uint8)[ride->type * 8]; + } + + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); +} + +/* rct2: 0x006BF483 */ +static int peep_update_patrolling_find_watering(rct_peep* peep){ + if (!(peep->staff_orders & STAFF_ORDERS_WATER_FLOWERS)) + return 0; + + uint8 chosen_position = scenario_rand() & 7; + for (int i = 0; i < 8; ++i, ++chosen_position){ + chosen_position &= 7; + + int x = peep->next_x + RCT2_ADDRESS(0x00993CCC, sint16)[chosen_position * 2]; + int y = peep->next_y + RCT2_ADDRESS(0x00993CCE, sint16)[chosen_position * 2]; + + rct_map_element* map_element = map_get_first_element_at(x / 32, y / 32); + + do { + if (map_element_get_type(map_element) != MAP_ELEMENT_TYPE_SCENERY){ + map_element++; + continue; + } + + uint8 z_diff = abs(peep->next_z - map_element->base_height); + + if (z_diff >= 4){ + map_element++; + continue; + } + + rct_scenery_entry* sceneryEntry = g_smallSceneryEntries[map_element->properties.scenery.type]; + + if (!(sceneryEntry->small_scenery.flags & SMALL_SCENERY_FLAG_CAN_BE_WATERED)){ + map_element++; + continue; + } + + if (map_element->properties.scenery.age < 55){ + if (chosen_position >= 4){ + map_element++; + continue; + } + + if (map_element->properties.scenery.age < 40){ + map_element++; + continue; + } + } + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_WATERING; + peep->var_37 = chosen_position; + peep_window_state_update(peep); + + peep->sub_state = 0; + peep->destination_x = (peep->x & 0xFFE0) + RCT2_ADDRESS(0x992A5C, uint16)[chosen_position * 2]; + peep->destination_y = (peep->y & 0xFFE0) + RCT2_ADDRESS(0x992A5E, uint16)[chosen_position * 2]; + peep->destination_tolerence = 3; + + return 1; + } while (!map_element_is_last_for_tile(map_element)); + } + return 0; +} + +/* rct2: 0x006BF3A1 */ +static int peep_update_patrolling_find_bin(rct_peep* peep){ + if (!(peep->staff_orders & STAFF_ORDERS_EMPTY_BINS)) + return 0; + + if ((peep->next_var_29 & 0x18) != 0) return 0; + + rct_map_element* map_element = map_get_first_element_at(peep->next_x / 32, peep->next_y / 32); + if (map_element == NULL)return 0; + + for (;; map_element++){ + + if (map_element_get_type(map_element) == MAP_ELEMENT_TYPE_PATH + && (map_element->base_height == peep->next_z)) + break; + + if (map_element_is_last_for_tile(map_element)) + return 0; + } + + uint8 additions = map_element->properties.path.additions & 0xF; + + if (additions == 0)return 0; + + rct_scenery_entry* sceneryEntry = RCT2_ADDRESS(0x9ADA50, rct_scenery_entry*)[additions]; + + if (!(sceneryEntry->path_bit.var_06 & 1)) + return 0; + + if (map_element->flags & MAP_ELEMENT_FLAG_BROKEN) + return 0; + + if (map_element->properties.path.additions & 0x80) + return 0; + + uint8 bin_positions = map_element->properties.path.edges & 0xF; + uint8 bin_quantity = map_element->properties.path.addition_status; + uint8 chosen_position = 0; + + for (; chosen_position < 4; ++chosen_position){ + if (!(bin_positions & 1) && + !(bin_quantity & 3)) + break; + bin_positions >>= 1; + bin_quantity >>= 2; + } + + if (chosen_position == 4)return 0; + + peep->var_37 = chosen_position; + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_EMPTYING_BIN; + peep_window_state_update(peep); + + peep->sub_state = 0; + peep->destination_x = (peep->x & 0xFFE0) + RCT2_ADDRESS(0x992A4C, uint16)[chosen_position * 2]; + peep->destination_y = (peep->y & 0xFFE0) + RCT2_ADDRESS(0x992A4E, uint16)[chosen_position * 2]; + peep->destination_tolerence = 3; + return 1; +} + +/* rct2: 0x006BF322 */ +static int peep_update_patrolling_find_grass(rct_peep* peep){ + if (!(peep->staff_orders & STAFF_ORDERS_MOWING)) + return 0; + + if (peep->var_E2 < 12)return 0; + + if ((peep->next_var_29 & 0x18) != 8) return 0; + + rct_map_element* map_element = map_get_surface_element_at(peep->next_x / 32, peep->next_y / 32); + + if ((map_element->properties.surface.terrain & MAP_ELEMENT_SURFACE_TERRAIN_MASK) != TERRAIN_GRASS) + return 0; + + if (map_element->properties.surface.grass_length < GRASS_LENGTH_CLEAR_1) + return 0; + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_MOWING; + peep_window_state_update(peep); + peep->var_37 = 0; + peep->destination_x = peep->next_x + RCT2_ADDRESS(0x9929CA, uint16)[0 * 2]; + peep->destination_y = peep->next_y + RCT2_ADDRESS(0x9929CA, uint16)[0 * 2]; + peep->destination_tolerence = 3; + return 1; +} + +/* rct2: 0x006BF295 */ +static int peep_update_patrolling_find_sweeping(rct_peep* peep){ + if (!(peep->staff_orders & STAFF_ORDERS_SWEEPING)) + return 0; + + uint16 sprite_id = RCT2_ADDRESS(0xF1EF60, uint16)[((peep->x & 0x1FE0) << 3) | (peep->y >> 5)]; + + for (rct_sprite* sprite = NULL; + sprite_id != 0xFFFF; + sprite_id = sprite->unknown.next_in_quadrant){ + + sprite = &g_sprite_list[sprite_id]; + + if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_LITTER)continue; + + uint16 z_diff = abs(peep->z - sprite->litter.z); + + if (z_diff >= 16)continue; + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_SWEEPING; + peep_window_state_update(peep); + peep->var_37 = 0; + peep->destination_x = sprite->litter.x; + peep->destination_y = sprite->litter.y; + peep->destination_tolerence = 5; + return 1; + } + + return 0; +} + +/* rct2: 0x006BF1FD */ +static void peep_update_patrolling(rct_peep* peep){ + + if (!sub_68F3AE(peep))return; + + RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); + if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 1))return; + + if ((peep->next_var_29 & 0x18) == 8){ + rct_map_element* map_element = map_get_surface_element_at(peep->next_x / 32, peep->next_y / 32); + + if (map_element != NULL){ + int water_height = map_element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK; + if (water_height){ + invalidate_sprite((rct_sprite*)peep); + water_height *= 16; + sprite_move(peep->x, peep->y, water_height, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + return; + } + } + } + + if (peep->staff_type != STAFF_TYPE_HANDYMAN) return; + + if (peep_update_patrolling_find_sweeping(peep))return; + + if (peep_update_patrolling_find_grass(peep))return; + + if (peep_update_patrolling_find_bin(peep))return; + + peep_update_patrolling_find_watering(peep); +} + /* rct2: 0x0069030A */ static void peep_update_walking(rct_peep* peep){ //RCT2_CALLPROC_X(0x0069030A, 0, 0, 0, 0, (int)peep, 0, 0); @@ -1573,7 +3978,7 @@ static void peep_update_walking(rct_peep* peep){ peep->action = PEEP_ACTION_WAVE_2; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -1588,7 +3993,7 @@ static void peep_update_walking(rct_peep* peep){ peep->action = PEEP_ACTION_TAKE_PHOTO; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -1603,7 +4008,7 @@ static void peep_update_walking(rct_peep* peep){ peep->action = PEEP_ACTION_DRAW_PICTURE; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); @@ -1645,7 +4050,7 @@ static void peep_update_walking(rct_peep* peep){ } peep->var_45 |= 8; - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); int x = peep->x + (scenario_rand() & 0x7) - 3; int y = peep->y + (scenario_rand() & 0x7) - 3; @@ -1743,7 +4148,7 @@ static void peep_update_walking(rct_peep* peep){ } uint16 sprite_id = RCT2_ADDRESS(0xF1EF60, uint16)[((peep->x & 0x1FE0) << 3) | (peep->y >> 5)]; - for (rct_sprite* sprite; sprite_id != SPRITE_INDEX_NULL; sprite_id = sprite->unknown.var_02){ + for (rct_sprite* sprite; sprite_id != SPRITE_INDEX_NULL; sprite_id = sprite->unknown.next_in_quadrant){ sprite = &g_sprite_list[sprite_id]; if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP)continue; @@ -1884,13 +4289,13 @@ static void peep_update(rct_peep *peep) peep_update_1(peep); break; case PEEP_STATE_QUEUING_FRONT: - peep_update_leaving_ride(peep); + peep_update_ride(peep); break; case PEEP_STATE_ON_RIDE: // No action break; case PEEP_STATE_LEAVING_RIDE: - peep_update_leaving_ride(peep); + peep_update_ride(peep); break; case PEEP_STATE_WALKING: peep_update_walking(peep); @@ -1899,8 +4304,7 @@ static void peep_update(rct_peep *peep) peep_update_queuing(peep); break; case PEEP_STATE_ENTERING_RIDE: - // Calls the same function as leaving ride - peep_update_leaving_ride(peep); + peep_update_ride(peep); break; case PEEP_STATE_SITTING: peep_update_sitting(peep); @@ -1909,7 +4313,7 @@ static void peep_update(rct_peep *peep) peep_update_picked(peep); break; case PEEP_STATE_PATROLLING: - RCT2_CALLPROC_X(0x006BF1FD, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_patrolling(peep); break; case PEEP_STATE_MOWING: peep_update_mowing(peep); @@ -1924,10 +4328,10 @@ static void peep_update(rct_peep *peep) peep_update_leaving_park(peep); break; case PEEP_STATE_ANSWERING: - RCT2_CALLPROC_X(0x006C0CB8, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_answering(peep); break; case PEEP_STATE_FIXING: - RCT2_CALLPROC_X(0x006C0E8B, stepsToTake, 0, 0, 0, (int)peep, 0, 0); + peep_update_fixing(stepsToTake, peep); break; case PEEP_STATE_BUYING: peep_update_buying(peep); @@ -1945,14 +4349,14 @@ static void peep_update(rct_peep *peep) peep_update_watering(peep); break; case PEEP_STATE_HEADING_TO_INSPECTION: - RCT2_CALLPROC_X(0x006C16D7, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_heading_to_inspect(peep); break; case PEEP_STATE_INSPECTING: - RCT2_CALLPROC_X(0x006C0E8B, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_fixing(stepsToTake, peep); break; //There shouldnt be any more default: - RCT2_CALLPROC_X(0x0068FD2F, 0, 0, 0, 0, (int)peep, 0, 0); + assert(0); break; } } @@ -2203,9 +4607,9 @@ void peep_applause() if (peep->item_standard_flags & PEEP_ITEM_BALLOON) { peep->item_standard_flags &= ~PEEP_ITEM_BALLOON; if (peep->x != 0x8000) { - create_balloon(peep->x, peep->y, peep->z + 9, peep->balloon_colour); + create_balloon(peep->x, peep->y, peep->z + 9, peep->balloon_colour, 0); peep->var_45 |= 8; - RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + peep_update_sprite_type(peep); } } @@ -2213,7 +4617,7 @@ void peep_applause() if ((peep->state == PEEP_STATE_WALKING || peep->state == PEEP_STATE_QUEUING) && peep->action >= 254) { peep->action = PEEP_ACTION_CLAP; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); } @@ -2247,12 +4651,157 @@ void peep_update_days_in_queue() */ rct_peep *peep_generate(int x, int y, int z) { - int eax, ebx, ecx, edx, esi, edi, ebp; - eax = x; - ecx = y; - edx = z; - RCT2_CALLFUNC_X(0x0069A05D, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp); - return (rct_peep*)esi; + //int eax, ebx, ecx, _edx, esi, edi, ebp; + //eax = x; + //ecx = y; + //_edx = z; + //RCT2_CALLFUNC_X(0x0069A05D, &eax, &ebx, &ecx, &_edx, &esi, &edi, &ebp); + //return (rct_peep*)esi; + + if (RCT2_GLOBAL(0x13573C8, uint16) < 400) + return NULL; + + rct_peep* peep = (rct_peep*)create_sprite(1); + + move_sprite_to_list((rct_sprite*)peep, SPRITE_LINKEDLIST_OFFSET_PEEP); + + peep->sprite_identifier = 1; + peep->sprite_type = 0; + peep->var_2A = 1; + peep->state = PEEP_STATE_FALLING; + peep->action = PEEP_ACTION_NONE_2; + peep->var_6D = 0; + peep->action_sprite_image_offset = 0; + peep->no_action_frame_no = 0; + peep->action_sprite_type = 0; + peep->flags = 0; + peep->favourite_ride = 0xFF; + peep->var_FA = 0; + + uint8* edx = RCT2_ADDRESS(0x98270C, uint8*)[peep->sprite_type * 2]; + peep->sprite_width = edx[peep->action_sprite_type * 4]; + peep->sprite_height_negative = edx[peep->action_sprite_type * 4 + 1]; + peep->sprite_height_positive = edx[peep->action_sprite_type * 4 + 2]; + + peep->sprite_direction = 0; + + sprite_move(x, y, z, (rct_sprite*)peep); + invalidate_sprite((rct_sprite*)peep); + + peep->var_41 = (scenario_rand() & 0x1F) + 45; + peep->var_C4 = 0; + peep->var_79 = 0xFF; + peep->type = PEEP_TYPE_GUEST; + peep->previous_ride = 0xFF; + peep->thoughts->type = PEEP_THOUGHT_TYPE_NONE; + peep->var_45 = 0; + + uint8 al = (scenario_rand() & 0x7) + 3; + uint8 ah = min(al, 7) - 3; + + if (al >= 7) al = 15; + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PREF_LESS_INTENSE_RIDES){ + ah = 0; + al = 4; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PREF_MORE_INTENSE_RIDES){ + ah = 9; + al = 15; + } + + peep->intensity = (al << 4) | ah; + + uint8 nausea_tolerance = scenario_rand() & 0x7; + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_PREF_MORE_INTENSE_RIDES){ + nausea_tolerance += 4; + } + + peep->nausea_tolerance = RCT2_ADDRESS(0x009823A0, uint8)[nausea_tolerance]; + + sint8 happiness = (scenario_rand() & 0x1F) - 15 + RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_HAPPINESS, uint8); + + if (RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_HAPPINESS, uint8) == 0) + happiness += 0x80; + + peep->happiness = happiness; + peep->happiness_growth_rate = happiness; + peep->nausea = 0; + peep->nausea_growth_rate = 0; + + sint8 hunger = (scenario_rand() & 0x1F) - 15 + RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_HUNGER, uint8); + + peep->hunger = hunger; + + sint8 thirst = (scenario_rand() & 0x1F) - 15 + RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_THIRST, uint8); + + peep->thirst = thirst; + + peep->bathroom = 0; + peep->var_42 = 0; + memset(&peep->rides_been_on, 0, 32); + + peep->no_of_rides = 0; + memset(&peep->var_48, 0, 16); + peep->id = RCT2_GLOBAL(0x013B0E6C, uint32)++; + peep->name_string_idx = 767; + + money32 cash = (scenario_rand() & 0x3) * 100 - 100 + RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16); + if (cash < 0) cash = 0; + + if (RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) == 0){ + cash = 500; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_NO_MONEY){ + cash = 0; + } + + if (RCT2_GLOBAL(RCT2_ADDRESS_GUEST_INITIAL_CASH, money16) == 0xFFFF){ + cash = 0; + } + + peep->cash_in_pocket = cash; + peep->cash_spent = 0; + peep->time_in_park = -1; + peep->var_CC = 0xFFFF; + peep->item_standard_flags = 0; + peep->item_extra_flags = 0; + peep->guest_heading_to_ride_id = 0xFF; + peep->var_E1 = 0; + peep->var_E3 = 0; + peep->var_EF = 0; + peep->paid_to_enter = 0; + peep->paid_on_rides = 0; + peep->paid_on_food = 0; + peep->paid_on_drink = 0; + peep->paid_on_souvenirs = 0; + peep->no_of_food = 0; + peep->no_of_drinks = 0; + peep->no_of_souvenirs = 0; + peep->var_F2 = 0; + peep->var_F3 = 0; + peep->var_F4 = 0; + + uint8 tshirt_colour = scenario_rand() % 33; + peep->tshirt_colour = RCT2_ADDRESS(0x009823D5, uint8)[tshirt_colour]; + + uint8 trousers_colour = scenario_rand() % 25; + peep->trousers_colour = RCT2_ADDRESS(0x009823BC, uint8)[trousers_colour]; + + uint8 energy = (scenario_rand() & 0x3F) + 65; + peep->energy = energy; + peep->energy_growth_rate = energy; + + if (RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_SHOW_REAL_GUEST_NAMES){ + RCT2_CALLPROC_X(0x0069C483, 0, 0, 0, 0, (int)peep, 0, 0); + } + RCT2_CALLPROC_X(0x00699115, 0, 0, 0, 0, (int)peep, 0, 0); + + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)++; + + return peep; } /** @@ -2663,12 +5212,12 @@ static int peep_should_find_bench(rct_peep* peep){ * esi: peep */ void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_arguments){ - int action = RCT2_ADDRESS(0x981DB0, uint16)[thought_type]; + uint8 action = RCT2_ADDRESS(0x981DB0, uint16)[thought_type] & 0xFF; if (action != 0xFF && peep->action >= 254){ peep->action = action; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); invalidate_sprite((rct_sprite*)peep); } diff --git a/src/peep/peep.h b/src/peep/peep.h index 468cde476b..260ad9cc84 100644 --- a/src/peep/peep.h +++ b/src/peep/peep.h @@ -209,6 +209,7 @@ enum PEEP_STATE { }; enum PEEP_ACTION_EVENTS { + PEEP_ACTION_CHECK_TIME = 0, // If no food then check watch PEEP_ACTION_EAT_FOOD = 1, PEEP_ACTION_SHAKE_HEAD = 2, @@ -344,18 +345,21 @@ typedef struct { typedef struct { uint8 sprite_identifier; // 0x00 uint8 var_01; - uint16 var_02; // 0x02 + uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - uint8 var_09; // 0x09 + // Height from center of sprite to bottom + uint8 sprite_height_negative; // 0x09 uint16 sprite_index; // 0x0A uint16 var_0C; sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 - uint8 var_14; // 0x14 - uint8 var_15; // 0x15 + // Width from center of sprite to edge + uint8 sprite_width; // 0x14 + // Height from center of sprite to top + uint8 sprite_height_positive; // 0x15 sint16 sprite_left; // 0x16 sint16 sprite_top; // 0x18 sint16 sprite_right; // 0x1A @@ -391,12 +395,13 @@ typedef struct { uint8 hunger; // 0x3E uint8 thirst; // 0x3F uint8 bathroom; // 0x40 - uint8 pad_41[0x2]; + uint8 var_41; + uint8 var_42; uint8 intensity; // 0x43 uint8 nausea_tolerance; // 0x44 uint8 var_45; // Some sort of flags? money16 paid_on_drink; // 0x46 - uint8 pad_48[0x10]; + uint8 var_48[16]; uint32 item_extra_flags; // 0x58 uint8 photo2_ride_ref; // 0x5C uint8 photo3_ride_ref; // 0x5D @@ -407,28 +412,34 @@ typedef struct { uint8 current_train; // 0x6A union{ struct{ - uint8 current_car; // 0x6B - uint8 current_seat; // 0x6C + uint8 current_car; // 0x6B + uint8 current_seat; // 0x6C }; - uint16 time_to_sitdown; //0x6B + uint16 time_to_sitdown; //0x6B struct{ uint8 time_to_stand; //0x6B uint8 standing_flags; //0x6C }; }; uint8 var_6D; // 0x6D - uint8 var_6E; // 0x6E + uint8 action_sprite_type; // 0x6E uint8 var_6F; - uint8 var_70; + uint8 action_sprite_image_offset; // 0x70 uint8 action; // 0x71 uint8 action_frame; // 0x72 uint8 var_73; - uint16 var_74; + union { + uint16 var_74; // time getting to ride to fix + uint16 next_in_queue; // 0x74 + }; uint8 var_76; uint8 pad_77; - uint8 var_78; - uint8 pad_79; - uint16 var_7A; // time waiting in line possibly + union{ + uint8 maze_last_edge; // 0x78 + uint8 var_78; + }; + uint8 var_79; + uint16 time_in_queue; // 0x7A uint8 rides_been_on[32]; // 0x7C // 255 bit bitmap of every ride the peep has been on see // window_peep_rides_update for how to use. @@ -436,7 +447,7 @@ typedef struct { money32 cash_in_pocket; // 0xA0 money32 cash_spent; // 0xA4 sint32 time_in_park; // 0xA8 - uint8 var_AC; // 0xAC + sint8 var_AC; // 0xAC uint8 previous_ride; // 0xAD uint16 previous_ride_time_out; // 0xAE rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 @@ -454,7 +465,7 @@ typedef struct { uint32 flags; // 0xC8 uint32 var_CC; uint8 pad_D0[0x10]; - uint8 var_E0; // 0xE0 + uint8 no_action_frame_no; // 0xE0 uint8 var_E1; uint8 var_E2; // 0xE2 uint8 var_E3; @@ -479,10 +490,10 @@ typedef struct { uint8 no_of_food; // 0xEC uint8 no_of_drinks; // 0xED uint8 no_of_souvenirs; // 0xEE - uint8 pad_EF; + uint8 var_EF; uint8 voucher_type; // 0xF0 uint8 voucher_arguments; // 0xF1 ride_id or string_offset_id - uint8 pad_F2; + uint8 var_F2; uint8 var_F3; uint8 var_F4; uint8 days_in_queue; // 0xF5 @@ -490,7 +501,8 @@ typedef struct { uint8 umbrella_colour; // 0xF7 uint8 hat_colour; // 0xF8 uint8 favourite_ride; // 0xF9 - uint16 pad_FA; + uint8 var_FA; + uint8 pad_FB; uint32 item_standard_flags; // 0xFC } rct_peep; diff --git a/src/peep/staff.c b/src/peep/staff.c index 1321bf01ea..3f14a749b1 100644 --- a/src/peep/staff.c +++ b/src/peep/staff.c @@ -107,9 +107,9 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, move_sprite_to_list((rct_sprite *)newPeep, SPRITE_LINKEDLIST_OFFSET_PEEP); newPeep->sprite_identifier = 1; - newPeep->var_09 = 0x0F; - newPeep->var_15 = 5; - newPeep->var_14 = 8; + newPeep->sprite_height_negative = 0x0F; + newPeep->sprite_height_positive = 5; + newPeep->sprite_width = 8; newPeep->sprite_direction = 0; sprite_move(_ax, *ecx, _dx, (rct_sprite*)newPeep); @@ -122,9 +122,9 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, newPeep->var_45 = 0; newPeep->action = 0xFF; newPeep->var_6D = 0; - newPeep->var_70 = 0; - newPeep->var_E0 = 0; - newPeep->var_6E = 0; + newPeep->action_sprite_image_offset = 0; + newPeep->no_action_frame_no = 0; + newPeep->action_sprite_type = 0; newPeep->var_C4 = 0; newPeep->type = PEEP_TYPE_STAFF; newPeep->var_2A = 0; @@ -176,9 +176,9 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, newPeep->sprite_type = _eax; _edx = RCT2_ADDRESS(0x0098270C, uint32)[_eax * 2]; - newPeep->var_14 = *((uint8*)_edx); - newPeep->var_09 = *((uint8*)(_edx + 1)); - newPeep->var_15 = *((uint8*)(_edx + 2)); + newPeep->sprite_width = *((uint8*)_edx); + newPeep->sprite_height_negative = *((uint8*)(_edx + 1)); + newPeep->sprite_height_positive = *((uint8*)(_edx + 2)); sprite_move( newPeep->x, newPeep->y, newPeep->z, (rct_sprite*)newPeep); invalidate_sprite((rct_sprite*)newPeep); diff --git a/src/peep/staff.h b/src/peep/staff.h index a036731abf..4d5bd4fa66 100644 --- a/src/peep/staff.h +++ b/src/peep/staff.h @@ -40,6 +40,13 @@ enum STAFF_TYPE { STAFF_TYPE_ENTERTAINER }; +enum STAFF_ORDERS{ + STAFF_ORDERS_SWEEPING = (1 << 0), + STAFF_ORDERS_WATER_FLOWERS = (1 << 1), + STAFF_ORDERS_EMPTY_BINS = (1 << 2), + STAFF_ORDERS_MOWING = (1 << 3) +}; + void game_command_update_staff_colour(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); void game_command_hire_new_staff_member(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); diff --git a/src/ride/ride.c b/src/ride/ride.c index 78a763e7f2..328a4ab704 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -1884,7 +1884,7 @@ void ride_measurement_update(rct_ride_measurement *measurement) return; measurement->flags &= ~RIDE_MEASUREMENT_FLAG_UNLOADING; - if (measurement->var_0B == vehicle->var_4B) + if (measurement->current_station == vehicle->current_station) measurement->current_item = 0; } @@ -1968,7 +1968,7 @@ void ride_measurements_update() vehicle = &(g_sprite_list[spriteIndex].vehicle); if (vehicle->status == VEHICLE_STATUS_DEPARTING || vehicle->status == VEHICLE_STATUS_STOPPING) { measurement->vehicle_index = j; - measurement->var_0B = vehicle->var_4B; + measurement->current_station = vehicle->current_station; measurement->flags |= RIDE_MEASUREMENT_FLAG_RUNNING; measurement->flags &= ~RIDE_MEASUREMENT_FLAG_UNLOADING; ride_measurement_update(measurement); diff --git a/src/ride/ride.h b/src/ride/ride.h index a33c86ffe1..2857ff81dc 100644 --- a/src/ride/ride.h +++ b/src/ride/ride.h @@ -82,12 +82,14 @@ typedef struct{ uint32 var_4C; // 0x4C , 0x66 uint32 no_vehicle_images; // 0x50 , 0x6A uint8 no_seating_rows; // 0x54 , 0x6E - uint8 pad_55[0x7]; + uint8 pad_55[0x5]; + uint8 var_5A; // 0x5A , 0x74 + uint8 pad_5B; // 0x5B , 0x75 uint8 var_5C; // 0x5C , 0x76 uint8 var_5D; // 0x5D , 0x77 uint8 pad_5E[0x2]; uint8 var_60; // 0x60 , 0x7A - uint32 var_61; // 0x61 , 0x7B + uint8* peep_loading_positions; // 0x61 , 0x7B } rct_ride_type_vehicle; /** @@ -103,12 +105,13 @@ typedef struct { uint8 var_00C; uint8 var_00D; uint8 var_00E; - uint8 var_00F; - uint8 var_010; + uint8 min_cars_in_train; // 0x00F + uint8 max_cars_in_train; // 0x010 uint8 var_011; uint8 var_012; uint8 var_013; - uint8 pad_014[0x6]; + uint8 var_014; + uint8 pad_015[0x5]; rct_ride_type_vehicle vehicles[4]; // 0x1A uint32 var_1AE; sint8 excitement_multipler; // 0x1B2 @@ -148,7 +151,8 @@ typedef struct { uint8 var_066[4]; uint16 entrances[4]; // 0x06A uint16 exits[4]; // 0x072 - uint8 pad_07A[0x0C]; + uint16 first_peep_in_queue[4]; // 0x07A + uint8 pad_082[4]; uint16 vehicles[32]; // 0x086 Points to the first car in the train uint8 depart_flags; // 0x0C6 @@ -224,7 +228,7 @@ typedef struct { uint8 satisfaction_time_out; // 0x14B uint8 satisfaction_next; // 0x14C // Various flags stating whether a window needs to be refreshed - uint8 window_invalidate_flags; + uint8 window_invalidate_flags; // 0x14D uint8 pad_14E[0x02]; uint32 total_customers; // 0x150 money32 total_profit; // 0x154 @@ -238,7 +242,9 @@ typedef struct { uint16 slide_peep; // 0x15E uint16 maze_tiles; // 0x15E }; - uint8 pad_160[0x16]; + uint8 pad_160[0xE]; + uint8 slide_peep_t_shirt_colour;// 0x16E + uint8 pad_16F[0x7]; uint8 var_176; uint8 pad_177[0x9]; sint16 build_date; // 0x180 @@ -314,7 +320,7 @@ typedef struct { uint16 num_items; // 0x0006 uint16 current_item; // 0x0008 uint8 vehicle_index; // 0x000A - uint8 var_0B; + uint8 current_station; // 0x000B sint8 vertical[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x000C sint8 lateral[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x12CC uint8 velocity[RIDE_MEASUREMENT_MAX_ITEMS]; // 0x258C @@ -363,7 +369,7 @@ enum { RIDE_TYPE_MINI_SUSPENDED_COASTER, RIDE_TYPE_BUMPER_BOATS, RIDE_TYPE_WOODEN_WILD_MOUSE, - RIDE_TYPE_STEEPLECHASE, + RIDE_TYPE_STEEPLECHASE = 10, RIDE_TYPE_CAR_RIDE, RIDE_TYPE_LAUNCHED_FREEFALL, RIDE_TYPE_BOBSLEIGH_COASTER, @@ -373,7 +379,7 @@ enum { RIDE_TYPE_MINE_TRAIN_COASTER, RIDE_TYPE_CHAIRLIFT, RIDE_TYPE_CORKSCREW_ROLLER_COASTER, - RIDE_TYPE_MAZE, + RIDE_TYPE_MAZE = 20, RIDE_TYPE_SPIRAL_SLIDE, RIDE_TYPE_GO_KARTS, RIDE_TYPE_LOG_FLUME, @@ -383,7 +389,7 @@ enum { RIDE_TYPE_SWINGING_INVERTER_SHIP, RIDE_TYPE_FOOD_STALL, RIDE_TYPE_1D, - RIDE_TYPE_DRINK_STALL, + RIDE_TYPE_DRINK_STALL = 30, RIDE_TYPE_1F, RIDE_TYPE_SHOP, RIDE_TYPE_MERRY_GO_ROUND, @@ -393,7 +399,7 @@ enum { RIDE_TYPE_FERRIS_WHEEL, RIDE_TYPE_MOTION_SIMULATOR, RIDE_TYPE_3D_CINEMA, - RIDE_TYPE_TOP_SPIN, + RIDE_TYPE_TOP_SPIN = 40, RIDE_TYPE_SPACE_RINGS, RIDE_TYPE_REVERSE_FREEFALL_COASTER, RIDE_TYPE_ELEVATOR, @@ -403,7 +409,7 @@ enum { RIDE_TYPE_HAUNTED_HOUSE, RIDE_TYPE_FIRST_AID, RIDE_TYPE_CIRCUS_SHOW, - RIDE_TYPE_GHOST_TRAIN, + RIDE_TYPE_GHOST_TRAIN = 50, RIDE_TYPE_TWISTER_ROLLER_COASTER, RIDE_TYPE_WOODEN_ROLLER_COASTER, RIDE_TYPE_SIDE_FRICTION_ROLLER_COASTER, @@ -413,7 +419,7 @@ enum { RIDE_TYPE_FLYING_ROLLER_COASTER, RIDE_TYPE_3A, RIDE_TYPE_VIRGINIA_REEL, - RIDE_TYPE_SPLASH_BOATS, + RIDE_TYPE_SPLASH_BOATS = 60, RIDE_TYPE_MINI_HELICOPTERS, RIDE_TYPE_LAY_DOWN_ROLLER_COASTER, RIDE_TYPE_SUSPENDED_MONORAIL, @@ -423,7 +429,7 @@ enum { RIDE_TYPE_MINI_GOLF, RIDE_TYPE_GIGA_COASTER, RIDE_TYPE_ROTO_DROP, - RIDE_TYPE_FLYING_SAUCERS, + RIDE_TYPE_FLYING_SAUCERS = 70, RIDE_TYPE_CROOKED_HOUSE, RIDE_TYPE_MONORAIL_CYCLES, RIDE_TYPE_COMPACT_INVERTED_COASTER, @@ -433,7 +439,7 @@ enum { RIDE_TYPE_MAGIC_CARPET, RIDE_TYPE_SUBMARINE_RIDE, RIDE_TYPE_RIVER_RAFTS, - RIDE_TYPE_50, + RIDE_TYPE_50 = 80, RIDE_TYPE_ENTERPRISE, RIDE_TYPE_52, RIDE_TYPE_53, @@ -443,7 +449,7 @@ enum { RIDE_TYPE_MINI_ROLLER_COASTER, RIDE_TYPE_MINE_RIDE, RIDE_TYPE_LIM_LAUNCHED_ROLLER_COASTER, - RIDE_TYPE_90 + RIDE_TYPE_90 = 90 }; enum { @@ -737,7 +743,8 @@ int sub_6C683D(int* x, int* y, int z, int direction, int type, int esi, int edi, 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(); - +rct_map_element *ride_get_station_start_track_element(rct_ride *ride, int stationIndex); +rct_map_element *ride_get_station_exit_element(rct_ride *ride, int x, int y, int z); 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); diff --git a/src/ride/station.c b/src/ride/station.c index 236b8b3359..33cf3e9d75 100644 --- a/src/ride/station.c +++ b/src/ride/station.c @@ -234,9 +234,9 @@ static void ride_race_init_vehicle_speeds(rct_ride *ride) vehicle = &g_sprite_list[ride->vehicles[i]].vehicle; vehicle->var_48 &= ~(1 << 6); - rideEntry = GET_RIDE_ENTRY(vehicle->var_D6); + rideEntry = GET_RIDE_ENTRY(vehicle->ride_subtype); - vehicle->speed = (scenario_rand() & 16) - 8 + rideEntry->vehicles[vehicle->var_31].var_5C; + vehicle->speed = (scenario_rand() & 16) - 8 + rideEntry->vehicles[vehicle->vehicle_type].var_5C; if (vehicle->num_peeps != 0) { rct_peep *peep = &g_sprite_list[vehicle->peep[0]].peep; diff --git a/src/ride/vehicle.c b/src/ride/vehicle.c index 41741979d1..7d3070fe8b 100644 --- a/src/ride/vehicle.c +++ b/src/ride/vehicle.c @@ -99,9 +99,8 @@ void vehicle_update_sound_params(rct_vehicle* vehicle) sint32 v19 = vehicle->velocity; - int testaddr = (vehicle->var_31 * 0x65); - testaddr += (int)RCT2_ADDRESS(0x009ACFA4, rct_ride_type*)[vehicle->var_D6]; - uint8 test = ((uint8*)testaddr)[0x74]; + rct_ride_type* ride_type = GET_RIDE_ENTRY(vehicle->ride_subtype); + uint8 test = ride_type->vehicles[vehicle->vehicle_type].var_5A; if (test & 1) { v19 *= 2; @@ -633,4 +632,9 @@ rct_vehicle *vehicle_get_head(rct_vehicle *vehicle) } return vehicle; +} + +int vehicle_is_used_in_pairs(rct_vehicle *vehicle) +{ + return vehicle->num_seats & VEHICLE_SEAT_PAIR_FLAG; } \ No newline at end of file diff --git a/src/ride/vehicle.h b/src/ride/vehicle.h index 292e3f399d..28f853ba13 100644 --- a/src/ride/vehicle.h +++ b/src/ride/vehicle.h @@ -26,31 +26,41 @@ typedef struct { uint8 sprite_identifier; // 0x00 uint8 var_01; - uint8 pad_02[0x02]; + uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - uint8 pad_09; + // Height from center of sprite to bottom + uint8 sprite_height_negative; // 0x09 uint16 sprite_index; // 0x0A uint8 pad_0C[2]; sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 - uint8 pad_14[0x02]; + // Width from center of sprite to edge + uint8 sprite_width; // 0x14 + // Height from center of sprite to top + uint8 sprite_height_positive; // 0x15 sint16 sprite_left; // 0x16 sint16 sprite_top; // 0x18 sint16 sprite_right; // 0x1A sint16 sprite_bottom; // 0x1C uint8 sprite_direction; // 0x1E - uint8 pad_1F[0x09]; + uint8 var_1F; + uint8 pad_20[0x08]; sint32 velocity; // 0x28 uint8 pad_2C[0x04]; uint8 ride; // 0x30 - uint8 var_31; + uint8 vehicle_type; // 0x31 uint8 pad_32[0x02]; uint16 var_34; sint16 var_36; - uint8 pad_38[0x06]; + //x related + uint16 var_38; + // y related + uint16 var_3A; + // z related + uint16 var_3C; uint16 next_vehicle_on_train; // 0x3E uint16 prev_vehicle_on_train; // 0x40 uint16 pad_42; @@ -58,14 +68,16 @@ typedef struct { uint16 var_46; uint16 var_48; uint8 pad_4A; - uint8 var_4B; + uint8 current_station; // 0x4B uint8 pad_4C[0x4]; uint8 status; // 0x50 uint8 var_51; uint16 peep[32]; // 0x52 - uint8 pad_92[0x21]; + uint8 peep_tshirt_colours[32]; // 0x92 + uint8 num_seats; // 0xB2 uint8 num_peeps; // 0xB3 - uint8 pad_B4[0x07]; + uint8 next_free_seat; // 0xB4 + uint8 pad_B5[0x06]; uint8 sound1_id; // 0xBB uint8 sound1_volume; // 0xBC uint8 sound2_id; // 0xBD @@ -78,10 +90,11 @@ typedef struct { uint8 var_CD; union { uint8 var_CE; - uint8 num_laps; // 0xCE + uint8 num_laps; // 0xCE }; - uint8 pad_CF[0x07]; - uint8 var_D6; + uint8 pad_CF[0x06]; + uint8 var_D5; + uint8 ride_subtype; // 0xD6 } rct_vehicle; enum { @@ -118,13 +131,16 @@ enum { VEHICLE_STATUS_STOPPED_BY_BLOCK_BRAKES }; +#define VEHICLE_SEAT_PAIR_FLAG 0x80 +#define VEHICLE_SEAT_NUM_MASK 0x7F + void vehicle_update_all(); int sub_6BC2F3(rct_vehicle* vehicle); void sub_6BB9FF(rct_vehicle* vehicle); void vehicle_sounds_update(); void vehicle_get_g_forces(rct_vehicle *vehicle, int *verticalG, int *lateralG); void vehicle_set_map_toolbar(rct_vehicle *vehicle); - +int vehicle_is_used_in_pairs(rct_vehicle *vehicle); rct_vehicle *vehicle_get_head(rct_vehicle *vehicle); /** Helper macro until rides are stored in this module. */ diff --git a/src/title.c b/src/title.c index e3d568ed5c..d7fbbd9f44 100644 --- a/src/title.c +++ b/src/title.c @@ -266,7 +266,6 @@ static void DrawOpenRCT2(int x, int y) void game_handle_input(); void title_update() { - screenshot_check(); title_handle_keyboard_input(); diff --git a/src/windows/guest.c b/src/windows/guest.c index 5e699750d2..d816d80bc9 100644 --- a/src/windows/guest.c +++ b/src/windows/guest.c @@ -1235,8 +1235,8 @@ void window_guest_overview_tool_down(){ peep_window_state_update(peep); peep->action = 0xFF; peep->var_6D = 0; - peep->var_70 = 0; - peep->var_6E = 0xFF; + peep->action_sprite_image_offset = 0; + peep->action_sprite_type = 0xFF; peep->var_C4 = 0; peep->happiness_growth_rate -= 10; @@ -1268,8 +1268,8 @@ void window_guest_overview_tool_abort(){ peep_window_state_update(peep); peep->action = 0xFF; peep->var_6D = 0; - peep->var_70 = 0; - peep->var_6E = 0; + peep->action_sprite_image_offset = 0; + peep->action_sprite_type = 0; peep->var_C4 = 0; } diff --git a/src/windows/ride.c b/src/windows/ride.c index dd63c5d7ac..5b16b8ea77 100644 --- a/src/windows/ride.c +++ b/src/windows/ride.c @@ -2070,7 +2070,7 @@ static rct_string_id window_ride_get_status_vehicle(rct_window *w, void *argumen stringId += 23; RCT2_GLOBAL((int)arguments + 4, uint16) = RideNameConvention[ride->type].station_name; - RCT2_GLOBAL((int)arguments + 6, uint16) = vehicle->var_4B + 1; + RCT2_GLOBAL((int)arguments + 6, uint16) = vehicle->current_station + 1; if (ride->num_stations > 1) RCT2_GLOBAL((int)arguments + 4, uint16) += 6; @@ -2390,7 +2390,7 @@ static void window_ride_vehicle_dropdown() break; case WIDX_VEHICLE_CARS_PER_TRAIN_DROPDOWN: RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, rct_string_id) = 1019; - game_do_command(0, (1 << 8) | 1, 0, ((rideEntry->var_00F + dropdownIndex) << 8) | w->number, GAME_COMMAND_9, 0, 0); + game_do_command(0, (1 << 8) | 1, 0, ((rideEntry->min_cars_in_train + dropdownIndex) << 8) | w->number, GAME_COMMAND_9, 0, 0); break; } } @@ -2461,7 +2461,7 @@ static void window_ride_vehicle_invalidate() } // Cars per train - if (rideEntry->var_012 + 1 < rideEntry->var_010) { + if (rideEntry->var_012 + 1 < rideEntry->max_cars_in_train) { window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].image = carsPerTrain > 1 ? 1023 : 1022; window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN].type = WWT_DROPDOWN; window_ride_vehicle_widgets[WIDX_VEHICLE_CARS_PER_TRAIN_DROPDOWN].type = WWT_DROPDOWN_BUTTON; @@ -3739,7 +3739,7 @@ static void window_ride_colour_mousedown(int widgetIndex, rct_window *w, rct_wid dropdownWidget->bottom - dropdownWidget->top + 1, w->colours[1], 0, - rideEntry->var_010 > 1 ? 3 : 2, + rideEntry->max_cars_in_train > 1 ? 3 : 2, widget->right - dropdownWidget->left ); diff --git a/src/windows/staff.c b/src/windows/staff.c index 2094182f5c..fb8c70e1f2 100644 --- a/src/windows/staff.c +++ b/src/windows/staff.c @@ -1158,8 +1158,8 @@ void window_staff_overview_tool_down(){ peep_window_state_update(peep); peep->action = 0xFF; peep->var_6D = 0; - peep->var_70 = 0; - peep->var_6E = 0; + peep->action_sprite_image_offset = 0; + peep->action_sprite_type = 0; peep->var_C4 = 0; tool_cancel(); @@ -1196,8 +1196,8 @@ void window_staff_overview_tool_abort(){ peep_window_state_update(peep); peep->action = 0xFF; peep->var_6D = 0; - peep->var_70 = 0; - peep->var_6E = 0; + peep->action_sprite_image_offset = 0; + peep->action_sprite_type = 0; peep->var_C4 = 0; } diff --git a/src/world/map.h b/src/world/map.h index 04e78b63e8..e45cf71503 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -39,8 +39,13 @@ typedef struct { typedef struct { uint8 type; //4 - uint8 sequence; //5 - uint8 colour; //6 + union{ + struct{ + uint8 sequence; //5 + uint8 colour; //6 + }; + uint16 maze_entry; // 5 + }; uint8 ride_index; //7 } rct_map_element_track_properties; diff --git a/src/world/map_animation.c b/src/world/map_animation.c index 5b188839f1..9ac1eee941 100644 --- a/src/world/map_animation.c +++ b/src/world/map_animation.c @@ -194,7 +194,7 @@ static bool map_animation_invalidate_small_scenery(int x, int y, int baseZ) int y2 = y - TileDirectionDelta[direction].y; uint16 spriteIdx = RCT2_ADDRESS(0x00F1EF60, uint16)[((x2 & 0x1FE0) << 3) | (y2 >> 5)]; - for (; spriteIdx != 0xFFFF; spriteIdx = sprite->unknown.var_02) { + for (; spriteIdx != 0xFFFF; spriteIdx = sprite->unknown.next_in_quadrant) { sprite = &g_sprite_list[spriteIdx]; if (sprite->unknown.linked_list_type_offset != SPRITE_LINKEDLIST_OFFSET_PEEP) continue; @@ -207,9 +207,9 @@ static bool map_animation_invalidate_small_scenery(int x, int y, int baseZ) if (peep->action < PEEP_ACTION_NONE_1) continue; - peep->action = 0; + peep->action = PEEP_ACTION_CHECK_TIME; peep->action_frame = 0; - peep->var_70 = 0; + peep->action_sprite_image_offset = 0; sub_693B58(peep); RCT2_CALLPROC_X(0x006EC53F, 0, 0, 0, 0, (int)peep, 0, 0); break; diff --git a/src/world/sprite.c b/src/world/sprite.c index 95762a9921..9e0902fed6 100644 --- a/src/world/sprite.c +++ b/src/world/sprite.c @@ -31,7 +31,7 @@ rct_sprite* g_sprite_list = RCT2_ADDRESS(RCT2_ADDRESS_SPRITE_LIST, rct_sprite); * * rct2: 0x006736C7 */ -void create_balloon(int x, int y, int z, int colour) +void create_balloon(int x, int y, int z, int colour, uint8 bl) { rct_sprite* sprite = create_sprite(2); if (sprite != NULL) @@ -44,7 +44,7 @@ void create_balloon(int x, int y, int z, int colour) sprite->balloon.misc_identifier = SPRITE_MISC_BALLOON; sprite->balloon.var_26 = 0; sprite->balloon.colour = colour; - sprite->balloon.popped = 0; + sprite->balloon.popped = bl; } } @@ -288,7 +288,7 @@ void reset_0x69EBE4(){ } uint16 ax = RCT2_ADDRESS(0xF1EF60,uint16)[edi]; RCT2_ADDRESS(0xF1EF60,uint16)[edi] = spr->unknown.sprite_index; - spr->unknown.var_02 = ax; + spr->unknown.next_in_quadrant = ax; } } } @@ -325,14 +325,14 @@ rct_sprite *create_sprite(uint8 bl) sprite->y = SPRITE_LOCATION_NULL; sprite->z = 0; sprite->name_string_idx = 0; - sprite->var_14 = 0x10; - sprite->var_09 = 0x14; - sprite->var_15 = 0x8; - sprite->pad_0C[0] = 0x0; + sprite->sprite_width = 0x10; + sprite->sprite_height_negative = 0x14; + sprite->sprite_height_positive = 0x8; + sprite->var_0C = 0; sprite->sprite_left = SPRITE_LOCATION_NULL; - sprite->var_02 = RCT2_GLOBAL(0xF3EF60, uint16); - RCT2_GLOBAL(0xF3EF60, uint16) = sprite->sprite_index; + sprite->next_in_quadrant = RCT2_ADDRESS(0xF1EF60, uint16)[0x10000]; + RCT2_ADDRESS(0xF1EF60, uint16)[0x10000] = sprite->sprite_index; return (rct_sprite*)sprite; } @@ -470,14 +470,14 @@ void sprite_move(int x, int y, int z, rct_sprite* sprite){ uint16* sprite_idx = &RCT2_ADDRESS(0xF1EF60, uint16)[current_position]; rct_sprite* sprite2 = &g_sprite_list[*sprite_idx]; while (sprite != sprite2){ - sprite_idx = &sprite2->unknown.var_02; + sprite_idx = &sprite2->unknown.next_in_quadrant; sprite2 = &g_sprite_list[*sprite_idx]; } - *sprite_idx = sprite->unknown.var_02; + *sprite_idx = sprite->unknown.next_in_quadrant; int temp_sprite_idx = RCT2_ADDRESS(0xF1EF60, uint16)[new_position]; RCT2_ADDRESS(0xF1EF60, uint16)[new_position] = sprite->unknown.sprite_index; - sprite->unknown.var_02 = temp_sprite_idx; + sprite->unknown.next_in_quadrant = temp_sprite_idx; } if (x == 0x8000){ @@ -507,10 +507,10 @@ void sprite_move(int x, int y, int z, rct_sprite* sprite){ break; } - sprite->unknown.sprite_left = new_x - sprite->unknown.var_14; - sprite->unknown.sprite_right = new_x + sprite->unknown.var_14; - sprite->unknown.sprite_top = new_y - sprite->unknown.var_09; - sprite->unknown.sprite_bottom = new_y + sprite->unknown.var_15; + sprite->unknown.sprite_left = new_x - sprite->unknown.sprite_width; + sprite->unknown.sprite_right = new_x + sprite->unknown.sprite_width; + sprite->unknown.sprite_top = new_y - sprite->unknown.sprite_height_negative; + sprite->unknown.sprite_bottom = new_y + sprite->unknown.sprite_height_positive; sprite->unknown.x = x; sprite->unknown.y = y; sprite->unknown.z = z; diff --git a/src/world/sprite.h b/src/world/sprite.h index 9364b7999a..fede1ba7e2 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -47,18 +47,21 @@ typedef enum { typedef struct { uint8 sprite_identifier; // 0x00 uint8 misc_identifier; // 0x01 - uint16 var_02; + uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - uint8 var_09; + // Height from center of sprite to bottom + uint8 sprite_height_negative; // 0x09 uint16 sprite_index; // 0x0A - uint8 pad_0C[2]; + uint16 var_0C; sint16 x; // 0x0E sint16 y; // 0x10 sint16 z; // 0x12 - uint8 var_14; // 0x14 - uint8 var_15; // 0x15 + // Width from center of sprite to edge + uint8 sprite_width; // 0x14 + // Height from center of sprite to top + uint8 sprite_height_positive; // 0x15 sint16 sprite_left; // 0x16 sint16 sprite_top; // 0x18 sint16 sprite_right; // 0x1A @@ -75,20 +78,24 @@ typedef struct { typedef struct { uint8 sprite_identifier; // 0x00 uint8 var_01; // 0x01 - uint16 var_02; // 0x02 + uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... uint8 pad_09; uint16 sprite_index; // 0x0A - uint8 pad_0B[0x19]; + uint16 pad_0C; + sint16 x; // 0x0E + sint16 y; // 0x10 + sint16 z; // 0x12 + uint8 pad_14[0x10]; uint32 var_24; } rct_litter; typedef struct { uint8 sprite_identifier; // 0x00 uint8 misc_identifier; // 0x01 - uint16 var_02; // 0x02 + uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... @@ -115,7 +122,7 @@ typedef struct { typedef struct { uint8 sprite_identifier; // 0x00 uint8 misc_identifier; // 0x01 - uint16 var_02; // 0x02 + uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... @@ -137,7 +144,7 @@ typedef struct { typedef struct { uint8 sprite_identifier; // 0x00 uint8 misc_identifier; // 0x01 - uint16 var_02; // 0x02 + uint16 next_in_quadrant; // 0x02 uint16 next; // 0x04 uint16 previous; // 0x06 uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... @@ -218,7 +225,7 @@ enum { // rct2: 0x010E63BC extern rct_sprite* g_sprite_list; -void create_balloon(int x, int y, int z, int colour); +void create_balloon(int x, int y, int z, int colour, uint8 bl); void create_duck(int targetX, int targetY); rct_sprite *create_sprite(uint8 bl); void reset_sprite_list();