diff --git a/src/openrct2/rct1/RCT1.h b/src/openrct2/rct1/RCT1.h index 3aa5cbd709..f8d5ac6a04 100644 --- a/src/openrct2/rct1/RCT1.h +++ b/src/openrct2/rct1/RCT1.h @@ -213,32 +213,10 @@ struct rct1_ride }; assert_struct_size(rct1_ride, 0x260); -struct rct1_unk_sprite +struct rct1_unk_sprite : RCT12SpriteBase { - uint8_t sprite_identifier; // 0x00 - uint8_t misc_identifier; // 0x01 - uint16_t next_in_quadrant; // 0x02 - uint16_t next; // 0x04 - uint16_t previous; // 0x06 - uint8_t linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - // Height from centre of sprite to bottom - uint8_t sprite_height_negative; // 0x09 - uint16_t sprite_index; // 0x0A - uint16_t flags; // 0x0C - int16_t x; // 0x0E - int16_t y; // 0x10 - int16_t z; // 0x12 - // Width from centre of sprite to edge - uint8_t sprite_width; // 0x14 - // Height from centre of sprite to top - uint8_t sprite_height_positive; // 0x15 - int16_t sprite_left; // 0x16 - int16_t sprite_top; // 0x18 - int16_t sprite_right; // 0x1A - int16_t sprite_bottom; // 0x1C - uint8_t sprite_direction; // direction of sprite? 0x1e - uint8_t pad_1F[3]; // 0x1f - rct_string_id name_string_idx; // 0x22 + uint8_t pad_1F[3]; // 0x1f + rct_string_id name_string_idx; // 0x22 uint16_t var_24; uint16_t frame; // 0x26 uint8_t var_28[3]; @@ -247,32 +225,10 @@ struct rct1_unk_sprite uint8_t var_71; }; -struct rct1_vehicle +struct rct1_vehicle : RCT12SpriteBase { - uint8_t sprite_identifier; // 0x00 - uint8_t is_child; // 0x01 - uint16_t next_in_quadrant; // 0x02 - uint16_t next; // 0x04 - uint16_t previous; // 0x06 - uint8_t linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - // Height from centre of sprite to bottom - uint8_t sprite_height_negative; // 0x09 - uint16_t sprite_index; // 0x0A - uint16_t flags; // 0x0C - int16_t x; // 0x0E - int16_t y; // 0x10 - int16_t z; // 0x12 - // Width from centre of sprite to edge - uint8_t sprite_width; // 0x14 - // Height from centre of sprite to top - uint8_t sprite_height_positive; // 0x15 - int16_t sprite_left; // 0x16 - int16_t sprite_top; // 0x18 - int16_t sprite_right; // 0x1A - int16_t sprite_bottom; // 0x1C - uint8_t sprite_direction; // 0x1E - uint8_t vehicle_sprite_type; // 0x1F - uint8_t bank_rotation; // 0x20 + uint8_t vehicle_sprite_type; // 0x1F + uint8_t bank_rotation; // 0x20 uint8_t pad_21[3]; int32_t remaining_distance; // 0x24 int32_t velocity; // 0x28 @@ -372,30 +328,8 @@ struct rct1_vehicle uint8_t colours_extended; // 0xD7 }; -struct rct1_peep +struct rct1_peep : RCT12SpriteBase { - uint8_t sprite_identifier; // 0x00 - uint8_t misc_identifier; // 0x01 - uint16_t next_in_quadrant; // 0x02 - uint16_t next; // 0x04 - uint16_t previous; // 0x06 - uint8_t linked_list_type_offset; // 0x08 Valid values are SPRITE_LINKEDLIST_OFFSET_... - // Height from centre of sprite to bottom - uint8_t sprite_height_negative; // 0x09 - uint16_t sprite_index; // 0x0A - uint16_t flags; // 0x0C - int16_t x; // 0x0E - int16_t y; // 0x10 - int16_t z; // 0x12 - // Width from centre of sprite to edge - uint8_t sprite_width; // 0x14 - // Height from centre of sprite to top - uint8_t sprite_height_positive; // 0x15 - int16_t sprite_left; // 0x16 - int16_t sprite_top; // 0x18 - int16_t sprite_right; // 0x1A - int16_t sprite_bottom; // 0x1C - uint8_t sprite_direction; // 0x1E uint8_t pad_1F[3]; rct_string_id name_string_idx; // 0x22 uint16_t next_x; // 0x24 @@ -483,14 +417,14 @@ struct rct1_peep uint8_t 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. - uint32_t id; // 0x9C - money32 cash_in_pocket; // 0xA0 - money32 cash_spent; // 0xA4 - int32_t time_in_park; // 0xA8 - int8_t rejoin_queue_timeout; // 0xAC - uint8_t previous_ride; // 0xAD - uint16_t previous_ride_time_out; // 0xAE - rct_peep_thought thoughts[PEEP_MAX_THOUGHTS]; // 0xB0 + uint32_t id; // 0x9C + money32 cash_in_pocket; // 0xA0 + money32 cash_spent; // 0xA4 + int32_t time_in_park; // 0xA8 + int8_t rejoin_queue_timeout; // 0xAC + uint8_t previous_ride; // 0xAD + uint16_t previous_ride_time_out; // 0xAE + RCT12PeepThought thoughts[RCT12_PEEP_MAX_THOUGHTS]; // 0xB0 uint8_t pad_C4; union { @@ -578,14 +512,14 @@ union rct1_sprite rct1_unk_sprite unknown; rct1_vehicle vehicle; rct1_peep peep; - rct_litter litter; - rct_balloon balloon; - rct_sprite duck; - rct_jumping_fountain jumping_fountain; - rct_money_effect money_effect; - rct_crashed_vehicle_particle crashed_vehicle_particle; - rct_crash_splash crash_splash; - rct_steam_particle steam_particle; + RCT12SpriteLitter litter; + RCT12SpriteBalloon balloon; + RCT12SpriteDuck duck; + RCT12SpriteJumpingFountain jumping_fountain; + RCT12SpriteMoneyEffect money_effect; + RCT12SpriteCrashedVehicleParticle crashed_vehicle_particle; + RCT12SpriteCrashSplash crash_splash; + RCT12SpriteSteamParticle steam_particle; }; assert_struct_size(rct1_sprite, 0x100); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 98bcef0446..7c2886c75a 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1174,7 +1174,7 @@ private: dst->ride_subtype = ride->subtype; dst->vehicle_type = vehicleEntryIndex; - dst->is_child = src->is_child; + dst->is_child = src->type; dst->var_44 = src->var_44; dst->remaining_distance = src->remaining_distance; @@ -1536,9 +1536,14 @@ private: dst->photo1_ride_ref = src->photo1_ride_ref; - for (size_t i = 0; i < PEEP_MAX_THOUGHTS; i++) + for (size_t i = 0; i < std::size(src->thoughts); i++) { - dst->thoughts[i] = src->thoughts[i]; + auto srcThought = &src->thoughts[i]; + auto dstThought = &dst->thoughts[i]; + dstThought->type = (PeepThoughtType)srcThought->type; + dstThought->item = srcThought->type; + dstThought->freshness = srcThought->freshness; + dstThought->fresh_timeout = srcThought->fresh_timeout; } dst->previous_ride = src->previous_ride; @@ -1652,7 +1657,7 @@ private: { if (sprite.unknown.sprite_identifier == SPRITE_IDENTIFIER_LITTER) { - rct_litter* srcLitter = &sprite.litter; + const auto* srcLitter = &sprite.litter; rct_litter* litter = (rct_litter*)create_sprite(SPRITE_IDENTIFIER_LITTER); move_sprite_to_list((rct_sprite*)litter, SPRITE_LIST_LITTER * 2); @@ -1685,7 +1690,7 @@ private: move_sprite_to_list((rct_sprite*)dst, SPRITE_LIST_MISC * 2); dst->sprite_identifier = src->sprite_identifier; - dst->type = src->misc_identifier; + dst->type = src->type; dst->flags = src->flags; dst->sprite_direction = src->sprite_direction; dst->sprite_width = src->sprite_width; @@ -1694,7 +1699,7 @@ private: sprite_move(src->x, src->y, src->z, (rct_sprite*)dst); - switch (src->misc_identifier) + switch (src->type) { case SPRITE_MISC_STEAM_PARTICLE: ImportSteamParticle((rct_steam_particle*)dst, (rct_steam_particle*)src); diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 21b3e6b059..d8277f102f 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -37,6 +37,8 @@ #define RCT12_MAX_USER_STRINGS 1024 #define RCT12_USER_STRING_MAX_LENGTH 32 +#define RCT12_PEEP_MAX_THOUGHTS 5 + #pragma pack(push, 1) struct rct12_award @@ -366,4 +368,134 @@ struct RCT12EightCarsCorruptElement15 : RCT12TileElementBase }; assert_struct_size(RCT12EightCarsCorruptElement15, 8); +struct RCT12SpriteBase +{ + uint8_t sprite_identifier; // 0x00 + uint8_t type; // 0x01 + uint16_t next_in_quadrant; // 0x02 + uint16_t next; // 0x04 + uint16_t previous; // 0x06 + uint8_t linked_list_type_offset; // 0x08 + uint8_t sprite_height_negative; // 0x09 + uint16_t sprite_index; // 0x0A + uint16_t flags; // 0x0C + int16_t x; // 0x0E + int16_t y; // 0x10 + int16_t z; // 0x12 + uint8_t sprite_width; // 0x14 + uint8_t sprite_height_positive; // 0x15 + int16_t sprite_left; // 0x16 + int16_t sprite_top; // 0x18 + int16_t sprite_right; // 0x1A + int16_t sprite_bottom; // 0x1C + uint8_t sprite_direction; // 0x1E +}; +assert_struct_size(RCT12SpriteBase, 0x1F); + +struct RCT12SpriteBalloon : RCT12SpriteBase +{ + uint8_t pad_1F[0x24 - 0x1F]; + uint16_t popped; // 0x24 + uint8_t time_to_move; // 0x26 + uint8_t frame; // 0x27 + uint8_t pad_28[4]; + uint8_t colour; // 0x2C +}; +assert_struct_size(RCT12SpriteBalloon, 0x2D); + +struct RCT12SpriteDuck : RCT12SpriteBase +{ + uint8_t pad_1F[0x26 - 0x1F]; + uint16_t frame; // 0x26 + uint8_t pad_28[0x30 - 0x28]; + int16_t target_x; // 0x30 + int16_t target_y; // 0x32 + uint8_t pad_34[0x14]; + uint8_t state; // 0x48 +}; +assert_struct_size(RCT12SpriteDuck, 0x49); + +struct RCT12SpriteLitter : RCT12SpriteBase +{ + uint8_t pad_1F[0x24 - 0x1F]; + uint32_t creationTick; // 0x24 +}; +assert_struct_size(RCT12SpriteLitter, 0x28); + +struct RCT12SpriteParticle : RCT12SpriteBase +{ + uint8_t pad_1F[0x26 - 0x1F]; + uint16_t frame; // 0x26 +}; +assert_struct_size(RCT12SpriteParticle, 0x28); + +struct RCT12SpriteJumpingFountain : RCT12SpriteBase +{ + uint8_t pad_1F[0x26 - 0x1F]; + uint8_t num_ticks_alive; // 0x26 + uint8_t frame; // 0x27 + uint8_t pad_28[0x2F - 0x28]; + uint8_t fountain_flags; // 0x2F + int16_t target_x; // 0x30 + int16_t target_y; // 0x32 + uint8_t pad_34[0x46 - 0x34]; + uint16_t iteration; // 0x46 +}; +assert_struct_size(RCT12SpriteJumpingFountain, 0x48); + +struct RCT12SpriteMoneyEffect : RCT12SpriteBase +{ + uint8_t pad_1F[0x24 - 0x1F]; + uint16_t move_delay; // 0x24 + uint8_t num_movements; // 0x26 + uint8_t vertical; + money32 value; // 0x28 + uint8_t pad_2C[0x44 - 0x2C]; + int16_t offset_x; // 0x44 + uint16_t wiggle; // 0x46 +}; +assert_struct_size(RCT12SpriteMoneyEffect, 0x48); + +struct RCT12SpriteCrashedVehicleParticle : RCT12SpriteBase +{ + uint8_t pad_1F[0x24 - 0x1F]; + uint16_t time_to_live; // 0x24 + uint16_t frame; // 0x26 + uint8_t pad_28[0x2C - 0x28]; + uint8_t colour[2]; // 0x2C + uint16_t crashed_sprite_base; // 0x2E + int16_t velocity_x; // 0x30 + int16_t velocity_y; // 0x32 + int16_t velocity_z; // 0x34 + uint8_t pad_36[0x38 - 0x36]; + int32_t acceleration_x; // 0x38 + int32_t acceleration_y; // 0x3C + int32_t acceleration_z; // 0x40 +}; +assert_struct_size(RCT12SpriteCrashedVehicleParticle, 0x44); + +struct RCT12SpriteCrashSplash : RCT12SpriteBase +{ + uint8_t pad_1F[0x26 - 0x1F]; + uint16_t frame; // 0x26 +}; +assert_struct_size(RCT12SpriteCrashSplash, 0x28); + +struct RCT12SpriteSteamParticle : RCT12SpriteBase +{ + uint8_t pad_1F[0x24 - 0x1F]; + uint16_t time_to_move; // 0x24 + uint16_t frame; // 0x26 +}; +assert_struct_size(RCT12SpriteSteamParticle, 0x28); + +struct RCT12PeepThought +{ + uint8_t type; + uint8_t item; + uint8_t freshness; + uint8_t fresh_timeout; +}; +assert_struct_size(RCT12PeepThought, 4); + #pragma pack(pop) diff --git a/src/openrct2/rct2/RCT2.h b/src/openrct2/rct2/RCT2.h index 241272cce1..f42fc51457 100644 --- a/src/openrct2/rct2/RCT2.h +++ b/src/openrct2/rct2/RCT2.h @@ -302,6 +302,297 @@ struct rct_scores_entry }; assert_struct_size(rct_scores_entry, 0x02B0); +struct RCT2SpriteVehicle : RCT12SpriteBase +{ + uint8_t vehicle_sprite_type; // 0x1F + uint8_t bank_rotation; // 0x20 + uint8_t pad_21[3]; + int32_t remaining_distance; // 0x24 + int32_t velocity; // 0x28 + int32_t acceleration; // 0x2C + ride_id_t ride; // 0x30 + uint8_t vehicle_type; // 0x31 + rct_vehicle_colour colours; // 0x32 + union + { + uint16_t track_progress; // 0x34 + struct + { + int8_t var_34; + uint8_t var_35; + }; + }; + union + { + int16_t track_direction; // 0x36 + int16_t track_type; // 0x36 + LocationXY8 boat_location; // 0x36 + }; + uint16_t track_x; // 0x38 + uint16_t track_y; // 0x3A + uint16_t track_z; // 0x3C + uint16_t next_vehicle_on_train; // 0x3E + uint16_t prev_vehicle_on_ride; // 0x40 + uint16_t next_vehicle_on_ride; // 0x42 + uint16_t var_44; + uint16_t mass; // 0x46 + uint16_t update_flags; // 0x48 + uint8_t swing_sprite; + uint8_t current_station; // 0x4B + union + { + int16_t swinging_car_var_0; // 0x4C + int16_t current_time; // 0x4C + struct + { + int8_t ferris_wheel_var_0; // 0x4C + int8_t ferris_wheel_var_1; // 0x4D + }; + }; + union + { + int16_t var_4E; + int16_t crash_z; // 0x4E + }; + uint8_t status; // 0x50 + uint8_t sub_state; // 0x51 + uint16_t peep[32]; // 0x52 + uint8_t peep_tshirt_colours[32]; // 0x92 + uint8_t num_seats; // 0xB2 + uint8_t num_peeps; // 0xB3 + uint8_t next_free_seat; // 0xB4 + uint8_t restraints_position; // 0xB5 + union + { + int16_t spin_speed; // 0xB6 + int16_t crash_x; // 0xB6 + }; + uint16_t sound2_flags; // 0xB8 + uint8_t spin_sprite; // 0xBA + uint8_t sound1_id; // 0xBB + uint8_t sound1_volume; // 0xBC + uint8_t sound2_id; // 0xBD + uint8_t sound2_volume; // 0xBE + int8_t sound_vector_factor; + union + { + uint16_t var_C0; + int16_t crash_y; // 0xC0 + uint16_t time_waiting; // 0xC0 + uint16_t cable_lift_target; // 0xC0 + }; + uint8_t speed; // 0xC2 + uint8_t powered_acceleration; // 0xC3 + union + { + uint8_t dodgems_collision_direction; // 0xC4 + uint8_t var_C4; + }; + uint8_t animation_frame; // 0xC5 + uint8_t pad_C6[0x2]; + uint16_t var_C8; + uint16_t var_CA; + uint8_t scream_sound_id; // 0xCC + uint8_t var_CD; + union + { + uint8_t var_CE; + uint8_t num_laps; // 0xCE + }; + union + { + uint8_t var_CF; + uint8_t brake_speed; // 0xCF + }; + uint16_t lost_time_out; // 0xD0 + int8_t vertical_drop_countdown; // 0xD1 + uint8_t var_D3; + uint8_t mini_golf_current_animation; + uint8_t mini_golf_flags; // 0xD5 + uint8_t ride_subtype; // 0xD6 + uint8_t colours_extended; // 0xD7 + uint8_t seat_rotation; // 0xD8 + uint8_t target_seat_rotation; // 0xD9 +}; +assert_struct_size(RCT2SpriteVehicle, 0xDA); + +struct RCT2SpritePeep : RCT12SpriteBase +{ + uint8_t pad_1F[0x22 - 0x1F]; + rct_string_id name_string_idx; // 0x22 + uint16_t next_x; // 0x24 + uint16_t next_y; // 0x26 + uint8_t next_z; // 0x28 + uint8_t next_flags; // 0x29 + uint8_t outside_of_park; // 0x2A + uint8_t state; // 0x2B + uint8_t sub_state; // 0x2C + uint8_t sprite_type; // 0x2D + uint8_t peep_type; // 0x2E + union + { + uint8_t staff_type; // 0x2F + uint8_t no_of_rides; // 0x2F + }; + uint8_t tshirt_colour; // 0x30 + uint8_t trousers_colour; // 0x31 + uint16_t destination_x; // 0x32 + uint16_t destination_y; // 0x34 + uint8_t destination_tolerance; // 0x36 + uint8_t var_37; + uint8_t energy; // 0x38 + uint8_t energy_target; // 0x39 + uint8_t happiness; // 0x3A + uint8_t happiness_target; // 0x3B + uint8_t nausea; // 0x3C + uint8_t nausea_target; // 0x3D + uint8_t hunger; // 0x3E + uint8_t thirst; // 0x3F + uint8_t toilet; // 0x40 + uint8_t mass; // 0x41 + uint8_t time_to_consume; // 0x42 + uint8_t intensity; // 0x43 + uint8_t nausea_tolerance; // 0x44 + uint8_t window_invalidate_flags; // 0x45 + money16 paid_on_drink; // 0x46 + uint8_t ride_types_been_on[16]; // 0x48 + uint32_t item_extra_flags; // 0x58 + uint8_t photo2_ride_ref; // 0x5C + uint8_t photo3_ride_ref; // 0x5D + uint8_t photo4_ride_ref; // 0x5E + uint8_t pad_5F[0x09]; // 0x5F + uint8_t current_ride; // 0x68 + uint8_t current_ride_station; // 0x69 + uint8_t current_train; // 0x6A + union + { + struct + { + uint8_t current_car; // 0x6B + uint8_t current_seat; // 0x6C + }; + uint16_t time_to_sitdown; // 0x6B + struct + { + uint8_t time_to_stand; // 0x6B + uint8_t standing_flags; // 0x6C + }; + }; + uint8_t special_sprite; // 0x6D + uint8_t action_sprite_type; // 0x6E + uint8_t next_action_sprite_type; // 0x6F + uint8_t action_sprite_image_offset; // 0x70 + uint8_t action; // 0x71 + uint8_t action_frame; // 0x72 + uint8_t step_progress; // 0x73 + union + { + uint16_t mechanic_time_since_call; + uint16_t next_in_queue; // 0x74 + }; + uint8_t pad_76; + uint8_t pad_77; + union + { + uint8_t maze_last_edge; // 0x78 + uint8_t direction; + }; + uint8_t interaction_ride_index; + uint16_t time_in_queue; // 0x7A + uint8_t rides_been_on[32]; // 0x7C + uint32_t id; // 0x9C + money32 cash_in_pocket; // 0xA0 + money32 cash_spent; // 0xA4 + int32_t time_in_park; // 0xA8 + int8_t rejoin_queue_timeout; // 0xAC + uint8_t previous_ride; // 0xAD + uint16_t previous_ride_time_out; // 0xAE + RCT12PeepThought thoughts[RCT12_PEEP_MAX_THOUGHTS]; // 0xB0 + uint8_t path_check_optimisation; // 0xC4 + union + { + uint8_t staff_id; // 0xC5 + uint8_t guest_heading_to_ride_id; // 0xC5 + }; + union + { + uint8_t staff_orders; // 0xC6 + uint8_t peep_is_lost_countdown; // 0xC6 + }; + uint8_t photo1_ride_ref; // 0xC7 + uint32_t peep_flags; // 0xC8 + rct12_xyzd8 pathfind_goal; // 0xCC + rct12_xyzd8 pathfind_history[4]; // 0xD0 + uint8_t no_action_frame_num; // 0xE0 + uint8_t litter_count; // 0xE1 + union + { + uint8_t time_on_ride; // 0xE2 + uint8_t staff_mowing_timeout; // 0xE2 + }; + uint8_t disgusting_count; // 0xE3 + union + { + money16 paid_to_enter; // 0xE4 + uint16_t staff_lawns_mown; // 0xE4 + uint16_t staff_rides_fixed; // 0xE4 + }; + union + { + money16 paid_on_rides; // 0xE6 + uint16_t staff_gardens_watered; // 0xE6 + uint16_t staff_rides_inspected; // 0xE6 + }; + union + { + money16 paid_on_food; // 0xE8 + uint16_t staff_litter_swept; // 0xE8 + }; + union + { + money16 paid_on_souvenirs; // 0xEA + uint16_t staff_bins_emptied; // 0xEA + }; + uint8_t no_of_food; // 0xEC + uint8_t no_of_drinks; // 0xED + uint8_t no_of_souvenirs; // 0xEE + uint8_t vandalism_seen; // 0xEF 0xC0 vandalism thought timeout, 0x3F vandalism tiles seen + uint8_t voucher_type; // 0xF0 + uint8_t voucher_arguments; // 0xF1 ride_id or string_offset_id + uint8_t surroundings_thought_timeout; // 0xF2 + uint8_t angriness; // 0xF3 + uint8_t time_lost; // 0xF4 the time the peep has been lost when it reaches 254 generates the lost thought + uint8_t days_in_queue; // 0xF5 + uint8_t balloon_colour; // 0xF6 + uint8_t umbrella_colour; // 0xF7 + uint8_t hat_colour; // 0xF8 + uint8_t favourite_ride; // 0xF9 + uint8_t favourite_ride_rating; // 0xFA + uint8_t pad_FB; + uint32_t item_standard_flags; // 0xFC +}; +assert_struct_size(RCT2SpritePeep, 0x100); + +union RCT2Sprite +{ +private: + uint8_t pad_00[0x100]; + +public: + RCT12SpriteBase unknown; + RCT2SpriteVehicle vehicle; + RCT2SpritePeep peep; + RCT12SpriteLitter litter; + RCT12SpriteBalloon balloon; + RCT12SpriteDuck duck; + RCT12SpriteJumpingFountain jumping_fountain; + RCT12SpriteMoneyEffect money_effect; + RCT12SpriteCrashedVehicleParticle crashed_vehicle_particle; + RCT12SpriteCrashSplash crash_splash; + RCT12SpriteSteamParticle steam_particle; +}; +assert_struct_size(RCT2Sprite, 0x100); + #pragma pack(pop) #endif diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 04739883d6..cb59affa99 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -196,21 +196,9 @@ void S6Exporter::Export() std::memcpy(_s6.tile_elements, gTileElements, sizeof(_s6.tile_elements)); _s6.next_free_tile_element_pointer_index = gNextFreeTileElementPointerIndex; - // Sprites needs to be reset before they get used. - // Might as well reset them in here to zero out the space and improve - // compression ratios. Especially useful for multiplayer servers that - // use zlib on the sent stream. - sprite_clear_all_unused(); - for (int32_t i = 0; i < RCT2_MAX_SPRITES; i++) - { - std::memcpy(&_s6.sprites[i], get_sprite(i), sizeof(rct_sprite)); - } - for (int32_t i = 0; i < NUM_SPRITE_LISTS; i++) - { - _s6.sprite_lists_head[i] = gSpriteListHead[i]; - _s6.sprite_lists_count[i] = gSpriteListCount[i]; - } + ExportSprites(); + _s6.park_name = gParkName; // pad_013573D6 _s6.park_name_args = gParkNameArgs; @@ -763,6 +751,353 @@ void S6Exporter::ExportMarketingCampaigns() } } +void S6Exporter::ExportSprites() +{ + // Sprites needs to be reset before they get used. + // Might as well reset them in here to zero out the space and improve + // compression ratios. Especially useful for multiplayer servers that + // use zlib on the sent stream. + sprite_clear_all_unused(); + for (int32_t i = 0; i < RCT2_MAX_SPRITES; i++) + { + ExportSprite(&_s6.sprites[i], get_sprite(i)); + } + + for (int32_t i = 0; i < NUM_SPRITE_LISTS; i++) + { + _s6.sprite_lists_head[i] = gSpriteListHead[i]; + _s6.sprite_lists_count[i] = gSpriteListCount[i]; + } +} + +void S6Exporter::ExportSprite(RCT2Sprite* dst, const rct_sprite* src) +{ + std::memset(dst, 0, sizeof(rct_sprite)); + switch (src->generic.sprite_identifier) + { + case SPRITE_IDENTIFIER_NULL: + ExportSpriteCommonProperties(&dst->unknown, &src->generic); + break; + case SPRITE_IDENTIFIER_VEHICLE: + ExportSpriteVehicle(&dst->vehicle, &src->vehicle); + break; + case SPRITE_IDENTIFIER_PEEP: + ExportSpritePeep(&dst->peep, &src->peep); + break; + case SPRITE_IDENTIFIER_MISC: + ExportSpriteMisc(&dst->unknown, &src->generic); + break; + case SPRITE_IDENTIFIER_LITTER: + ExportSpriteLitter(&dst->litter, &src->litter); + break; + default: + ExportSpriteCommonProperties(&dst->unknown, &src->generic); + log_warning("Sprite identifier %d can not be exported.", src->generic.sprite_identifier); + break; + } +} + +void S6Exporter::ExportSpriteCommonProperties(RCT12SpriteBase* dst, const rct_sprite_common* src) +{ + dst->sprite_identifier = src->sprite_identifier; + dst->type = src->type; + dst->next_in_quadrant = src->next_in_quadrant; + dst->next = src->next; + dst->previous = src->previous; + dst->linked_list_type_offset = src->linked_list_type_offset; + dst->sprite_height_negative = src->sprite_height_negative; + dst->sprite_index = src->sprite_index; + dst->flags = src->flags; + dst->x = src->x; + dst->y = src->y; + dst->z = src->z; + dst->sprite_width = src->sprite_width; + dst->sprite_height_positive = src->sprite_height_positive; + dst->sprite_left = src->sprite_left; + dst->sprite_top = src->sprite_top; + dst->sprite_right = src->sprite_right; + dst->sprite_bottom = src->sprite_bottom; + dst->sprite_direction = src->sprite_direction; +} + +void S6Exporter::ExportSpriteVehicle(RCT2SpriteVehicle* dst, const rct_vehicle* src) +{ + ExportSpriteCommonProperties(dst, (const rct_sprite_common*)src); + dst->vehicle_sprite_type = src->vehicle_sprite_type; + dst->bank_rotation = src->bank_rotation; + dst->remaining_distance = src->remaining_distance; + dst->velocity = src->velocity; + dst->acceleration = src->acceleration; + dst->ride = src->ride; + dst->vehicle_type = src->vehicle_type; + dst->colours = src->colours; + dst->track_progress = src->track_progress; + dst->track_direction = src->track_direction; + dst->track_type = src->track_type; + dst->track_x = src->track_x; + dst->track_y = src->track_y; + dst->track_z = src->track_z; + dst->next_vehicle_on_train = src->next_vehicle_on_train; + dst->prev_vehicle_on_ride = src->prev_vehicle_on_ride; + dst->next_vehicle_on_ride = src->next_vehicle_on_ride; + dst->var_44 = src->var_44; + dst->mass = src->mass; + dst->update_flags = src->update_flags; + dst->swing_sprite = src->swing_sprite; + dst->current_station = src->current_station; + dst->current_time = src->current_time; + dst->crash_z = src->crash_z; + dst->status = src->status; + dst->sub_state = src->sub_state; + for (size_t i = 0; i < std::size(src->peep); i++) + { + dst->peep[i] = src->peep[i]; + dst->peep_tshirt_colours[i] = src->peep_tshirt_colours[i]; + } + dst->num_seats = src->num_seats; + dst->num_peeps = src->num_peeps; + dst->next_free_seat = src->next_free_seat; + dst->restraints_position = src->restraints_position; + dst->crash_x = src->crash_x; + dst->sound2_flags = src->sound2_flags; + dst->spin_sprite = src->spin_sprite; + dst->sound1_id = src->sound1_id; + dst->sound1_volume = src->sound1_volume; + dst->sound2_id = src->sound2_id; + dst->sound2_volume = src->sound2_volume; + dst->sound_vector_factor = src->sound_vector_factor; + dst->time_waiting = src->time_waiting; + dst->speed = src->speed; + dst->powered_acceleration = src->powered_acceleration; + dst->dodgems_collision_direction = src->dodgems_collision_direction; + dst->animation_frame = src->animation_frame; + dst->var_C8 = src->var_C8; + dst->var_CA = src->var_CA; + dst->scream_sound_id = src->scream_sound_id; + dst->var_CD = src->var_CD; + dst->var_CE = src->var_CE; + dst->var_CF = src->var_CF; + dst->lost_time_out = src->lost_time_out; + dst->vertical_drop_countdown = src->vertical_drop_countdown; + dst->var_D3 = src->var_D3; + dst->mini_golf_current_animation = src->mini_golf_current_animation; + dst->mini_golf_flags = src->mini_golf_flags; + dst->ride_subtype = src->ride_subtype; + dst->colours_extended = src->colours_extended; + dst->seat_rotation = src->seat_rotation; + dst->target_seat_rotation = src->target_seat_rotation; +} + +void S6Exporter::ExportSpritePeep(RCT2SpritePeep* dst, const rct_peep* src) +{ + ExportSpriteCommonProperties(dst, (const rct_sprite_common*)src); + dst->name_string_idx = src->name_string_idx; + dst->next_x = src->next_x; + dst->next_y = src->next_y; + dst->next_z = src->next_z; + dst->next_flags = src->next_flags; + dst->outside_of_park = src->outside_of_park; + dst->state = (uint8_t)src->state; + dst->sub_state = src->sub_state; + dst->sprite_type = (uint8_t)src->sprite_type; + dst->peep_type = (uint8_t)src->type; + dst->no_of_rides = src->no_of_rides; + dst->tshirt_colour = src->tshirt_colour; + dst->trousers_colour = src->trousers_colour; + dst->destination_x = src->destination_x; + dst->destination_y = src->destination_y; + dst->destination_tolerance = src->destination_tolerance; + dst->var_37 = src->var_37; + dst->energy = src->energy; + dst->energy_target = src->energy_target; + dst->happiness = src->happiness; + dst->happiness_target = src->happiness_target; + dst->nausea = src->nausea; + dst->nausea_target = src->nausea_target; + dst->hunger = src->hunger; + dst->thirst = src->thirst; + dst->toilet = src->toilet; + dst->mass = src->mass; + dst->time_to_consume = src->time_to_consume; + dst->intensity = src->intensity; + dst->nausea_tolerance = src->nausea_tolerance; + dst->window_invalidate_flags = src->window_invalidate_flags; + dst->paid_on_drink = src->paid_on_drink; + for (size_t i = 0; i < std::size(src->ride_types_been_on); i++) + { + dst->ride_types_been_on[i] = src->ride_types_been_on[i]; + } + dst->item_extra_flags = src->item_extra_flags; + dst->photo2_ride_ref = src->photo2_ride_ref; + dst->photo3_ride_ref = src->photo3_ride_ref; + dst->photo4_ride_ref = src->photo4_ride_ref; + dst->current_ride = src->current_ride; + dst->current_ride_station = src->current_ride_station; + dst->current_train = src->current_train; + dst->time_to_sitdown = src->time_to_sitdown; + dst->special_sprite = src->special_sprite; + dst->action_sprite_type = (uint8_t)src->action_sprite_type; + dst->next_action_sprite_type = (uint8_t)src->next_action_sprite_type; + dst->action_sprite_image_offset = src->action_sprite_image_offset; + dst->action = (uint8_t)src->action; + dst->action_frame = src->action_frame; + dst->step_progress = src->step_progress; + dst->next_in_queue = src->next_in_queue; + dst->direction = src->direction; + dst->interaction_ride_index = src->interaction_ride_index; + dst->time_in_queue = src->time_in_queue; + for (size_t i = 0; i < std::size(src->rides_been_on); i++) + { + dst->rides_been_on[i] = src->rides_been_on[i]; + } + dst->id = src->id; + dst->cash_in_pocket = src->cash_in_pocket; + dst->cash_spent = src->cash_spent; + dst->time_in_park = src->time_in_park; + dst->rejoin_queue_timeout = src->rejoin_queue_timeout; + dst->previous_ride = src->previous_ride; + dst->previous_ride_time_out = src->previous_ride_time_out; + for (size_t i = 0; i < std::size(src->thoughts); i++) + { + auto srcThought = &src->thoughts[i]; + auto dstThought = &dst->thoughts[i]; + dstThought->type = (uint8_t)srcThought->type; + dstThought->item = srcThought->type; + dstThought->freshness = srcThought->freshness; + dstThought->fresh_timeout = srcThought->fresh_timeout; + } + dst->path_check_optimisation = src->path_check_optimisation; + dst->guest_heading_to_ride_id = src->guest_heading_to_ride_id; + dst->peep_is_lost_countdown = src->peep_is_lost_countdown; + dst->photo1_ride_ref = src->photo1_ride_ref; + dst->peep_flags = src->peep_flags; + dst->pathfind_goal = src->pathfind_goal; + for (size_t i = 0; i < std::size(src->pathfind_history); i++) + { + dst->pathfind_history[i] = src->pathfind_history[i]; + } + dst->no_action_frame_num = src->no_action_frame_num; + dst->litter_count = src->litter_count; + dst->time_on_ride = src->time_on_ride; + dst->disgusting_count = src->disgusting_count; + dst->paid_to_enter = src->paid_to_enter; + dst->paid_on_rides = src->paid_on_rides; + dst->paid_on_food = src->paid_on_food; + dst->paid_on_souvenirs = src->paid_on_souvenirs; + dst->no_of_drinks = src->no_of_drinks; + dst->no_of_souvenirs = src->no_of_souvenirs; + dst->vandalism_seen = src->vandalism_seen; + dst->voucher_type = src->voucher_type; + dst->voucher_arguments = src->voucher_arguments; + dst->surroundings_thought_timeout = src->surroundings_thought_timeout; + dst->angriness = src->angriness; + dst->time_lost = src->time_lost; + dst->days_in_queue = src->days_in_queue; + dst->balloon_colour = src->balloon_colour; + dst->umbrella_colour = src->umbrella_colour; + dst->hat_colour = src->hat_colour; + dst->favourite_ride = src->favourite_ride; + dst->favourite_ride_rating = src->favourite_ride_rating; + dst->item_standard_flags = src->item_standard_flags; +} + +void S6Exporter::ExportSpriteMisc(RCT12SpriteBase* cdst, const rct_sprite_common* csrc) +{ + ExportSpriteCommonProperties(cdst, csrc); + switch (cdst->type) + { + case SPRITE_MISC_STEAM_PARTICLE: + { + auto src = (const RCT12SpriteSteamParticle*)csrc; + auto dst = (rct_steam_particle*)cdst; + dst->time_to_move = src->time_to_move; + dst->frame = src->frame; + break; + } + case SPRITE_MISC_MONEY_EFFECT: + { + auto src = (const RCT12SpriteMoneyEffect*)csrc; + auto dst = (rct_money_effect*)cdst; + dst->move_delay = src->move_delay; + dst->num_movements = src->num_movements; + dst->vertical = src->vertical; + dst->value = src->value; + dst->offset_x = src->offset_x; + dst->wiggle = src->wiggle; + break; + } + case SPRITE_MISC_CRASHED_VEHICLE_PARTICLE: + { + auto src = (const RCT12SpriteCrashedVehicleParticle*)csrc; + auto dst = (rct_crashed_vehicle_particle*)cdst; + dst->frame = src->frame; + dst->time_to_live = src->time_to_live; + dst->frame = src->frame; + dst->colour[0] = src->colour[0]; + dst->colour[1] = src->colour[1]; + dst->crashed_sprite_base = src->crashed_sprite_base; + dst->velocity_x = src->velocity_x; + dst->velocity_y = src->velocity_y; + dst->velocity_z = src->velocity_z; + dst->acceleration_x = src->acceleration_x; + dst->acceleration_y = src->acceleration_y; + dst->acceleration_z = src->acceleration_z; + break; + } + case SPRITE_MISC_EXPLOSION_CLOUD: + case SPRITE_MISC_EXPLOSION_FLARE: + case SPRITE_MISC_CRASH_SPLASH: + { + auto src = (const rct_sprite_generic*)csrc; + auto dst = (RCT12SpriteParticle*)cdst; + dst->frame = src->frame; + break; + } + case SPRITE_MISC_JUMPING_FOUNTAIN_WATER: + case SPRITE_MISC_JUMPING_FOUNTAIN_SNOW: + { + auto src = (const rct_jumping_fountain*)csrc; + auto dst = (RCT12SpriteJumpingFountain*)cdst; + dst->num_ticks_alive = src->num_ticks_alive; + dst->frame = src->frame; + dst->fountain_flags = src->fountain_flags; + dst->target_x = src->target_x; + dst->target_y = src->target_y; + dst->iteration = src->iteration; + break; + } + case SPRITE_MISC_BALLOON: + { + auto src = (const rct_balloon*)csrc; + auto dst = (RCT12SpriteBalloon*)cdst; + dst->popped = src->popped; + dst->time_to_move = src->time_to_move; + dst->frame = src->frame; + dst->colour = src->colour; + break; + } + case SPRITE_MISC_DUCK: + { + auto src = (const rct_duck*)csrc; + auto dst = (RCT12SpriteDuck*)cdst; + dst->frame = src->frame; + dst->target_x = src->target_x; + dst->target_y = src->target_y; + dst->state = src->state; + break; + } + default: + log_warning("Misc. sprite type %d can not be exported.", cdst->type); + break; + } +} + +void S6Exporter::ExportSpriteLitter(RCT12SpriteLitter* dst, const rct_litter* src) +{ + ExportSpriteCommonProperties(dst, src); + dst->creationTick = src->creationTick; +} + enum : uint32_t { S6_SAVE_FLAG_EXPORT = 1 << 0, diff --git a/src/openrct2/rct2/S6Exporter.h b/src/openrct2/rct2/S6Exporter.h index 315051a6cc..873d374de9 100644 --- a/src/openrct2/rct2/S6Exporter.h +++ b/src/openrct2/rct2/S6Exporter.h @@ -17,6 +17,8 @@ interface IStream; struct ObjectRepositoryItem; +struct RCT12SpriteBase; +struct rct_sprite_common; /** * Class to export RollerCoaster Tycoon 2 scenarios (*.SC6) and saved games (*.SV6). @@ -36,6 +38,13 @@ public: void Export(); void ExportRides(); void ExportRide(rct2_ride* dst, const Ride* src); + void ExportSprites(); + void ExportSprite(RCT2Sprite* dst, const rct_sprite* src); + void ExportSpriteCommonProperties(RCT12SpriteBase* dst, const rct_sprite_common* src); + void ExportSpriteVehicle(RCT2SpriteVehicle* dst, const rct_vehicle* src); + void ExportSpritePeep(RCT2SpritePeep* dst, const rct_peep* src); + void ExportSpriteMisc(RCT12SpriteBase* dst, const rct_sprite_common* src); + void ExportSpriteLitter(RCT12SpriteLitter* dst, const rct_litter* src); private: rct_s6_data _s6{}; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 997f6ed410..44d5826a3d 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -212,20 +212,7 @@ public: scenario_rand_seed(_s6.scenario_srand_0, _s6.scenario_srand_1); ImportTileElements(); - - gNextFreeTileElementPointerIndex = _s6.next_free_tile_element_pointer_index; - for (int32_t i = 0; i < RCT2_MAX_SPRITES; i++) - { - std::memcpy(get_sprite(i), &_s6.sprites[i], sizeof(rct_sprite)); - } - - for (int32_t i = 0; i < NUM_SPRITE_LISTS; i++) - { - gSpriteListHead[i] = _s6.sprite_lists_head[i]; - gSpriteListCount[i] = _s6.sprite_lists_count[i]; - } - // This list contains the number of free slots. Increase it according to our own sprite limit. - gSpriteListCount[SPRITE_LIST_NULL] += (MAX_SPRITES - RCT2_MAX_SPRITES); + ImportSprites(); gParkName = _s6.park_name; // pad_013573D6 @@ -845,9 +832,9 @@ public: { // The number of riders might have overflown or underflown. Re-calculate the value. uint16_t numRiders = 0; - for (const rct_sprite& sprite : _s6.sprites) + for (const auto& sprite : _s6.sprites) { - if (sprite.generic.sprite_identifier == SPRITE_IDENTIFIER_PEEP) + if (sprite.unknown.sprite_identifier == SPRITE_IDENTIFIER_PEEP) { if (sprite.peep.current_ride == rideIndex && (sprite.peep.state == PEEP_STATE_ON_RIDE || sprite.peep.state == PEEP_STATE_ENTERING_RIDE)) @@ -881,7 +868,9 @@ public: ImportTileElement(dst, src); } } + gNextFreeTileElementPointerIndex = _s6.next_free_tile_element_pointer_index; } + void ImportTileElement(TileElement* dst, const RCT12TileElement* src) { // Todo: allow for changing defition of OpenRCT2 tile element types - replace with a map @@ -1049,6 +1038,352 @@ public: } } } + + void ImportSprites() + { + for (int32_t i = 0; i < RCT2_MAX_SPRITES; i++) + { + auto src = &_s6.sprites[i]; + auto dst = get_sprite(i); + ImportSprite(dst, src); + } + + for (int32_t i = 0; i < NUM_SPRITE_LISTS; i++) + { + gSpriteListHead[i] = _s6.sprite_lists_head[i]; + gSpriteListCount[i] = _s6.sprite_lists_count[i]; + } + // This list contains the number of free slots. Increase it according to our own sprite limit. + gSpriteListCount[SPRITE_LIST_NULL] += (MAX_SPRITES - RCT2_MAX_SPRITES); + } + + void ImportSprite(rct_sprite* dst, const RCT2Sprite* src) + { + std::memset(dst, 0, sizeof(rct_sprite)); + switch (src->unknown.sprite_identifier) + { + case SPRITE_IDENTIFIER_NULL: + ImportSpriteCommonProperties((rct_sprite_common*)dst, &src->unknown); + break; + case SPRITE_IDENTIFIER_VEHICLE: + ImportSpriteVehicle(&dst->vehicle, &src->vehicle); + break; + case SPRITE_IDENTIFIER_PEEP: + ImportSpritePeep(&dst->peep, &src->peep); + break; + case SPRITE_IDENTIFIER_MISC: + ImportSpriteMisc(&dst->generic, &src->unknown); + break; + case SPRITE_IDENTIFIER_LITTER: + ImportSpriteLitter(&dst->litter, &src->litter); + break; + default: + ImportSpriteCommonProperties((rct_sprite_common*)dst, (const RCT12SpriteBase*)src); + log_warning("Sprite identifier %d can not be imported.", src->unknown.sprite_identifier); + break; + } + } + + void ImportSpriteVehicle(rct_vehicle* dst, const RCT2SpriteVehicle* src) + { + ImportSpriteCommonProperties((rct_sprite_common*)dst, src); + dst->vehicle_sprite_type = src->vehicle_sprite_type; + dst->bank_rotation = src->bank_rotation; + dst->remaining_distance = src->remaining_distance; + dst->velocity = src->velocity; + dst->acceleration = src->acceleration; + dst->ride = src->ride; + dst->vehicle_type = src->vehicle_type; + dst->colours = src->colours; + dst->track_progress = src->track_progress; + dst->track_direction = src->track_direction; + dst->track_type = src->track_type; + dst->track_x = src->track_x; + dst->track_y = src->track_y; + dst->track_z = src->track_z; + dst->next_vehicle_on_train = src->next_vehicle_on_train; + dst->prev_vehicle_on_ride = src->prev_vehicle_on_ride; + dst->next_vehicle_on_ride = src->next_vehicle_on_ride; + dst->var_44 = src->var_44; + dst->mass = src->mass; + dst->update_flags = src->update_flags; + dst->swing_sprite = src->swing_sprite; + dst->current_station = src->current_station; + dst->current_time = src->current_time; + dst->crash_z = src->crash_z; + dst->status = src->status; + dst->sub_state = src->sub_state; + for (size_t i = 0; i < std::size(src->peep); i++) + { + dst->peep[i] = src->peep[i]; + dst->peep_tshirt_colours[i] = src->peep_tshirt_colours[i]; + } + dst->num_seats = src->num_seats; + dst->num_peeps = src->num_peeps; + dst->next_free_seat = src->next_free_seat; + dst->restraints_position = src->restraints_position; + dst->crash_x = src->crash_x; + dst->sound2_flags = src->sound2_flags; + dst->spin_sprite = src->spin_sprite; + dst->sound1_id = src->sound1_id; + dst->sound1_volume = src->sound1_volume; + dst->sound2_id = src->sound2_id; + dst->sound2_volume = src->sound2_volume; + dst->sound_vector_factor = src->sound_vector_factor; + dst->time_waiting = src->time_waiting; + dst->speed = src->speed; + dst->powered_acceleration = src->powered_acceleration; + dst->dodgems_collision_direction = src->dodgems_collision_direction; + dst->animation_frame = src->animation_frame; + dst->var_C8 = src->var_C8; + dst->var_CA = src->var_CA; + dst->scream_sound_id = src->scream_sound_id; + dst->var_CD = src->var_CD; + dst->var_CE = src->var_CE; + dst->var_CF = src->var_CF; + dst->lost_time_out = src->lost_time_out; + dst->vertical_drop_countdown = src->vertical_drop_countdown; + dst->var_D3 = src->var_D3; + dst->mini_golf_current_animation = src->mini_golf_current_animation; + dst->mini_golf_flags = src->mini_golf_flags; + dst->ride_subtype = src->ride_subtype; + dst->colours_extended = src->colours_extended; + dst->seat_rotation = src->seat_rotation; + dst->target_seat_rotation = src->target_seat_rotation; + } + + void ImportSpritePeep(rct_peep* dst, const RCT2SpritePeep* src) + { + ImportSpriteCommonProperties((rct_sprite_common*)dst, src); + dst->name_string_idx = src->name_string_idx; + dst->next_x = src->next_x; + dst->next_y = src->next_y; + dst->next_z = src->next_z; + dst->next_flags = src->next_flags; + dst->outside_of_park = src->outside_of_park; + dst->state = (PeepState)src->state; + dst->sub_state = src->sub_state; + dst->sprite_type = (PeepSpriteType)src->sprite_type; + dst->type = (PeepType)src->peep_type; + dst->no_of_rides = src->no_of_rides; + dst->tshirt_colour = src->tshirt_colour; + dst->trousers_colour = src->trousers_colour; + dst->destination_x = src->destination_x; + dst->destination_y = src->destination_y; + dst->destination_tolerance = src->destination_tolerance; + dst->var_37 = src->var_37; + dst->energy = src->energy; + dst->energy_target = src->energy_target; + dst->happiness = src->happiness; + dst->happiness_target = src->happiness_target; + dst->nausea = src->nausea; + dst->nausea_target = src->nausea_target; + dst->hunger = src->hunger; + dst->thirst = src->thirst; + dst->toilet = src->toilet; + dst->mass = src->mass; + dst->time_to_consume = src->time_to_consume; + dst->intensity = src->intensity; + dst->nausea_tolerance = src->nausea_tolerance; + dst->window_invalidate_flags = src->window_invalidate_flags; + dst->paid_on_drink = src->paid_on_drink; + for (size_t i = 0; i < std::size(src->ride_types_been_on); i++) + { + dst->ride_types_been_on[i] = src->ride_types_been_on[i]; + } + dst->item_extra_flags = src->item_extra_flags; + dst->photo2_ride_ref = src->photo2_ride_ref; + dst->photo3_ride_ref = src->photo3_ride_ref; + dst->photo4_ride_ref = src->photo4_ride_ref; + dst->current_ride = src->current_ride; + dst->current_ride_station = src->current_ride_station; + dst->current_train = src->current_train; + dst->time_to_sitdown = src->time_to_sitdown; + dst->special_sprite = src->special_sprite; + dst->action_sprite_type = (PeepActionSpriteType)src->action_sprite_type; + dst->next_action_sprite_type = (PeepActionSpriteType)src->next_action_sprite_type; + dst->action_sprite_image_offset = src->action_sprite_image_offset; + dst->action = (PeepActionType)src->action; + dst->action_frame = src->action_frame; + dst->step_progress = src->step_progress; + dst->next_in_queue = src->next_in_queue; + dst->direction = src->direction; + dst->interaction_ride_index = src->interaction_ride_index; + dst->time_in_queue = src->time_in_queue; + for (size_t i = 0; i < std::size(src->rides_been_on); i++) + { + dst->rides_been_on[i] = src->rides_been_on[i]; + } + dst->id = src->id; + dst->cash_in_pocket = src->cash_in_pocket; + dst->cash_spent = src->cash_spent; + dst->time_in_park = src->time_in_park; + dst->rejoin_queue_timeout = src->rejoin_queue_timeout; + dst->previous_ride = src->previous_ride; + dst->previous_ride_time_out = src->previous_ride_time_out; + for (size_t i = 0; i < std::size(src->thoughts); i++) + { + auto srcThought = &src->thoughts[i]; + auto dstThought = &dst->thoughts[i]; + dstThought->type = (PeepThoughtType)srcThought->type; + dstThought->item = srcThought->type; + dstThought->freshness = srcThought->freshness; + dstThought->fresh_timeout = srcThought->fresh_timeout; + } + dst->path_check_optimisation = src->path_check_optimisation; + dst->guest_heading_to_ride_id = src->guest_heading_to_ride_id; + dst->peep_is_lost_countdown = src->peep_is_lost_countdown; + dst->photo1_ride_ref = src->photo1_ride_ref; + dst->peep_flags = src->peep_flags; + dst->pathfind_goal = src->pathfind_goal; + for (size_t i = 0; i < std::size(src->pathfind_history); i++) + { + dst->pathfind_history[i] = src->pathfind_history[i]; + } + dst->no_action_frame_num = src->no_action_frame_num; + dst->litter_count = src->litter_count; + dst->time_on_ride = src->time_on_ride; + dst->disgusting_count = src->disgusting_count; + dst->paid_to_enter = src->paid_to_enter; + dst->paid_on_rides = src->paid_on_rides; + dst->paid_on_food = src->paid_on_food; + dst->paid_on_souvenirs = src->paid_on_souvenirs; + dst->no_of_drinks = src->no_of_drinks; + dst->no_of_souvenirs = src->no_of_souvenirs; + dst->vandalism_seen = src->vandalism_seen; + dst->voucher_type = src->voucher_type; + dst->voucher_arguments = src->voucher_arguments; + dst->surroundings_thought_timeout = src->surroundings_thought_timeout; + dst->angriness = src->angriness; + dst->time_lost = src->time_lost; + dst->days_in_queue = src->days_in_queue; + dst->balloon_colour = src->balloon_colour; + dst->umbrella_colour = src->umbrella_colour; + dst->hat_colour = src->hat_colour; + dst->favourite_ride = src->favourite_ride; + dst->favourite_ride_rating = src->favourite_ride_rating; + dst->item_standard_flags = src->item_standard_flags; + } + + void ImportSpriteMisc(rct_sprite_common* cdst, const RCT12SpriteBase* csrc) + { + ImportSpriteCommonProperties(cdst, csrc); + switch (cdst->type) + { + case SPRITE_MISC_STEAM_PARTICLE: + { + auto src = (const rct_steam_particle*)csrc; + auto dst = (RCT12SpriteSteamParticle*)cdst; + dst->time_to_move = src->time_to_move; + dst->frame = src->frame; + break; + } + case SPRITE_MISC_MONEY_EFFECT: + { + auto src = (const rct_money_effect*)csrc; + auto dst = (RCT12SpriteMoneyEffect*)cdst; + dst->move_delay = src->move_delay; + dst->num_movements = src->num_movements; + dst->vertical = src->vertical; + dst->value = src->value; + dst->offset_x = src->offset_x; + dst->wiggle = src->wiggle; + break; + } + case SPRITE_MISC_CRASHED_VEHICLE_PARTICLE: + { + auto src = (const rct_crashed_vehicle_particle*)csrc; + auto dst = (RCT12SpriteCrashedVehicleParticle*)cdst; + dst->frame = src->frame; + dst->time_to_live = src->time_to_live; + dst->frame = src->frame; + dst->colour[0] = src->colour[0]; + dst->colour[1] = src->colour[1]; + dst->crashed_sprite_base = src->crashed_sprite_base; + dst->velocity_x = src->velocity_x; + dst->velocity_y = src->velocity_y; + dst->velocity_z = src->velocity_z; + dst->acceleration_x = src->acceleration_x; + dst->acceleration_y = src->acceleration_y; + dst->acceleration_z = src->acceleration_z; + break; + } + case SPRITE_MISC_EXPLOSION_CLOUD: + case SPRITE_MISC_EXPLOSION_FLARE: + case SPRITE_MISC_CRASH_SPLASH: + { + auto src = (const RCT12SpriteParticle*)csrc; + auto dst = (rct_sprite_generic*)cdst; + dst->frame = src->frame; + break; + } + case SPRITE_MISC_JUMPING_FOUNTAIN_WATER: + case SPRITE_MISC_JUMPING_FOUNTAIN_SNOW: + { + auto src = (const RCT12SpriteJumpingFountain*)csrc; + auto dst = (rct_jumping_fountain*)cdst; + dst->num_ticks_alive = src->num_ticks_alive; + dst->frame = src->frame; + dst->fountain_flags = src->fountain_flags; + dst->target_x = src->target_x; + dst->target_y = src->target_y; + dst->iteration = src->iteration; + break; + } + case SPRITE_MISC_BALLOON: + { + auto src = (const RCT12SpriteBalloon*)csrc; + auto dst = (rct_balloon*)cdst; + dst->popped = src->popped; + dst->time_to_move = src->time_to_move; + dst->frame = src->frame; + dst->colour = src->colour; + break; + } + case SPRITE_MISC_DUCK: + { + auto src = (const RCT12SpriteDuck*)csrc; + auto dst = (rct_duck*)cdst; + dst->frame = src->frame; + dst->target_x = src->target_x; + dst->target_y = src->target_y; + dst->state = src->state; + break; + } + default: + log_warning("Misc. sprite type %d can not be imported.", cdst->type); + break; + } + } + + void ImportSpriteLitter(rct_litter* dst, const RCT12SpriteLitter* src) + { + ImportSpriteCommonProperties(dst, src); + dst->creationTick = src->creationTick; + } + + void ImportSpriteCommonProperties(rct_sprite_common* dst, const RCT12SpriteBase* src) + { + dst->sprite_identifier = src->sprite_identifier; + dst->type = src->type; + dst->next_in_quadrant = src->next_in_quadrant; + dst->next = src->next; + dst->previous = src->previous; + dst->linked_list_type_offset = src->linked_list_type_offset; + dst->sprite_height_negative = src->sprite_height_negative; + dst->sprite_index = src->sprite_index; + dst->flags = src->flags; + dst->x = src->x; + dst->y = src->y; + dst->z = src->z; + dst->sprite_width = src->sprite_width; + dst->sprite_height_positive = src->sprite_height_positive; + dst->sprite_left = src->sprite_left; + dst->sprite_top = src->sprite_top; + dst->sprite_right = src->sprite_right; + dst->sprite_bottom = src->sprite_bottom; + dst->sprite_direction = src->sprite_direction; + } }; std::unique_ptr ParkImporter::CreateS6(IObjectRepository& objectRepository) diff --git a/src/openrct2/scenario/Scenario.h b/src/openrct2/scenario/Scenario.h index 3b2a68188a..39c4667a10 100644 --- a/src/openrct2/scenario/Scenario.h +++ b/src/openrct2/scenario/Scenario.h @@ -111,7 +111,7 @@ struct rct_s6_data // SC6[6] uint32_t next_free_tile_element_pointer_index; - rct_sprite sprites[RCT2_MAX_SPRITES]; + RCT2Sprite sprites[RCT2_MAX_SPRITES]; uint16_t sprite_lists_head[6]; uint16_t sprite_lists_count[6]; rct_string_id park_name;