Implement train view and remove linked_list_index (#13956)

* Make train manager view

* Remove linked list index field

* Remove merge mistake

* Fix further rebase errors

* Rename and add comments

* Update replays

* Fix Xcode project

* Increment network version

Co-authored-by: Michael Steenbeek <m.o.steenbeek@gmail.com>
This commit is contained in:
Duncan 2021-03-15 08:13:00 +00:00 committed by GitHub
parent cc68b8bf4d
commit 5474194905
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 166 additions and 85 deletions

View File

@ -48,8 +48,8 @@ set(TITLE_SEQUENCE_SHA1 "304d13a126c15bf2c86ff13b81a2f2cc1856ac8d")
set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip")
set(OBJECTS_SHA1 "c38af45d51a6e440386180feacf76c64720b6ac5")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.31/replays.zip")
set(REPLAYS_SHA1 "693BDD6F4B7C3B312AABEBCAEA4800FE97B33527")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.32/replays.zip")
set(REPLAYS_SHA1 "45843591A8C6739CA1D60899B7E54FC0792EF896")
option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.")
option(WITH_TESTS "Build tests")

View File

@ -51,6 +51,7 @@
4C3B4236205914F7000C5BB7 /* InGameConsole.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C3B4234205914F7000C5BB7 /* InGameConsole.cpp */; };
4C724B2221F0AD790012ADD0 /* BenchSpriteSort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C724B2121F0AD790012ADD0 /* BenchSpriteSort.cpp */; };
4C81F7E124672C4D000E61BF /* CustomListView.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C81F7DF24672C4D000E61BF /* CustomListView.cpp */; };
4C882FBA25FEA80E0039D1C4 /* TrainManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C882FB825FEA80D0039D1C4 /* TrainManager.cpp */; };
4C8A6FF323EB5326001A8255 /* Http.cURL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C8A6FF223EB5326001A8255 /* Http.cURL.cpp */; };
4C8BB67925533D4C005C8830 /* FileStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C8BB67825533D4C005C8830 /* FileStream.cpp */; };
4C8BB67C25533D59005C8830 /* JobPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C8BB67B25533D59005C8830 /* JobPool.cpp */; };
@ -1017,6 +1018,10 @@
4C81F7DF24672C4D000E61BF /* CustomListView.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CustomListView.cpp; path = scripting/CustomListView.cpp; sourceTree = "<group>"; };
4C81F7E024672C4D000E61BF /* CustomListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomListView.h; path = scripting/CustomListView.h; sourceTree = "<group>"; };
4C81F7E224672C58000E61BF /* ScTileSelection.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScTileSelection.hpp; path = scripting/ScTileSelection.hpp; sourceTree = "<group>"; };
4C882FB825FEA80D0039D1C4 /* TrainManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrainManager.cpp; sourceTree = "<group>"; };
4C882FB925FEA80E0039D1C4 /* TrainManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrainManager.h; sourceTree = "<group>"; };
4C882FBB25FEA8260039D1C4 /* VehicleColour.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VehicleColour.h; sourceTree = "<group>"; };
4C882FBC25FEA8270039D1C4 /* VehicleEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VehicleEntry.h; sourceTree = "<group>"; };
4C8A6FF123EB5325001A8255 /* Http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Http.h; sourceTree = "<group>"; };
4C8A6FF223EB5326001A8255 /* Http.cURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Http.cURL.cpp; sourceTree = "<group>"; };
4C8B426E1EEB1ABD00F015CA /* X8DrawingEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = X8DrawingEngine.cpp; sourceTree = "<group>"; };
@ -3587,10 +3592,14 @@
F73E320E2011589F00C4D975 /* TrackDesignSave.cpp */,
4C7B540B20060D8100A52E21 /* TrackPaint.cpp */,
4C7B540C20060D8100A52E21 /* TrackPaint.h */,
4C882FB825FEA80D0039D1C4 /* TrainManager.cpp */,
4C882FB925FEA80E0039D1C4 /* TrainManager.h */,
4CFE4E831F90AF41005243C2 /* Vehicle.cpp */,
4CFE4E841F90AF41005243C2 /* Vehicle.h */,
4C882FBB25FEA8260039D1C4 /* VehicleColour.h */,
4C7B54052005735F00A52E21 /* VehicleData.cpp */,
4C7B540920060D7000A52E21 /* VehicleData.h */,
4C882FBC25FEA8270039D1C4 /* VehicleEntry.h */,
4C7B54072005736700A52E21 /* VehiclePaint.cpp */,
4C7B540A20060D7900A52E21 /* VehiclePaint.h */,
4CB2716824195B45000CF9EE /* VehicleSubpositionData.cpp */,
@ -4502,6 +4511,7 @@
6341F4E12400AA0F0052902B /* Drawing.Sprite.RLE.cpp in Sources */,
C666EE6C1F37ACB10061AA04 /* Changelog.cpp in Sources */,
C64644FC1F3FA4120026AC2D /* Footpath.cpp in Sources */,
4C882FBA25FEA80E0039D1C4 /* TrainManager.cpp in Sources */,
F76C887C1EC5324E00FA49E2 /* MemoryAudioSource.cpp in Sources */,
C654DF3D1F69C0430040F43D /* TrackDesignPlace.cpp in Sources */,
C666EE721F37ACB10061AA04 /* Multiplayer.cpp in Sources */,

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.31/replays.zip</ReplaysUrl>
<ReplaysSha1>693BDD6F4B7C3B312AABEBCAEA4800FE97B33527</ReplaysSha1>
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.32/replays.zip</ReplaysUrl>
<ReplaysSha1>45843591A8C6739CA1D60899B7E54FC0792EF896</ReplaysSha1>
</PropertyGroup>
<ItemGroup>

