diff --git a/src/rct1.h b/src/rct1.h index eb7e0f4fc5..3f341d5c3a 100644 --- a/src/rct1.h +++ b/src/rct1.h @@ -164,6 +164,64 @@ typedef struct rct1_ride { } rct1_ride; assert_struct_size(rct1_ride, 0x260); +typedef struct rct1_unk_sprite { + uint8 sprite_identifier; // 0x00 + uint8 misc_identifier; // 0x01 + uint16 next_in_quadrant; // 0x02 + uint16 next; // 0x04 + uint16 previous; // 0x06 + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... + // Height from center of sprite to bottom + uint8 sprite_height_negative; // 0x09 + uint16 sprite_index; // 0x0A + uint16 flags; // 0x0C + sint16 x; // 0x0E + sint16 y; // 0x10 + sint16 z; // 0x12 + // 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; //direction of sprite? 0x1e + uint8 pad_1F[3]; // 0x1f + rct_string_id name_string_idx; // 0x22 + uint16 var_24; + uint16 frame; // 0x26 + uint8 var_28[3]; + uint8 var_2B; + uint8 pad_2C[0x45]; + uint8 var_71; +} rct1_unk_sprite; + +typedef struct rct1_peep { + uint8 sprite_identifier; // 0x00 + uint8 misc_identifier; // 0x01 + uint16 next_in_quadrant; // 0x02 + uint16 next; // 0x04 + uint16 previous; // 0x06 + uint8 linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... + // Height from center of sprite to bottom + uint8 sprite_height_negative; // 0x09 + uint16 sprite_index; // 0x0A + uint16 flags; // 0x0C + sint16 x; // 0x0E + sint16 y; // 0x10 + sint16 z; // 0x12 + uint8 pad_14[0xEC]; +} rct1_peep; +assert_struct_size(rct1_peep, 0x100); + +typedef union rct1_sprite { + uint8 pad_00[0x100]; + rct1_unk_sprite unknown; + rct1_peep peep; +} rct1_sprite; +assert_struct_size(rct1_sprite, 0x100); + typedef struct rct1_research_item { uint8 item; uint8 related_ride; @@ -185,7 +243,7 @@ typedef struct rct1_s4 { uint32 random_b; rct_map_element map_elements[0xC000]; uint32 unk_counter; - rct_sprite sprites[5000]; + rct1_sprite sprites[5000]; uint16 next_sprite_index; uint16 first_vehicle_sprite_index; uint16 first_peep_sprite_index; diff --git a/src/rct1/S4Importer.cpp b/src/rct1/S4Importer.cpp index 8dc9e65cd4..e8111d136b 100644 --- a/src/rct1/S4Importer.cpp +++ b/src/rct1/S4Importer.cpp @@ -41,6 +41,7 @@ extern "C" #include "../management/marketing.h" #include "../object.h" #include "../object/ObjectManager.h" + #include "../peep/peep.h" #include "../peep/staff.h" #include "../rct1.h" #include "../util/sawyercoding.h" @@ -144,6 +145,7 @@ public: ImportRides(); ImportRideMeasurements(); + ImportSprites(); ImportMapElements(); ImportMapAnimations(); ImportPeepSpawns(); @@ -723,6 +725,83 @@ private: // } } + void ImportSprites() + { + ImportPeeps(); + } + + void ImportPeeps() + { + for (int i = 0; i < 5000; i++) + { + if (_s4.sprites[i].unknown.sprite_identifier == SPRITE_IDENTIFIER_PEEP) + { + rct1_peep *srcPeep = &_s4.sprites[i].peep; + if (srcPeep->x != (sint16)0x8000) + { + rct_peep *peep = (rct_peep*)create_sprite(1); + move_sprite_to_list((rct_sprite*)peep, SPRITE_LIST_PEEP * 2); + + ImportPeep(peep, srcPeep); + } + } + } + } + + void ImportPeep(rct_peep * dst, rct1_peep * src) + { + dst->sprite_identifier = SPRITE_IDENTIFIER_PEEP; + dst->sprite_type = PEEP_SPRITE_TYPE_NORMAL; + dst->outside_of_park = 1; + dst->state = PEEP_STATE_FALLING; + dst->action = PEEP_ACTION_NONE_2; + dst->special_sprite = 0; + dst->action_sprite_image_offset = 0; + dst->no_action_frame_no = 0; + dst->action_sprite_type = 0; + dst->peep_flags = 0; + dst->favourite_ride = 0xFF; + dst->favourite_ride_rating = 0; + + const rct_sprite_bounds* spriteBounds = g_sprite_entries[dst->sprite_type].sprite_bounds; + dst->sprite_width = spriteBounds[dst->action_sprite_type].sprite_width; + dst->sprite_height_negative = spriteBounds[dst->action_sprite_type].sprite_height_negative; + dst->sprite_height_positive = spriteBounds[dst->action_sprite_type].sprite_height_positive; + + dst->sprite_direction = 0; + + rct_xyz16 position = { src->x, src->y, src->z }; + + sprite_move(position.x, position.y, position.z, (rct_sprite*)dst); + invalidate_sprite_2((rct_sprite*)dst); + + dst->var_41 = (scenario_rand() & 0x1F) + 45; + dst->var_C4 = 0; + dst->var_79 = 0xFF; + dst->type = PEEP_TYPE_GUEST; + dst->previous_ride = 0xFF; + dst->thoughts->type = PEEP_THOUGHT_TYPE_NONE; + dst->window_invalidate_flags = 0; + + dst->time_in_park = -1; + dst->pathfind_goal.x = 0xFF; + dst->pathfind_goal.y = 0xFF; + dst->pathfind_goal.z = 0xFF; + dst->pathfind_goal.direction = 0xFF; + dst->guest_heading_to_ride_id = 0xFF; + + dst->tshirt_colour = 12; + dst->trousers_colour = 15; + + uint8 energy = (scenario_rand() & 0x3F) + 65; + dst->energy = energy; + dst->energy_growth_rate = energy; + + peep_update_name_sort(dst); + + gNumGuestsInPark++; + } + void ImportPeepSpawns() { for (int i = 0; i < 2; i++)