mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 19:13:07 +01:00
Do not import garbage data in RCT1/2 news queues
This commit is contained in:
@@ -889,7 +889,8 @@ namespace OpenRCT2::RCT1
|
||||
uint8_t TargetWeatherGloom;
|
||||
uint8_t Rain;
|
||||
uint8_t TargetRain;
|
||||
RCT12NewsItem Messages[Limits::MaxNewsItems];
|
||||
RCT12NewsItem recentMessages[Limits::kMaxRecentNewsItems];
|
||||
RCT12NewsItem archivedMessages[Limits::kMaxArchivedNewsItems];
|
||||
char ScenarioName[62];
|
||||
uint16_t ScenarioSlotIndex;
|
||||
uint32_t ScenarioFlags;
|
||||
|
||||
@@ -2192,6 +2192,46 @@ namespace OpenRCT2::RCT1
|
||||
park.Name = std::move(parkName);
|
||||
}
|
||||
|
||||
std::vector<OpenRCT2::News::Item> convertNewsQueue(const RCT12NewsItem* queue, uint8_t size)
|
||||
{
|
||||
std::vector<OpenRCT2::News::Item> output{};
|
||||
const RCT12NewsItem* src = queue;
|
||||
|
||||
for (uint8_t i = 0; i < size; i++)
|
||||
{
|
||||
News::Item dst{};
|
||||
|
||||
if (src->Type == 0)
|
||||
break;
|
||||
|
||||
dst.Type = static_cast<News::ItemType>(src->Type);
|
||||
dst.Flags = src->Flags;
|
||||
dst.Ticks = src->Ticks;
|
||||
dst.MonthYear = src->MonthYear;
|
||||
dst.Day = src->Day;
|
||||
dst.Text = ConvertFormattedStringToOpenRCT2(std::string_view(src->Text, sizeof(src->Text)));
|
||||
|
||||
if (dst.Type == News::ItemType::Research)
|
||||
{
|
||||
uint8_t researchItem = src->Assoc & 0x000000FF;
|
||||
uint8_t researchType = (src->Assoc & 0x00FF0000) >> 16;
|
||||
|
||||
::ResearchItem tmpResearchItem = {};
|
||||
ConvertResearchEntry(&tmpResearchItem, researchItem, researchType);
|
||||
dst.Assoc = tmpResearchItem.rawValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.Assoc = src->Assoc;
|
||||
}
|
||||
|
||||
output.emplace_back(dst);
|
||||
src++;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void ImportParkFlags(GameState_t& gameState)
|
||||
{
|
||||
// Date and srand
|
||||
@@ -2241,32 +2281,9 @@ namespace OpenRCT2::RCT1
|
||||
}
|
||||
|
||||
// News items
|
||||
for (size_t i = 0; i < Limits::MaxNewsItems; i++)
|
||||
{
|
||||
const RCT12NewsItem* src = &_s4.Messages[i];
|
||||
News::Item* dst = &gameState.NewsItems[i];
|
||||
|
||||
dst->Type = static_cast<News::ItemType>(src->Type);
|
||||
dst->Flags = src->Flags;
|
||||
dst->Ticks = src->Ticks;
|
||||
dst->MonthYear = src->MonthYear;
|
||||
dst->Day = src->Day;
|
||||
dst->Text = ConvertFormattedStringToOpenRCT2(std::string_view(src->Text, sizeof(src->Text)));
|
||||
|
||||
if (dst->Type == News::ItemType::Research)
|
||||
{
|
||||
uint8_t researchItem = src->Assoc & 0x000000FF;
|
||||
uint8_t researchType = (src->Assoc & 0x00FF0000) >> 16;
|
||||
|
||||
::ResearchItem tmpResearchItem = {};
|
||||
ConvertResearchEntry(&tmpResearchItem, researchItem, researchType);
|
||||
dst->Assoc = tmpResearchItem.rawValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst->Assoc = src->Assoc;
|
||||
}
|
||||
}
|
||||
auto recentMessages = convertNewsQueue(_s4.recentMessages, std::size(_s4.recentMessages));
|
||||
auto archivedMessages = convertNewsQueue(_s4.archivedMessages, std::size(_s4.archivedMessages));
|
||||
News::importNewsItems(gameState, recentMessages, archivedMessages);
|
||||
|
||||
// Initial guest status
|
||||
gameState.GuestInitialCash = ToMoney64(_s4.GuestInitialCash);
|
||||
|
||||
@@ -16,7 +16,8 @@ namespace OpenRCT2::RCT12::Limits
|
||||
|
||||
constexpr uint8_t kMaxRidesInPark = 255;
|
||||
constexpr uint8_t kMaxAwards = 4;
|
||||
constexpr uint8_t MaxNewsItems = 61;
|
||||
constexpr uint8_t kMaxRecentNewsItems = 11;
|
||||
constexpr uint8_t kMaxArchivedNewsItems = 50;
|
||||
constexpr uint8_t kMaxStationsPerRide = 4;
|
||||
constexpr uint8_t kMaxPeepSpawns = 2;
|
||||
constexpr uint8_t kMaxParkEntrances = 4;
|
||||
|
||||
@@ -990,7 +990,8 @@ namespace OpenRCT2::RCT2
|
||||
uint8_t NextWeatherGloom;
|
||||
uint8_t CurrentWeatherLevel;
|
||||
uint8_t NextWeatherLevel;
|
||||
RCT12NewsItem NewsItems[Limits::MaxNewsItems];
|
||||
RCT12NewsItem recentMessages[Limits::kMaxRecentNewsItems];
|
||||
RCT12NewsItem archivedMessages[Limits::kMaxArchivedNewsItems];
|
||||
char RCT1ScenarioName[62]; // Unused in RCT2
|
||||
uint16_t RCT1ScenarioSlotIndex; // Unused in RCT2
|
||||
uint32_t RCT1ScenarioFlags; // Unused in RCT2
|
||||
|
||||
@@ -320,6 +320,38 @@ namespace OpenRCT2::RCT2
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<OpenRCT2::News::Item> convertNewsQueue(const RCT12NewsItem* queue, uint8_t size)
|
||||
{
|
||||
std::vector<OpenRCT2::News::Item> output{};
|
||||
const RCT12NewsItem* src = queue;
|
||||
|
||||
for (uint8_t i = 0; i < size; i++)
|
||||
{
|
||||
if (src->Type == 0)
|
||||
break;
|
||||
|
||||
if (src->Type >= News::ItemTypeCount)
|
||||
{
|
||||
LOG_ERROR("Invalid news type 0x%x for news item %d, ignoring remaining news items", src->Type, i);
|
||||
break;
|
||||
}
|
||||
|
||||
News::Item dst{};
|
||||
dst.Type = static_cast<News::ItemType>(src->Type);
|
||||
dst.Flags = src->Flags;
|
||||
dst.Assoc = src->Assoc;
|
||||
dst.Ticks = src->Ticks;
|
||||
dst.MonthYear = src->MonthYear;
|
||||
dst.Day = src->Day;
|
||||
dst.Text = ConvertFormattedStringToOpenRCT2(std::string_view(src->Text, sizeof(src->Text)));
|
||||
|
||||
output.emplace_back(dst);
|
||||
src++;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void Import(GameState_t& gameState) override
|
||||
{
|
||||
Initialise(gameState);
|
||||
@@ -573,30 +605,9 @@ namespace OpenRCT2::RCT2
|
||||
};
|
||||
|
||||
// News items
|
||||
News::InitQueue();
|
||||
for (size_t i = 0; i < Limits::MaxNewsItems; i++)
|
||||
{
|
||||
const RCT12NewsItem* src = &_s6.NewsItems[i];
|
||||
News::Item* dst = &gameState.NewsItems[i];
|
||||
if (src->Type < News::ItemTypeCount)
|
||||
{
|
||||
dst->Type = static_cast<News::ItemType>(src->Type);
|
||||
dst->Flags = src->Flags;
|
||||
dst->Assoc = src->Assoc;
|
||||
dst->Ticks = src->Ticks;
|
||||
dst->MonthYear = src->MonthYear;
|
||||
dst->Day = src->Day;
|
||||
dst->Text = ConvertFormattedStringToOpenRCT2(std::string_view(src->Text, sizeof(src->Text)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// In case where news item type is broken, consider all remaining news items invalid.
|
||||
LOG_ERROR("Invalid news type 0x%x for news item %d, ignoring remaining news items", src->Type, i);
|
||||
// Still need to set the correct type to properly terminate the queue
|
||||
dst->Type = News::ItemType::Null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto recentMessages = convertNewsQueue(_s6.recentMessages, std::size(_s6.recentMessages));
|
||||
auto archivedMessages = convertNewsQueue(_s6.archivedMessages, std::size(_s6.archivedMessages));
|
||||
News::importNewsItems(gameState, recentMessages, archivedMessages);
|
||||
|
||||
// Pad13CE730
|
||||
// rct1_scenario_flags
|
||||
|
||||
Reference in New Issue
Block a user