From e6faf6b7c425e1bdbdf891ee31fc01ffde48e756 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 2 Oct 2017 23:05:08 +0200 Subject: [PATCH] Fix #6201, #6250: custom RCT1 scenarios cause empty scenario list entry The scenario repository did not correctly handle custom RCT1 scenarios. They were not listed, but if they existed, an empty entry would appear in the scenario list. This fixes both issues, and also prints a warning message, should this ever happen again. --- distribution/changelog.txt | 1 + src/openrct2/rct1/S4Importer.cpp | 77 +++++++++++--------- src/openrct2/scenario/ScenarioRepository.cpp | 36 +++++---- 3 files changed, 64 insertions(+), 50 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 858edf9a6b..b91b1ad1b3 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -6,6 +6,7 @@ - Feature: [#6235] Add drawing debug option for showing visuals when and where blocks of the screen are painted. - Feature: [#6292] Allow building queue lines in the Scenario Editor. - Feature: [#6325] Allow using g1.dat from RCT Classic. +- Feature: [#6353] Show custom RCT1 scenarios in New Scenario window. - Feature: Allow using object files from RCT Classic. - Fix: [#816] In the map window, there are more peeps flickering than there are selected (original bug). - Fix: [#1833, #4937, #6138] 'Too low!' warning when building rides and shops on the lowest land level (original bug). diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index e4f25e82a9..e13b5a55a3 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -237,48 +237,53 @@ public: bool GetDetails(scenario_index_entry * dst) override { - bool result = false; Memory::Set(dst, 0, sizeof(scenario_index_entry)); source_desc desc; - if (ScenarioSources::TryGetById(_s4.scenario_slot_index, &desc)) + // If no entry is found, this is a custom scenario. + bool isOfficial = ScenarioSources::TryGetById(_s4.scenario_slot_index, &desc); + + dst->category = desc.category; + dst->source_game = desc.source; + dst->source_index = desc.index; + dst->sc_id = desc.id; + + dst->objective_type = _s4.scenario_objective_type; + dst->objective_arg_1 = _s4.scenario_objective_years; + // RCT1 used another way of calculating park value. + if (_s4.scenario_objective_type == OBJECTIVE_PARK_VALUE_BY) + dst->objective_arg_2 = CorrectRCT1ParkValue(_s4.scenario_objective_currency); + else + dst->objective_arg_2 = _s4.scenario_objective_currency; + dst->objective_arg_3 = _s4.scenario_objective_num_guests; + + std::string name = std::string(_s4.scenario_name, sizeof(_s4.scenario_name)); + std::string details; + + // TryGetById won't set this property if the scenario is not recognised, + // but localisation needs it. + if (!isOfficial) { - dst->category = desc.category; - dst->source_game = desc.source; - dst->source_index = desc.index; - dst->sc_id = desc.id; - - dst->objective_type = _s4.scenario_objective_type; - dst->objective_arg_1 = _s4.scenario_objective_years; - // RCT1 used another way of calculating park value. - if (_s4.scenario_objective_type == OBJECTIVE_PARK_VALUE_BY) - dst->objective_arg_2 = CorrectRCT1ParkValue(_s4.scenario_objective_currency); - else - dst->objective_arg_2 = _s4.scenario_objective_currency; - dst->objective_arg_3 = _s4.scenario_objective_num_guests; - - std::string name = std::string(_s4.scenario_name, sizeof(_s4.scenario_name)); - std::string details; - rct_string_id localisedStringIds[3]; - if (language_get_localised_scenario_strings(desc.title, localisedStringIds)) - { - if (localisedStringIds[0] != STR_NONE) - { - name = String::ToStd(language_get_string(localisedStringIds[0])); - } - if (localisedStringIds[2] != STR_NONE) - { - details = String::ToStd(language_get_string(localisedStringIds[2])); - } - } - - String::Set(dst->name, sizeof(dst->name), name.c_str()); - String::Set(dst->details, sizeof(dst->details), details.c_str()); - - result = true; + desc.title = name.c_str(); } - return result; + rct_string_id localisedStringIds[3]; + if (language_get_localised_scenario_strings(desc.title, localisedStringIds)) + { + if (localisedStringIds[0] != STR_NONE) + { + name = String::ToStd(language_get_string(localisedStringIds[0])); + } + if (localisedStringIds[2] != STR_NONE) + { + details = String::ToStd(language_get_string(localisedStringIds[2])); + } + } + + String::Set(dst->name, sizeof(dst->name), name.c_str()); + String::Set(dst->details, sizeof(dst->details), details.c_str()); + + return true; } sint32 CorrectRCT1ParkValue(money32 oldParkValue) diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 96fd7d6dfc..efce36d9d2 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -460,28 +460,36 @@ private: void AddScenario(const scenario_index_entry &entry) { auto filename = Path::GetFileName(entry.path); - auto existingEntry = GetByFilename(filename); - if (existingEntry != nullptr) - { - std::string conflictPath; - if (existingEntry->timestamp > entry.timestamp) - { - // Existing entry is more recent - conflictPath = String::ToStd(existingEntry->path); - // Overwrite existing entry with this one - *existingEntry = entry; + if (!String::Equals(filename, "")) + { + auto existingEntry = GetByFilename(filename); + if (existingEntry != nullptr) + { + std::string conflictPath; + if (existingEntry->timestamp > entry.timestamp) + { + // Existing entry is more recent + conflictPath = String::ToStd(existingEntry->path); + + // Overwrite existing entry with this one + *existingEntry = entry; + } + else + { + // This entry is more recent + conflictPath = entry.path; + } + Console::WriteLine("Scenario conflict: '%s' ignored because it is newer.", conflictPath.c_str()); } else { - // This entry is more recent - conflictPath = entry.path; + _scenarios.push_back(entry); } - Console::WriteLine("Scenario conflict: '%s' ignored because it is newer.", conflictPath.c_str()); } else { - _scenarios.push_back(entry); + log_error("Tried to add scenario with an empty filename!"); } }