mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Move SC6 specific code from ScenarioRepository to S6Importer
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "world/Climate.h"
|
||||
#include "world/Location.hpp"
|
||||
#include "world/Park.h"
|
||||
#include "world/ScenerySelection.h"
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
#include "../ride/Vehicle.h"
|
||||
#include "../scenario/Scenario.h"
|
||||
#include "../scenario/ScenarioRepository.h"
|
||||
#include "../scenario/ScenarioSources.h"
|
||||
#include "../util/SawyerCoding.h"
|
||||
#include "../util/Util.h"
|
||||
#include "../world/Climate.h"
|
||||
@@ -156,6 +157,14 @@ namespace OpenRCT2::RCT2
|
||||
throw std::runtime_error("Park is not a scenario.");
|
||||
}
|
||||
chunkReader.ReadChunk(&_s6.Info, sizeof(_s6.Info));
|
||||
|
||||
// If the name or the details contain a colour code, they might be in UTF-8 already.
|
||||
// This is caused by a bug that was in OpenRCT2 for 3 years.
|
||||
if (!IsLikelyUTF8(_s6.Info.Name) && !IsLikelyUTF8(_s6.Info.Details))
|
||||
{
|
||||
RCT2StringToUTF8Self(_s6.Info.Name, sizeof(_s6.Info.Name));
|
||||
RCT2StringToUTF8Self(_s6.Info.Details, sizeof(_s6.Info.Details));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -225,7 +234,69 @@ namespace OpenRCT2::RCT2
|
||||
bool GetDetails(ScenarioIndexEntry* dst) override
|
||||
{
|
||||
*dst = {};
|
||||
return false;
|
||||
|
||||
dst->Category = _s6.Info.Category;
|
||||
dst->ObjectiveType = _s6.Info.ObjectiveType;
|
||||
dst->ObjectiveArg1 = _s6.Info.ObjectiveArg1;
|
||||
dst->ObjectiveArg2 = _s6.Info.ObjectiveArg2;
|
||||
dst->ObjectiveArg3 = _s6.Info.ObjectiveArg3;
|
||||
dst->Highscore = nullptr;
|
||||
|
||||
if (String::IsNullOrEmpty(_s6.Info.Name))
|
||||
{
|
||||
// If the scenario doesn't have a name, set it to the filename
|
||||
String::Set(dst->Name, sizeof(dst->Name), Path::GetFileNameWithoutExtension(dst->Path).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
String::Set(dst->Name, sizeof(dst->Name), _s6.Info.Name);
|
||||
// Normalise the name to make the scenario as recognisable as possible.
|
||||
ScenarioSources::NormaliseName(dst->Name, sizeof(dst->Name), dst->Name);
|
||||
}
|
||||
|
||||
// dst->name will be translated later so keep the untranslated name here
|
||||
String::Set(dst->InternalName, sizeof(dst->InternalName), dst->Name);
|
||||
|
||||
String::Set(dst->Details, sizeof(dst->Details), _s6.Info.Details);
|
||||
|
||||
// Look up and store information regarding the origins of this scenario.
|
||||
SourceDescriptor desc;
|
||||
if (ScenarioSources::TryGetByName(dst->Name, &desc))
|
||||
{
|
||||
dst->ScenarioId = desc.id;
|
||||
dst->SourceIndex = desc.index;
|
||||
dst->SourceGame = ScenarioSource{ desc.source };
|
||||
dst->Category = desc.category;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst->ScenarioId = SC_UNIDENTIFIED;
|
||||
dst->SourceIndex = -1;
|
||||
if (dst->Category == SCENARIO_CATEGORY_REAL)
|
||||
{
|
||||
dst->SourceGame = ScenarioSource::Real;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst->SourceGame = ScenarioSource::Other;
|
||||
}
|
||||
}
|
||||
|
||||
// Localise the park name and description
|
||||
StringId localisedStringIds[3];
|
||||
if (LanguageGetLocalisedScenarioStrings(dst->Name, localisedStringIds))
|
||||
{
|
||||
if (localisedStringIds[0] != STR_NONE)
|
||||
{
|
||||
String::Set(dst->Name, sizeof(dst->Name), LanguageGetString(localisedStringIds[0]));
|
||||
}
|
||||
if (localisedStringIds[2] != STR_NONE)
|
||||
{
|
||||
String::Set(dst->Details, sizeof(dst->Details), LanguageGetString(localisedStringIds[2]));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Import(GameState_t& gameState) override
|
||||
|
||||
@@ -249,26 +249,25 @@ private:
|
||||
}
|
||||
|
||||
// RCT2 or RCTC scenario
|
||||
auto stream = GetStreamFromRCT2Scenario(path);
|
||||
auto chunkReader = SawyerChunkReader(stream.get());
|
||||
|
||||
const auto header = chunkReader.ReadChunkAs<RCT2::S6Header>();
|
||||
if (header.Type == S6_TYPE_SCENARIO)
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
auto info = chunkReader.ReadChunkAs<RCT2::S6Info>();
|
||||
// If the name or the details contain a colour code, they might be in UTF-8 already.
|
||||
// This is caused by a bug that was in OpenRCT2 for 3 years.
|
||||
if (!IsLikelyUTF8(info.Name) && !IsLikelyUTF8(info.Details))
|
||||
auto& objRepository = OpenRCT2::GetContext()->GetObjectRepository();
|
||||
auto s6Importer = ParkImporter::CreateS6(objRepository);
|
||||
s6Importer->LoadScenario(path, true);
|
||||
if (s6Importer->GetDetails(entry))
|
||||
{
|
||||
RCT2StringToUTF8Self(info.Name, sizeof(info.Name));
|
||||
RCT2StringToUTF8Self(info.Details, sizeof(info.Details));
|
||||
entry->Path = path;
|
||||
entry->Timestamp = timestamp;
|
||||
result = true;
|
||||
}
|
||||
|
||||
*entry = CreateNewScenarioEntry(path, timestamp, &info);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
}
|
||||
|
||||
LOG_VERBOSE("%s is not a scenario", path.c_str());
|
||||
return result;
|
||||
}
|
||||
catch (const std::exception&)
|
||||
{
|
||||
@@ -276,63 +275,6 @@ private:
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static ScenarioIndexEntry CreateNewScenarioEntry(const std::string& path, uint64_t timestamp, RCT2::S6Info* s6Info)
|
||||
{
|
||||
ScenarioIndexEntry entry = {};
|
||||
|
||||
// Set new entry
|
||||
entry.Path = path;
|
||||
entry.Timestamp = timestamp;
|
||||
entry.Category = s6Info->Category;
|
||||
entry.ObjectiveType = s6Info->ObjectiveType;
|
||||
entry.ObjectiveArg1 = s6Info->ObjectiveArg1;
|
||||
entry.ObjectiveArg2 = s6Info->ObjectiveArg2;
|
||||
entry.ObjectiveArg3 = s6Info->ObjectiveArg3;
|
||||
entry.Highscore = nullptr;
|
||||
if (String::IsNullOrEmpty(s6Info->Name))
|
||||
{
|
||||
// If the scenario doesn't have a name, set it to the filename
|
||||
String::Set(entry.Name, sizeof(entry.Name), Path::GetFileNameWithoutExtension(entry.Path).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
String::Set(entry.Name, sizeof(entry.Name), s6Info->Name);
|
||||
// Normalise the name to make the scenario as recognisable as possible.
|
||||
ScenarioSources::NormaliseName(entry.Name, sizeof(entry.Name), entry.Name);
|
||||
}
|
||||
|
||||
// entry.name will be translated later so keep the untranslated name here
|
||||
String::Set(entry.InternalName, sizeof(entry.InternalName), entry.Name);
|
||||
|
||||
String::Set(entry.Details, sizeof(entry.Details), s6Info->Details);
|
||||
|
||||
// Look up and store information regarding the origins of this scenario.
|
||||
SourceDescriptor desc;
|
||||
if (ScenarioSources::TryGetByName(entry.Name, &desc))
|
||||
{
|
||||
entry.ScenarioId = desc.id;
|
||||
entry.SourceIndex = desc.index;
|
||||
entry.SourceGame = ScenarioSource{ desc.source };
|
||||
entry.Category = desc.category;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.ScenarioId = SC_UNIDENTIFIED;
|
||||
entry.SourceIndex = -1;
|
||||
if (entry.Category == SCENARIO_CATEGORY_REAL)
|
||||
{
|
||||
entry.SourceGame = ScenarioSource::Real;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.SourceGame = ScenarioSource::Other;
|
||||
}
|
||||
}
|
||||
|
||||
ScenarioTranslate(&entry);
|
||||
return entry;
|
||||
}
|
||||
};
|
||||
|
||||
class ScenarioRepository final : public IScenarioRepository
|
||||
@@ -813,19 +755,3 @@ bool ScenarioRepositoryTryRecordHighscore(const utf8* scenarioFileName, money64
|
||||
IScenarioRepository* repo = GetScenarioRepository();
|
||||
return repo->TryRecordHighscore(LocalisationService_GetCurrentLanguage(), scenarioFileName, companyValue, name);
|
||||
}
|
||||
|
||||
void ScenarioTranslate(ScenarioIndexEntry* scenarioEntry)
|
||||
{
|
||||
StringId localisedStringIds[3];
|
||||
if (LanguageGetLocalisedScenarioStrings(scenarioEntry->Name, localisedStringIds))
|
||||
{
|
||||
if (localisedStringIds[0] != STR_NONE)
|
||||
{
|
||||
String::Set(scenarioEntry->Name, sizeof(scenarioEntry->Name), LanguageGetString(localisedStringIds[0]));
|
||||
}
|
||||
if (localisedStringIds[2] != STR_NONE)
|
||||
{
|
||||
String::Set(scenarioEntry->Details, sizeof(scenarioEntry->Details), LanguageGetString(localisedStringIds[2]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,4 +97,3 @@ void ScenarioRepositoryScan();
|
||||
[[nodiscard]] size_t ScenarioRepositoryGetCount();
|
||||
[[nodiscard]] const ScenarioIndexEntry* ScenarioRepositoryGetByIndex(size_t index);
|
||||
[[nodiscard]] bool ScenarioRepositoryTryRecordHighscore(const utf8* scenarioFileName, money64 companyValue, const utf8* name);
|
||||
void ScenarioTranslate(ScenarioIndexEntry* scenarioEntry);
|
||||
|
||||
Reference in New Issue
Block a user