1
0
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:
Aaron van Geffen
2024-08-29 15:20:03 +02:00
parent a45d701574
commit 4f7385addb
4 changed files with 86 additions and 89 deletions

View File

@@ -26,6 +26,7 @@
#include "world/Climate.h"
#include "world/Location.hpp"
#include "world/Park.h"
#include "world/ScenerySelection.h"
#include <array>
#include <chrono>

View File

@@ -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

View File

@@ -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]));
}
}
}

View File

@@ -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);