mirror of https://github.com/OpenRCT2/OpenRCT2.git
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:
parent
399f6f27b4
commit
223b926f8c
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
};
|
|
@ -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" />
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue