Fix #10549: 'Build the best ride you can' objective missing ride name

This is implemented in a way that is compatible with RCT2 (as long as the ride type was not split).
This commit is contained in:
Michael Steenbeek 2020-08-13 00:23:08 +02:00 committed by GitHub
parent 68ce06e833
commit 33d9fc2b75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 79 additions and 8 deletions

View File

@ -27,6 +27,7 @@
- Fix: [#7006] Submarine Ride is in the wrong research group.
- Fix: [#7324] Research window shows vehicle name instead of ride name.
- Fix: [#7969, #8175, #12501] When loading a landscape in the Scenario Editor, the inventions list, financial settings and objective settings are reset.
- Fix: [#10549] 'Build the best ride you can' objective missing ride name.
- Fix: [#10634] Guests are unable to use uphill paths out of toilets.
- Fix: [#10751] Saved mazes are incomplete.
- Fix: [#10876] When removing a path, its guest entry point is not removed.

View File

@ -26,6 +26,7 @@
#include <openrct2/localisation/Date.h>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/management/Award.h>
#include <openrct2/ride/RideData.h>
#include <openrct2/scenario/Scenario.h>
#include <openrct2/util/Util.h>
#include <openrct2/world/Entrance.h>
@ -1609,9 +1610,22 @@ static void window_park_objective_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Objective
ft = Formatter::Common();
ft.Add<uint16_t>(gScenarioObjectiveNumGuests);
ft.Add<int16_t>(date_get_total_months(MONTH_OCTOBER, gScenarioObjectiveYear));
ft.Add<money32>(gScenarioObjectiveCurrency);
if (gScenarioObjectiveType == OBJECTIVE_BUILD_THE_BEST)
{
rct_string_id rideTypeString = STR_NONE;
auto rideTypeId = gScenarioObjectiveNumGuests;
if (rideTypeId != RIDE_TYPE_NULL && rideTypeId < RIDE_TYPE_COUNT)
{
rideTypeString = RideTypeDescriptors[rideTypeId].Naming.Name;
}
ft.Add<rct_string_id>(rideTypeString);
}
else
{
ft.Add<uint16_t>(gScenarioObjectiveNumGuests);
ft.Add<int16_t>(date_get_total_months(MONTH_OCTOBER, gScenarioObjectiveYear));
ft.Add<money32>(gScenarioObjectiveCurrency);
}
screenCoords.y += gfx_draw_string_left_wrapped(
dpi, gCommonFormatArgs, screenCoords, 221, ObjectiveNames[gScenarioObjectiveType], COLOUR_BLACK);

View File

@ -17,6 +17,7 @@
#include <openrct2/localisation/Date.h>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/localisation/LocalisationService.h>
#include <openrct2/ride/RideData.h>
#include <openrct2/scenario/Scenario.h>
#include <openrct2/scenario/ScenarioRepository.h>
#include <openrct2/scenario/ScenarioSources.h>
@ -517,9 +518,22 @@ static void window_scenarioselect_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Scenario objective
ft = Formatter::Common();
ft.Add<rct_string_id>(ObjectiveNames[scenario->objective_type]);
ft.Add<int16_t>(scenario->objective_arg_3);
ft.Add<int16_t>(date_get_total_months(MONTH_OCTOBER, scenario->objective_arg_1));
ft.Add<int32_t>(scenario->objective_arg_2);
if (scenario->objective_type == OBJECTIVE_BUILD_THE_BEST)
{
rct_string_id rideTypeString = STR_NONE;
auto rideTypeId = scenario->objective_arg_3;
if (rideTypeId != RIDE_TYPE_NULL && rideTypeId < RIDE_TYPE_COUNT)
{
rideTypeString = RideTypeDescriptors[rideTypeId].Naming.Name;
}
ft.Add<rct_string_id>(rideTypeString);
}
else
{
ft.Add<int16_t>(scenario->objective_arg_3);
ft.Add<int16_t>(date_get_total_months(MONTH_OCTOBER, scenario->objective_arg_1));
ft.Add<int32_t>(scenario->objective_arg_2);
}
screenPos.y += gfx_draw_string_left_wrapped(dpi, gCommonFormatArgs, screenPos, 170, STR_OBJECTIVE, COLOUR_BLACK) + 5;
// Scenario score

View File

@ -234,6 +234,11 @@ public:
else
dst->objective_arg_2 = _s4.scenario_objective_currency;
dst->objective_arg_3 = _s4.scenario_objective_num_guests;
// This does not seem to be saved in the objective arguments, so look up the ID from the available rides instead.
if (_s4.scenario_objective_type == OBJECTIVE_BUILD_THE_BEST)
{
dst->objective_arg_3 = GetBuildTheBestRideId();
}
auto name = rct2_to_utf8(_s4.scenario_name, RCT2_LANGUAGE_ID_ENGLISH_UK);
std::string details;
@ -2713,6 +2718,7 @@ private:
gScenarioObjectiveType = _s4.scenario_objective_type;
gScenarioObjectiveYear = _s4.scenario_objective_years;
gScenarioObjectiveNumGuests = _s4.scenario_objective_num_guests;
// RCT1 used a different way of calculating the park value.
// This is corrected here, but since scenario_objective_currency doubles as minimum excitement rating,
// we need to check the goal to avoid affecting scenarios like Volcania.
@ -2720,6 +2726,10 @@ private:
gScenarioObjectiveCurrency = CorrectRCT1ParkValue(_s4.scenario_objective_currency);
else
gScenarioObjectiveCurrency = _s4.scenario_objective_currency;
// This does not seem to be saved in the objective arguments, so look up the ID from the available rides instead.
if (_s4.scenario_objective_type == OBJECTIVE_BUILD_THE_BEST)
gScenarioObjectiveNumGuests = GetBuildTheBestRideId();
}
void ImportSavedView()
@ -3121,6 +3131,26 @@ private:
}
}
}
ObjectEntryIndex GetBuildTheBestRideId()
{
size_t researchListCount;
const rct1_research_item* researchList = GetResearchList(&researchListCount);
for (size_t i = 0; i < researchListCount; i++)
{
if (researchList[i].flags == 0xFF)
{
break;
}
if (researchList[i].type == RCT1_RESEARCH_TYPE_RIDE)
{
return RCT1::GetRideType(researchList[i].item, 0);
}
}
return RIDE_TYPE_NULL;
}
};
std::unique_ptr<IParkImporter> ParkImporter::CreateS4()

View File

@ -52,6 +52,8 @@ constexpr const uint8_t RCT2_MAX_WATER_OBJECTS = 1;
constexpr const uint8_t RCT2_MAX_SCENARIO_TEXT_OBJECTS = 1;
constexpr const uint8_t RCT2_RIDE_TYPE_COUNT = 91;
constexpr const rct_string_id RCT2_RIDE_STRING_START = 2;
// clang-format off
constexpr const uint16_t RCT2_OBJECT_ENTRY_COUNT =
RCT2_MAX_RIDE_OBJECTS +

View File

@ -276,7 +276,12 @@ void S6Exporter::Export()
_s6.objective_year = gScenarioObjectiveYear;
// pad_013580FA
_s6.objective_currency = gScenarioObjectiveCurrency;
_s6.objective_guests = gScenarioObjectiveNumGuests;
// In RCT2, the ride string IDs start at index STR_0002 and are directly mappable.
// This is not always the case in OpenRCT2, so we use the actual ride ID.
if (gScenarioObjectiveType == OBJECTIVE_BUILD_THE_BEST)
_s6.objective_guests = gScenarioObjectiveNumGuests + RCT2_RIDE_STRING_START;
else
_s6.objective_guests = gScenarioObjectiveNumGuests;
ExportMarketingCampaigns();
std::memcpy(_s6.balance_history, gCashHistory, sizeof(_s6.balance_history));

View File

@ -296,7 +296,12 @@ public:
gScenarioObjectiveYear = _s6.objective_year;
// pad_013580FA
gScenarioObjectiveCurrency = _s6.objective_currency;
gScenarioObjectiveNumGuests = _s6.objective_guests;
// In RCT2, the ride string IDs start at index STR_0002 and are directly mappable.
// This is not always the case in OpenRCT2, so we use the actual ride ID.
if (gScenarioObjectiveType == OBJECTIVE_BUILD_THE_BEST)
gScenarioObjectiveNumGuests = _s6.objective_guests - RCT2_RIDE_STRING_START;
else
gScenarioObjectiveNumGuests = _s6.objective_guests;
ImportMarketingCampaigns();
gCurrentExpenditure = _s6.current_expenditure;