mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #15285 from duncanspumpkin/rct2
Move RCT2 structs into RCT2 header
This commit is contained in:
commit
1730673ca3
|
@ -15,6 +15,7 @@
|
|||
#include "../rct12/RCT12.h"
|
||||
#include "../ride/RideRatings.h"
|
||||
#include "../ride/VehicleColour.h"
|
||||
#include "../world/EntityList.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -37,6 +38,8 @@ constexpr const uint8_t RCT2_MAX_RESEARCHED_RIDE_ENTRY_QUADS = 8; // With 32 bit
|
|||
constexpr const uint8_t RCT2_MAX_RESEARCHED_SCENERY_ITEM_QUADS = 56;
|
||||
constexpr const uint16_t RCT2_MAX_RESEARCHED_SCENERY_ITEMS = (RCT2_MAX_RESEARCHED_SCENERY_ITEM_QUADS * 32); // There are 32 bits
|
||||
// per quad.
|
||||
constexpr const uint16_t RCT2_MAX_RESEARCH_ITEMS = 500;
|
||||
|
||||
constexpr uint16_t TD6MaxTrackElements = 8192;
|
||||
|
||||
constexpr const uint8_t RCT2_MAX_SMALL_SCENERY_OBJECTS = 252;
|
||||
|
@ -786,6 +789,263 @@ struct RCT2RideRatingCalculationData
|
|||
};
|
||||
assert_struct_size(RCT2RideRatingCalculationData, 76);
|
||||
|
||||
/**
|
||||
* SV6/SC6 header chunk
|
||||
* size: 0x20
|
||||
*/
|
||||
struct rct_s6_header
|
||||
{
|
||||
uint8_t type; // 0x00
|
||||
uint8_t classic_flag; // 0x01
|
||||
uint16_t num_packed_objects; // 0x02
|
||||
uint32_t version; // 0x04
|
||||
uint32_t magic_number; // 0x08
|
||||
uint8_t pad_0C[0x14];
|
||||
};
|
||||
assert_struct_size(rct_s6_header, 0x20);
|
||||
|
||||
enum class EditorStep : uint8_t;
|
||||
|
||||
/**
|
||||
* SC6 information chunk
|
||||
* size: 0x198
|
||||
*/
|
||||
struct rct_s6_info
|
||||
{
|
||||
EditorStep editor_step;
|
||||
uint8_t category; // 0x01
|
||||
uint8_t objective_type; // 0x02
|
||||
uint8_t objective_arg_1; // 0x03
|
||||
int32_t objective_arg_2; // 0x04
|
||||
int16_t objective_arg_3; // 0x08
|
||||
uint8_t pad_00A[0x3E];
|
||||
char name[64]; // 0x48
|
||||
char details[256]; // 0x88
|
||||
rct_object_entry entry; // 0x188
|
||||
};
|
||||
assert_struct_size(rct_s6_info, 0x198);
|
||||
|
||||
struct rct_s6_data
|
||||
{
|
||||
// SC6[0]
|
||||
rct_s6_header header;
|
||||
|
||||
// SC6[1]
|
||||
rct_s6_info info;
|
||||
|
||||
// SC6[2]
|
||||
// packed objects
|
||||
|
||||
// SC6[3]
|
||||
rct_object_entry objects[RCT2_OBJECT_ENTRY_COUNT];
|
||||
|
||||
// SC6[4]
|
||||
uint16_t elapsed_months;
|
||||
uint16_t current_day;
|
||||
uint32_t scenario_ticks;
|
||||
uint32_t scenario_srand_0;
|
||||
uint32_t scenario_srand_1;
|
||||
|
||||
// SC6[5]
|
||||
RCT12TileElement tile_elements[RCT2_MAX_TILE_ELEMENTS];
|
||||
|
||||
// SC6[6]
|
||||
uint32_t next_free_tile_element_pointer_index;
|
||||
RCT2Sprite sprites[RCT2_MAX_SPRITES];
|
||||
uint16_t sprite_lists_head[static_cast<uint8_t>(EntityListId::Count)];
|
||||
uint16_t sprite_lists_count[static_cast<uint8_t>(EntityListId::Count)];
|
||||
rct_string_id park_name;
|
||||
uint8_t pad_013573D6[2];
|
||||
uint32_t park_name_args;
|
||||
money32 initial_cash;
|
||||
money32 current_loan;
|
||||
uint32_t park_flags;
|
||||
money16 park_entrance_fee;
|
||||
uint16_t rct1_park_entrance_x;
|
||||
uint16_t rct1_park_entrance_y;
|
||||
uint8_t pad_013573EE[2];
|
||||
uint8_t rct1_park_entrance_z;
|
||||
uint8_t pad_013573F1;
|
||||
rct12_peep_spawn peep_spawns[RCT12_MAX_PEEP_SPAWNS];
|
||||
uint8_t guest_count_change_modifier;
|
||||
uint8_t current_research_level;
|
||||
uint8_t pad_01357400[4];
|
||||
uint32_t researched_ride_types[RCT2_MAX_RESEARCHED_RIDE_TYPE_QUADS];
|
||||
uint32_t researched_ride_entries[RCT2_MAX_RESEARCHED_RIDE_ENTRY_QUADS];
|
||||
uint32_t researched_track_types_a[128];
|
||||
uint32_t researched_track_types_b[128];
|
||||
|
||||
// SC6[7]
|
||||
uint16_t guests_in_park;
|
||||
uint16_t guests_heading_for_park;
|
||||
|
||||
// Ignored in scenario
|
||||
money32 expenditure_table[RCT12_EXPENDITURE_TABLE_MONTH_COUNT][RCT12_EXPENDITURE_TYPE_COUNT];
|
||||
|
||||
// SC6[8]
|
||||
uint16_t last_guests_in_park;
|
||||
uint8_t pad_01357BCA[3];
|
||||
uint8_t handyman_colour;
|
||||
uint8_t mechanic_colour;
|
||||
uint8_t security_colour;
|
||||
|
||||
// Ignored in scenario
|
||||
uint32_t researched_scenery_items[RCT2_MAX_RESEARCHED_SCENERY_ITEM_QUADS];
|
||||
|
||||
// SC6[9]
|
||||
uint16_t park_rating;
|
||||
|
||||
// Ignored in scenario
|
||||
uint8_t park_rating_history[32];
|
||||
uint8_t guests_in_park_history[32];
|
||||
|
||||
// SC6[10]
|
||||
uint8_t active_research_types;
|
||||
uint8_t research_progress_stage;
|
||||
uint32_t last_researched_item_subject;
|
||||
uint8_t pad_01357CF8[1000];
|
||||
uint32_t next_research_item;
|
||||
uint16_t research_progress;
|
||||
uint8_t next_research_category;
|
||||
uint8_t next_research_expected_day;
|
||||
uint8_t next_research_expected_month;
|
||||
uint8_t guest_initial_happiness;
|
||||
uint16_t park_size;
|
||||
uint16_t guest_generation_probability;
|
||||
uint16_t total_ride_value_for_money;
|
||||
money32 maximum_loan;
|
||||
money16 guest_initial_cash;
|
||||
uint8_t guest_initial_hunger;
|
||||
uint8_t guest_initial_thirst;
|
||||
uint8_t objective_type;
|
||||
uint8_t objective_year;
|
||||
uint8_t pad_013580FA[2];
|
||||
money32 objective_currency;
|
||||
uint16_t objective_guests;
|
||||
uint8_t campaign_weeks_left[20];
|
||||
uint8_t campaign_ride_index[22];
|
||||
|
||||
// Ignored in scenario
|
||||
money32 balance_history[RCT12_FINANCE_GRAPH_SIZE];
|
||||
|
||||
// SC6[11]
|
||||
money32 current_expenditure;
|
||||
money32 current_profit;
|
||||
money32 weekly_profit_average_dividend;
|
||||
uint16_t weekly_profit_average_divisor;
|
||||
uint8_t pad_0135833A[2];
|
||||
|
||||
// Ignored in scenario
|
||||
money32 weekly_profit_history[RCT12_FINANCE_GRAPH_SIZE];
|
||||
|
||||
// SC6[12]
|
||||
money32 park_value;
|
||||
|
||||
// Ignored in scenario
|
||||
money32 park_value_history[RCT12_FINANCE_GRAPH_SIZE];
|
||||
|
||||
// SC6[13]
|
||||
money32 completed_company_value;
|
||||
uint32_t total_admissions;
|
||||
money32 income_from_admissions;
|
||||
money32 company_value;
|
||||
uint8_t peep_warning_throttle[16];
|
||||
rct12_award awards[RCT12_MAX_AWARDS];
|
||||
money16 land_price;
|
||||
money16 construction_rights_price;
|
||||
uint16_t word_01358774;
|
||||
uint8_t pad_01358776[2];
|
||||
uint32_t cd_key;
|
||||
uint8_t pad_0135877C[64];
|
||||
uint32_t game_version_number;
|
||||
money32 completed_company_value_record;
|
||||
uint32_t loan_hash;
|
||||
uint16_t ride_count;
|
||||
uint8_t pad_013587CA[6];
|
||||
money32 historical_profit;
|
||||
uint8_t pad_013587D4[4];
|
||||
char scenario_completed_name[32];
|
||||
money32 cash;
|
||||
uint8_t pad_013587FC[50];
|
||||
uint16_t park_rating_casualty_penalty;
|
||||
uint16_t map_size_units;
|
||||
uint16_t map_size_minus_2;
|
||||
uint16_t map_size;
|
||||
uint16_t map_max_xy;
|
||||
uint32_t same_price_throughout;
|
||||
uint16_t suggested_max_guests;
|
||||
uint16_t park_rating_warning_days;
|
||||
uint8_t last_entrance_style;
|
||||
uint8_t rct1_water_colour;
|
||||
uint8_t pad_01358842[2];
|
||||
RCT12ResearchItem research_items[RCT2_MAX_RESEARCH_ITEMS];
|
||||
uint16_t map_base_z;
|
||||
char scenario_name[64];
|
||||
char scenario_description[256];
|
||||
uint8_t current_interest_rate;
|
||||
uint8_t pad_0135934B;
|
||||
uint32_t same_price_throughout_extended;
|
||||
int16_t park_entrance_x[RCT12_MAX_PARK_ENTRANCES];
|
||||
int16_t park_entrance_y[RCT12_MAX_PARK_ENTRANCES];
|
||||
int16_t park_entrance_z[RCT12_MAX_PARK_ENTRANCES];
|
||||
uint8_t park_entrance_direction[RCT12_MAX_PARK_ENTRANCES];
|
||||
char scenario_filename[256];
|
||||
uint8_t saved_expansion_pack_names[3256];
|
||||
RCT12Banner banners[RCT2_MAX_BANNERS_IN_PARK];
|
||||
char custom_strings[RCT12_MAX_USER_STRINGS][RCT12_USER_STRING_MAX_LENGTH];
|
||||
uint32_t game_ticks_1;
|
||||
rct2_ride rides[RCT12_MAX_RIDES_IN_PARK];
|
||||
uint16_t saved_age;
|
||||
int16_t saved_view_x;
|
||||
int16_t saved_view_y;
|
||||
uint8_t saved_view_zoom;
|
||||
uint8_t saved_view_rotation;
|
||||
RCT12MapAnimation map_animations[RCT2_MAX_ANIMATED_OBJECTS];
|
||||
uint16_t num_map_animations;
|
||||
uint8_t pad_0138B582[2];
|
||||
RCT2RideRatingCalculationData ride_ratings_calc_data;
|
||||
uint8_t pad_0138B5D0[60];
|
||||
RCT12RideMeasurement ride_measurements[8];
|
||||
uint32_t next_guest_index;
|
||||
uint16_t grass_and_scenery_tilepos;
|
||||
uint32_t patrol_areas[(RCT2_MAX_STAFF + RCT12_STAFF_TYPE_COUNT) * RCT12_PATROL_AREA_SIZE];
|
||||
uint8_t staff_modes[RCT2_MAX_STAFF + RCT12_STAFF_TYPE_COUNT];
|
||||
uint8_t pad_13CA73E;
|
||||
uint8_t pad_13CA73F;
|
||||
uint8_t byte_13CA740;
|
||||
uint8_t pad_13CA741;
|
||||
uint8_t byte_13CA742[4]; // unused
|
||||
uint8_t climate;
|
||||
uint8_t pad_013CA747;
|
||||
uint16_t climate_update_timer;
|
||||
uint8_t current_weather;
|
||||
uint8_t next_weather;
|
||||
uint8_t temperature;
|
||||
uint8_t next_temperature;
|
||||
uint8_t current_weather_effect;
|
||||
uint8_t next_weather_effect;
|
||||
uint8_t current_weather_gloom;
|
||||
uint8_t next_weather_gloom;
|
||||
uint8_t current_weather_level;
|
||||
uint8_t next_weather_level;
|
||||
rct12_news_item news_items[RCT12_MAX_NEWS_ITEMS];
|
||||
char rct1_scenario_name[62]; // Unused in RCT2
|
||||
uint16_t rct1_scenario_slot_index; // Unused in RCT2
|
||||
uint32_t rct1_scenario_flags; // Unused in RCT2
|
||||
uint16_t wide_path_tile_loop_x;
|
||||
uint16_t wide_path_tile_loop_y;
|
||||
uint8_t pad_13CE778[434];
|
||||
};
|
||||
assert_struct_size(rct_s6_data, 0x46b44a);
|
||||
|
||||
struct rct_stex_entry
|
||||
{
|
||||
rct_string_id scenario_name; // 0x00
|
||||
rct_string_id park_name; // 0x02
|
||||
rct_string_id details; // 0x04
|
||||
uint8_t var_06;
|
||||
};
|
||||
assert_struct_size(rct_stex_entry, 7);
|
||||
#pragma pack(pop)
|
||||
|
||||
std::vector<uint8_t> DecryptSea(const fs::path& path);
|
||||
|
|
|
@ -159,6 +159,102 @@ void S6Exporter::Save(OpenRCT2::IStream* stream, bool isScenario)
|
|||
stream->WriteValue(checksum);
|
||||
}
|
||||
|
||||
static void ride_all_has_any_track_elements(std::array<bool, RCT12_MAX_RIDES_IN_PARK>& rideIndexArray)
|
||||
{
|
||||
tile_element_iterator it;
|
||||
tile_element_iterator_begin(&it);
|
||||
while (tile_element_iterator_next(&it))
|
||||
{
|
||||
if (it.element->GetType() != TILE_ELEMENT_TYPE_TRACK)
|
||||
continue;
|
||||
if (it.element->IsGhost())
|
||||
continue;
|
||||
|
||||
rideIndexArray[it.element->AsTrack()->GetRideIndex()] = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void scenario_remove_trackless_rides(rct_s6_data* s6)
|
||||
{
|
||||
std::array<bool, RCT12_MAX_RIDES_IN_PARK> rideHasTrack{};
|
||||
ride_all_has_any_track_elements(rideHasTrack);
|
||||
for (int32_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++)
|
||||
{
|
||||
auto ride = &s6->rides[i];
|
||||
if (rideHasTrack[i] || ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ride->type = RIDE_TYPE_NULL;
|
||||
if (is_user_string_id(ride->name))
|
||||
{
|
||||
s6->custom_strings[(ride->name % RCT12_MAX_USER_STRINGS)][0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the given S6 data so that ghost elements, rides with no track elements or unused banners / user strings are saved.
|
||||
*/
|
||||
static void scenario_fix_ghosts(rct_s6_data* s6)
|
||||
{
|
||||
// Build tile pointer cache (needed to get the first element at a certain location)
|
||||
RCT12TileElement* tilePointers[MAX_TILE_TILE_ELEMENT_POINTERS];
|
||||
for (size_t i = 0; i < MAX_TILE_TILE_ELEMENT_POINTERS; i++)
|
||||
{
|
||||
tilePointers[i] = TILE_UNDEFINED_TILE_ELEMENT;
|
||||
}
|
||||
|
||||
RCT12TileElement* tileElement = s6->tile_elements;
|
||||
RCT12TileElement** tile = tilePointers;
|
||||
for (size_t y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
|
||||
{
|
||||
for (size_t x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
|
||||
{
|
||||
*tile++ = tileElement;
|
||||
while (!(tileElement++)->IsLastForTile())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all ghost elements
|
||||
RCT12TileElement* destinationElement = s6->tile_elements;
|
||||
|
||||
for (int32_t y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
|
||||
{
|
||||
// This is the equivalent of map_get_first_element_at(x, y), but on S6 data.
|
||||
RCT12TileElement* originalElement = tilePointers[x + y * MAXIMUM_MAP_SIZE_TECHNICAL];
|
||||
do
|
||||
{
|
||||
if (originalElement->IsGhost())
|
||||
{
|
||||
uint8_t bannerIndex = originalElement->GetBannerIndex();
|
||||
if (bannerIndex != RCT12_BANNER_INDEX_NULL)
|
||||
{
|
||||
auto banner = &s6->banners[bannerIndex];
|
||||
if (banner->type != RCT12_OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
banner->type = RCT12_OBJECT_ENTRY_INDEX_NULL;
|
||||
if (is_user_string_id(banner->string_idx))
|
||||
s6->custom_strings[(banner->string_idx % RCT12_MAX_USER_STRINGS)][0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*destinationElement++ = *originalElement;
|
||||
}
|
||||
} while (!(originalElement++)->IsLastForTile());
|
||||
|
||||
// Set last element flag in case the original last element was never added
|
||||
(destinationElement - 1)->flags |= TILE_ELEMENT_FLAG_LAST_TILE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void S6Exporter::Export()
|
||||
{
|
||||
_s6.info = {};
|
||||
|
|
|
@ -598,102 +598,6 @@ bool scenario_prepare_for_save()
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the given S6 data so that ghost elements, rides with no track elements or unused banners / user strings are saved.
|
||||
*/
|
||||
void scenario_fix_ghosts(rct_s6_data* s6)
|
||||
{
|
||||
// Build tile pointer cache (needed to get the first element at a certain location)
|
||||
RCT12TileElement* tilePointers[MAX_TILE_TILE_ELEMENT_POINTERS];
|
||||
for (size_t i = 0; i < MAX_TILE_TILE_ELEMENT_POINTERS; i++)
|
||||
{
|
||||
tilePointers[i] = TILE_UNDEFINED_TILE_ELEMENT;
|
||||
}
|
||||
|
||||
RCT12TileElement* tileElement = s6->tile_elements;
|
||||
RCT12TileElement** tile = tilePointers;
|
||||
for (size_t y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
|
||||
{
|
||||
for (size_t x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
|
||||
{
|
||||
*tile++ = tileElement;
|
||||
while (!(tileElement++)->IsLastForTile())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all ghost elements
|
||||
RCT12TileElement* destinationElement = s6->tile_elements;
|
||||
|
||||
for (int32_t y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++)
|
||||
{
|
||||
for (int32_t x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++)
|
||||
{
|
||||
// This is the equivalent of map_get_first_element_at(x, y), but on S6 data.
|
||||
RCT12TileElement* originalElement = tilePointers[x + y * MAXIMUM_MAP_SIZE_TECHNICAL];
|
||||
do
|
||||
{
|
||||
if (originalElement->IsGhost())
|
||||
{
|
||||
uint8_t bannerIndex = originalElement->GetBannerIndex();
|
||||
if (bannerIndex != RCT12_BANNER_INDEX_NULL)
|
||||
{
|
||||
auto banner = &s6->banners[bannerIndex];
|
||||
if (banner->type != RCT12_OBJECT_ENTRY_INDEX_NULL)
|
||||
{
|
||||
banner->type = RCT12_OBJECT_ENTRY_INDEX_NULL;
|
||||
if (is_user_string_id(banner->string_idx))
|
||||
s6->custom_strings[(banner->string_idx % RCT12_MAX_USER_STRINGS)][0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*destinationElement++ = *originalElement;
|
||||
}
|
||||
} while (!(originalElement++)->IsLastForTile());
|
||||
|
||||
// Set last element flag in case the original last element was never added
|
||||
(destinationElement - 1)->flags |= TILE_ELEMENT_FLAG_LAST_TILE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ride_all_has_any_track_elements(std::array<bool, RCT12_MAX_RIDES_IN_PARK>& rideIndexArray)
|
||||
{
|
||||
tile_element_iterator it;
|
||||
tile_element_iterator_begin(&it);
|
||||
while (tile_element_iterator_next(&it))
|
||||
{
|
||||
if (it.element->GetType() != TILE_ELEMENT_TYPE_TRACK)
|
||||
continue;
|
||||
if (it.element->IsGhost())
|
||||
continue;
|
||||
|
||||
rideIndexArray[it.element->AsTrack()->GetRideIndex()] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void scenario_remove_trackless_rides(rct_s6_data* s6)
|
||||
{
|
||||
std::array<bool, RCT12_MAX_RIDES_IN_PARK> rideHasTrack{};
|
||||
ride_all_has_any_track_elements(rideHasTrack);
|
||||
for (int32_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++)
|
||||
{
|
||||
auto ride = &s6->rides[i];
|
||||
if (rideHasTrack[i] || ride->type == RIDE_TYPE_NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ride->type = RIDE_TYPE_NULL;
|
||||
if (is_user_string_id(ride->name))
|
||||
{
|
||||
s6->custom_strings[(ride->name % RCT12_MAX_USER_STRINGS)][0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectiveStatus Objective::CheckGuestsBy() const
|
||||
{
|
||||
auto parkRating = gParkRating;
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include "../management/Finance.h"
|
||||
#include "../management/Research.h"
|
||||
#include "../object/Object.h"
|
||||
#include "../rct12/RCT12.h"
|
||||
#include "../rct2/RCT2.h"
|
||||
#include "../ride/Ride.h"
|
||||
#include "../ride/RideRatings.h"
|
||||
#include "../world/Banner.h"
|
||||
|
@ -26,281 +24,6 @@
|
|||
|
||||
using random_engine_t = Random::Rct2::Engine;
|
||||
|
||||
enum class EditorStep : uint8_t;
|
||||
|
||||
struct ParkLoadResult;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
/**
|
||||
* SV6/SC6 header chunk
|
||||
* size: 0x20
|
||||
*/
|
||||
struct rct_s6_header
|
||||
{
|
||||
uint8_t type; // 0x00
|
||||
uint8_t classic_flag; // 0x01
|
||||
uint16_t num_packed_objects; // 0x02
|
||||
uint32_t version; // 0x04
|
||||
uint32_t magic_number; // 0x08
|
||||
uint8_t pad_0C[0x14];
|
||||
};
|
||||
assert_struct_size(rct_s6_header, 0x20);
|
||||
|
||||
/**
|
||||
* SC6 information chunk
|
||||
* size: 0x198
|
||||
*/
|
||||
struct rct_s6_info
|
||||
{
|
||||
EditorStep editor_step;
|
||||
uint8_t category; // 0x01
|
||||
uint8_t objective_type; // 0x02
|
||||
uint8_t objective_arg_1; // 0x03
|
||||
int32_t objective_arg_2; // 0x04
|
||||
int16_t objective_arg_3; // 0x08
|
||||
uint8_t pad_00A[0x3E];
|
||||
char name[64]; // 0x48
|
||||
char details[256]; // 0x88
|
||||
rct_object_entry entry; // 0x188
|
||||
};
|
||||
assert_struct_size(rct_s6_info, 0x198);
|
||||
|
||||
enum class ScenarioSource : uint8_t
|
||||
{
|
||||
RCT1,
|
||||
RCT1_AA,
|
||||
RCT1_LL,
|
||||
RCT2,
|
||||
RCT2_WW,
|
||||
RCT2_TT,
|
||||
Real,
|
||||
Other
|
||||
};
|
||||
|
||||
struct rct_stex_entry
|
||||
{
|
||||
rct_string_id scenario_name; // 0x00
|
||||
rct_string_id park_name; // 0x02
|
||||
rct_string_id details; // 0x04
|
||||
uint8_t var_06;
|
||||
};
|
||||
assert_struct_size(rct_stex_entry, 7);
|
||||
|
||||
// This will be useful for backwards compatibility
|
||||
struct rct_s6_data
|
||||
{
|
||||
// SC6[0]
|
||||
rct_s6_header header;
|
||||
|
||||
// SC6[1]
|
||||
rct_s6_info info;
|
||||
|
||||
// SC6[2]
|
||||
// packed objects
|
||||
|
||||
// SC6[3]
|
||||
rct_object_entry objects[RCT2_OBJECT_ENTRY_COUNT];
|
||||
|
||||
// SC6[4]
|
||||
uint16_t elapsed_months;
|
||||
uint16_t current_day;
|
||||
uint32_t scenario_ticks;
|
||||
uint32_t scenario_srand_0;
|
||||
uint32_t scenario_srand_1;
|
||||
|
||||
// SC6[5]
|
||||
RCT12TileElement tile_elements[RCT2_MAX_TILE_ELEMENTS];
|
||||
|
||||
// SC6[6]
|
||||
uint32_t next_free_tile_element_pointer_index;
|
||||
RCT2Sprite sprites[RCT2_MAX_SPRITES];
|
||||
uint16_t sprite_lists_head[static_cast<uint8_t>(EntityListId::Count)];
|
||||
uint16_t sprite_lists_count[static_cast<uint8_t>(EntityListId::Count)];
|
||||
rct_string_id park_name;
|
||||
uint8_t pad_013573D6[2];
|
||||
uint32_t park_name_args;
|
||||
money32 initial_cash;
|
||||
money32 current_loan;
|
||||
uint32_t park_flags;
|
||||
money16 park_entrance_fee;
|
||||
uint16_t rct1_park_entrance_x;
|
||||
uint16_t rct1_park_entrance_y;
|
||||
uint8_t pad_013573EE[2];
|
||||
uint8_t rct1_park_entrance_z;
|
||||
uint8_t pad_013573F1;
|
||||
rct12_peep_spawn peep_spawns[RCT12_MAX_PEEP_SPAWNS];
|
||||
uint8_t guest_count_change_modifier;
|
||||
uint8_t current_research_level;
|
||||
uint8_t pad_01357400[4];
|
||||
uint32_t researched_ride_types[RCT2_MAX_RESEARCHED_RIDE_TYPE_QUADS];
|
||||
uint32_t researched_ride_entries[RCT2_MAX_RESEARCHED_RIDE_ENTRY_QUADS];
|
||||
uint32_t researched_track_types_a[128];
|
||||
uint32_t researched_track_types_b[128];
|
||||
|
||||
// SC6[7]
|
||||
uint16_t guests_in_park;
|
||||
uint16_t guests_heading_for_park;
|
||||
|
||||
// Ignored in scenario
|
||||
money32 expenditure_table[RCT12_EXPENDITURE_TABLE_MONTH_COUNT][RCT12_EXPENDITURE_TYPE_COUNT];
|
||||
|
||||
// SC6[8]
|
||||
uint16_t last_guests_in_park;
|
||||
uint8_t pad_01357BCA[3];
|
||||
uint8_t handyman_colour;
|
||||
uint8_t mechanic_colour;
|
||||
uint8_t security_colour;
|
||||
|
||||
// Ignored in scenario
|
||||
uint32_t researched_scenery_items[RCT2_MAX_RESEARCHED_SCENERY_ITEM_QUADS];
|
||||
|
||||
// SC6[9]
|
||||
uint16_t park_rating;
|
||||
|
||||
// Ignored in scenario
|
||||
uint8_t park_rating_history[32];
|
||||
uint8_t guests_in_park_history[32];
|
||||
|
||||
// SC6[10]
|
||||
uint8_t active_research_types;
|
||||
uint8_t research_progress_stage;
|
||||
uint32_t last_researched_item_subject;
|
||||
uint8_t pad_01357CF8[1000];
|
||||
uint32_t next_research_item;
|
||||
uint16_t research_progress;
|
||||
uint8_t next_research_category;
|
||||
uint8_t next_research_expected_day;
|
||||
uint8_t next_research_expected_month;
|
||||
uint8_t guest_initial_happiness;
|
||||
uint16_t park_size;
|
||||
uint16_t guest_generation_probability;
|
||||
uint16_t total_ride_value_for_money;
|
||||
money32 maximum_loan;
|
||||
money16 guest_initial_cash;
|
||||
uint8_t guest_initial_hunger;
|
||||
uint8_t guest_initial_thirst;
|
||||
uint8_t objective_type;
|
||||
uint8_t objective_year;
|
||||
uint8_t pad_013580FA[2];
|
||||
money32 objective_currency;
|
||||
uint16_t objective_guests;
|
||||
uint8_t campaign_weeks_left[20];
|
||||
uint8_t campaign_ride_index[22];
|
||||
|
||||
// Ignored in scenario
|
||||
money32 balance_history[RCT12_FINANCE_GRAPH_SIZE];
|
||||
|
||||
// SC6[11]
|
||||
money32 current_expenditure;
|
||||
money32 current_profit;
|
||||
money32 weekly_profit_average_dividend;
|
||||
uint16_t weekly_profit_average_divisor;
|
||||
uint8_t pad_0135833A[2];
|
||||
|
||||
// Ignored in scenario
|
||||
money32 weekly_profit_history[RCT12_FINANCE_GRAPH_SIZE];
|
||||
|
||||
// SC6[12]
|
||||
money32 park_value;
|
||||
|
||||
// Ignored in scenario
|
||||
money32 park_value_history[RCT12_FINANCE_GRAPH_SIZE];
|
||||
|
||||
// SC6[13]
|
||||
money32 completed_company_value;
|
||||
uint32_t total_admissions;
|
||||
money32 income_from_admissions;
|
||||
money32 company_value;
|
||||
uint8_t peep_warning_throttle[16];
|
||||
rct12_award awards[RCT12_MAX_AWARDS];
|
||||
money16 land_price;
|
||||
money16 construction_rights_price;
|
||||
uint16_t word_01358774;
|
||||
uint8_t pad_01358776[2];
|
||||
uint32_t cd_key;
|
||||
uint8_t pad_0135877C[64];
|
||||
uint32_t game_version_number;
|
||||
money32 completed_company_value_record;
|
||||
uint32_t loan_hash;
|
||||
uint16_t ride_count;
|
||||
uint8_t pad_013587CA[6];
|
||||
money32 historical_profit;
|
||||
uint8_t pad_013587D4[4];
|
||||
char scenario_completed_name[32];
|
||||
money32 cash;
|
||||
uint8_t pad_013587FC[50];
|
||||
uint16_t park_rating_casualty_penalty;
|
||||
uint16_t map_size_units;
|
||||
uint16_t map_size_minus_2;
|
||||
uint16_t map_size;
|
||||
uint16_t map_max_xy;
|
||||
uint32_t same_price_throughout;
|
||||
uint16_t suggested_max_guests;
|
||||
uint16_t park_rating_warning_days;
|
||||
uint8_t last_entrance_style;
|
||||
uint8_t rct1_water_colour;
|
||||
uint8_t pad_01358842[2];
|
||||
RCT12ResearchItem research_items[MAX_RESEARCH_ITEMS];
|
||||
uint16_t map_base_z;
|
||||
char scenario_name[64];
|
||||
char scenario_description[256];
|
||||
uint8_t current_interest_rate;
|
||||
uint8_t pad_0135934B;
|
||||
uint32_t same_price_throughout_extended;
|
||||
int16_t park_entrance_x[RCT12_MAX_PARK_ENTRANCES];
|
||||
int16_t park_entrance_y[RCT12_MAX_PARK_ENTRANCES];
|
||||
int16_t park_entrance_z[RCT12_MAX_PARK_ENTRANCES];
|
||||
uint8_t park_entrance_direction[RCT12_MAX_PARK_ENTRANCES];
|
||||
char scenario_filename[256];
|
||||
uint8_t saved_expansion_pack_names[3256];
|
||||
RCT12Banner banners[RCT2_MAX_BANNERS_IN_PARK];
|
||||
char custom_strings[RCT12_MAX_USER_STRINGS][RCT12_USER_STRING_MAX_LENGTH];
|
||||
uint32_t game_ticks_1;
|
||||
rct2_ride rides[RCT12_MAX_RIDES_IN_PARK];
|
||||
uint16_t saved_age;
|
||||
int16_t saved_view_x;
|
||||
int16_t saved_view_y;
|
||||
uint8_t saved_view_zoom;
|
||||
uint8_t saved_view_rotation;
|
||||
RCT12MapAnimation map_animations[RCT2_MAX_ANIMATED_OBJECTS];
|
||||
uint16_t num_map_animations;
|
||||
uint8_t pad_0138B582[2];
|
||||
RCT2RideRatingCalculationData ride_ratings_calc_data;
|
||||
uint8_t pad_0138B5D0[60];
|
||||
RCT12RideMeasurement ride_measurements[8];
|
||||
uint32_t next_guest_index;
|
||||
uint16_t grass_and_scenery_tilepos;
|
||||
uint32_t patrol_areas[(RCT2_MAX_STAFF + RCT12_STAFF_TYPE_COUNT) * RCT12_PATROL_AREA_SIZE];
|
||||
uint8_t staff_modes[RCT2_MAX_STAFF + RCT12_STAFF_TYPE_COUNT];
|
||||
uint8_t pad_13CA73E;
|
||||
uint8_t pad_13CA73F;
|
||||
uint8_t byte_13CA740;
|
||||
uint8_t pad_13CA741;
|
||||
uint8_t byte_13CA742[4]; // unused
|
||||
uint8_t climate;
|
||||
uint8_t pad_013CA747;
|
||||
uint16_t climate_update_timer;
|
||||
uint8_t current_weather;
|
||||
uint8_t next_weather;
|
||||
uint8_t temperature;
|
||||
uint8_t next_temperature;
|
||||
uint8_t current_weather_effect;
|
||||
uint8_t next_weather_effect;
|
||||
uint8_t current_weather_gloom;
|
||||
uint8_t next_weather_gloom;
|
||||
uint8_t current_weather_level;
|
||||
uint8_t next_weather_level;
|
||||
rct12_news_item news_items[RCT12_MAX_NEWS_ITEMS];
|
||||
char rct1_scenario_name[62]; // Unused in RCT2
|
||||
uint16_t rct1_scenario_slot_index; // Unused in RCT2
|
||||
uint32_t rct1_scenario_flags; // Unused in RCT2
|
||||
uint16_t wide_path_tile_loop_x;
|
||||
uint16_t wide_path_tile_loop_y;
|
||||
uint8_t pad_13CE778[434];
|
||||
};
|
||||
assert_struct_size(rct_s6_data, 0x46b44a);
|
||||
#pragma pack(pop)
|
||||
|
||||
enum
|
||||
{
|
||||
SCENARIO_FLAGS_VISIBLE = (1 << 0),
|
||||
|
@ -460,8 +183,6 @@ uint32_t scenario_rand_max(uint32_t max);
|
|||
|
||||
bool scenario_prepare_for_save();
|
||||
int32_t scenario_save(const utf8* path, int32_t flags);
|
||||
void scenario_remove_trackless_rides(rct_s6_data* s6);
|
||||
void scenario_fix_ghosts(rct_s6_data* s6);
|
||||
void scenario_failure();
|
||||
void scenario_success();
|
||||
void scenario_success_submit_name(const char* name);
|
||||
|
|
|
@ -24,6 +24,18 @@ struct scenario_highscore_entry
|
|||
datetime64 timestamp;
|
||||
};
|
||||
|
||||
enum class ScenarioSource : uint8_t
|
||||
{
|
||||
RCT1,
|
||||
RCT1_AA,
|
||||
RCT1_LL,
|
||||
RCT2,
|
||||
RCT2_WW,
|
||||
RCT2_TT,
|
||||
Real,
|
||||
Other
|
||||
};
|
||||
|
||||
struct scenario_index_entry
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../core/Guard.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "Scenario.h"
|
||||
#include "ScenarioRepository.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
|
|
Loading…
Reference in New Issue