From 5474194905c006663f027ab09767b752425988ca Mon Sep 17 00:00:00 2001 From: Duncan Date: Mon, 15 Mar 2021 08:13:00 +0000 Subject: [PATCH] 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 --- CMakeLists.txt | 4 +- OpenRCT2.xcodeproj/project.pbxproj | 10 +++ openrct2.proj | 4 +- src/openrct2-ui/windows/Map.cpp | 3 +- src/openrct2/GameStateSnapshots.cpp | 1 - src/openrct2/actions/StaffHireNewAction.cpp | 1 - src/openrct2/libopenrct2.vcxproj | 2 + src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/peep/Peep.cpp | 1 - src/openrct2/rct1/S4Importer.cpp | 7 +- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/ride/CableLift.cpp | 4 +- src/openrct2/ride/Ride.cpp | 5 +- src/openrct2/ride/TrainManager.cpp | 37 ++++++++++ src/openrct2/ride/TrainManager.h | 77 +++++++++++++++++++++ src/openrct2/ride/Vehicle.cpp | 6 +- src/openrct2/scripting/ScMap.hpp | 22 +++--- src/openrct2/world/Balloon.cpp | 1 - src/openrct2/world/Duck.cpp | 1 - src/openrct2/world/Fountain.cpp | 1 - src/openrct2/world/MoneyEffect.cpp | 1 - src/openrct2/world/Particle.cpp | 2 - src/openrct2/world/Sprite.cpp | 53 ++++---------- src/openrct2/world/Sprite.h | 1 - src/openrct2/world/SpriteBase.h | 2 - test/tests/S6ImportExportTests.cpp | 1 - 26 files changed, 166 insertions(+), 85 deletions(-) create mode 100644 src/openrct2/ride/TrainManager.cpp create mode 100644 src/openrct2/ride/TrainManager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dfa149cd0f..2d8be726b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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") diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index 6660cb8c30..5d7be5e124 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -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 = ""; }; 4C81F7E024672C4D000E61BF /* CustomListView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomListView.h; path = scripting/CustomListView.h; sourceTree = ""; }; 4C81F7E224672C58000E61BF /* ScTileSelection.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ScTileSelection.hpp; path = scripting/ScTileSelection.hpp; sourceTree = ""; }; + 4C882FB825FEA80D0039D1C4 /* TrainManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrainManager.cpp; sourceTree = ""; }; + 4C882FB925FEA80E0039D1C4 /* TrainManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrainManager.h; sourceTree = ""; }; + 4C882FBB25FEA8260039D1C4 /* VehicleColour.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VehicleColour.h; sourceTree = ""; }; + 4C882FBC25FEA8270039D1C4 /* VehicleEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VehicleEntry.h; sourceTree = ""; }; 4C8A6FF123EB5325001A8255 /* Http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Http.h; sourceTree = ""; }; 4C8A6FF223EB5326001A8255 /* Http.cURL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Http.cURL.cpp; sourceTree = ""; }; 4C8B426E1EEB1ABD00F015CA /* X8DrawingEngine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = X8DrawingEngine.cpp; sourceTree = ""; }; @@ -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 */, diff --git a/openrct2.proj b/openrct2.proj index 77c0bb2de9..7760c0227b 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -48,8 +48,8 @@ 304d13a126c15bf2c86ff13b81a2f2cc1856ac8d https://github.com/OpenRCT2/objects/releases/download/v1.0.21/objects.zip c38af45d51a6e440386180feacf76c64720b6ac5 - https://github.com/OpenRCT2/replays/releases/download/v0.0.31/replays.zip - 693BDD6F4B7C3B312AABEBCAEA4800FE97B33527 + https://github.com/OpenRCT2/replays/releases/download/v0.0.32/replays.zip + 45843591A8C6739CA1D60899B7E54FC0792EF896 diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index 50431cf9ff..b0c93171d6 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -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(EntityListId::TrainHead)) + for (auto train : TrainManager::View()) { for (Vehicle* vehicle = train; vehicle != nullptr; vehicle = GetEntity(vehicle->next_vehicle_on_train)) { diff --git a/src/openrct2/GameStateSnapshots.cpp b/src/openrct2/GameStateSnapshots.cpp index e1e9c3875c..ad0ce9a415 100644 --- a/src/openrct2/GameStateSnapshots.cpp +++ b/src/openrct2/GameStateSnapshots.cpp @@ -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); diff --git a/src/openrct2/actions/StaffHireNewAction.cpp b/src/openrct2/actions/StaffHireNewAction.cpp index bf60a3a45f..3edefece24 100644 --- a/src/openrct2/actions/StaffHireNewAction.cpp +++ b/src/openrct2/actions/StaffHireNewAction.cpp @@ -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; diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 1623118c3d..bc136f1e1a 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -383,6 +383,7 @@ + @@ -815,6 +816,7 @@ + diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index c2f48ebe7a..bed98f680a 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -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; diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index d53c1c37b1..bd3fa1d393 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -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; diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 39da1b9539..9debb11428 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -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(Vehicle::Type::Head); - auto llt = isFirstCar ? EntityListId::TrainHead : EntityListId::Vehicle; - - Vehicle* vehicle = reinterpret_cast(create_sprite(SpriteIdentifier::Vehicle, llt)); + Vehicle* vehicle = reinterpret_cast(create_sprite(SpriteIdentifier::Vehicle)); spriteIndexMap[i] = vehicle->sprite_index; vehicles.push_back(vehicle); diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index ca69b1fa8f..e73f8dd97e 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -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(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; diff --git a/src/openrct2/ride/CableLift.cpp b/src/openrct2/ride/CableLift.cpp index 55c599b786..ad0ef54865 100644 --- a/src/openrct2/ride/CableLift.cpp +++ b/src/openrct2/ride/CableLift.cpp @@ -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) diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 6e6ac771d6..846180ae57 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -63,6 +63,7 @@ #include "Track.h" #include "TrackData.h" #include "TrackDesign.h" +#include "TrainManager.h" #include "Vehicle.h" #include @@ -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; diff --git a/src/openrct2/ride/TrainManager.cpp b/src/openrct2/ride/TrainManager.cpp new file mode 100644 index 0000000000..8c5e2f970e --- /dev/null +++ b/src/openrct2/ride/TrainManager.cpp @@ -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(*iter++); + if (Entity && !Entity->IsHead()) + { + Entity = nullptr; + } + } + return *this; + } + + View::View() + { + vec = &GetEntityList(EntityListId::Vehicle); + } +} // namespace TrainManager diff --git a/src/openrct2/ride/TrainManager.h b/src/openrct2/ride/TrainManager.h new file mode 100644 index 0000000000..301780c37c --- /dev/null +++ b/src/openrct2/ride/TrainManager.h @@ -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 +#include + +struct Vehicle; + +namespace TrainManager +{ + // Iteration of heads of trains + class View + { + private: + const std::list* vec; + + class Iterator + { + private: + std::list::const_iterator iter; + std::list::const_iterator end; + Vehicle* Entity = nullptr; + + public: + Iterator(std::list::const_iterator _iter, std::list::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 diff --git a/src/openrct2/ride/Vehicle.cpp b/src/openrct2/ride/Vehicle.cpp index d78e182c25..c6ceaae2ff 100644 --- a/src/openrct2/ride/Vehicle.cpp +++ b/src/openrct2/ride/Vehicle.cpp @@ -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(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(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; diff --git a/src/openrct2/scripting/ScMap.hpp b/src/openrct2/scripting/ScMap.hpp index 870c266dd4..7cd865bd9e 100644 --- a/src/openrct2/scripting/ScMap.hpp +++ b/src/openrct2/scripting/ScMap.hpp @@ -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 result; + for (auto trainHead : TrainManager::View()) + { + for (auto carId = trainHead->sprite_index; carId != SPRITE_INDEX_NULL;) + { + auto car = GetEntity(carId); + result.push_back(GetObjectAsDukValue(_context, std::make_shared(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(sprite->sprite_index))); } - else if (targetList == EntityListId::TrainHead) - { - for (auto carId = sprite->sprite_index; carId != SPRITE_INDEX_NULL;) - { - auto car = GetEntity(carId); - result.push_back(GetObjectAsDukValue(_context, std::make_shared(carId))); - carId = car->next_vehicle_on_train; - } - } else if (targetList == EntityListId::Misc) { auto* misc = sprite->As(); diff --git a/src/openrct2/world/Balloon.cpp b/src/openrct2/world/Balloon.cpp index bdb00a6abc..54ef0e58a1 100644 --- a/src/openrct2/world/Balloon.cpp +++ b/src/openrct2/world/Balloon.cpp @@ -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(); if (balloon == nullptr) diff --git a/src/openrct2/world/Duck.cpp b/src/openrct2/world/Duck.cpp index af8167f502..8414482932 100644 --- a/src/openrct2/world/Duck.cpp +++ b/src/openrct2/world/Duck.cpp @@ -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(); if (duck == nullptr) diff --git a/src/openrct2/world/Fountain.cpp b/src/openrct2/world/Fountain.cpp index 33fc38d85b..90f98185ca 100644 --- a/src/openrct2/world/Fountain.cpp +++ b/src/openrct2/world/Fountain.cpp @@ -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; diff --git a/src/openrct2/world/MoneyEffect.cpp b/src/openrct2/world/MoneyEffect.cpp index 944f75c309..20a9525f19 100644 --- a/src/openrct2/world/MoneyEffect.cpp +++ b/src/openrct2/world/MoneyEffect.cpp @@ -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; diff --git a/src/openrct2/world/Particle.cpp b/src/openrct2/world/Particle.cpp index 7c3bbcf9de..4c1ae4ab5a 100644 --- a/src/openrct2/world/Particle.cpp +++ b/src/openrct2/world/Particle.cpp @@ -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; diff --git a/src/openrct2/world/Sprite.cpp b/src/openrct2/world/Sprite.cpp index 2bba77688d..8c31c37dab 100644 --- a/src/openrct2/world/Sprite.cpp +++ b/src/openrct2/world/Sprite.cpp @@ -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(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() diff --git a/src/openrct2/world/Sprite.h b/src/openrct2/world/Sprite.h index 0058633787..fde11c243c 100644 --- a/src/openrct2/world/Sprite.h +++ b/src/openrct2/world/Sprite.h @@ -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(); diff --git a/src/openrct2/world/SpriteBase.h b/src/openrct2/world/SpriteBase.h index 25d792b819..baaa6d0a92 100644 --- a/src/openrct2/world/SpriteBase.h +++ b/src/openrct2/world/SpriteBase.h @@ -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; diff --git a/test/tests/S6ImportExportTests.cpp b/test/tests/S6ImportExportTests.cpp index 3ea6af2704..1efc50d4cf 100644 --- a/test/tests/S6ImportExportTests.cpp +++ b/test/tests/S6ImportExportTests.cpp @@ -131,7 +131,6 @@ static void AdvanceGameTicks(uint32_t ticks, std::unique_ptr& 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);