Use std::vector for ride use memory (#14884)

* Use std::vector for ride use memory

* Use new system for import/export

* Remove legacy field

* Add replay entity size protection to prevent crash

* Increment network version

* Update replays

* Move function to header

* Move constant to RCT12 header as used for both 1 and 2

* Align naming with nsf
This commit is contained in:
Duncan 2021-08-17 21:29:35 +01:00 committed by GitHub
parent 399f6f27b4
commit 223b926f8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 260 additions and 61 deletions

View File

@ -50,9 +50,9 @@ set(OBJECTS_VERSION "1.0.21")
set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip")
set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5")
set(REPLAYS_VERSION "0.0.46")
set(REPLAYS_VERSION "0.0.47")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip")
set(REPLAYS_SHA1 "4DDCF0A78F8B9A20601607173247C418A2526CC3")
set(REPLAYS_SHA1 "61CAB8A0AD0B057B13B003DF32748977C2B5975F")
option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.")
option(WITH_TESTS "Build tests")

View File

@ -796,6 +796,9 @@
5B6E418A2F264952BA0CC2F2 /* ScTileElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43D18154E96444749737E3F6 /* ScTileElement.cpp */; };
DEC539DE402F4B8993E4C357 /* ScTileElement.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F4C26E211F1D44C9ADA70740 /* ScTileElement.hpp */; };
6C90BE01D190493295071B23 /* ScTile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5B67E36A8620400CA70FBA49 /* ScTile.cpp */; };
258C212125F84FA2B4C3BCAE /* RideUseSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58DEACC694664E7C8DACB93D /* RideUseSystem.cpp */; };
E6C71B6165224F65AA87E65B /* RideUseSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DA720D496604387806AC168 /* RideUseSystem.h */; };
C8D612EB56BD4214BEC0F7FF /* GroupVector.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F4D523B8782E4C458AF1490D /* GroupVector.hpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -1894,6 +1897,9 @@
43D18154E96444749737E3F6 /* ScTileElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScTileElement.cpp; path = src/openrct2/scripting/bindings/world/ScTileElement.cpp; sourceTree = SOURCE_ROOT; };
F4C26E211F1D44C9ADA70740 /* ScTileElement.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScTileElement.hpp; path = src/openrct2/scripting/bindings/world/ScTileElement.hpp; sourceTree = SOURCE_ROOT; };
5B67E36A8620400CA70FBA49 /* ScTile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ScTile.cpp; path = src/openrct2/scripting/bindings/world/ScTile.cpp; sourceTree = SOURCE_ROOT; };
58DEACC694664E7C8DACB93D /* RideUseSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RideUseSystem.cpp; path = src/openrct2/peep/RideUseSystem.cpp; sourceTree = SOURCE_ROOT; };
2DA720D496604387806AC168 /* RideUseSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RideUseSystem.h; path = src/openrct2/peep/RideUseSystem.h; sourceTree = SOURCE_ROOT; };
F4D523B8782E4C458AF1490D /* GroupVector.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = GroupVector.hpp; path = src/openrct2/core/GroupVector.hpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -2563,6 +2569,7 @@
F76C83991EC4E7CC00FA49E2 /* Zip.cpp */,
F76C839A1EC4E7CC00FA49E2 /* Zip.h */,
BA2317BF6FB54E328DEB7055 /* EnumMap.hpp */,
F4D523B8782E4C458AF1490D /* GroupVector.hpp */,
);
path = core;
sourceTree = "<group>";
@ -2831,6 +2838,8 @@
4CFE4E7D1F90A3F1005243C2 /* PeepData.cpp */,
4CFE4E7E1F90A3F1005243C2 /* Staff.cpp */,
4CFE4E7F1F90A3F1005243C2 /* Staff.h */,
58DEACC694664E7C8DACB93D /* RideUseSystem.cpp */,
2DA720D496604387806AC168 /* RideUseSystem.h */,
);
path = peep;
sourceTree = "<group>";
@ -3638,6 +3647,8 @@
63858E295E3F451283987982 /* ScRideStation.hpp in Headers */,
AD5EC8B5EBF240B3874BC581 /* ScParkMessage.hpp in Headers */,
DEC539DE402F4B8993E4C357 /* ScTileElement.hpp in Headers */,
E6C71B6165224F65AA87E65B /* RideUseSystem.h in Headers */,
C8D612EB56BD4214BEC0F7FF /* GroupVector.hpp in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -4457,6 +4468,7 @@
887B0043454440BAB322A9E8 /* ScPark.cpp in Sources */,
5B6E418A2F264952BA0CC2F2 /* ScTileElement.cpp in Sources */,
6C90BE01D190493295071B23 /* ScTile.cpp in Sources */,
258C212125F84FA2B4C3BCAE /* RideUseSystem.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -48,8 +48,8 @@
<TitleSequencesSha1>304d13a126c15bf2c86ff13b81a2f2cc1856ac8d</TitleSequencesSha1>
<ObjectsUrl>https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip</ObjectsUrl>
<ObjectsSha1>c38af45d51a6e440386180feacf76c64720b6ac5</ObjectsSha1>
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.46/replays.zip</ReplaysUrl>
<ReplaysSha1>4DDCF0A78F8B9A20601607173247C418A2526CC3</ReplaysSha1>
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.47/replays.zip</ReplaysUrl>
<ReplaysSha1>61CAB8A0AD0B057B13B003DF32748977C2B5975F</ReplaysSha1>
</PropertyGroup>
<ItemGroup>

View File

@ -39,6 +39,21 @@ struct GameStateSnapshot_t
OpenRCT2::MemoryStream storedSprites;
OpenRCT2::MemoryStream parkParameters;
template<typename T> bool EntitySizeCheck(DataSerialiser& ds)
{
uint32_t size = sizeof(T);
ds << size;
if (ds.IsLoading())
{
return size == sizeof(T);
}
return true;
}
template<typename... T> bool EntitiesSizeCheck(DataSerialiser& ds)
{
return (EntitySizeCheck<T>(ds) && ...);
}
// Must pass a function that can access the sprite.
void SerialiseSprites(std::function<rct_sprite*(const size_t)> getEntity, const size_t numSprites, bool saving)
{
@ -64,6 +79,13 @@ struct GameStateSnapshot_t
numSavedSprites = static_cast<uint32_t>(indexTable.size());
}
// Encodes and checks the size of each of the entity so that we
// can fail gracefully when fields added/removed
if (!EntitiesSizeCheck<Vehicle, Guest, Staff, Litter, MoneyEffect, Balloon, Duck, JumpingFountain, SteamParticle>(ds))
{
log_error("Entity index corrupted!");
return;
}
ds << numSavedSprites;
if (loading)
@ -300,20 +322,12 @@ struct GameStateSnapshots final : public IGameStateSnapshots
COMPARE_FIELD(Guest, Intensity);
COMPARE_FIELD(Guest, NauseaTolerance);
COMPARE_FIELD(Guest, PaidOnDrink);
for (int i = 0; i < 16; i++)
{
COMPARE_FIELD(Guest, RideTypesBeenOn[i]);
}
COMPARE_FIELD(Guest, ItemFlags);
COMPARE_FIELD(Guest, Photo2RideRef);
COMPARE_FIELD(Guest, Photo3RideRef);
COMPARE_FIELD(Guest, Photo4RideRef);
COMPARE_FIELD(Guest, GuestNextInQueue);
COMPARE_FIELD(Guest, TimeInQueue);
for (int i = 0; i < 32; i++)
{
COMPARE_FIELD(Guest, RidesBeenOn[i]);
}
COMPARE_FIELD(Guest, CashInPocket);
COMPARE_FIELD(Guest, CashSpent);

View File

@ -17,6 +17,7 @@
#include "../interface/Window.h"
#include "../localisation/Localisation.h"
#include "../management/NewsItem.h"
#include "../peep/RideUseSystem.h"
#include "../ride/Ride.h"
#include "../ride/RideData.h"
#include "../ui/UiContext.h"
@ -134,6 +135,7 @@ GameActions::Result::Ptr RideDemolishAction::DemolishRide(Ride* ride) const
UnlinkAllBannersForRide(_rideIndex);
RideUse::GetHistory().RemoveValue(_rideIndex);
for (auto peep : EntityList<Guest>())
{
peep->RemoveRideFromMemory(_rideIndex);

View File

@ -0,0 +1,81 @@
/*****************************************************************************
* Copyright (c) 2014-2021 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include <algorithm>
#include <vector>
template<typename Handle, typename V> class GroupVector
{
std::vector<std::vector<V>> _data;
public:
bool Contains(Handle handle, V value)
{
if (handle >= _data.size())
return false;
const auto& values = _data[handle];
return std::find(values.begin(), values.end(), value) != values.end();
}
void Add(Handle handle, V value)
{
if (handle >= _data.size())
{
_data.resize(handle + 1);
}
auto& values = _data[handle];
auto it = std::find(values.begin(), values.end(), value);
if (it != values.end())
return;
values.push_back(value);
}
void Set(Handle handle, std::vector<V>&& values)
{
if (handle >= _data.size())
{
_data.resize(handle + 1);
}
_data[handle] = values;
}
std::vector<V>* GetAll(Handle handle)
{
if (handle < _data.size())
{
return &_data[handle];
}
return nullptr;
}
void Clear()
{
_data.clear();
}
void RemoveHandle(Handle handle)
{
if (handle < _data.size())
{
_data[handle].clear();
}
}
void RemoveValue(V value)
{
for (auto& values : _data)
{
values.erase(std::remove_if(values.begin(), values.end(), [value](auto v) { return v == value; }), values.end());
}
}
};

View File

@ -164,6 +164,7 @@
<ClInclude Include="core\FileStream.h" />
<ClInclude Include="core\FileSystem.hpp" />
<ClInclude Include="core\FileWatcher.h" />
<ClInclude Include="core\GroupVector.hpp" />
<ClInclude Include="core\Guard.hpp" />
<ClInclude Include="core\Http.h" />
<ClInclude Include="core\Imaging.h" />
@ -285,6 +286,7 @@
<ClInclude Include="ParkImporter.h" />
<ClInclude Include="peep\GuestPathfinding.h" />
<ClInclude Include="peep\Peep.h" />
<ClInclude Include="peep\RideUseSystem.h" />
<ClInclude Include="peep\Staff.h" />
<ClInclude Include="PlatformEnvironment.h" />
<ClInclude Include="platform\Crash.h" />
@ -735,6 +737,7 @@
<ClCompile Include="peep\GuestPathfinding.cpp" />
<ClCompile Include="peep\Peep.cpp" />
<ClCompile Include="peep\PeepData.cpp" />
<ClCompile Include="peep\RideUseSystem.cpp" />
<ClCompile Include="peep\Staff.cpp" />
<ClCompile Include="PlatformEnvironment.cpp" />
<ClCompile Include="platform\Android.cpp" />

View File

@ -37,7 +37,7 @@
// This string specifies which version of network stream current build uses.
// It is used for making sure only compatible builds get connected, even within
// single OpenRCT2 version.
#define NETWORK_STREAM_VERSION "3"
#define NETWORK_STREAM_VERSION "4"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
static Peep* _pickup_peep = nullptr;

View File

@ -45,6 +45,7 @@
#include "../world/TileElementsView.h"
#include "GuestPathfinding.h"
#include "Peep.h"
#include "RideUseSystem.h"
#include "Staff.h"
#include <algorithm>
@ -2296,27 +2297,30 @@ void Guest::SpendMoney(money16& peep_expend_type, money32 amount, ExpenditureTyp
void Guest::SetHasRidden(const Ride* ride)
{
RidesBeenOn[ride->id / 8] |= 1 << (ride->id % 8);
OpenRCT2::RideUse::GetHistory().Add(sprite_index, ride->id);
SetHasRiddenRideType(ride->type);
}
bool Guest::HasRidden(const Ride* ride) const
{
return RidesBeenOn[ride->id / 8] & (1 << (ride->id % 8));
return OpenRCT2::RideUse::GetHistory().Contains(sprite_index, ride->id);
}
void Guest::SetHasRiddenRideType(int32_t rideType)
{
// This is needed to avoid desyncs. TODO: remove once the new save format is introduced.
rideType = OpenRCT2RideTypeToRCT2RideType(rideType);
RideTypesBeenOn[rideType / 8] |= 1 << (rideType % 8);
OpenRCT2::RideUse::GetTypeHistory().Add(sprite_index, rideType);
}
bool Guest::HasRiddenRideType(int32_t rideType) const
{
// This is needed to avoid desyncs. TODO: remove once the new save format is introduced.
rideType = OpenRCT2RideTypeToRCT2RideType(rideType);
return RideTypesBeenOn[rideType / 8] & (1 << (rideType % 8));
return OpenRCT2::RideUse::GetTypeHistory().Contains(sprite_index, rideType);
}
void Guest::SetParkEntryTime(int32_t entryTime)
@ -7030,10 +7034,8 @@ Guest* Guest::Generate(const CoordsXYZ& coords)
peep->Toilet = 0;
peep->TimeToConsume = 0;
std::fill_n(peep->RidesBeenOn, 32, 0x00);
peep->GuestNumRides = 0;
std::fill_n(peep->RideTypesBeenOn, 16, 0x00);
peep->Id = gNextGuestNumber++;
peep->Name = nullptr;
@ -7373,11 +7375,6 @@ static bool IsThoughtShopItemRelated(const PeepThoughtType type)
void Guest::RemoveRideFromMemory(ride_id_t rideId)
{
uint8_t ride_id_bit = rideId % 8;
uint8_t ride_id_offset = rideId / 8;
// clear ride from potentially being in RidesBeenOn
RidesBeenOn[ride_id_offset] &= ~(1 << ride_id_bit);
if (State == PeepState::Watching)
{
if (CurrentRide == rideId)

View File

@ -693,11 +693,7 @@ public:
uint8_t TimeToConsume;
IntensityRange Intensity{ 0 };
PeepNauseaTolerance NauseaTolerance;
uint8_t RideTypesBeenOn[16];
uint16_t TimeInQueue;
// 255 bit bitmap of every ride the peep has been on see
// window_peep_rides_update for how to use.
uint8_t RidesBeenOn[32];
money32 CashInPocket;
money32 CashSpent;
ride_id_t Photo1RideRef;

View File

@ -0,0 +1,26 @@
/*****************************************************************************
* Copyright (c) 2014-2021 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#include "RideUseSystem.h"
namespace OpenRCT2::RideUse
{
static RideHistory _history;
static RideTypeHistory _typeHistory;
RideHistory& GetHistory()
{
return _history;
}
RideTypeHistory& GetTypeHistory()
{
return _typeHistory;
}
} // namespace OpenRCT2::RideUse

View File

@ -0,0 +1,22 @@
/*****************************************************************************
* Copyright (c) 2014-2021 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include "../core/GroupVector.hpp"
#include "../ride/RideTypes.h"
namespace OpenRCT2::RideUse
{
using RideHistory = GroupVector<uint16_t, ride_id_t>;
using RideTypeHistory = GroupVector<uint16_t, uint16_t>;
RideHistory& GetHistory();
RideTypeHistory& GetTypeHistory();
} // namespace OpenRCT2::RideUse

View File

@ -33,6 +33,7 @@
#include "../object/ObjectManager.h"
#include "../object/ObjectRepository.h"
#include "../peep/Peep.h"
#include "../peep/RideUseSystem.h"
#include "../peep/Staff.h"
#include "../ride/RideData.h"
#include "../ride/Station.h"
@ -2832,14 +2833,8 @@ template<> void S4Importer::ImportEntity<Guest>(const RCT12SpriteBase& srcBase)
dst->Angriness = src->angriness;
dst->TimeLost = src->time_lost;
for (size_t i = 0; i < 32; i++)
{
dst->RidesBeenOn[i] = src->rides_been_on[i];
}
for (size_t i = 0; i < 16; i++)
{
dst->RideTypesBeenOn[i] = src->ride_types_been_on[i];
}
OpenRCT2::RideUse::GetHistory().Set(dst->sprite_index, RCT12GetRidesBeenOn(src));
OpenRCT2::RideUse::GetTypeHistory().Set(dst->sprite_index, RCT12GetRideTypesBeenOn(src));
dst->Photo1RideRef = RCT12RideIdToOpenRCT2RideId(src->photo1_ride_ref);

View File

@ -17,6 +17,7 @@
#include <string>
#include <string_view>
#include <vector>
using track_type_t = uint16_t;
using RCT12TrackType = uint8_t;
@ -26,6 +27,8 @@ constexpr uint8_t RCT2_STRING_FORMAT_ARG_END = 141;
constexpr uint8_t RCT2_STRING_FORMAT_COLOUR_START = 142;
constexpr uint8_t RCT2_STRING_FORMAT_COLOUR_END = 156;
constexpr const uint8_t RCT12_MAX_RIDE_OBJECTS = 128;
constexpr const uint8_t RCT12_MAX_RIDES_IN_PARK = 255;
constexpr const uint8_t RCT12_MAX_AWARDS = 4;
constexpr const uint8_t RCT12_MAX_NEWS_ITEMS = 61;
@ -937,3 +940,28 @@ static constexpr money32 RCT12_COMPANY_VALUE_ON_FAILED_OBJECTIVE = 0x80000001;
money64 RCT12CompletedCompanyValueToOpenRCT2(money32 origValue);
money32 OpenRCT2CompletedCompanyValueToRCT12(money64 origValue);
template<typename T> std::vector<uint16_t> RCT12GetRideTypesBeenOn(T* srcPeep)
{
std::vector<uint16_t> ridesTypesBeenOn;
for (uint16_t i = 0; i < RCT12_MAX_RIDE_OBJECTS; i++)
{
if (srcPeep->ride_types_been_on[i / 8] & (1 << (i % 8)))
{
ridesTypesBeenOn.push_back(i);
}
}
return ridesTypesBeenOn;
}
template<typename T> std::vector<ride_id_t> RCT12GetRidesBeenOn(T* srcPeep)
{
std::vector<ride_id_t> ridesBeenOn;
for (uint16_t i = 0; i < RCT12_MAX_RIDES_IN_PARK; i++)
{
if (srcPeep->rides_been_on[i / 8] & (1 << (i % 8)))
{
ridesBeenOn.push_back(i);
}
}
return ridesBeenOn;
}

View File

@ -39,7 +39,6 @@ constexpr const uint16_t RCT2_MAX_RESEARCHED_SCENERY_ITEMS = (RCT2_MAX_RESEARCHE
// per quad.
constexpr uint16_t TD6MaxTrackElements = 8192;
constexpr const uint8_t RCT2_MAX_RIDE_OBJECTS = 128;
constexpr const uint8_t RCT2_MAX_SMALL_SCENERY_OBJECTS = 252;
constexpr const uint8_t RCT2_MAX_LARGE_SCENERY_OBJECTS = 128;
constexpr const uint8_t RCT2_MAX_WALL_SCENERY_OBJECTS = 128;
@ -58,7 +57,7 @@ constexpr const uint16_t RCT2_MAXIMUM_MAP_SIZE_TECHNICAL = 256;
// clang-format off
constexpr const uint16_t RCT2_OBJECT_ENTRY_COUNT =
RCT2_MAX_RIDE_OBJECTS +
RCT12_MAX_RIDE_OBJECTS +
RCT2_MAX_SMALL_SCENERY_OBJECTS +
RCT2_MAX_LARGE_SCENERY_OBJECTS +
RCT2_MAX_WALL_SCENERY_OBJECTS +
@ -74,7 +73,7 @@ static_assert(RCT2_OBJECT_ENTRY_COUNT == 721);
// clang-format off
constexpr const int32_t rct2_object_entry_group_counts[] = {
RCT2_MAX_RIDE_OBJECTS,
RCT12_MAX_RIDE_OBJECTS,
RCT2_MAX_SMALL_SCENERY_OBJECTS,
RCT2_MAX_LARGE_SCENERY_OBJECTS,
RCT2_MAX_WALL_SCENERY_OBJECTS,

View File

@ -33,6 +33,7 @@
#include "../object/ObjectManager.h"
#include "../object/ObjectRepository.h"
#include "../peep/Peep.h"
#include "../peep/RideUseSystem.h"
#include "../peep/Staff.h"
#include "../rct12/SawyerChunkWriter.h"
#include "../ride/Ride.h"
@ -1212,9 +1213,21 @@ template<> void S6Exporter::ExportEntity(RCT2SpritePeep* dst, const Guest* src)
dst->intensity = static_cast<uint8_t>(src->Intensity);
dst->nausea_tolerance = EnumValue(src->NauseaTolerance);
dst->paid_on_drink = src->PaidOnDrink;
for (size_t i = 0; i < std::size(src->RideTypesBeenOn); i++)
auto* typeHistory = OpenRCT2::RideUse::GetTypeHistory().GetAll(src->sprite_index);
if (typeHistory != nullptr)
{
dst->ride_types_been_on[i] = src->RideTypesBeenOn[i];
for (auto typeId : *typeHistory)
{
dst->ride_types_been_on[typeId / 8] |= (1 << (typeId % 8));
}
}
auto* rideHistory = OpenRCT2::RideUse::GetHistory().GetAll(src->sprite_index);
if (rideHistory != nullptr)
{
for (auto rideId : *rideHistory)
{
dst->rides_been_on[rideId / 8] |= (1 << (rideId % 8));
}
}
dst->item_extra_flags = static_cast<uint32_t>(src->GetItemFlags() >> 32);
dst->photo1_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo1RideRef);
@ -1223,10 +1236,6 @@ template<> void S6Exporter::ExportEntity(RCT2SpritePeep* dst, const Guest* src)
dst->photo4_ride_ref = OpenRCT2RideIdToRCT12RideId(src->Photo4RideRef);
dst->next_in_queue = src->GuestNextInQueue;
dst->time_in_queue = src->TimeInQueue;
for (size_t i = 0; i < std::size(src->RidesBeenOn); i++)
{
dst->rides_been_on[i] = src->RidesBeenOn[i];
}
dst->cash_in_pocket = src->CashInPocket;
dst->cash_spent = src->CashSpent;
dst->park_entry_time = src->ParkEntryTime;

View File

@ -34,6 +34,7 @@
#include "../object/ObjectManager.h"
#include "../object/ObjectRepository.h"
#include "../peep/Peep.h"
#include "../peep/RideUseSystem.h"
#include "../peep/Staff.h"
#include "../rct12/RCT12.h"
#include "../rct12/SawyerChunkReader.h"
@ -1699,10 +1700,10 @@ template<> void S6Importer::ImportEntity<Guest>(const RCT12SpriteBase& baseSrc)
dst->Intensity = static_cast<IntensityRange>(src->intensity);
dst->NauseaTolerance = static_cast<PeepNauseaTolerance>(src->nausea_tolerance);
dst->PaidOnDrink = src->paid_on_drink;
for (size_t i = 0; i < std::size(src->ride_types_been_on); i++)
{
dst->RideTypesBeenOn[i] = src->ride_types_been_on[i];
}
OpenRCT2::RideUse::GetHistory().Set(dst->sprite_index, RCT12GetRidesBeenOn(src));
OpenRCT2::RideUse::GetTypeHistory().Set(dst->sprite_index, RCT12GetRideTypesBeenOn(src));
dst->SetItemFlags(src->GetItemFlags());
dst->Photo1RideRef = RCT12RideIdToOpenRCT2RideId(src->photo1_ride_ref);
dst->Photo2RideRef = RCT12RideIdToOpenRCT2RideId(src->photo2_ride_ref);
@ -1710,10 +1711,6 @@ template<> void S6Importer::ImportEntity<Guest>(const RCT12SpriteBase& baseSrc)
dst->Photo4RideRef = RCT12RideIdToOpenRCT2RideId(src->photo4_ride_ref);
dst->GuestNextInQueue = src->next_in_queue;
dst->TimeInQueue = src->time_in_queue;
for (size_t i = 0; i < std::size(src->rides_been_on); i++)
{
dst->RidesBeenOn[i] = src->rides_been_on[i];
}
dst->CashInPocket = src->cash_in_pocket;
dst->CashSpent = src->cash_spent;
dst->ParkEntryTime = src->park_entry_time;

View File

@ -186,9 +186,7 @@ void Guest::Serialise(DataSerialiser& stream)
stream << TimeToConsume;
stream << Intensity;
stream << NauseaTolerance;
stream << RideTypesBeenOn;
stream << TimeInQueue;
stream << RidesBeenOn;
stream << CashInPocket;
stream << CashSpent;
stream << Photo1RideRef;

View File

@ -17,6 +17,7 @@
#include "../core/MemoryStream.h"
#include "../interface/Viewport.h"
#include "../peep/Peep.h"
#include "../peep/RideUseSystem.h"
#include "../ride/Vehicle.h"
#include "../scenario/Scenario.h"
#include "Balloon.h"
@ -43,6 +44,8 @@ constexpr const uint32_t SPATIAL_INDEX_LOCATION_NULL = SPATIAL_INDEX_SIZE - 1;
static std::array<std::vector<uint16_t>, SPATIAL_INDEX_SIZE> gSpriteSpatialIndex;
static void FreeEntity(SpriteBase* entity);
constexpr size_t GetSpatialIndexOffset(int32_t x, int32_t y)
{
size_t index = SPATIAL_INDEX_LOCATION_NULL;
@ -226,6 +229,8 @@ void reset_sprite_list()
{
gSavedAge = 0;
std::memset(static_cast<void*>(_spriteList), 0, sizeof(_spriteList));
OpenRCT2::RideUse::GetHistory().Clear();
OpenRCT2::RideUse::GetTypeHistory().Clear();
for (int32_t i = 0; i < MAX_ENTITIES; ++i)
{
auto* spr = GetEntity(i);
@ -233,7 +238,7 @@ void reset_sprite_list()
{
continue;
}
FreeEntity(spr);
spr->Type = EntityType::Null;
spr->sprite_index = i;
@ -537,17 +542,32 @@ void sprite_set_coordinates(const CoordsXYZ& spritePos, SpriteBase* sprite)
sprite->z = spritePos.z;
}
/**
* Frees any dynamically attached memory to the entity, such as peep name.
*/
static void FreeEntity(SpriteBase* entity)
{
auto* guest = entity->As<Guest>();
auto* staff = entity->As<Staff>();
if (staff != nullptr)
{
staff->SetName({});
}
else if (guest != nullptr)
{
guest->SetName({});
OpenRCT2::RideUse::GetHistory().RemoveHandle(guest->sprite_index);
OpenRCT2::RideUse::GetTypeHistory().RemoveHandle(guest->sprite_index);
}
}
/**
*
* rct2: 0x0069EDB6
*/
void sprite_remove(SpriteBase* sprite)
{
auto peep = sprite->As<Peep>();
if (peep != nullptr)
{
peep->SetName({});
}
FreeEntity(sprite);
EntityTweener::Get().RemoveEntity(sprite);
RemoveFromEntityList(sprite); // remove from existing list