1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 04:23:20 +01:00

Improve saving and playing of .park scenario

This commit is contained in:
Ted John
2021-04-03 17:27:56 +01:00
parent 68cb57fbb0
commit 4b980d6b58
6 changed files with 98 additions and 12 deletions

View File

@@ -112,7 +112,7 @@ rct_window* window_title_menu_open()
static void window_title_menu_scenarioselect_callback(const utf8* path)
{
context_load_park_from_file(path);
OpenRCT2::GetContext()->LoadParkFromFile(path, false, true);
game_load_scripts();
}

View File

@@ -555,7 +555,8 @@ namespace OpenRCT2
_drawingEngine = nullptr;
}
bool LoadParkFromFile(const std::string& path, bool loadTitleScreenOnFail) final override
bool LoadParkFromFile(
const std::string& path, bool loadTitleScreenOnFail = false, bool asScenario = false) final override
{
log_verbose("Context::LoadParkFromFile(%s)", path.c_str());
try
@@ -564,7 +565,7 @@ namespace OpenRCT2
{
auto data = DecryptSea(fs::u8path(path));
auto ms = MemoryStream(data.data(), data.size(), MEMORY_ACCESS::READ);
if (!LoadParkFromStream(&ms, path, loadTitleScreenOnFail))
if (!LoadParkFromStream(&ms, path, loadTitleScreenOnFail, asScenario))
{
throw std::runtime_error(".sea file may have been renamed.");
}
@@ -573,7 +574,7 @@ namespace OpenRCT2
else
{
auto fs = FileStream(path, FILE_MODE_OPEN);
if (!LoadParkFromStream(&fs, path, loadTitleScreenOnFail))
if (!LoadParkFromStream(&fs, path, loadTitleScreenOnFail, asScenario))
{
return false;
}
@@ -593,7 +594,9 @@ namespace OpenRCT2
return false;
}
bool LoadParkFromStream(IStream* stream, const std::string& path, bool loadTitleScreenFirstOnFail) final override
bool LoadParkFromStream(
IStream* stream, const std::string& path, bool loadTitleScreenFirstOnFail = false,
bool asScenario = false) final override
{
try
{
@@ -642,7 +645,7 @@ namespace OpenRCT2
gLastAutoSaveUpdate = AUTOSAVE_PAUSE;
bool sendMap = false;
if (info.Type == FILE_TYPE::PARK || info.Type == FILE_TYPE::SAVED_GAME)
if (!asScenario && (info.Type == FILE_TYPE::PARK || info.Type == FILE_TYPE::SAVED_GAME))
{
if (network_get_mode() == NETWORK_MODE_CLIENT)
{

View File

@@ -137,9 +137,11 @@ namespace OpenRCT2
virtual bool Initialise() abstract;
virtual void InitialiseDrawingEngine() abstract;
virtual void DisposeDrawingEngine() abstract;
virtual bool LoadParkFromFile(const std::string& path, bool loadTitleScreenOnFail = false) abstract;
virtual bool LoadParkFromFile(
const std::string& path, bool loadTitleScreenOnFail = false, bool asScenario = false) abstract;
virtual bool LoadParkFromStream(
IStream* stream, const std::string& path, bool loadTitleScreenFirstOnFail = false) abstract;
IStream* stream, const std::string& path, bool loadTitleScreenFirstOnFail = false,
bool asScenario = false) abstract;
virtual void WriteLine(const std::string& s) abstract;
virtual void WriteErrorLine(const std::string& s) abstract;
virtual void Finish() abstract;

View File

@@ -24,6 +24,7 @@
#include "localisation/Localisation.h"
#include "localisation/LocalisationService.h"
#include "management/NewsItem.h"
#include "object/DefaultObjects.h"
#include "object/ObjectManager.h"
#include "object/ObjectRepository.h"
#include "peep/Staff.h"
@@ -40,7 +41,6 @@
#include "world/Park.h"
#include "world/Scenery.h"
#include "world/Sprite.h"
#include "object/DefaultObjects.h"
#include <algorithm>
#include <array>
@@ -58,6 +58,7 @@ namespace Editor
static bool LoadLandscapeFromSC4(const char* path);
static void FinaliseMainView();
static bool ReadS6(const char* path);
static bool ReadPark(const char* path);
static void ClearMapForEditing(bool fromSave);
static void object_list_load()
@@ -233,6 +234,8 @@ namespace Editor
return LoadLandscapeFromSC4(path);
case FILE_EXTENSION_SV4:
return LoadLandscapeFromSV4(path);
case FILE_EXTENSION_PARK:
return ReadPark(path);
default:
return false;
}
@@ -299,6 +302,32 @@ namespace Editor
return true;
}
static bool ReadPark(const char* path)
{
try
{
auto context = GetContext();
auto& objManager = context->GetObjectManager();
auto importer = ParkImporter::CreateParkFile(context->GetObjectRepository());
auto loadResult = importer->Load(path);
objManager.LoadObjects(loadResult.RequiredObjects);
importer->Import();
ClearMapForEditing(true);
gS6Info.editor_step = EditorStep::LandscapeEditor;
gScreenAge = 0;
gScreenFlags = SCREEN_FLAGS_SCENARIO_EDITOR;
viewport_init_all();
context_open_window_view(WV_EDITOR_MAIN);
FinaliseMainView();
return true;
}
catch (const std::exception&)
{
return false;
}
}
static void ClearMapForEditing(bool fromSave)
{
map_remove_all_rides();

View File

@@ -33,6 +33,7 @@
#include "ride/ShopItem.h"
#include "ride/Vehicle.h"
#include "scenario/Scenario.h"
#include "scenario/ScenarioRepository.h"
#include "world/Climate.h"
#include "world/EntityList.h"
#include "world/Entrance.h"
@@ -161,6 +162,35 @@ namespace OpenRCT2
Save(fs);
}
scenario_index_entry ReadScenarioChunk()
{
scenario_index_entry entry{};
auto& os = *_os;
os.ReadWriteChunk(ParkFileChunkType::SCENARIO, [this, &entry](OrcaStream::ChunkStream& cs) {
entry.category = cs.Read<uint8_t>();
std::string name;
ReadWriteStringTable(cs, name, "en-GB");
String::Set(entry.name, sizeof(entry.name), name.c_str());
String::Set(entry.internal_name, sizeof(entry.internal_name), name.c_str());
std::string parkName;
ReadWriteStringTable(cs, parkName, "en-GB");
std::string scenarioDetails;
ReadWriteStringTable(cs, scenarioDetails, "en-GB");
String::Set(entry.details, sizeof(entry.details), scenarioDetails.c_str());
entry.objective_type = cs.Read<uint8_t>();
entry.objective_arg_1 = cs.Read<uint8_t>();
entry.objective_arg_3 = cs.Read<int16_t>();
entry.objective_arg_2 = cs.Read<int32_t>();
entry.source_game = ScenarioSource::Other;
});
return entry;
}
private:
void ReadWriteAuthoringChunk(OrcaStream& os)
{
@@ -1404,7 +1434,8 @@ public:
bool GetDetails(scenario_index_entry* dst) override
{
return false;
*dst = _parkFile->ReadScenarioChunk();
return true;
}
};

View File

@@ -130,7 +130,7 @@ class ScenarioFileIndex final : public FileIndex<scenario_index_entry>
private:
static constexpr uint32_t MAGIC_NUMBER = 0x58444953; // SIDX
static constexpr uint16_t VERSION = 5;
static constexpr auto PATTERN = "*.sc4;*.sc6;*.sea";
static constexpr auto PATTERN = "*.sc4;*.sc6;*.sea;*.park";
public:
explicit ScenarioFileIndex(const IPlatformEnvironment& env)
@@ -203,7 +203,28 @@ private:
try
{
std::string extension = Path::GetExtension(path);
if (String::Equals(extension, ".sc4", true))
if (String::Equals(extension, ".park", true))
{
// OpenRCT2 park
bool result = false;
try
{
auto& objRepository = OpenRCT2::GetContext()->GetObjectRepository();
auto importer = ParkImporter::CreateParkFile(objRepository);
importer->LoadScenario(path.c_str(), true);
if (importer->GetDetails(entry))
{
String::Set(entry->path, sizeof(entry->path), path.c_str());
entry->timestamp = timestamp;
result = true;
}
}
catch (const std::exception&)
{
}
return result;
}
else if (String::Equals(extension, ".sc4", true))
{
// RCT1 scenario
bool result = false;