/***************************************************************************** * Copyright (c) 2014 Ted John * OpenRCT2, an open source clone of Roller Coaster Tycoon 2. * * This file is part of OpenRCT2. * * OpenRCT2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . *****************************************************************************/ #ifndef _SCENARIO_H_ #define _SCENARIO_H_ #include "common.h" #include "management/award.h" #include "management/news_item.h" #include "management/research.h" #include "ride/ride.h" #include "object.h" #include "platform/platform.h" #include "world/banner.h" #include "world/map.h" #include "world/sprite.h" /** * SV6/SC6 header chunk * size: 0x20 */ typedef struct { uint16 type; // 0x00 uint16 num_packed_objects; // 0x02 uint32 version; // 0x04 uint32 magic_number; // 0x08 uint8 pad_0C[0x14]; } rct_s6_header; /** * SC6 information chunk * size: 0x198 */ typedef struct { uint8 editor_step; uint8 category; // 0x01 uint8 objective_type; // 0x02 uint8 objective_arg_1; // 0x03 sint32 objective_arg_2; // 0x04 sint16 objective_arg_3; // 0x08 uint8 pad_00A[0x3E]; char name[64]; // 0x48 char details[256]; // 0x88 rct_object_entry entry; // 0x188 } rct_s6_info; /* * Scenario scores file header. * size: 0x10 */ typedef struct { uint32 var_0; uint32 var_4; uint32 var_8; uint32 scenario_count; // 0x0C } rct_scenario_scores_header; /** * Scenario basic structure, mainly for scenario select * size: 0x02B0 */ typedef struct { char path[256]; // 0x0000 uint8 category; // 0x0100 uint8 pad_0101[0x1F]; sint8 objective_type; // 0x0120 sint8 objective_arg_1; // 0x0121 sint32 objective_arg_2; // 0x0122 sint16 objective_arg_3; // 0x0126 char name[64]; // 0x0128 char details[256]; // 0x0168 sint32 flags; // 0x0268 uint32 company_value; // 0x026C char completed_by[64]; // 0x0270 } rct_scenario_basic; typedef struct { rct_string_id scenario_name; // 0x00 rct_string_id park_name; // 0x02 rct_string_id details; // 0x04 uint8 var_06; } rct_stex_entry; #define g_stexEntries ((rct_stex_entry**)object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].chunks) // This will be useful for backwards compatibility typedef struct { // SC6[0] rct_s6_header header; // SC6[1] rct_s6_info info; // SC6[2] // packed objects // SC6[3] rct_object_entry objects[721]; // SC6[4] uint16 elapsed_months; uint16 current_day; uint32 dword_F663AC; uint32 scenario_srand_0; uint32 scenario_srand_1; // SC6[5] rct_map_element map_elements[0x30000]; // SC6[6] uint32 dword_010E63B8; rct_sprite sprites[10000]; uint16 sprites_next_index; uint16 sprites_start_vehicle; uint16 sprites_start_peep; uint16 sprites_start_textfx; uint16 sprites_start_litter; uint8 pad_013573C6[2]; uint16 word_013573C8; uint16 sprites_count_vehicle; uint16 sprites_count_peep; uint16 sprites_count_misc; uint16 sprites_count_litter; uint8 pad_013573D2[2]; rct_string_id park_name; uint8 pad_013573D6[2]; uint32 park_name_args; money32 initial_cash; money32 current_loan; uint32 park_flags; money16 park_entrance_fee; uint16 word_013573EA; uint16 word_013573EC; uint8 pad_013573EE[2]; uint8 byte_013573F0; uint8 pad_013573F1; rct2_peep_spawn peep_spawns[2]; uint8 guest_count_change_modifier; uint8 current_research_level; uint8 pad_01357400[4]; uint32 dword_01357404; uint32 dword_01357408; uint32 dword_0135740C; uint32 dword_01357410[5]; uint32 dword_01357424[8]; uint32 dword_01357444[128]; uint32 dword_01357644[128]; // SC6[7] uint16 guests_in_park; uint16 guests_heading_for_park; // Ignored in scenario money32 expenditure_table[14]; uint32 dword_01357880[5]; uint32 dword_01357894; uint32 dword_01357898; uint32 dword_0135789C; uint32 dword_013578A0; uint32 dword_013578A4[201]; // SC6[8] uint16 last_guests_in_park; uint8 pad_01357BCA[3]; uint8 handyman_colour; uint8 mechanic_colour; uint8 security_colour; // Ignored in scenario uint32 dword_01357BD0[56]; // SC6[9] uint16 park_rating; // Ignored in scenario uint8 park_rating_history[32]; uint8 guests_in_park_history[32]; // SC6[10] uint8 active_research_types; uint8 research_progress_stage; uint32 dword_01357CF4; uint8 byte_01357CF8[1000]; uint32 next_research_item; uint16 research_progress; uint8 next_research_category; uint8 next_research_expected_day; uint8 next_research_expected_month; uint8 guest_initial_happiness; uint16 park_size; uint16 guest_generation_probability; uint16 total_ride_value; money32 maximum_loan; money16 guest_initial_cash; uint8 guest_initial_hunger; uint8 guest_initial_thirst; uint8 objective_type; uint8 objective_year; uint8 pad_013580FA[2]; money32 objective_currency; uint16 objective_guests; uint8 campaign_weeks_left[20]; uint8 campaign_ride_index[22]; // Ignored in scenario money32 balance_history[128]; // SC6[11] money32 current_expenditure; money32 current_profit; uint32 dword_01358334; uint16 word_01358338; uint8 pad_0135833A[2]; // Ignored in scenario money32 weekly_profit_history[128]; // SC6[12] money32 park_value; // Ignored in scenario money32 park_value_history[128]; // SC6[13] money32 completed_company_value; uint32 total_admissions; money32 income_from_admissions; money32 company_value; uint8 byte_01358750[16]; rct_award awards[4]; money16 land_price; money16 construction_rights_price; uint16 word_01358774; uint8 pad_01358776[2]; uint32 dword_01358778[17]; uint32 dword_013587BC; uint32 dword_013587C0; uint32 dword_013587C4; uint16 dword_013587C8; uint8 pad_013587CA[6]; uint32 dword_013587D0; uint8 pad_013587D4[4]; char scenario_completed_name[32]; money32 cash; uint8 pad_013587FC[50]; uint16 word_0135882E; uint16 map_size_units; uint16 map_size_minus_2; uint16 map_size; uint16 map_max_xy; uint32 word_01358838; uint16 suggested_max_guests; uint16 park_rating_warning_days; uint8 word_01358840; uint8 rct1_water_colour; uint8 pad_01358842[2]; rct_research_item research_items[500]; uint16 word_01359208; char scenario_name[64]; char scenario_description[255]; uint8 byte_01359349; uint8 current_interest_rate; uint8 pad_0135934B; uint32 dword_0135934C; uint16 park_entrance_x[4]; uint16 park_entrance_y[4]; uint16 park_entrance_z[4]; uint8 park_entrance_direction[4]; char scenario_filename[256]; uint8 saved_expansion_pack_names[3256]; rct_banner banners[250]; char custom_strings[0x8000]; uint32 game_ticks_1; rct_ride rides[255]; uint16 word_01388698; uint16 saved_view_x; uint16 saved_view_y; uint16 saved_view_zoom_and_rotation; uint8 map_animations[6000]; uint8 byte_01389E10[6000]; uint16 num_map_animations; uint8 pad_0138B582[2]; uint16 word_0138B584; uint16 word_0138B586; uint16 word_0138B588; uint16 word_0138B58A; uint16 word_0138B58C; uint16 word_0138B58E; uint8 ride_ratings_current_ride; uint8 ride_ratings_state; uint8 byte_0138B592; uint8 byte_0138B593; uint16 word_0138B594; uint16 word_0138B596; uint16 word_0138B598; uint16 word_0138B59A; uint16 word_0138B59C; uint16 word_0138B59E; uint16 word_0138B5A0; uint16 word_0138B5A2; uint16 word_0138B5A4; uint16 word_0138B5A6; uint16 word_0138B5A8; uint16 word_0138B5AA; uint16 word_0138B5AC; uint16 word_0138B5AE; uint16 word_0138B5B0; uint16 word_0138B5B2; uint16 word_0138B5B4; uint16 word_0138B5B6; uint16 word_0138B5B8; uint16 word_0138B5BA; uint16 word_0138B5BC; uint16 word_0138B5BE; uint16 word_0138B5C0; uint16 word_0138B5C2; uint16 word_0138B5C4; uint16 word_0138B5C6; uint16 word_0138B5C8; uint16 word_0138B5CA; uint16 word_0138B5CC; uint16 word_0138B5CE[31]; uint8 ride_measurements[0x25860]; uint32 next_guest_index; uint16 grass_and_scenery_tilepos; uint32 patrol_areas[0x6600]; // 512 bytes per staff peep uint8 byte_13CA672[116]; uint8 byte_13CA6E6[84]; uint8 byte_13CA73A[4]; uint8 unk_13CA73E; uint8 pad_13CA73F; uint8 byte_13CA740; uint8 byte_13CA741; uint8 byte_13CA742[4]; uint8 climate; uint8 pad_013CA747; uint16 climate_update_timer; uint8 current_weather; uint8 next_weather; uint8 temperature; uint8 next_temperature; uint8 current_weather_effect; uint8 next_weather_effect; uint8 current_weather_gloom; uint8 next_weather_gloom; uint8 current_rain_level; uint8 next_rain_level; rct_news_item news_items[61]; uint8 byte_13CE730[64]; uint32 dword_13CE770; uint16 word_13CE774; uint16 word_13CE776; uint8 pad_13CE778[434]; } rct_s6_data; enum { SCENARIO_FLAGS_VISIBLE = (1 << 0), SCENARIO_FLAGS_COMPLETED = (1 << 1), SCENARIO_FLAGS_SIXFLAGS = (1 << 2) }; enum { S6_TYPE_SAVEDGAME, S6_TYPE_SCENARIO }; #define S6_RCT2_VERSION 120001 #define S6_MAGIC_NUMBER 0x00031144 enum { SCENARIO_CATEGORY_BEGINNER, SCENARIO_CATEGORY_CHALLENGING, SCENARIO_CATEGORY_EXPERT, SCENARIO_CATEGORY_REAL, SCENARIO_CATEGORY_BUILDYOUROWN }; enum { OBJECTIVE_NONE, OBJECTIVE_GUESTS_BY, OBJECTIVE_PARK_VALUE_BY, OBJECTIVE_HAVE_FUN, OBJECTIVE_BUILD_THE_BEST, OBJECTIVE_10_ROLLERCOASTERS, OBJECTIVE_GUESTS_AND_RATING, OBJECTIVE_MONTHLY_RIDE_INCOME, OBJECTIVE_10_ROLLERCOASTERS_LENGTH, OBJECTIVE_FINISH_5_ROLLERCOASTERS, OBJECTIVE_REPLAY_LOAN_AND_PARK_VALUE, OBJECTIVE_MONTHLY_FOOD_INCOME }; // Scenario list extern int gScenarioListCount; extern int gScenarioListCapacity; extern rct_scenario_basic *gScenarioList; extern char gScenarioSavePath[MAX_PATH]; extern int gFirstTimeSave; int scenario_scores_save(); void scenario_load_list(); rct_scenario_basic *get_scenario_by_filename(const char *filename); int scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *info); int scenario_load(const char *path); int scenario_load_and_play(const rct_scenario_basic *scenario); int scenario_load_and_play_from_path(const char *path); void scenario_begin(); void scenario_update(); unsigned int scenario_rand(); unsigned int scenario_rand_max(unsigned int max); int scenario_prepare_for_save(); int scenario_save(SDL_RWops* rw, int flags); int scenario_save_network(SDL_RWops* rw); bool scenario_save_s6(SDL_RWops* rw, rct_s6_data *s6); void scenario_set_filename(const char *value); void scenario_failure(); void scenario_success(); void scenario_success_submit_name(const char *name); void scenario_autosave_check(); #endif