OpenRCT2/src/scenario.h

587 lines
14 KiB
C
Raw Normal View History

#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
2014-04-06 18:45:09 +02:00
/*****************************************************************************
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
2014-04-06 18:45:09 +02:00
*
* 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.
*
* A full copy of the GNU General Public License can be found in licence.txt
2014-04-06 18:45:09 +02:00
*****************************************************************************/
#pragma endregion
2014-04-06 18:45:09 +02:00
#ifndef _SCENARIO_H_
#define _SCENARIO_H_
#include "common.h"
#include "management/award.h"
#include "management/finance.h"
#include "management/news_item.h"
#include "management/research.h"
#include "ride/ride.h"
2014-05-24 23:14:42 +02:00
#include "object.h"
#include "platform/platform.h"
#include "world/banner.h"
#include "world/map.h"
#include "world/map_animation.h"
#include "world/sprite.h"
2014-04-06 18:45:09 +02:00
2014-04-10 04:23:12 +02:00
/**
* 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;
2014-04-10 04:23:12 +02:00
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
2014-05-24 23:14:42 +02:00
rct_object_entry entry; // 0x188
2014-04-10 04:23:12 +02:00
} rct_s6_info;
/**
2014-05-24 00:52:13 +02:00
* 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;
2014-04-10 04:23:12 +02:00
typedef enum {
SCENARIO_SOURCE_RCT1,
SCENARIO_SOURCE_RCT1_AA,
SCENARIO_SOURCE_RCT1_LL,
SCENARIO_SOURCE_RCT2,
SCENARIO_SOURCE_RCT2_WW,
SCENARIO_SOURCE_RCT2_TT,
SCENARIO_SOURCE_REAL,
SCENARIO_SOURCE_OTHER
} scenario_source;
2014-04-06 18:45:09 +02:00
/**
* Scenario basic structure, mainly for scenario select
* size: 0x02B0
*/
typedef struct {
char path[256]; // 0x0000
uint8 category; // 0x0100
uint8 pad_0101[0x1F];
2014-04-10 04:23:12 +02:00
sint8 objective_type; // 0x0120
sint8 objective_arg_1; // 0x0121
sint32 objective_arg_2; // 0x0122
sint16 objective_arg_3; // 0x0126
2014-04-06 18:45:09 +02:00
char name[64]; // 0x0128
char details[256]; // 0x0168
2014-04-10 04:23:12 +02:00
sint32 flags; // 0x0268
uint32 company_value; // 0x026C
char completed_by[64]; // 0x0270
// uint8 source_game; // new in OpenRCT2
// sint16 source_index; // new in OpenRCT2
2014-04-06 18:45:09 +02:00
} rct_scenario_basic;
typedef struct {
2015-03-07 10:44:34 +01:00
rct_string_id scenario_name; // 0x00
rct_string_id park_name; // 0x02
rct_string_id details; // 0x04
uint8 var_06;
} rct_stex_entry;
2015-03-07 10:44:34 +01:00
#define g_stexEntries ((rct_stex_entry**)object_entry_groups[OBJECT_TYPE_SCENARIO_TEXT].chunks)
// This will be useful for backwards compatibility
2014-05-28 01:05:11 +02:00
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 scenario_ticks;
2014-05-28 01:05:11 +02:00
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];
2016-05-09 01:08:03 +02:00
uint16 sprite_lists_head[6];
uint16 sprite_lists_count[6];
rct_string_id park_name;
uint8 pad_013573D6[2];
uint32 park_name_args;
money32 initial_cash;
2014-05-28 01:05:11 +02:00
money32 current_loan;
uint32 park_flags;
money16 park_entrance_fee;
uint16 rct1_park_entrance_x;
uint16 rct1_park_entrance_y;
uint8 pad_013573EE[2];
uint8 rct1_park_entrance_z;
uint8 pad_013573F1;
2014-05-28 01:05:11 +02:00
rct2_peep_spawn peep_spawns[2];
uint8 guest_count_change_modifier;
uint8 current_research_level;
2014-05-28 01:05:11 +02:00
uint8 pad_01357400[4];
uint32 researched_ride_types[8];
uint32 researched_ride_entries[8];
uint32 researched_track_types_a[128];
uint32 researched_track_types_b[128];
2014-05-28 01:05:11 +02:00
// SC6[7]
uint16 guests_in_park;
uint16 guests_heading_for_park;
// Ignored in scenario
money32 expenditure_table[224];
2015-10-12 22:18:14 +02:00
2014-05-28 01:05:11 +02:00
// SC6[8]
uint16 last_guests_in_park;
uint8 pad_01357BCA[3];
uint8 handyman_colour;
uint8 mechanic_colour;
uint8 security_colour;
// Ignored in scenario
2016-05-11 20:18:59 +02:00
uint32 researched_scenery_items[56];
2014-05-28 01:05:11 +02:00
// SC6[9]
uint16 park_rating;
// Ignored in scenario
uint8 park_rating_history[32];
uint8 guests_in_park_history[32];
// SC6[10]
2014-10-08 00:42:17 +02:00
uint8 active_research_types;
uint8 research_progress_stage;
uint32 last_researched_item_subject;
uint8 pad_01357CF8[1000];
uint32 next_research_item;
2014-10-08 00:42:17 +02:00
uint16 research_progress;
uint8 next_research_category;
uint8 next_research_expected_day;
uint8 next_research_expected_month;
uint8 guest_initial_happiness;
2014-05-28 01:05:11 +02:00
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;
2014-05-28 01:05:11 +02:00
uint8 objective_type;
uint8 objective_year;
uint8 pad_013580FA[2];
2014-05-28 01:05:11 +02:00
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 weekly_profit_average_dividend;
uint16 weekly_profit_average_divisor;
2014-05-28 01:05:11 +02:00
uint8 pad_0135833A[2];
// Ignored in scenario
money32 weekly_profit_history[128];
// SC6[12]
2014-05-28 01:05:11 +02:00
money32 park_value;
// Ignored in scenario
2014-05-28 01:05:11 +02:00
money32 park_value_history[128];
// SC6[13]
2014-05-28 01:05:11 +02:00
money32 completed_company_value;
uint32 total_admissions;
money32 income_from_admissions;
money32 company_value;
2016-05-11 22:15:43 +02:00
uint8 peep_warning_throttle[16];
2014-05-28 01:05:11 +02:00
rct_award awards[4];
money16 land_price;
money16 construction_rights_price;
2014-05-28 01:05:11 +02:00
uint16 word_01358774;
uint8 pad_01358776[2];
2016-05-11 23:30:06 +02:00
uint32 cd_key;
uint8 pad_0135877C[64];
uint32 game_version_number;
2016-05-11 23:30:06 +02:00
money32 completed_company_value_record;
uint32 loan_hash;
uint16 ride_count;
uint8 pad_013587CA[6];
2014-05-28 01:05:11 +02:00
uint32 dword_013587D0;
uint8 pad_013587D4[4];
char scenario_completed_name[32];
2014-05-28 01:05:11 +02:00
money32 cash;
uint8 pad_013587FC[50];
uint16 word_0135882E;
2015-06-13 19:58:58 +02:00
uint16 map_size_units;
uint16 map_size_minus_2;
2014-05-28 01:05:11 +02:00
uint16 map_size;
2015-06-13 19:58:58 +02:00
uint16 map_max_xy;
uint32 same_price_throughout;
2014-05-28 01:05:11 +02:00
uint16 suggested_max_guests;
uint16 park_rating_warning_days;
2016-05-08 19:11:44 +02:00
uint8 last_entrance_style;
uint8 rct1_water_colour;
uint8 pad_01358842[2];
rct_research_item research_items[500];
2014-05-28 01:05:11 +02:00
uint16 word_01359208;
char scenario_name[64];
char scenario_description[256];
uint8 current_interest_rate;
uint8 pad_0135934B;
uint32 same_price_throughout_extended;
2014-05-28 01:05:11 +02:00
uint16 park_entrance_x[4];
uint16 park_entrance_y[4];
uint16 park_entrance_z[4];
uint8 park_entrance_direction[4];
2015-10-12 22:18:14 +02:00
char scenario_filename[256];
uint8 saved_expansion_pack_names[3256];
rct_banner banners[250];
2014-05-28 01:05:11 +02:00
char custom_strings[0x8000];
uint32 game_ticks_1;
rct_ride rides[255];
uint16 saved_age;
2014-05-28 01:05:11 +02:00
uint16 saved_view_x;
uint16 saved_view_y;
uint8 saved_view_zoom;
uint8 saved_view_rotation;
rct_map_animation map_animations[1000];
rct_map_animation rct1_map_animations[1000];
uint16 num_map_animations;
uint8 pad_0138B582[2];
uint16 ride_ratings_proximity_x;
uint16 ride_ratings_proximity_y;
uint16 ride_ratings_proximity_z;
uint16 ride_ratings_proximity_start_x;
uint16 ride_ratings_proximity_start_y;
uint16 ride_ratings_proximity_start_z;
uint8 ride_ratings_current_ride;
uint8 ride_ratings_state;
uint8 ride_ratings_proximity_track_type;
uint8 ride_ratings_proximity_base_height;
uint16 ride_ratings_proximity_total;
uint16 ride_ratings_proximity_scores[26];
uint16 ride_ratings_num_brakes;
uint16 ride_ratings_num_reversers;
uint16 ride_ratings_station_flags;
2016-05-07 23:47:29 +02:00
uint8 pad_0138B5D0[60];
rct_ride_measurement ride_measurements[8];
uint32 next_guest_index;
uint16 grass_and_scenery_tilepos;
2016-05-11 23:30:06 +02:00
uint32 patrol_areas[204 * 128];
uint8 staff_modes[204];
2016-05-11 23:30:06 +02:00
uint8 pad_13CA73E;
uint8 pad_13CA73F;
2014-05-28 01:05:11 +02:00
uint8 byte_13CA740;
uint8 pad_13CA741;
uint8 byte_13CA742[4];
2014-05-28 01:05:11 +02:00
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 pad_13CE730[64];
uint32 rct1_scenario_flags;
uint16 wide_path_tile_loop_x;
uint16 wide_path_tile_loop_y;
uint8 pad_13CE778[434];
2014-05-28 01:05:11 +02:00
} rct_s6_data;
2014-04-10 04:23:12 +02:00
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
2014-04-10 04:23:12 +02:00
enum {
// RCT2 categories (keep order)
2014-04-10 04:23:12 +02:00
SCENARIO_CATEGORY_BEGINNER,
SCENARIO_CATEGORY_CHALLENGING,
SCENARIO_CATEGORY_EXPERT,
SCENARIO_CATEGORY_REAL,
SCENARIO_CATEGORY_OTHER,
// OpenRCT2 categories
SCENARIO_CATEGORY_DLC,
SCENARIO_CATEGORY_BUILD_YOUR_OWN,
SCENARIO_CATEGORY_COUNT
2014-04-10 04:23:12 +02:00
};
2014-04-09 12:16:35 +02:00
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
};
typedef struct {
utf8 *fileName;
utf8 *name;
money32 company_value;
2016-01-03 02:48:52 +01:00
datetime64 timestamp;
} scenario_highscore_entry;
typedef struct {
utf8 path[MAX_PATH];
2015-12-31 22:13:49 +01:00
uint64 timestamp;
// Category / sequence
uint8 category;
uint8 source_game;
sint16 source_index;
uint16 sc_id;
// Objective
uint8 objective_type;
uint8 objective_arg_1;
sint32 objective_arg_2;
sint16 objective_arg_3;
scenario_highscore_entry *highscore;
utf8 name[64];
utf8 details[256];
} scenario_index_entry;
typedef struct {
2016-01-01 17:30:18 +01:00
const utf8 *title;
uint8 id;
uint8 source;
sint32 index;
uint8 category;
} source_desc;
extern const rct_string_id ScenarioCategoryStringIds[SCENARIO_CATEGORY_COUNT];
2016-05-09 00:20:42 +02:00
#define gScenarioTicks RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_TICKS, uint32)
#define gScenarioSrand0 RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_0, uint32)
#define gScenarioSrand1 RCT2_GLOBAL(RCT2_ADDRESS_SCENARIO_SRAND_1, uint32)
#define gScenarioObjectiveType RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8)
#define gScenarioObjectiveYear RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_YEAR, uint8)
#define gScenarioObjectiveNumGuests RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_NUM_GUESTS, uint16)
#define gScenarioObjectiveCurrency RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_CURRENCY, money32)
#define gScenarioParkRatingWarningDays RCT2_GLOBAL(RCT2_ADDRESS_PARK_RATING_WARNING_DAYS, uint16)
#define gScenarioCompletedCompanyValue RCT2_GLOBAL(RCT2_ADDRESS_COMPLETED_COMPANY_VALUE, money32)
2016-05-11 23:30:06 +02:00
#define gScenarioCompanyValueRecord RCT2_GLOBAL(RCT2_ADDRESS_COMPANY_VALUE_RECORD, money32)
2014-05-24 00:52:13 +02:00
// Scenario list
extern int gScenarioListCount;
extern int gScenarioListCapacity;
extern scenario_index_entry *gScenarioList;
2014-05-24 00:52:13 +02:00
extern char *gScenarioName;
extern char *gScenarioDetails;
extern char *gScenarioCompletedBy;
extern char gScenarioSavePath[MAX_PATH];
extern int gFirstTimeSave;
extern uint32 gLastAutoSaveTick;
2016-05-08 02:22:32 +02:00
extern const char *_scenarioFileName;
bool scenario_scores_save();
2014-04-06 18:45:09 +02:00
void scenario_load_list();
void scenario_list_dispose();
scenario_index_entry *scenario_list_find_by_filename(const utf8 *filename);
scenario_index_entry *scenario_list_find_by_path(const utf8 *path);
scenario_highscore_entry *scenario_highscore_insert();
void scenario_highscore_free(scenario_highscore_entry *highscore);
2015-12-31 23:11:36 +01:00
bool 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_from_path(const char *path);
void scenario_begin();
void scenario_update();
2014-11-02 02:41:00 +01:00
unsigned int scenario_rand();
2015-06-14 09:08:28 +02:00
unsigned int scenario_rand_max(unsigned int max);
int scenario_prepare_for_save();
2015-07-05 06:36:25 +02:00
int scenario_save(SDL_RWops* rw, int flags);
2015-07-31 16:14:44 +02:00
int scenario_save_network(SDL_RWops* rw);
2016-05-08 02:22:32 +02:00
int scenario_get_num_packed_objects_to_write();
int scenario_write_packed_objects(SDL_RWops* rw);
2016-05-08 17:02:00 +02:00
void scenario_remove_trackless_rides(rct_s6_data *s6);
2016-05-08 02:22:32 +02:00
void scenario_fix_ghosts(rct_s6_data *s6);
void scenario_set_filename(const char *value);
2015-02-21 03:04:33 +01:00
void scenario_failure();
void scenario_success();
void scenario_success_submit_name(const char *name);
void scenario_autosave_check();
2014-04-06 18:45:09 +02:00
bool scenario_get_source_desc(const utf8 *name, source_desc *outDesc);
2016-01-01 17:30:18 +01:00
bool scenario_get_source_desc_by_id(uint8 id, source_desc *outDesc);
void scenario_normalise_name(utf8 *name);
2016-01-01 17:30:18 +01:00
// RCT1 scenario index map
enum {
SC_UNIDENTIFIED = 255,
// RCT
SC_FOREST_FRONTIERS = 0,
SC_DYNAMITE_DUNES,
SC_LEAFY_LAKES,
SC_DIAMOND_HEIGHTS,
SC_EVERGREEN_GARDENS,
SC_BUMBLY_BEACH,
SC_TRINITY_ISLANDS,
SC_KATIES_DREAMLAND,
SC_POKEY_PARK,
SC_WHITE_WATER_PARK,
SC_MILLENNIUM_MINES,
SC_KARTS_COASTERS,
SC_MELS_WORLD,
SC_MYSTIC_MOUNTAIN,
SC_PACIFIC_PYRAMIDS,
SC_CRUMBLY_WOODS,
SC_PARADISE_PIER,
SC_LIGHTNING_PEAKS,
SC_IVORY_TOWERS,
SC_RAINBOW_VALLEY,
SC_THUNDER_ROCK,
SC_MEGA_PARK,
// Loopy Landscapes
SC_ICEBERG_ISLANDS,
SC_VOLCANIA,
SC_ARID_HEIGHTS,
SC_RAZOR_ROCKS,
SC_CRATER_LAKE,
SC_VERTIGO_VIEWS,
SC_PARADISE_PIER_2,
SC_DRAGONS_COVE,
SC_GOOD_KNIGHT_PARK,
SC_WACKY_WARREN,
// Special
ALTON_TOWERS,
FORT_ANACHRONISM,
// Added Attractions
SC_WHISPERING_CLIFFS = 40,
SC_THREE_MONKEYS_PARK,
SC_CANARY_MINES,
SC_BARONY_BRIDGE,
SC_FUNTOPIA,
SC_HAUNTED_HARBOUR,
2016-01-01 17:30:18 +01:00
SC_FUN_FORTRESS,
SC_FUTURE_WORLD,
SC_GENTLE_GLEN,
SC_JOLLY_JUNGLE,
SC_HYDRO_HILLS,
SC_SPRIGHTLY_PARK,
SC_MAGIC_QUARTERS,
SC_FRUIT_FARM,
SC_BUTTERFLY_DAM,
SC_COASTER_CANYON,
SC_THUNDERSTORM_PARK,
SC_HARMONIC_HILLS,
SC_ROMAN_VILLAGE,
SC_SWAMP_COVE,
SC_ADRENALINE_HEIGHTS,
SC_UTOPIA,
SC_ROTTING_HEIGHTS,
SC_FIASCO_FOREST,
SC_PICKLE_PARK,
SC_GIGGLE_DOWNS,
SC_MINERAL_PARK,
SC_COASTER_CRAZY,
SC_URBAN_PARK,
SC_GEOFFREY_GARDENS,
// Special
SC_HEIDE_PARK,
SC_PCPLAYER,
SC_PCGW,
SC_GAMEPLAY,
SC_BLACKPOOL_PLEASURE_BEACH,
// Loopy Landscapes
SC_GRAND_GLACIER = 80,
SC_CRAZY_CRATERS,
SC_DUSTY_DESERT,
SC_WOODWORM_PARK,
SC_ICARUS_PARK,
SC_SUNNY_SWAMPS,
SC_FRIGHTMARE_HILLS,
SC_THUNDER_ROCKS,
SC_OCTAGON_PARK,
SC_PLEASURE_ISLAND,
SC_ICICLE_WORLDS,
SC_SOUTHERN_SANDS,
SC_TINY_TOWERS,
SC_NEVERMORE_PARK,
SC_PACIFICA,
SC_URBAN_JUNGLE,
SC_TERROR_TOWN,
SC_MEGAWORLD_PARK,
SC_VENUS_PONDS,
SC_MICRO_PARK,
};
#endif