diff --git a/src/addresses.h b/src/addresses.h index fcd74c5c49..3d7dd8e34d 100644 --- a/src/addresses.h +++ b/src/addresses.h @@ -219,6 +219,10 @@ #define RCT2_ADDRESS_MAP_IMAGE_DATA 0x00F1AD68 +// No longer used +#define RCT2_ADDRESS_PEEP_UPDATE_FALLING_MAP 0x00F1AEC4 +#define RCT2_ADDRESS_PEEP_UPDATE_FALLING_HEIGHT 0x00F1AEC8 + #define RCT2_ADDRESS_PROVISIONAL_PATH_FLAGS 0x00F3EF92 #define RCT2_ADDRESS_PROVISIONAL_PATH_X 0x00F3EF94 #define RCT2_ADDRESS_PROVISIONAL_PATH_Y 0x00F3EF96 diff --git a/src/game.c b/src/game.c index 7654cbbf3a..eb9caadad4 100644 --- a/src/game.c +++ b/src/game.c @@ -716,7 +716,7 @@ void sub_0x0069E9A7(){ //return; for (rct_sprite* spr = g_sprite_list; spr < (rct_sprite*)RCT2_ADDRESS_SPRITES_NEXT_INDEX; ++spr){ if (spr->unknown.sprite_identifier != 0xFF){ - RCT2_CALLPROC_X(0x0069E9D3, spr->unknown.x, 0, spr->unknown.y, spr->unknown.z, (int)spr, 0, 0); + sub_69E9D3(spr->unknown.x, spr->unknown.y, spr->unknown.z, spr); } } } diff --git a/src/peep/peep.c b/src/peep/peep.c index 59c60138cc..0571b422a5 100644 --- a/src/peep/peep.c +++ b/src/peep/peep.c @@ -18,6 +18,7 @@ * along with this program. If not, see . *****************************************************************************/ +#include #include #include "../addresses.h" #include "../audio/audio.h" @@ -26,6 +27,7 @@ #include "../localisation/localisation.h" #include "../management/news_item.h" #include "../ride/ride.h" +#include "../scenario.h" #include "../sprites.h" #include "../world/sprite.h" #include "peep.h" @@ -105,14 +107,546 @@ void peep_update_all() } } +/* rct2: 0x6939EB */ +int sub_6939EB(sint16* x, sint16* y, rct_peep* peep){ + RCT2_GLOBAL(0xF1AEF0, uint8) = peep->var_70; + if (peep->var_71 == 0xFE){ + peep->var_71 = 0xFF; + } + + *x = peep->x - peep->var_32; + *y = peep->y - peep->var_34; + int ebx = *x; + int edx = *y; + if (ebx < 0) ebx = -ebx; + if (edx < 0) edx = -edx; + + int ebp = ebx + edx; + if (peep->var_71 >= 0xFE){ + if (ebp <= peep->var_36){ + + return 0; + } + int direction = 0; + if (ebx <= edx){ + direction = 8; + if (*y > 0){ + direction = 24; + } + } + else{ + direction = 16; + if (*x > 0){ + direction = 0; + } + } + peep->sprite_direction = direction; + *x = peep->x + RCT2_ADDRESS(0x981D7C, uint16)[direction / 2]; + *y = peep->y + RCT2_ADDRESS(0x981D7E, uint16)[direction / 2]; + ebx = peep->var_E0 + 1; + uint32* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2]; + uint8* _edi = (uint8*)(edi[peep->var_6E * 2 + 1]); + if (ebx > *_edi){ + ebx = 0; + } + peep->var_E0 = ebx; + peep->var_70 = _edi[ebx + 1]; + return 1; + } + + int* edi = RCT2_ADDRESS(0x982708, uint32*)[peep->sprite_type * 2]; + uint8* _edi = (uint8*)(edi[peep->var_6E * 2 + 1]); + peep->var_72++; + ebx = _edi[peep->var_72 + 1]; + + if (ebx == 0xFF){ + peep->var_70 = 0; + peep->var_71 = 0xFF; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + *x = peep->x; + *y = peep->y; + return 1; + } + peep->var_70 = ebx; + if (peep->var_71 != 8 || peep->var_71 != 15){ + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + *x = peep->x; + *y = peep->y; + return 1; + } + + peep->hunger /= 2; + peep->nausea_growth_rate /= 2; + + if (peep->nausea < 30) + peep->nausea = 0; + else + peep->nausea -= 30; + + peep->var_45 |= (1 << 2); + + RCT2_CALLPROC_X(0x67375D, peep->x, peep->sprite_direction, peep->y, peep->z, 0, 0, peep->sprite_index & 1); + + int sound_id = scenario_rand() & 3 + 24; + + sound_play_panned(sound_id, 0x8001, peep->x, peep->y, peep->z); + + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + *x = peep->x; + *y = peep->y; + return 1; +} +/** +* rct2: 0x0069A409 +* Decreases rider count if on/entering a ride. +*/ +void peep_decrement_num_riders(rct_peep* peep){ + if (peep->state == PEEP_STATE_ON_RIDE + || peep->state == PEEP_STATE_ENTERING_RIDE){ + + rct_ride* ride = GET_RIDE(peep->current_ride); + ride->num_riders--; + ride->var_14D |= 0xC; + } +} + +/** + * rct2: 0x0069A42F + * Call after changing a peeps state to insure that + * all relevant windows update. Note also increase ride + * count if on/entering a ride. + */ +void peep_window_state_update(rct_peep* peep){ + + rct_window* w = window_find_by_number(WC_PEEP, peep->sprite_index); + if (w){ + RCT2_CALLPROC_X(w->event_handlers[WE_INVALIDATE], 0, 0, 0, 0, (int)w, 0, 0); + } + + if (peep->type == PEEP_TYPE_GUEST){ + // Update action label + widget_invalidate_by_number(WC_PEEP, peep->sprite_index, 12); + + if (peep->state == PEEP_STATE_ON_RIDE || peep->state == PEEP_STATE_ENTERING_RIDE){ + rct_ride* ride = GET_RIDE(peep->current_ride); + ride->num_riders++; + ride->var_14D |= 0xC; + } + + window_invalidate_by_class(WC_GUEST_LIST); + } + else{ + // Update action label + widget_invalidate_by_number(WC_PEEP, peep->sprite_index, 9); + window_invalidate_by_class(WC_STAFF_LIST); + } +} + +/** New function removes peep from + * park existance. Works with staff. + */ +void peep_remove(rct_peep* peep){ + if (peep->type == PEEP_TYPE_GUEST){ + if (peep->var_2A == 0){ + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16)--; + RCT2_GLOBAL(0x9A9804, uint16) |= (1 << 2); + } + if (peep->state == PEEP_STATE_ENTERING_PARK){ + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--; + } + } + RCT2_CALLPROC_X(0x69A535, 0, 0, 0, 0, (int)peep, 0, 0); +} + +/** + * rct2: 0x690028 + * Falling and its subset drowning + */ +void peep_update_falling(rct_peep* peep){ + if (peep->var_71 == 11){ + // Check to see if we are ready to drown. + sint16 x, y; + sub_6939EB(&x, &y, peep); + //RCT2_CALLPROC_X(0x6939EB, 0, 0, 0, 0, (int)peep, 0, 0); + if (peep->var_71 == 11) return; + if (!(RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & 0x80000)){ + RCT2_GLOBAL(0x13CE952, uint16) = peep->name_string_idx; + RCT2_GLOBAL(0x13CE954, uint32) = peep->id; + news_item_add_to_queue(NEWS_ITEM_BLANK, 2347, peep->x | (peep->y << 16)); + } + RCT2_GLOBAL(0x135882E, uint16) += 25; + if (RCT2_GLOBAL(0x135882E, uint16) > 1000){ + RCT2_GLOBAL(0x135882E, uint16) = 1000; + } + peep_remove(peep); + return; + } + + // If not drowning then falling. Note: peeps 'fall' after leaving a ride/enter the park. + + rct_map_element *map_element = TILE_MAP_ELEMENT_POINTER((peep->y / 32) * 256 + (peep->x /32)); + rct_map_element *saved_map = NULL; + int saved_height = 0; + + for (int final_element = 0; !final_element; map_element++){ + final_element = map_element->flags & MAP_ELEMENT_FLAG_LAST_TILE; + + // If a path check if we are on it + if (map_element->type == MAP_ELEMENT_TYPE_PATH){ + int height = map_height_from_slope(peep->x, peep->y, map_element->properties.surface.slope) + + map_element->base_height * 8; + + if (height < peep->z - 1 || height - 4 > peep->z) continue; + + saved_height = height; + saved_map = map_element; + break; + } // If a surface get the height and see if we are on it + else if (map_element->type == MAP_ELEMENT_TYPE_SURFACE){ + // If the surface is water check to see if we could be drowning + if (map_element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK){ + int height = (map_element->properties.surface.terrain & MAP_ELEMENT_WATER_HEIGHT_MASK) * 16; + + if (height - 4 >= peep->z && height < peep->z + 20){ + // Looks like we are drowning! + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + sub_69E9D3(peep->x, peep->y, height, (rct_sprite*)peep); + // Drop balloon if held + if (peep->item_standard_flags & PEEP_ITEM_BALLOON){ + 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); + peep->var_45 |= (1 << 3); + RCT2_CALLPROC_X(0x0069B8CC, 0, 0, 0, 0, (int)peep, 0, 0); + } + } + + peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_DROWNING, -1); + + peep->var_71 = 11; + peep->var_72 = 0; + peep->var_70 = 0; + + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + peep_window_state_update(peep); + return; + } + } + int map_height = map_element_height(0xFFFF & peep->x, 0xFFFF & peep->y) & 0xFFFF; + if (map_height < peep->z || map_height - 4 > peep->z) continue; + saved_height = map_height; + saved_map = map_element; + } // If not a path or surface go see next element + else continue; + } + + // This will be null if peep is falling + if (saved_map == NULL){ + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + if (peep->z <= 1){ + // Remove peep if it has gone to the void + peep_remove(peep); + return; + } + sub_69E9D3(peep->x, peep->y, peep->z - 2, (rct_sprite*)peep); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + return; + } + + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + sub_69E9D3(peep->x, peep->y, saved_height, (rct_sprite*)peep); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + + peep->next_x = peep->x & 0xFFE0; + peep->next_y = peep->y & 0xFFE0; + peep->next_z = saved_map->base_height; + + int edx = saved_map->properties.surface.slope & 0x7; + if (saved_map->type != MAP_ELEMENT_TYPE_PATH){ + edx = 8; + } + peep->next_z += edx << 8; + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_1; + peep_window_state_update(peep); +} + +/** + * rct2: 0x00691677 + */ +void peep_try_get_up_from_sitting(rct_peep* peep){ + // Eats all food first + if (peep_has_food(peep))return; + + peep->time_to_sitdown--; + if (peep->time_to_sitdown) return; + + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_WALKING; + peep_window_state_update(peep); + + int x = (peep->x & 0xFFE0) + 16; + int y = (peep->y & 0xFFE0) + 16; + peep->var_32 = x; + peep->var_34 = y; + peep->var_36 = 5; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); +} + +/** + * rct2: 0x0069152B + */ +void peep_update_sitting(rct_peep* peep){ + if (peep->var_2C == 0){ + if (RCT2_CALLPROC_X(0x68F3AE, 0, 0, 0, 0, (int)peep, 0, 0) & 0x4000)return; + //691541 + + RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); + if (!(RCT2_GLOBAL(0xF1EE18, uint16) & 1))return; + + int ebx = peep->var_37 & 0x7; + int x = peep->x & 0xFFE0 + RCT2_ADDRESS(0x981F2C, uint16)[ebx * 2]; + int y = peep->y & 0xFFE0 + RCT2_ADDRESS(0x981F2E, uint16)[ebx * 2]; + int z = peep->z; + + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + sub_69E9D3(x, y, z, (rct_sprite*)peep); + + peep->sprite_direction = ((peep->var_37 + 2) & 3) * 8; + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + peep->var_71 = 254; + peep->var_6F = 7; + RCT2_CALLPROC_X(0x693BAB, 0, 0, 0, 0, (int)peep, 0, 0); + + peep->var_2C++; + + // Sets time to sit on seat + peep->time_to_sitdown = (129 - peep->energy) * 16 + 50; + } + else if (peep->var_2C == 1){ + if (peep->var_71 < 0xFE){ + sint16 x, y; + sub_6939EB(&x, &y, peep); + //RCT2_CALLPROC_X(0x6939EB, 0, 0, 0, 0, (int)peep, 0, 0); + if (peep->var_71 != 0xFF) return; + + peep->var_71 = 0xFE; + peep_try_get_up_from_sitting(peep); + return; + } + + if ((peep->flags & PEEP_FLAGS_LEAVING_PARK)){ + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_WALKING; + peep_window_state_update(peep); + + int x = (peep->x & 0xFFE0) + 16; + int y = (peep->y & 0xFFE0) + 16; + peep->var_32 = x; + peep->var_34 = y; + peep->var_36 = 5; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + return; + } + + if (peep->sprite_type == 0x15){ + peep_try_get_up_from_sitting(peep); + return; + } + + if (peep_has_food(peep)){ + if ((scenario_rand() & 0xFFFF) > 1310){ + peep_try_get_up_from_sitting(peep); + return; + } + peep->var_71 = 4; + peep->var_72 = 0; + peep->var_70 = 0; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + return; + } + + int rand = scenario_rand(); + if ((rand & 0xFFFF) > 131){ + peep_try_get_up_from_sitting(peep); + return; + } + if (peep->sprite_type == 0x13 || peep->sprite_type == 0x1E){ + peep_try_get_up_from_sitting(peep); + return; + } + + peep->var_71 = 5; + if (rand & 0x80000000){ + peep->var_71 = 6; + } + + if (rand & 0x40000000){ + peep->var_71 = 4; + } + peep->var_72 = 0; + peep->var_70 = 0; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + return; + } +} + +/** + * rct2: 0x69185D + */ +void peep_update_queuing(rct_peep* peep){ + if (RCT2_CALLPROC_X(0x68F3AE, 0, 0, 0, 0, (int)peep, 0, 0) & 0x4000){ + RCT2_CALLPROC_X(0x691A23, 0, 0, 0, 0, (int)peep, 0, 0); + 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); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_1; + peep_window_state_update(peep); + return; + } + + if (peep->var_2C != 0xA){ + if (peep->var_74 == 0xFFFF){ + //Happens every time peep goes onto ride. + peep->var_36 = 0; + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_QUEUING_FRONT; + peep_window_state_update(peep); + peep->var_2C = 0; + return; + } + //Give up queueing for the ride + peep->sprite_direction ^= (1 << 4); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_1; + peep_window_state_update(peep); + } + + RCT2_CALLPROC_X(0x693C9E, 0, 0, 0, 0, (int)peep, 0, 0); + if (peep->var_71 < 0xFE)return; + if (peep->sprite_type == 0){ + if (peep->var_7A >= 2000 && (0xFFFF & scenario_rand()) <= 119){ + // Look at watch + peep->var_71 = 1; + peep->var_72 = 0; + peep->var_70 = 0; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + } + if (peep->var_7A >= 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->var_71 == 0xFE && peep->var_6F == 2){ + switch (peep->sprite_type){ + case 0xF: + case 0x10: + case 0x11: + case 0x12: + case 0x14: + case 0x16: + case 0x18: + case 0x1F: + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x27: + case 0x29: + case 0x2A: + case 0x2B: + case 0x2C: + case 0x2D: + case 0x2E: + case 0x2F: + // Look at watch + peep->var_71 = 1; + peep->var_72 = 0; + peep->var_70 = 0; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + break; + } + } + } + if (peep->var_7A < 4300) return; + + if (peep->happiness <= 65 && (0xFFFF & scenario_rand()) < 2184){ + //Give up queueing for the ride + peep->sprite_direction ^= (1 << 4); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6966A9, 0, 0, 0, 0, (int)peep, 0, 0); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_1; + peep_window_state_update(peep); + } +} + +/** + * rct2: 0x690009 + */ +static void peep_update_picked(rct_peep* peep){ + if (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_TICKS, uint32) & 0x1F) return; + peep->var_2C++; + if (peep->var_2C == 13){ + peep_insert_new_thought(peep, PEEP_THOUGHT_HELP, 0xFF); + } +} + +/** +* rct2: 0x691451 +*/ +static void peep_update_entering_park(rct_peep* peep){ + if (peep->var_37 != 1){ + 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); + } + return; + } + sint16 x = 0, y = 0; + if (sub_6939EB(&x, &y, peep)){ + RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); + sub_69E9D3(x, y, peep->z, (rct_sprite*)peep); + RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); + return; + } + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); + + peep->var_2A = 0; + peep->time_in_park = RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, sint32); + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_IN_PARK, uint16); + RCT2_GLOBAL(RCT2_ADDRESS_GUESTS_HEADING_FOR_PARK, uint16)--; + RCT2_GLOBAL(0x9A9804, uint16) |= (1 << 2); + window_invalidate_by_class(WC_GUEST_LIST); +} + /** * * rct2: 0x0068FC1E */ static void peep_update(rct_peep *peep) { - // RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); return; - + //RCT2_CALLPROC_X(0x0068FC1E, 0, 0, 0, 0, (int)peep, 0, 0); return; + //return; int i, j; if (peep->type == PEEP_TYPE_GUEST) { @@ -175,9 +709,86 @@ static void peep_update(rct_peep *peep) RCT2_CALLPROC_X(0x0068FD3A, 0, 0, 0, 0, (int)peep, 0, 0); } else { // loc_68FD2F - RCT2_CALLPROC_X(0x0068FD2F, 0, 0, 0, 0, (int)peep, 0, 0); + //RCT2_CALLPROC_X(0x68FD2F, 0, 0, 0, 0, (int)peep, 0, 0); + //return; switch (peep->state) { - + case PEEP_STATE_FALLING: + peep_update_falling(peep); + break; + case PEEP_STATE_1: + RCT2_CALLPROC_X(0x006902A2, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_QUEUING_FRONT: + RCT2_CALLPROC_X(0x00691A24, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_ON_RIDE: + // No action + break; + case PEEP_STATE_LEAVING_RIDE: + RCT2_CALLPROC_X(0x00691A30, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_WALKING: + RCT2_CALLPROC_X(0x0069030A, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_QUEUING: + peep_update_queuing(peep); + break; + case PEEP_STATE_ENTERING_RIDE: + RCT2_CALLPROC_X(0x00691A24, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_SITTING: + peep_update_sitting(peep); + break; + case PEEP_STATE_PICKED: + peep_update_picked(peep); + break; + case PEEP_STATE_PATROLLING: + RCT2_CALLPROC_X(0x006BF1FD, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_MOWING: + RCT2_CALLPROC_X(0x006BF567, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_SWEEPING: + RCT2_CALLPROC_X(0x006BF641, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_ENTERING_PARK: + peep_update_entering_park(peep); + //RCT2_CALLPROC_X(0x00691451, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_LEAVING_PARK: + RCT2_CALLPROC_X(0x006914CD, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_ANSWERING: + RCT2_CALLPROC_X(0x006C0CB8, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_FIXING: + RCT2_CALLPROC_X(0x006C0E8B, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_BUYING: + RCT2_CALLPROC_X(0x006912A3, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_WATCHING: + RCT2_CALLPROC_X(0x006916D6, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_EMPTYING_BIN: + RCT2_CALLPROC_X(0x006BF6C9, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_20: + RCT2_CALLPROC_X(0x00691089, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_WATERING: + RCT2_CALLPROC_X(0x006BF7E6, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_HEADING_TO_INSPECTION: + RCT2_CALLPROC_X(0x006C16D7, 0, 0, 0, 0, (int)peep, 0, 0); + break; + case PEEP_STATE_INSPECTING: + RCT2_CALLPROC_X(0x006C0E8B, 0, 0, 0, 0, (int)peep, 0, 0); + break; + //There shouldnt be any more + default: + RCT2_CALLPROC_X(0x0068FD2F, 0, 0, 0, 0, (int)peep, 0, 0); + break; } } } @@ -470,11 +1081,11 @@ void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argum rct_ride ride; switch (peep->state){ - case 0: + case PEEP_STATE_FALLING: *argument_1 = peep->var_71 == 0xB ? STR_DROWNING : STR_WALKING; *argument_2 = 0; break; - case 1: + case PEEP_STATE_1: *argument_1 = STR_WALKING; *argument_2 = 0; break; @@ -495,7 +1106,7 @@ void get_arguments_from_action(rct_peep* peep, uint32 *argument_1, uint32* argum *argument_2 = ride.name_arguments; break; case PEEP_STATE_WALKING: - case 0x14: + case PEEP_STATE_20: if (peep->guest_heading_to_ride_id != 0xFF){ ride = g_ride_list[peep->guest_heading_to_ride_id]; *argument_1 = STR_HEADING_FOR | (ride.name << 16); @@ -769,3 +1380,81 @@ int peep_is_mechanic(rct_peep *peep) peep->staff_type == STAFF_TYPE_MECHANIC ); } + +/* To simplify check of 0x36BA3E0 and 0x11FF78 + * returns 0 on no food. + */ +int peep_has_food(rct_peep* peep){ + return (peep->item_standard_flags &( + PEEP_ITEM_DRINK | + PEEP_ITEM_BURGER | + PEEP_ITEM_FRIES | + PEEP_ITEM_ICE_CREAM | + PEEP_ITEM_COTTON_CANDY | + PEEP_ITEM_PIZZA | + PEEP_ITEM_POPCORN | + PEEP_ITEM_HOT_DOG | + PEEP_ITEM_TENTACLE | + PEEP_ITEM_CANDY_APPLE | + PEEP_ITEM_DONUT | + PEEP_ITEM_COFFEE | + PEEP_ITEM_CHICKEN | + PEEP_ITEM_LEMONADE)) || + (peep->item_extra_flags &( + PEEP_ITEM_PRETZEL | + PEEP_ITEM_CHOCOLATE | + PEEP_ITEM_ICED_TEA | + PEEP_ITEM_FUNNEL_CAKE | + PEEP_ITEM_BEEF_NOODLES | + PEEP_ITEM_FRIED_RICE_NOODLES | + PEEP_ITEM_WONTON_SOUP | + PEEP_ITEM_MEATBALL_SOUP | + PEEP_ITEM_FRUIT_JUICE | + PEEP_ITEM_SOYBEAN_MILK | + PEEP_ITEM_SU_JONGKWA | + PEEP_ITEM_SUB_SANDWICH | + PEEP_ITEM_COOKIE | + PEEP_ITEM_ROAST_SAUSAGE + )); +} + +/** + * rct2: 0x699F5A + * al:thought_type + * ah:thought_arguments + * esi: peep + */ +void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_arguments){ + int var_71 = RCT2_ADDRESS(0x981DB0, uint16)[thought_type]; + + if (var_71 != 0xFF && peep->var_71 >= 254){ + peep->var_71 = var_71; + peep->var_72 = 0; + peep->var_70 = 0; + RCT2_CALLPROC_X(0x693B58, 0, 0, 0, 0, (int)peep, 0, 0); + RCT2_CALLPROC_X(0x6EC473, 0, 0, 0, 0, (int)peep, 0, 0); + } + + for (int i = 0; i < PEEP_MAX_THOUGHTS; ++i){ + rct_peep_thought* thought = &peep->thoughts[i]; + // Remove the oldest thought by setting it to NONE. + if (thought->type == PEEP_THOUGHT_TYPE_NONE) break; + + if (thought->type == thought_type && thought->item == thought_arguments){ + // If the thought type has not changed then we need to move + // it to the top of the thought list. This is done by first removing the + // existing thought and placing it at the top. + memmove(thought, thought + 1, sizeof(rct_peep_thought)*(PEEP_MAX_THOUGHTS - i - 1)); + break; + } + } + + memmove(&peep->thoughts[1], &peep->thoughts[0], sizeof(rct_peep_thought)*(PEEP_MAX_THOUGHTS - 1)); + + peep->thoughts[0].type = thought_type; + peep->thoughts[0].item = thought_arguments; + peep->thoughts[0].var_2 = 0; + peep->thoughts[0].var_3 = 0; + + peep->var_45 |= (1 << 0); +} diff --git a/src/peep/peep.h b/src/peep/peep.h index 22a35ed190..e89ee8f93d 100644 --- a/src/peep/peep.h +++ b/src/peep/peep.h @@ -182,8 +182,8 @@ enum PEEP_THOUGHT_TYPE { }; enum PEEP_STATE { - PEEP_STATE_0 = 0, - + PEEP_STATE_FALLING = 0, //Drowning is part of falling + PEEP_STATE_1 = 1, PEEP_STATE_QUEUING_FRONT = 2, PEEP_STATE_ON_RIDE = 3, PEEP_STATE_LEAVING_RIDE = 4, @@ -202,7 +202,7 @@ enum PEEP_STATE { PEEP_STATE_BUYING = 17, PEEP_STATE_WATCHING = 18, PEEP_STATE_EMPTYING_BIN = 19, - + PEEP_STATE_20 = 20, PEEP_STATE_WATERING = 21, PEEP_STATE_HEADING_TO_INSPECTION = 22, PEEP_STATE_INSPECTING = 23 @@ -367,20 +367,26 @@ typedef struct { uint8 current_ride; // 0x68 uint8 current_ride_station; // 0x69 uint8 current_train; // 0x6A - uint8 current_car; // 0x6B - uint8 current_seat; // 0x6C + union{ + struct{ + uint8 current_car; // 0x6B + uint8 current_seat; // 0x6C + }; + uint16 time_to_sitdown; //0x6B + }; uint8 var_6D; // 0x6D uint8 var_6E; // 0x6E - uint8 pad_6F; + uint8 var_6F; uint8 var_70; uint8 var_71; uint8 var_72; uint8 var_73; - uint16 pad_74; + uint16 var_74; uint8 var_76; uint8 pad_77; uint8 var_78; - uint8 pad_79[0x03]; + uint8 pad_79; + uint16 var_7A; // time waiting in line possibly 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. @@ -410,10 +416,24 @@ typedef struct { uint8 pad_E1; uint8 var_E2; // 0xE2 uint8 pad_E3; - money16 paid_to_enter; // 0xE4 - money16 paid_on_rides; // 0xE6 - money16 paid_on_food; // 0xE8 - money16 paid_on_souvenirs; // 0xEA + union{ + money16 paid_to_enter; // 0xE4 + uint16 staff_lawns_mown; // 0xE4 + uint16 staff_rides_fixed; // 0xE4 + }; + union{ + money16 paid_on_rides; // 0xE6 + uint16 staff_gardens_watered; // 0xE6 + uint16 staff_rides_inspected; // 0xE6 + }; + union { + money16 paid_on_food; // 0xE8 + uint16 staff_litter_swept; // 0xE8 + }; + union{ + money16 paid_on_souvenirs; // 0xEA + uint16 staff_bins_emptied; // 0xEA + }; uint8 no_of_food; // 0xEC uint8 no_of_drinks; // 0xED uint8 no_of_souvenirs; // 0xEE @@ -493,5 +513,16 @@ int get_peep_face_sprite_large(rct_peep *peep); int peep_check_easteregg_name(int index, rct_peep *peep); int peep_get_easteregg_name_id(rct_peep *peep); int peep_is_mechanic(rct_peep *peep); +int peep_has_food(rct_peep* peep); + +void peep_window_state_update(rct_peep* peep); +void peep_decrement_num_riders(rct_peep* peep); +/** +* rct2: 0x699F5A +* al:thought_type +* ah:thought_arguments +* esi: peep +*/ +void peep_insert_new_thought(rct_peep *peep, uint8 thought_type, uint8 thought_arguments); #endif diff --git a/src/peep/staff.c b/src/peep/staff.c index bd176a3781..8ca40ac75a 100644 --- a/src/peep/staff.c +++ b/src/peep/staff.c @@ -134,7 +134,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, newPeep->var_14 = 8; newPeep->sprite_direction = 0; - RCT2_CALLPROC_X(0x0069E9D3, _ax, 0, *ecx, _dx, (int)newPeep, 0, 0); + sub_69E9D3(_ax, *ecx, _dx, (rct_sprite*)newPeep); newPeep->state = PEEP_STATE_PICKED; if (newPeep->x != -32768) { @@ -202,7 +202,7 @@ void game_command_hire_new_staff_member(int* eax, int* ebx, int* ecx, int* edx, newPeep->var_09 = *((uint8*)(_edx + 1)); newPeep->var_15 = *((uint8*)(_edx + 2)); - RCT2_CALLPROC_X(0x0069E9D3, newPeep->x, 0, newPeep->y, newPeep->z, (int)newPeep, 0, 0); + sub_69E9D3( newPeep->x, newPeep->y, newPeep->z, (rct_sprite*)newPeep); RCT2_CALLPROC_X(0x006EC473, *eax, 0, 0, 0, (int)newPeep, 0, 0); newPeep->var_AD = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint8); diff --git a/src/ride/ride.c b/src/ride/ride.c index f6217fe2ca..6d9e0f0cd6 100644 --- a/src/ride/ride.c +++ b/src/ride/ride.c @@ -667,7 +667,7 @@ static void ride_remove_peeps(int rideIndex) if (peep->current_ride != rideIndex) continue; - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0); + peep_decrement_num_riders(peep); if (peep->state == PEEP_STATE_QUEUING_FRONT && peep->var_2C == 0) RCT2_CALLPROC_X(0x006966A9, 0, 0, 0, 0, (int)peep, 0, 0); @@ -687,7 +687,7 @@ static void ride_remove_peeps(int rideIndex) } RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); - peep->state = PEEP_STATE_0; + peep->state = PEEP_STATE_FALLING; RCT2_CALLPROC_X(0x00693BE5, 0, 0, 0, 0, (int)peep, 0, 0); peep->happiness = min(peep->happiness, peep->happiness_growth_rate) / 2; @@ -1539,9 +1539,9 @@ static void ride_call_mechanic(int rideIndex, rct_peep *mechanic, int forInspect rct_ride *ride; ride = GET_RIDE(rideIndex); - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)mechanic, 0, 0); + peep_decrement_num_riders(mechanic); mechanic->state = forInspection ? PEEP_STATE_HEADING_TO_INSPECTION : PEEP_STATE_ANSWERING; - RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)mechanic, 0, 0); + peep_window_state_update(mechanic); mechanic->var_2C = 0; ride->mechanic_status = RIDE_MECHANIC_STATUS_HEADING; ride->var_14D |= 0x20; diff --git a/src/windows/guest.c b/src/windows/guest.c index 842a936510..05034d516a 100644 --- a/src/windows/guest.c +++ b/src/windows/guest.c @@ -624,11 +624,11 @@ void window_guest_overview_mouse_up(){ RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0); RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x0069E9D3, 0x8000, 0, peep->y, peep->z, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0); - peep->state = 9; + sub_69E9D3(0x8000, peep->y, peep->z, (rct_sprite*)peep); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_PICKED; peep->var_2C = 0; - RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0); + peep_window_state_update(peep); break; case WIDX_RENAME: window_text_input_open(w, widgetIndex, 0x5AC, 0x5AD, peep->name_string_idx, peep->id); @@ -1098,7 +1098,8 @@ void window_guest_overview_update(rct_window* w){ int rand = scenario_rand() & 0xFFFF; if (rand <= 0x2AAA){ rct_peep* peep = GET_PEEP(w->number); - RCT2_CALLPROC_X(0x699F5A, 0xFF47, 0, 0, 0, (int)peep, 0, 0); + peep_insert_new_thought(peep, PEEP_THOUGHT_TYPE_WATCHED, 0xFF); + //RCT2_CALLPROC_X(0x699F5A, 0xFF00 | PEEP_THOUGHT_TYPE_WATCHED, 0, 0, 0, (int)peep, 0, 0); } } } @@ -1223,11 +1224,11 @@ void window_guest_overview_tool_down(){ } rct_peep* peep = GET_PEEP(w->number); - RCT2_CALLPROC_X(0x0069E9D3, dest_x, 0, dest_y, dest_z, (int)peep, 0, 0); + sub_69E9D3(dest_x, dest_y, dest_z, (rct_sprite*)peep); RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0); + peep_decrement_num_riders(peep); peep->state = 0; - RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0); + peep_window_state_update(peep); peep->var_71 = 0xFF; peep->var_6D = 0; peep->var_70 = 0; @@ -1254,13 +1255,13 @@ void window_guest_overview_tool_abort(){ rct_peep* peep = GET_PEEP(w->number); if (peep->state != PEEP_STATE_PICKED) return; - RCT2_CALLPROC_X(0x0069E9D3, w->var_48C, 0, peep->y, peep->z + 8, (int)peep, 0, 0); + sub_69E9D3( w->var_48C, peep->y, peep->z + 8, (rct_sprite*)peep); RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); if (peep->x != 0x8000){ - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0); + peep_decrement_num_riders(peep); peep->state = 0; - RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0); + peep_window_state_update(peep); peep->var_71 = 0xFF; peep->var_6D = 0; peep->var_70 = 0; diff --git a/src/windows/staff.c b/src/windows/staff.c index c6a8e2141f..da698a8ee3 100644 --- a/src/windows/staff.c +++ b/src/windows/staff.c @@ -460,10 +460,10 @@ void window_staff_overview_mouseup() RCT2_CALLPROC_X(0x0069A512, 0, 0, 0, 0, (int)peep, 0, 0); RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x0069E9D3, 0x8000, 0, peep->y, peep->z, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0); - peep->state = 9; - RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0); + sub_69E9D3( 0x8000, peep->y, peep->z, (rct_sprite*)peep); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_PICKED; + peep_window_state_update(peep); break; case WIDX_FIRE: window_staff_fire_prompt_open(peep); @@ -1049,18 +1049,24 @@ void window_staff_stats_paint(){ switch (peep->staff_type){ case STAFF_TYPE_HANDYMAN: - gfx_draw_string_left(dpi, 2351, (void*)&peep->paid_to_enter, 0, x, y); + // Lawns mown + gfx_draw_string_left(dpi, 2351, (void*)&peep->staff_lawns_mown, 0, x, y); y += 10; - gfx_draw_string_left(dpi, 2352, (void*)&peep->paid_on_rides, 0, x, y); + // Gardens Watered + gfx_draw_string_left(dpi, 2352, (void*)&peep->staff_gardens_watered, 0, x, y); y += 10; - gfx_draw_string_left(dpi, 2353, (void*)&peep->paid_on_food, 0, x, y); + // Litter Swept + gfx_draw_string_left(dpi, 2353, (void*)&peep->staff_litter_swept, 0, x, y); y += 10; - gfx_draw_string_left(dpi, 2354, (void*)&peep->paid_on_souvenirs, 0, x, y); + // Bins Emptied + gfx_draw_string_left(dpi, 2354, (void*)&peep->staff_bins_emptied, 0, x, y); break; case STAFF_TYPE_MECHANIC: - gfx_draw_string_left(dpi, 2356, (void*)&peep->paid_on_rides, 0, x, y); + // Rides Inspected + gfx_draw_string_left(dpi, 2356, (void*)&peep->staff_rides_inspected, 0, x, y); y += 10; - gfx_draw_string_left(dpi, 2355, (void*)&peep->paid_to_enter, 0, x, y); + // Rides Fixed + gfx_draw_string_left(dpi, 2355, (void*)&peep->staff_rides_fixed, 0, x, y); break; } } @@ -1143,11 +1149,11 @@ void window_staff_overview_tool_down(){ } rct_peep* peep = GET_PEEP(w->number); - RCT2_CALLPROC_X(0x0069E9D3, dest_x, 0, dest_y, dest_z, (int)peep, 0, 0); + sub_69E9D3(dest_x, dest_y, dest_z, (rct_sprite*)peep); RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0); - peep->state = 0; - RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); peep->var_71 = 0xFF; peep->var_6D = 0; peep->var_70 = 0; @@ -1183,9 +1189,9 @@ void window_staff_overview_tool_abort(){ RCT2_CALLPROC_X(0x006EC473, 0, 0, 0, 0, (int)peep, 0, 0); if (peep->x != 0x8000){ - RCT2_CALLPROC_X(0x0069A409, 0, 0, 0, 0, (int)peep, 0, 0); - peep->state = 0; - RCT2_CALLPROC_X(0x0069A42F, 0, 0, 0, 0, (int)peep, 0, 0); + peep_decrement_num_riders(peep); + peep->state = PEEP_STATE_FALLING; + peep_window_state_update(peep); peep->var_71 = 0xFF; peep->var_6D = 0; peep->var_70 = 0; diff --git a/src/world/map.c b/src/world/map.c index 4733a25745..7cf86a85e9 100644 --- a/src/world/map.c +++ b/src/world/map.c @@ -437,6 +437,23 @@ static void sub_6A87BB(int x, int y) RCT2_CALLPROC_X(0x006A87BB, x, 0, y, 0, 0, 0, 0); } +/* rct2: 0x6A7B84 */ +int map_height_from_slope(int x, int y, int slope){ + if (!(slope & 4)) return 0; + + switch (slope & 3){ + case 0: + return (31 - (x & 31)) / 2; + case 1: + return (y & 31) / 2; + case 2: + return (x & 31) / 2; + case 3: + return (31 - (y & 31)) / 2; + } + return 0; +} + /** * * rct2: 0x00664F72 @@ -453,8 +470,8 @@ int sub_664F72(int x, int y, int z) if (mapElement->properties.surface.ownership & 0x10) { z /= 8; if (z < mapElement->base_height || z - 2 > mapElement->base_height) - return 1; - } + return 1; + } } RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16) = 1729; diff --git a/src/world/map.h b/src/world/map.h index a658d959b6..86ba26880b 100644 --- a/src/world/map.h +++ b/src/world/map.h @@ -199,6 +199,7 @@ int map_element_get_terrain(rct_map_element *element); int map_element_get_terrain_edge(rct_map_element *element); void map_element_set_terrain(rct_map_element *element, int terrain); void map_element_set_terrain_edge(rct_map_element *element, int terrain); +int map_height_from_slope(int x, int y, int slope); rct_map_element *map_get_surface_element_at(int x, int y); int map_element_height(int x, int y); void sub_68B089(); diff --git a/src/world/sprite.c b/src/world/sprite.c index 85afc6045c..33805baf8b 100644 --- a/src/world/sprite.c +++ b/src/world/sprite.c @@ -209,4 +209,75 @@ void move_sprite_to_list(rct_sprite *sprite, uint8 cl) void texteffect_update_all() { RCT2_CALLPROC_EBPSAFE(0x00672AA4); +} + +/** + * rct2: 0x0069E9D3 + * ax: x + * cx: y + * dx: z + */ +void sub_69E9D3(int x, int y, int z, rct_sprite* sprite){ + int new_position = x; + if ((uint16)x == 0x8000)new_position = 0x10000; + else{ + new_position &= 0x1FE0; + new_position = (y >> 5) | (new_position << 3); + } + + int current_position = sprite->unknown.x; + if ((uint16)sprite->unknown.x == 0x8000)current_position = 0x10000; + else{ + current_position &= 0x1FE0; + current_position = (sprite->unknown.y >> 5) | (current_position << 3); + } + + if (new_position != current_position){ + 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; + sprite2 = &g_sprite_list[*sprite_idx]; + } + *sprite_idx = sprite->unknown.var_02; + + 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; + } + + if (x == 0x8000){ + sprite->unknown.var_16 = 0x8000; + sprite->unknown.x = x; + sprite->unknown.y = y; + sprite->unknown.z = z; + return; + } + int new_x = x, new_y = y, start_x = x; + switch (RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_ROTATION, uint32)){ + case 0: + new_x = new_y - new_x; + new_y = (new_y + start_x) / 2 - z; + break; + case 1: + new_x = -new_y - new_x; + new_y = (new_y - start_x) / 2 - z; + break; + case 2: + new_x = -new_y + new_x; + new_y = (-new_y - start_x) / 2 - z; + break; + case 3: + new_x = new_y + new_x; + new_y = (-new_y + start_x) / 2 - z; + break; + } + + sprite->unknown.var_16 = new_x - sprite->unknown.var_14; + sprite->unknown.var_1A = new_x + sprite->unknown.var_14; + sprite->unknown.var_18 = new_y - sprite->unknown.pad_09; + sprite->unknown.var_1C = new_y + sprite->unknown.var_15; + sprite->unknown.x = x; + sprite->unknown.y = y; + sprite->unknown.z = z; } \ No newline at end of file diff --git a/src/world/sprite.h b/src/world/sprite.h index 3b33862d7b..f0be7de49f 100644 --- a/src/world/sprite.h +++ b/src/world/sprite.h @@ -102,5 +102,6 @@ void reset_sprite_list(); void reset_0x69EBE4(); void move_sprite_to_list(rct_sprite *sprite, uint8 cl); void texteffect_update_all(); +void sub_69E9D3(int x, int y, int z, rct_sprite* sprite); #endif