View File

@ -26,6 +26,7 @@
#include <openrct2/localisation/Localisation.h>
#include <openrct2/ride/RideData.h>
#include <openrct2/ride/Track.h>
#include <openrct2/ride/TrainManager.h>
#include <openrct2/world/EntityList.h>
#include <openrct2/world/Entrance.h>
#include <openrct2/world/Footpath.h>
@ -1118,7 +1119,7 @@ static void window_map_paint_peep_overlay(rct_drawpixelinfo* dpi)
*/
static void window_map_paint_train_overlay(rct_drawpixelinfo* dpi)
{
for (auto train : EntityList<Vehicle>(EntityListId::TrainHead))
for (auto train : TrainManager::View())
{
for (Vehicle* vehicle = train; vehicle != nullptr; vehicle = GetEntity<Vehicle>(vehicle->next_vehicle_on_train))
{

View File

@ -201,7 +201,6 @@ struct GameStateSnapshots final : public IGameStateSnapshots
const SpriteBase& spriteBase, const SpriteBase& spriteCmp, GameStateSpriteChange_t& changeData) const
{
COMPARE_FIELD(SpriteBase, sprite_identifier);
COMPARE_FIELD(SpriteBase, linked_list_index);
COMPARE_FIELD(SpriteBase, sprite_index);
COMPARE_FIELD(SpriteBase, flags);
COMPARE_FIELD(SpriteBase, x);

View File

@ -142,7 +142,6 @@ GameActions::Result::Ptr StaffHireNewAction::QueryExecute(bool execute) const
}
else
{
newPeep->sprite_identifier = SpriteIdentifier::Peep;
newPeep->WindowInvalidateFlags = 0;
newPeep->Action = PeepActionType::None2;
newPeep->SpecialSprite = 0;

View File

@ -383,6 +383,7 @@
<ClInclude Include="ride\TrackDesign.h" />
<ClInclude Include="ride\TrackDesignRepository.h" />
<ClInclude Include="ride\TrackPaint.h" />
<ClInclude Include="ride\TrainManager.h" />
<ClInclude Include="ride\transport\meta\Chairlift.h" />
<ClInclude Include="ride\transport\meta\Lift.h" />
<ClInclude Include="ride\transport\meta\MiniatureRailway.h" />
@ -815,6 +816,7 @@
<ClCompile Include="ride\TrackDesignRepository.cpp" />
<ClCompile Include="ride\TrackDesignSave.cpp" />
<ClCompile Include="ride\TrackPaint.cpp" />
<ClCompile Include="ride\TrainManager.cpp" />
<ClCompile Include="ride\transport\Chairlift.cpp" />
<ClCompile Include="ride\transport\Lift.cpp" />
<ClCompile Include="ride\transport\MiniatureRailway.cpp" />

View File

@ -36,7 +36,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 "1"
#define NETWORK_STREAM_VERSION "2"
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
static Peep* _pickup_peep = nullptr;

View File

@ -1612,7 +1612,6 @@ Peep* Peep::Generate(const CoordsXYZ& coords)
return nullptr;
Peep* peep = &create_sprite(SpriteIdentifier::Peep)->peep;
peep->sprite_identifier = SpriteIdentifier::Peep;
peep->SpriteType = PeepSpriteType::Normal;
peep->OutsideOfPark = true;
peep->State = PeepState::Falling;

View File

@ -37,6 +37,7 @@
#include "../ride/RideData.h"
#include "../ride/Station.h"
#include "../ride/Track.h"
#include "../ride/TrainManager.h"
#include "../scenario/Scenario.h"
#include "../scenario/ScenarioRepository.h"
#include "../scenario/ScenarioSources.h"
@ -1136,11 +1137,7 @@ private:
rct1_vehicle* srcVehicle = &_s4.sprites[i].vehicle;
if (srcVehicle->x != LOCATION_NULL)
{
// If vehicle is the first car on a train add to train list
auto isFirstCar = srcVehicle->type == static_cast<uint8_t>(Vehicle::Type::Head);
auto llt = isFirstCar ? EntityListId::TrainHead : EntityListId::Vehicle;
Vehicle* vehicle = reinterpret_cast<Vehicle*>(create_sprite(SpriteIdentifier::Vehicle, llt));
Vehicle* vehicle = reinterpret_cast<Vehicle*>(create_sprite(SpriteIdentifier::Vehicle));
spriteIndexMap[i] = vehicle->sprite_index;
vehicles.push_back(vehicle);

View File

@ -43,6 +43,7 @@
#include "../ride/ShopItem.h"
#include "../ride/Station.h"
#include "../ride/Track.h"
#include "../ride/TrainManager.h"
#include "../scenario/Scenario.h"
#include "../scenario/ScenarioRepository.h"
#include "../util/SawyerCoding.h"
@ -1680,7 +1681,6 @@ public:
void ImportSpriteCommonProperties(SpriteBase* dst, const RCT12SpriteBase* src)
{
dst->sprite_identifier = src->sprite_identifier;
dst->linked_list_index = static_cast<EntityListId>(EnumValue(src->linked_list_type_offset) >> 1);
dst->sprite_height_negative = src->sprite_height_negative;
dst->sprite_index = src->sprite_index;
dst->flags = src->flags;

View File

@ -24,9 +24,7 @@
Vehicle* cable_lift_segment_create(
Ride& ride, int32_t x, int32_t y, int32_t z, int32_t direction, uint16_t var_44, int32_t remaining_distance, bool head)
{
Vehicle* current = &(
create_sprite(SpriteIdentifier::Vehicle, head ? EntityListId::TrainHead : EntityListId::Vehicle)->vehicle);
current->sprite_identifier = SpriteIdentifier::Vehicle;
Vehicle* current = &(create_sprite(SpriteIdentifier::Vehicle)->vehicle);
current->ride = ride.id;
current->ride_subtype = RIDE_ENTRY_INDEX_NULL;
if (head)

View File

@ -63,6 +63,7 @@
#include "Track.h"
#include "TrackData.h"
#include "TrackDesign.h"
#include "TrainManager.h"
#include "Vehicle.h"
#include <algorithm>
@ -4092,12 +4093,10 @@ static Vehicle* vehicle_create_car(
return nullptr;
auto vehicleEntry = &rideEntry->vehicles[vehicleEntryIndex];
auto vehicle = &create_sprite(SpriteIdentifier::Vehicle, carIndex == 0 ? EntityListId::TrainHead : EntityListId::Vehicle)
->vehicle;
auto vehicle = &create_sprite(SpriteIdentifier::Vehicle)->vehicle;
if (vehicle == nullptr)
return nullptr;
vehicle->sprite_identifier = SpriteIdentifier::Vehicle;
vehicle->ride = rideIndex;
vehicle->ride_subtype = ride->subtype;

View File

@ -0,0 +1,37 @@
/*****************************************************************************
* 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 "TrainManager.h"
#include "../world/Entity.h"
#include "../world/EntityList.h"
#include "Vehicle.h"
namespace TrainManager
{
View::Iterator& View::Iterator::operator++()
{
Entity = nullptr;
while (iter != end && Entity == nullptr)
{
Entity = GetEntity<Vehicle>(*iter++);
if (Entity && !Entity->IsHead())
{
Entity = nullptr;
}
}
return *this;
}
View::View()
{
vec = &GetEntityList(EntityListId::Vehicle);
}
} // namespace TrainManager

View File

@ -0,0 +1,77 @@
/*****************************************************************************
* 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 <cstdint>
#include <list>
struct Vehicle;
namespace TrainManager
{
// Iteration of heads of trains
class View
{
private:
const std::list<uint16_t>* vec;
class Iterator
{
private:
std::list<uint16_t>::const_iterator iter;
std::list<uint16_t>::const_iterator end;
Vehicle* Entity = nullptr;
public:
Iterator(std::list<uint16_t>::const_iterator _iter, std::list<uint16_t>::const_iterator _end)
: iter(_iter)
, end(_end)
{
++(*this);
}
Iterator& operator++();
Iterator operator++(int)
{
Iterator retval = *this;
++(*this);
return retval;
}
bool operator==(Iterator other) const
{
return Entity == other.Entity;
}
bool operator!=(Iterator other) const
{
return !(*this == other);
}
Vehicle* operator*()
{
return Entity;
}
// iterator traits
using difference_type = std::ptrdiff_t;
using value_type = Vehicle;
using pointer = const Vehicle*;
using reference = const Vehicle&;
using iterator_category = std::forward_iterator_tag;
};
public:
View();
Iterator begin()
{
return Iterator(std::cbegin(*vec), std::cend(*vec));
}
Iterator end()
{
return Iterator(std::cend(*vec), std::cend(*vec));
}
};
} // namespace TrainManager

View File

@ -40,6 +40,7 @@
#include "Station.h"
#include "Track.h"
#include "TrackData.h"
#include "TrainManager.h"
#include "VehicleData.h"
#include "VehicleSubpositionData.h"
@ -1295,7 +1296,7 @@ void vehicle_sounds_update()
vehicle_sounds_update_window_setup();
for (auto vehicle : EntityList<Vehicle>(EntityListId::TrainHead))
for (auto vehicle : TrainManager::View())
{
vehicle->UpdateSoundParams(vehicleSoundParamsList);
}
@ -1378,7 +1379,7 @@ void vehicle_update_all()
if ((gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) && gS6Info.editor_step != EditorStep::RollercoasterDesigner)
return;
for (auto vehicle : EntityList<Vehicle>(EntityListId::TrainHead))
for (auto vehicle : TrainManager::View())
{
vehicle->Update();
}
@ -7243,7 +7244,6 @@ static void steam_particle_create(const CoordsXYZ& coords)
steam->sprite_width = 20;
steam->sprite_height_negative = 18;
steam->sprite_height_positive = 16;
steam->sprite_identifier = SpriteIdentifier::Misc;
steam->SubType = MiscEntityType::SteamParticle;
steam->frame = 256;
steam->time_to_move = 0;

View File

@ -13,6 +13,7 @@
# include "../common.h"
# include "../ride/Ride.h"
# include "../ride/TrainManager.h"
# include "../world/EntityList.h"
# include "../world/Map.h"
# include "Duktape.hpp"
@ -108,7 +109,17 @@ namespace OpenRCT2::Scripting
}
if (type == "car")
{
targetList = EntityListId::TrainHead;
std::vector<DukValue> result;
for (auto trainHead : TrainManager::View())
{
for (auto carId = trainHead->sprite_index; carId != SPRITE_INDEX_NULL;)
{
auto car = GetEntity<Vehicle>(carId);
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScVehicle>(carId)));
carId = car->next_vehicle_on_train;
}
}
return result;
}
else if (type == "litter")
{
@ -138,15 +149,6 @@ namespace OpenRCT2::Scripting
else
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScGuest>(sprite->sprite_index)));
}
else if (targetList == EntityListId::TrainHead)
{
for (auto carId = sprite->sprite_index; carId != SPRITE_INDEX_NULL;)
{
auto car = GetEntity<Vehicle>(carId);
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScVehicle>(carId)));
carId = car->next_vehicle_on_train;
}
}
else if (targetList == EntityListId::Misc)
{
auto* misc = sprite->As<MiscEntity>();

View File

@ -85,7 +85,6 @@ void create_balloon(const CoordsXYZ& balloonPos, int32_t colour, bool isPopped)
rct_sprite* sprite = create_sprite(SpriteIdentifier::Misc);
if (sprite == nullptr)
return;
sprite->misc.sprite_identifier = SpriteIdentifier::Misc;
sprite->misc.SubType = MiscEntityType::Balloon;
auto balloon = sprite->misc.As<Balloon>();
if (balloon == nullptr)

View File

@ -291,7 +291,6 @@ void create_duck(const CoordsXY& pos)
targetPos.x += offsetXY;
targetPos.y += offsetXY;
sprite->misc.sprite_identifier = SpriteIdentifier::Misc;
sprite->misc.SubType = MiscEntityType::Duck;
auto duck = sprite->misc.As<Duck>();
if (duck == nullptr)

View File

@ -138,7 +138,6 @@ void JumpingFountain::Create(
jumpingFountain->sprite_width = 33;
jumpingFountain->sprite_height_negative = 36;
jumpingFountain->sprite_height_positive = 12;
jumpingFountain->sprite_identifier = SpriteIdentifier::Misc;
jumpingFountain->MoveTo(newLoc);
jumpingFountain->SubType = newType == JUMPING_FOUNTAIN_TYPE_SNOW ? MiscEntityType::JumpingFountainSnow
: MiscEntityType::JumpingFountainWater;

View File

@ -42,7 +42,6 @@ void MoneyEffect::CreateAt(money32 value, const CoordsXYZ& effectPos, bool verti
moneyEffect->sprite_width = 64;
moneyEffect->sprite_height_negative = 20;
moneyEffect->sprite_height_positive = 30;
moneyEffect->sprite_identifier = SpriteIdentifier::Misc;
moneyEffect->MoveTo(effectPos);
moneyEffect->SubType = MiscEntityType::MoneyEffect;
moneyEffect->NumMovements = 0;

View File

@ -39,7 +39,6 @@ void crashed_vehicle_particle_create(rct_vehicle_colour colours, const CoordsXYZ
sprite->sprite_width = 8;
sprite->sprite_height_negative = 8;
sprite->sprite_height_positive = 8;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(vehiclePos);
sprite->SubType = MiscEntityType::CrashedVehicleParticle;
@ -128,7 +127,6 @@ void crash_splash_create(const CoordsXYZ& splashPos)
sprite->sprite_width = 33;
sprite->sprite_height_negative = 51;
sprite->sprite_height_positive = 16;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(splashPos + CoordsXYZ{ 0, 0, 3 });
sprite->SubType = MiscEntityType::CrashSplash;
sprite->frame = 0;

View File

@ -237,8 +237,8 @@ void RebuildEntityLists()
}
else
{
// auto listId = EntityIdentifierToListId(ent.misc.sprite_identifier);
gEntityLists[EnumValue(ent.misc.linked_list_index)].push_back(ent.misc.sprite_index);
auto listId = EntityIdentifierToListId(ent.misc.sprite_identifier);
gEntityLists[EnumValue(listId)].push_back(ent.misc.sprite_index);
}
}
// List needs to be back to front to simplify removing
@ -268,7 +268,6 @@ void reset_sprite_list()
spr->sprite_identifier = SpriteIdentifier::Null;
spr->sprite_index = i;
spr->linked_list_index = EntityListId::Free;
_spriteFlashingList[i] = false;
}
@ -371,13 +370,11 @@ rct_sprite_checksum sprite_checksum()
static void sprite_reset(SpriteBase* sprite)
{
// Need to retain how the sprite is linked in lists
auto llto = sprite->linked_list_index;
uint16_t sprite_index = sprite->sprite_index;
_spriteFlashingList[sprite_index] = false;
std::memset(sprite, 0, sizeof(rct_sprite));
sprite->linked_list_index = llto;
sprite->sprite_index = sprite_index;
sprite->sprite_identifier = SpriteIdentifier::Null;
}
@ -396,17 +393,16 @@ void sprite_clear_all_unused()
continue;
}
sprite_reset(entity);
entity->linked_list_index = EntityListId::Free;
_spriteFlashingList[entity->sprite_index] = false;
}
}
static constexpr uint16_t MAX_MISC_SPRITES = 300;
static void AddToEntityList(const EntityListId linkedListIndex, SpriteBase* entity)
static void AddToEntityList(SpriteBase* entity)
{
auto& list = gEntityLists[EnumValue(linkedListIndex)];
entity->linked_list_index = linkedListIndex;
auto listId = EntityIdentifierToListId(entity->sprite_identifier);
auto& list = gEntityLists[EnumValue(listId)];
// Entity list must be in sprite_index order to prevent desync issues
list.insert(std::lower_bound(std::begin(list), std::end(list), entity->sprite_index), entity->sprite_index);
}
@ -419,7 +415,8 @@ static void AddToFreeList(uint16_t index)
static void RemoveFromEntityList(SpriteBase* entity)
{
auto& list = gEntityLists[EnumValue(entity->linked_list_index)];
auto listId = EntityIdentifierToListId(entity->sprite_identifier);
auto& list = gEntityLists[EnumValue(listId)];
auto ptr = std::lower_bound(std::begin(list), std::end(list), entity->sprite_index);
if (ptr != std::end(list) && *ptr == entity->sprite_index)
{
@ -427,7 +424,7 @@ static void RemoveFromEntityList(SpriteBase* entity)
}
}
rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier, EntityListId linkedListIndex)
rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier)
{
if (_freeIdList.size() == 0)
{
@ -435,7 +432,7 @@ rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier, EntityListId linked
return nullptr;
}
if (linkedListIndex == EntityListId::Misc)
if (spriteIdentifier == SpriteIdentifier::Misc)
{
// Misc sprites are commonly used for effects, if there are less than MAX_MISC_SPRITES
// free it will fail to keep slots for more relevant sprites.
@ -454,11 +451,13 @@ rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier, EntityListId linked
}
_freeIdList.pop_back();
AddToEntityList(linkedListIndex, sprite);
// Need to reset all sprite data, as the uninitialised values
// may contain garbage and cause a desync later on.
sprite_reset(sprite);
sprite->sprite_identifier = spriteIdentifier;
AddToEntityList(sprite);
sprite->x = LOCATION_NULL;
sprite->y = LOCATION_NULL;
sprite->z = 0;
@ -473,30 +472,6 @@ rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier, EntityListId linked
return reinterpret_cast<rct_sprite*>(sprite);
}
rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier)
{
EntityListId linkedListIndex = EntityListId::Free;
switch (spriteIdentifier)
{
case SpriteIdentifier::Vehicle:
linkedListIndex = EntityListId::Vehicle;
break;
case SpriteIdentifier::Peep:
linkedListIndex = EntityListId::Peep;
break;
case SpriteIdentifier::Misc:
linkedListIndex = EntityListId::Misc;
break;
case SpriteIdentifier::Litter:
linkedListIndex = EntityListId::Litter;
break;
default:
Guard::Assert(false, "Invalid sprite identifier: 0x%02X", spriteIdentifier);
return nullptr;
}
return create_sprite(spriteIdentifier, linkedListIndex);
}
/**
*
* rct2: 0x00673200
@ -530,7 +505,6 @@ void sprite_misc_explosion_cloud_create(const CoordsXYZ& cloudPos)
sprite->sprite_width = 44;
sprite->sprite_height_negative = 32;
sprite->sprite_height_positive = 34;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(cloudPos + CoordsXYZ{ 0, 0, 4 });
sprite->SubType = MiscEntityType::ExplosionCloud;
sprite->frame = 0;
@ -563,7 +537,6 @@ void sprite_misc_explosion_flare_create(const CoordsXYZ& flarePos)
sprite->sprite_width = 25;
sprite->sprite_height_negative = 85;
sprite->sprite_height_positive = 8;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(flarePos + CoordsXYZ{ 0, 0, 4 });
sprite->SubType = MiscEntityType::ExplosionFlare;
sprite->frame = 0;
@ -787,7 +760,6 @@ void litter_create(const CoordsXYZD& litterPos, LitterType type)
litter->sprite_width = 6;
litter->sprite_height_negative = 6;
litter->sprite_height_positive = 3;
litter->sprite_identifier = SpriteIdentifier::Litter;
litter->SubType = type;
litter->MoveTo(offsetLitterPos);
litter->creationTick = gScenarioTicks;
@ -860,7 +832,6 @@ void EntityTweener::PreTick()
Reset();
PopulateEntities(EntityListId::Peep);
PopulateEntities(EntityListId::Vehicle);
PopulateEntities(EntityListId::TrainHead);
}
void EntityTweener::PostTick()

View File

@ -204,7 +204,6 @@ constexpr const uint32_t SPATIAL_INDEX_LOCATION_NULL = SPATIAL_INDEX_SIZE - 1;
extern const rct_string_id litterNames[12];
rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier);
rct_sprite* create_sprite(SpriteIdentifier spriteIdentifier, EntityListId linkedListIndex);
void reset_sprite_list();
void reset_sprite_spatial_index();
void sprite_clear_all_unused();

View File

@ -9,8 +9,6 @@ enum class SpriteIdentifier : uint8_t;
struct SpriteBase
{
SpriteIdentifier sprite_identifier;
// Valid values are EntityListId::...
EntityListId linked_list_index;
// Height from centre of sprite to bottom
uint8_t sprite_height_negative;
uint16_t sprite_index;

View File

@ -131,7 +131,6 @@ static void AdvanceGameTicks(uint32_t ticks, std::unique_ptr<IContext>& context)
static void CompareSpriteDataCommon(const SpriteBase& left, const SpriteBase& right)
{
COMPARE_FIELD(sprite_identifier);
COMPARE_FIELD(linked_list_index);
COMPARE_FIELD(sprite_index);
COMPARE_FIELD(flags);
COMPARE_FIELD(x);