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:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user