mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-19 04:53:12 +01:00
Merge pull request #11972 from Gymnasiast/fix/7324
Fix #7324: Research window shows vehicle name instead of ride name
This commit is contained in:
@@ -3670,6 +3670,8 @@ STR_6372 :The specified path contains a RollerCoaster Tycoon 1 installation,
|
||||
STR_6373 :Toggle clearance checks
|
||||
STR_6374 :C
|
||||
STR_6375 :Unknown Ride
|
||||
STR_6376 :{WINDOW_COLOUR_2}Ride vehicle:{NEWLINE}{BLACK}{STRINGID} for {STRINGID}
|
||||
STR_6377 :{WINDOW_COLOUR_2}Type: {BLACK}{STRINGID} for {STRINGID}
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
- Fix: [#5451] Guests scream on every descent, no matter how small.
|
||||
- Fix: [#6119] Advertising campaign for ride window not updated properly (original bug).
|
||||
- Fix: [#7006] Submarine Ride is in the wrong research group.
|
||||
- Fix: [#7324] Research window shows vehicle name instead of ride name.
|
||||
- Fix: [#10634] Guests are unable to use uphill paths out of toilets.
|
||||
- Fix: [#10876] When removing a path, its guest entry point is not removed.
|
||||
- Fix: [#10876] There can be multiple peep spawns on the same location.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <openrct2/management/Finance.h>
|
||||
#include <openrct2/management/NewsItem.h>
|
||||
#include <openrct2/management/Research.h>
|
||||
#include <openrct2/ride/RideData.h>
|
||||
#include <openrct2/sprites.h>
|
||||
#include <openrct2/world/Park.h>
|
||||
#include <openrct2/world/Scenery.h>
|
||||
@@ -362,16 +363,33 @@ void window_research_development_page_paint(rct_window* w, rct_drawpixelinfo* dp
|
||||
else
|
||||
{
|
||||
// Research type
|
||||
stringId = STR_RESEARCH_UNKNOWN;
|
||||
std::array<rct_string_id, 2> strings = { STR_RESEARCH_UNKNOWN, 0 };
|
||||
rct_string_id label = STR_RESEARCH_TYPE_LABEL;
|
||||
if (gResearchProgressStage != RESEARCH_STAGE_INITIAL_RESEARCH)
|
||||
{
|
||||
stringId = ResearchCategoryNames[gResearchNextItem->category];
|
||||
strings[0] = ResearchCategoryNames[gResearchNextItem->category];
|
||||
if (gResearchProgressStage != RESEARCH_STAGE_DESIGNING)
|
||||
{
|
||||
stringId = gResearchNextItem->GetName();
|
||||
strings[0] = gResearchNextItem->GetName();
|
||||
if (gResearchNextItem->type == RESEARCH_ENTRY_TYPE_RIDE)
|
||||
{
|
||||
auto rtd = RideTypeDescriptors[gResearchNextItem->baseRideType];
|
||||
if (!rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
{
|
||||
if (gResearchNextItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
|
||||
{
|
||||
strings[0] = rtd.Naming.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
strings[1] = rtd.Naming.Name;
|
||||
label = STR_RESEARCH_TYPE_LABEL_VEHICLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_TYPE_LABEL, COLOUR_BLACK);
|
||||
gfx_draw_string_left_wrapped(dpi, &strings, x, y, 296, label, COLOUR_BLACK);
|
||||
y += 25;
|
||||
|
||||
// Progress
|
||||
@@ -399,14 +417,34 @@ void window_research_development_page_paint(rct_window* w, rct_drawpixelinfo* dp
|
||||
x = w->windowPos.x + 10;
|
||||
y = w->windowPos.y + w->widgets[WIDX_LAST_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12;
|
||||
|
||||
rct_string_id lastDevelopmentFormat;
|
||||
if (gResearchLastItem.has_value())
|
||||
{
|
||||
stringId = gResearchLastItem->GetName();
|
||||
rct_string_id lastDevelopmentFormat = STR_EMPTY;
|
||||
std::array<rct_string_id, 2> strings = { gResearchLastItem->GetName(), 0 };
|
||||
uint8_t type = gResearchLastItem->type;
|
||||
lastDevelopmentFormat = (type == RESEARCH_ENTRY_TYPE_RIDE) ? STR_RESEARCH_RIDE_LABEL : STR_RESEARCH_SCENERY_LABEL;
|
||||
if (type == RESEARCH_ENTRY_TYPE_SCENERY)
|
||||
{
|
||||
lastDevelopmentFormat = STR_RESEARCH_SCENERY_LABEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastDevelopmentFormat = STR_RESEARCH_RIDE_LABEL;
|
||||
auto rtd = RideTypeDescriptors[gResearchLastItem->baseRideType];
|
||||
if (!rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
{
|
||||
if (gResearchLastItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
|
||||
{
|
||||
strings[0] = rtd.Naming.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
strings[1] = rtd.Naming.Name;
|
||||
lastDevelopmentFormat = STR_RESEARCH_VEHICLE_LABEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, lastDevelopmentFormat, COLOUR_BLACK);
|
||||
gfx_draw_string_left_wrapped(dpi, &strings, x, y, 266, lastDevelopmentFormat, COLOUR_BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3911,6 +3911,9 @@ enum
|
||||
|
||||
STR_UNKNOWN_RIDE = 6375,
|
||||
|
||||
STR_RESEARCH_VEHICLE_LABEL = 6376,
|
||||
STR_RESEARCH_TYPE_LABEL_VEHICLE = 6377,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
/* MAX_STR_COUNT = 32768 */ // MAX_STR_COUNT - upper limit for number of strings, not the current count strings
|
||||
};
|
||||
|
||||
@@ -201,21 +201,8 @@ void research_finish_item(ResearchItem* researchItem)
|
||||
|
||||
if (rideEntry != nullptr && base_ride_type != RIDE_TYPE_NULL)
|
||||
{
|
||||
bool ride_group_was_invented_before = false;
|
||||
bool ride_type_was_invented_before = ride_type_is_invented(base_ride_type);
|
||||
rct_string_id availabilityString;
|
||||
|
||||
// Determine if the ride group this entry belongs to was invented before.
|
||||
if (RideTypeDescriptors[base_ride_type].HasFlag(RIDE_TYPE_FLAG_HAS_RIDE_GROUPS))
|
||||
{
|
||||
const RideGroup* rideGroup = RideGroupManager::GetRideGroup(base_ride_type, rideEntry);
|
||||
|
||||
if (rideGroup->IsInvented())
|
||||
{
|
||||
ride_group_was_invented_before = true;
|
||||
}
|
||||
}
|
||||
|
||||
ride_type_set_invented(base_ride_type);
|
||||
openrct2_assert(base_ride_type < RIDE_TYPE_COUNT, "Invalid base_ride_type = %d", base_ride_type);
|
||||
|
||||
@@ -256,17 +243,10 @@ void research_finish_item(ResearchItem* researchItem)
|
||||
|
||||
auto ft = Formatter::Common();
|
||||
|
||||
// If a vehicle should be listed separately (maze, mini golf, flat rides, shops)
|
||||
if (RideTypeDescriptors[base_ride_type].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
{
|
||||
availabilityString = STR_NEWS_ITEM_RESEARCH_NEW_RIDE_AVAILABLE;
|
||||
ft.Add<rct_string_id>(rideEntry->naming.Name);
|
||||
}
|
||||
// If a vehicle is the first to be invented for its ride group, show the ride group name.
|
||||
else if (
|
||||
!ride_type_was_invented_before
|
||||
|| (RideTypeDescriptors[base_ride_type].HasFlag(RIDE_TYPE_FLAG_HAS_RIDE_GROUPS)
|
||||
&& !ride_group_was_invented_before))
|
||||
// If a vehicle is the first to be invented for its ride type or group, show the ride type/group name.
|
||||
// Independently listed vehicles (like all flat rides and shops) should always be announced as such.
|
||||
if (RideTypeDescriptors[base_ride_type].HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY)
|
||||
|| researchItem->flags & RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE)
|
||||
{
|
||||
RideNaming naming = get_ride_naming(base_ride_type, rideEntry);
|
||||
availabilityString = STR_NEWS_ITEM_RESEARCH_NEW_RIDE_AVAILABLE;
|
||||
@@ -740,11 +720,11 @@ void research_remove_flags()
|
||||
{
|
||||
for (auto& researchItem : gResearchItemsUninvented)
|
||||
{
|
||||
researchItem.flags = 0;
|
||||
researchItem.flags &= ~(RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED);
|
||||
}
|
||||
for (auto& researchItem : gResearchItemsInvented)
|
||||
{
|
||||
researchItem.flags = 0;
|
||||
researchItem.flags &= ~(RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -910,3 +890,121 @@ bool ResearchItem::Exists() const
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::bitset<RIDE_TYPE_COUNT> _seenRideType = {};
|
||||
static std::bitset<RIDE_TYPE_COUNT* MAX_RIDE_GROUPS_PER_RIDE_TYPE> _seenRideGroup = {};
|
||||
|
||||
static void research_update_first_of_type(ResearchItem* researchItem)
|
||||
{
|
||||
if (researchItem->IsNull())
|
||||
return;
|
||||
|
||||
if (researchItem->type != RESEARCH_ENTRY_TYPE_RIDE)
|
||||
return;
|
||||
|
||||
auto rideType = researchItem->baseRideType;
|
||||
if (rideType >= RIDE_TYPE_COUNT)
|
||||
{
|
||||
log_error("Research item has non-existant ride type index %d", rideType);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& rtd = RideTypeDescriptors[rideType];
|
||||
if (rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
{
|
||||
researchItem->flags |= RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rtd.HasFlag(RIDE_TYPE_FLAG_HAS_RIDE_GROUPS))
|
||||
{
|
||||
if (!_seenRideType[rideType])
|
||||
researchItem->flags |= RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE;
|
||||
|
||||
_seenRideType[rideType] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& entry = get_ride_entry(researchItem->entryIndex);
|
||||
if (entry != nullptr)
|
||||
{
|
||||
auto rideGroupIndex = RideGroupManager::GetRideGroupIndex(rideType, entry);
|
||||
assert(rideGroupIndex < MAX_RIDE_GROUPS_PER_RIDE_TYPE);
|
||||
|
||||
if (!_seenRideGroup[rideType * rideGroupIndex])
|
||||
researchItem->flags |= RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE;
|
||||
|
||||
_seenRideGroup[rideType * rideGroupIndex] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void research_mark_ride_type_as_seen(const ResearchItem& researchItem)
|
||||
{
|
||||
auto rideType = researchItem.baseRideType;
|
||||
if (rideType >= RIDE_TYPE_COUNT)
|
||||
return;
|
||||
|
||||
const auto& rtd = RideTypeDescriptors[rideType];
|
||||
if (!rtd.HasFlag(RIDE_TYPE_FLAG_HAS_RIDE_GROUPS))
|
||||
{
|
||||
_seenRideType[rideType] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& entry = get_ride_entry(researchItem.entryIndex);
|
||||
if (entry != nullptr)
|
||||
{
|
||||
auto rideGroupIndex = RideGroupManager::GetRideGroupIndex(rideType, entry);
|
||||
assert(rideGroupIndex < MAX_RIDE_GROUPS_PER_RIDE_TYPE);
|
||||
_seenRideGroup[rideType * rideGroupIndex] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void research_determine_first_of_type()
|
||||
{
|
||||
_seenRideType.reset();
|
||||
_seenRideGroup.reset();
|
||||
|
||||
for (const auto& researchItem : gResearchItemsInvented)
|
||||
{
|
||||
if (researchItem.type != RESEARCH_ENTRY_TYPE_RIDE)
|
||||
continue;
|
||||
|
||||
auto rideType = researchItem.baseRideType;
|
||||
if (rideType >= RIDE_TYPE_COUNT)
|
||||
continue;
|
||||
|
||||
const auto& rtd = RideTypeDescriptors[rideType];
|
||||
if (rtd.HasFlag(RIDE_TYPE_FLAG_LIST_VEHICLES_SEPARATELY))
|
||||
continue;
|
||||
|
||||
// The last research item will also be present in gResearchItemsInvented.
|
||||
// Avoid marking its ride type as "invented" prematurely.
|
||||
if (gResearchLastItem.has_value() && !gResearchLastItem->IsNull() && researchItem.Equals(&gResearchLastItem.value()))
|
||||
continue;
|
||||
|
||||
// The next research item is also present in gResearchItemsInvented, even though it isn't invented yet(!)
|
||||
if (gResearchNextItem.has_value() && !gResearchNextItem->IsNull() && researchItem.Equals(&gResearchNextItem.value()))
|
||||
continue;
|
||||
|
||||
research_mark_ride_type_as_seen(researchItem);
|
||||
}
|
||||
|
||||
if (gResearchLastItem.has_value())
|
||||
{
|
||||
research_update_first_of_type(&gResearchLastItem.value());
|
||||
research_mark_ride_type_as_seen(gResearchLastItem.value());
|
||||
}
|
||||
if (gResearchNextItem.has_value())
|
||||
{
|
||||
research_update_first_of_type(&gResearchNextItem.value());
|
||||
research_mark_ride_type_as_seen(gResearchNextItem.value());
|
||||
}
|
||||
|
||||
for (auto& researchItem : gResearchItemsUninvented)
|
||||
{
|
||||
research_update_first_of_type(&researchItem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,19 @@
|
||||
|
||||
struct rct_ride_entry;
|
||||
|
||||
enum
|
||||
{
|
||||
RESEARCH_ENTRY_TYPE_SCENERY = 0,
|
||||
RESEARCH_ENTRY_TYPE_RIDE = 1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE = (1 << 0),
|
||||
RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED = (1 << 5),
|
||||
RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED = (1 << 6),
|
||||
};
|
||||
|
||||
struct ResearchItem
|
||||
{
|
||||
union
|
||||
@@ -67,7 +80,7 @@ struct ResearchItem
|
||||
retItem.entryIndex = OpenRCT2EntryIndexToRCTEntryIndex(entryIndex);
|
||||
retItem.baseRideType = baseRideType;
|
||||
retItem.type = type;
|
||||
retItem.flags = flags;
|
||||
retItem.flags = (flags & ~RESEARCH_ENTRY_FLAG_FIRST_OF_TYPE);
|
||||
retItem.category = category;
|
||||
}
|
||||
|
||||
@@ -95,18 +108,6 @@ struct ResearchItem
|
||||
}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RESEARCH_ENTRY_TYPE_SCENERY = 0,
|
||||
RESEARCH_ENTRY_TYPE_RIDE = 1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED = (1 << 5),
|
||||
RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED = (1 << 6),
|
||||
};
|
||||
|
||||
// Only used to mark as null nowadays. Deprecated. TODO: remove.
|
||||
#define RESEARCH_ITEM_NULL 0xFFFFFFFF
|
||||
|
||||
@@ -192,3 +193,8 @@ void research_fix();
|
||||
void research_items_make_all_unresearched();
|
||||
void research_items_make_all_researched();
|
||||
void research_items_shuffle();
|
||||
/**
|
||||
* Determines if a newly invented ride entry should be listed as a new ride
|
||||
* or as a new vehicle for a pre-existing ride.
|
||||
*/
|
||||
void research_determine_first_of_type();
|
||||
|
||||
@@ -399,31 +399,7 @@ void RideObject::SetRepositoryItem(ObjectRepositoryItem* item) const
|
||||
}
|
||||
|
||||
item->RideInfo.RideFlags = 0;
|
||||
|
||||
// Determines the ride group. Will fall back to 0 if there is none found.
|
||||
uint8_t rideGroupIndex = 0;
|
||||
|
||||
const RideGroup* rideGroup = RideGroupManager::GetRideGroup(firstRideType, &_legacyType);
|
||||
|
||||
// If the ride group is nullptr, the track type does not have ride groups.
|
||||
if (rideGroup != nullptr)
|
||||
{
|
||||
for (uint8_t i = rideGroupIndex + 1; i < MAX_RIDE_GROUPS_PER_RIDE_TYPE; i++)
|
||||
{
|
||||
const RideGroup* irg = RideGroupManager::RideGroupFind(firstRideType, i);
|
||||
|
||||
if (irg != nullptr)
|
||||
{
|
||||
if (irg->Equals(rideGroup))
|
||||
{
|
||||
rideGroupIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item->RideInfo.RideGroupIndex = rideGroupIndex;
|
||||
item->RideInfo.RideGroupIndex = RideGroupManager::GetRideGroupIndex(firstRideType, &_legacyType);
|
||||
}
|
||||
|
||||
void RideObject::ReadLegacyVehicle(
|
||||
|
||||
@@ -210,6 +210,7 @@ public:
|
||||
|
||||
game_convert_news_items_to_utf8();
|
||||
map_count_remaining_land_rights();
|
||||
research_determine_first_of_type();
|
||||
}
|
||||
|
||||
bool GetDetails(scenario_index_entry* dst) override
|
||||
|
||||
@@ -487,6 +487,8 @@ public:
|
||||
OWNERSHIP_OWNED);
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
research_determine_first_of_type();
|
||||
}
|
||||
|
||||
void ImportRides()
|
||||
|
||||
@@ -245,3 +245,30 @@ const RideGroup* RideGroupManager::RideGroupFind(const uint8_t rideType, const u
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t RideGroupManager::GetRideGroupIndex(const uint8_t rideType, const rct_ride_entry* rideEntry)
|
||||
{
|
||||
uint8_t rideGroupIndex = 0;
|
||||
|
||||
const RideGroup* rideGroup = RideGroupManager::GetRideGroup(rideType, rideEntry);
|
||||
|
||||
// If the ride group is nullptr, the track type does not have ride groups.
|
||||
if (rideGroup != nullptr)
|
||||
{
|
||||
for (uint8_t i = rideGroupIndex + 1; i < MAX_RIDE_GROUPS_PER_RIDE_TYPE; i++)
|
||||
{
|
||||
const RideGroup* irg = RideGroupManager::RideGroupFind(rideType, i);
|
||||
|
||||
if (irg != nullptr)
|
||||
{
|
||||
if (irg->Equals(rideGroup))
|
||||
{
|
||||
rideGroupIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rideGroupIndex;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ class RideGroupManager
|
||||
{
|
||||
public:
|
||||
static const RideGroup* GetRideGroup(const uint8_t trackType, const rct_ride_entry* rideEntry);
|
||||
/** Will fall back to 0 if there is none found. */
|
||||
static uint8_t GetRideGroupIndex(const uint8_t trackType, const rct_ride_entry* rideEntry);
|
||||
static const RideGroup* RideGroupFind(const uint8_t rideType, const uint8_t index);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user