Remove type from SpriteBase (#13735)

* Move type field into sub structures

* Use type for misc_type

* Use type for l_type

* Rename to SubType

* Rename SpriteGeneric to MiscEntity

* Rename generic to misc

* Add extra nullptr checks for compilers that cant understand

* Make review changes

* Increment network version

* Update replays
This commit is contained in:
Duncan 2021-01-10 15:14:34 +00:00 committed by GitHub
parent d55bff7587
commit d5ada2dca1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 203 additions and 166 deletions

View File

@ -44,8 +44,8 @@ set(TITLE_SEQUENCE_SHA1 "304d13a126c15bf2c86ff13b81a2f2cc1856ac8d")
set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.20/objects.zip")
set(OBJECTS_SHA1 "151424d24b1d49a167932b58319bedaa6ec368e9")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.23/replays.zip")
set(REPLAYS_SHA1 "AC67B93731B6246A31D9A8B01A6CA12AE98AE0D1")
set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.24/replays.zip")
set(REPLAYS_SHA1 "58AD8B2D2A804D2FEE787597A2A4DEADBF4D2A65")
option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.")
option(WITH_TESTS "Build tests")

View File

@ -48,8 +48,8 @@
<TitleSequencesSha1>304d13a126c15bf2c86ff13b81a2f2cc1856ac8d</TitleSequencesSha1>
<ObjectsUrl>https://github.com/OpenRCT2/objects/releases/download/v1.0.20/objects.zip</ObjectsUrl>
<ObjectsSha1>151424d24b1d49a167932b58319bedaa6ec368e9</ObjectsSha1>
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.23/replays.zip</ReplaysUrl>
<ReplaysSha1>AC67B93731B6246A31D9A8B01A6CA12AE98AE0D1</ReplaysSha1>
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.24/replays.zip</ReplaysUrl>
<ReplaysSha1>58AD8B2D2A804D2FEE787597A2A4DEADBF4D2A65</ReplaysSha1>
</PropertyGroup>
<ItemGroup>

View File

@ -195,7 +195,7 @@ bool ViewportInteractionLeftClick(const ScreenCoordsXY& screenCoords)
case SpriteIdentifier::Misc:
if (game_is_not_paused())
{
switch (static_cast<MiscEntityType>(entity->type))
switch (entity->As<MiscEntity>()->SubType)
{
case MiscEntityType::Balloon:
{

View File

@ -657,10 +657,10 @@ static void window_title_command_editor_tool_down(
}
else if (litter != nullptr)
{
if (litter->type < std::size(litterNames))
if (litter->SubType < std::size(litterNames))
{
validSprite = true;
format_string(_command.SpriteName, USER_STRING_MAX_LENGTH, litterNames[litter->type], nullptr);
format_string(_command.SpriteName, USER_STRING_MAX_LENGTH, litterNames[litter->SubType], nullptr);
}
}
else if (balloon != nullptr)

View File

@ -49,7 +49,7 @@ struct GameStateSnapshot_t
for (size_t i = 0; i < numSprites; i++)
{
auto entity = getEntity(i);
if (entity == nullptr || entity->generic.sprite_identifier == SpriteIdentifier::Null)
if (entity == nullptr || entity->misc.sprite_identifier == SpriteIdentifier::Null)
continue;
indexTable.push_back(static_cast<uint32_t>(i));
}
@ -76,9 +76,9 @@ struct GameStateSnapshot_t
}
auto& sprite = *entity;
ds << sprite.generic.sprite_identifier;
ds << sprite.misc.sprite_identifier;
switch (sprite.generic.sprite_identifier)
switch (sprite.misc.sprite_identifier)
{
case SpriteIdentifier::Vehicle:
ds << reinterpret_cast<uint8_t(&)[sizeof(Vehicle)]>(sprite.vehicle);
@ -91,8 +91,8 @@ struct GameStateSnapshot_t
break;
case SpriteIdentifier::Misc:
{
ds << sprite.generic.type;
switch (static_cast<MiscEntityType>(sprite.generic.type))
ds << sprite.misc.SubType;
switch (sprite.misc.SubType)
{
case MiscEntityType::MoneyEffect:
ds << reinterpret_cast<uint8_t(&)[sizeof(MoneyEffect)]>(sprite.money_effect);
@ -176,7 +176,7 @@ struct GameStateSnapshots final : public IGameStateSnapshots
for (auto& sprite : spriteList)
{
// By default they don't exist.
sprite.generic.sprite_identifier = SpriteIdentifier::Null;
sprite.misc.sprite_identifier = SpriteIdentifier::Null;
}
snapshot.SerialiseSprites([&spriteList](const size_t index) { return &spriteList[index]; }, MAX_SPRITES, false);
@ -200,7 +200,6 @@ struct GameStateSnapshots final : public IGameStateSnapshots
const SpriteBase& spriteBase, const SpriteBase& spriteCmp, GameStateSpriteChange_t& changeData) const
{
COMPARE_FIELD(SpriteBase, sprite_identifier);
COMPARE_FIELD(SpriteBase, type);
COMPARE_FIELD(SpriteBase, next_in_quadrant);
COMPARE_FIELD(SpriteBase, next);
COMPARE_FIELD(SpriteBase, previous);
@ -469,18 +468,19 @@ struct GameStateSnapshots final : public IGameStateSnapshots
COMPARE_FIELD(JumpingFountain, Iteration);
}
void CompareSpriteDataGeneric(
const SpriteGeneric& spriteBase, const SpriteGeneric& spriteCmp, GameStateSpriteChange_t& changeData) const
void CompareSpriteDataMisc(
const MiscEntity& spriteBase, const MiscEntity& spriteCmp, GameStateSpriteChange_t& changeData) const
{
COMPARE_FIELD(SpriteGeneric, frame);
COMPARE_FIELD(MiscEntity, SubType);
COMPARE_FIELD(MiscEntity, frame);
}
void CompareSpriteData(const rct_sprite& spriteBase, const rct_sprite& spriteCmp, GameStateSpriteChange_t& changeData) const
{
CompareSpriteDataCommon(spriteBase.generic, spriteCmp.generic, changeData);
if (spriteBase.generic.sprite_identifier == spriteCmp.generic.sprite_identifier)
CompareSpriteDataCommon(spriteBase.misc, spriteCmp.misc, changeData);
if (spriteBase.misc.sprite_identifier == spriteCmp.misc.sprite_identifier)
{
switch (spriteBase.generic.sprite_identifier)
switch (spriteBase.misc.sprite_identifier)
{
case SpriteIdentifier::Peep:
CompareSpriteDataPeep(spriteBase.peep, spriteCmp.peep, changeData);
@ -493,8 +493,8 @@ struct GameStateSnapshots final : public IGameStateSnapshots
break;
case SpriteIdentifier::Misc:
// This is not expected to happen, as misc sprites do not constitute sprite checksum
CompareSpriteDataGeneric(spriteBase.generic, spriteCmp.generic, changeData);
switch (static_cast<MiscEntityType>(spriteBase.generic.type))
CompareSpriteDataMisc(spriteBase.misc, spriteCmp.misc, changeData);
switch (spriteBase.misc.SubType)
{
case MiscEntityType::SteamParticle:
CompareSpriteDataSteamParticle(spriteBase.steam_particle, spriteCmp.steam_particle, changeData);
@ -509,7 +509,7 @@ struct GameStateSnapshots final : public IGameStateSnapshots
case MiscEntityType::ExplosionCloud:
case MiscEntityType::CrashSplash:
case MiscEntityType::ExplosionFlare:
// SpriteGeneric
// MiscEntity
break;
case MiscEntityType::JumpingFountainWater:
case MiscEntityType::JumpingFountainSnow:
@ -550,27 +550,30 @@ struct GameStateSnapshots final : public IGameStateSnapshots
const rct_sprite& spriteBase = spritesBase[i];
const rct_sprite& spriteCmp = spritesCmp[i];
changeData.spriteIdentifier = spriteBase.generic.sprite_identifier;
changeData.miscIdentifier = spriteBase.generic.type;
changeData.spriteIdentifier = spriteBase.misc.sprite_identifier;
// This will be nonsense information for all types apart from MiscEntities.
// This is not an issue though as only MiscEntities will use this field in GetSpriteIdentifierName
// TODO: Don't do this.
changeData.miscIdentifier = spriteBase.misc.SubType;
if (spriteBase.generic.sprite_identifier == SpriteIdentifier::Null
&& spriteCmp.generic.sprite_identifier != SpriteIdentifier::Null)
if (spriteBase.misc.sprite_identifier == SpriteIdentifier::Null
&& spriteCmp.misc.sprite_identifier != SpriteIdentifier::Null)
{
// Sprite was added.
changeData.changeType = GameStateSpriteChange_t::ADDED;
changeData.spriteIdentifier = spriteCmp.generic.sprite_identifier;
changeData.spriteIdentifier = spriteCmp.misc.sprite_identifier;
}
else if (
spriteBase.generic.sprite_identifier != SpriteIdentifier::Null
&& spriteCmp.generic.sprite_identifier == SpriteIdentifier::Null)
spriteBase.misc.sprite_identifier != SpriteIdentifier::Null
&& spriteCmp.misc.sprite_identifier == SpriteIdentifier::Null)
{
// Sprite was removed.
changeData.changeType = GameStateSpriteChange_t::REMOVED;
changeData.spriteIdentifier = spriteBase.generic.sprite_identifier;
changeData.spriteIdentifier = spriteBase.misc.sprite_identifier;
}
else if (
spriteBase.generic.sprite_identifier == SpriteIdentifier::Null
&& spriteCmp.generic.sprite_identifier == SpriteIdentifier::Null)
spriteBase.misc.sprite_identifier == SpriteIdentifier::Null
&& spriteCmp.misc.sprite_identifier == SpriteIdentifier::Null)
{
// Do nothing.
changeData.changeType = GameStateSpriteChange_t::EQUAL;
@ -655,8 +658,7 @@ struct GameStateSnapshots final : public IGameStateSnapshots
if (change.changeType == GameStateSpriteChange_t::EQUAL)
continue;
const char* typeName = GetSpriteIdentifierName(
change.spriteIdentifier, static_cast<MiscEntityType>(change.miscIdentifier));
const char* typeName = GetSpriteIdentifierName(change.spriteIdentifier, change.miscIdentifier);
if (change.changeType == GameStateSpriteChange_t::ADDED)
{

View File

@ -40,7 +40,7 @@ struct GameStateSpriteChange_t
uint8_t changeType;
SpriteIdentifier spriteIdentifier;
uint8_t miscIdentifier;
MiscEntityType miscIdentifier;
uint32_t spriteIndex;
std::vector<Diff_t> diffs;

View File

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

View File

@ -77,9 +77,9 @@ void litter_paint(paint_session* session, const Litter* litter, int32_t imageDir
imageDirection >>= 3;
// Some litter types have only 1 direction so remove
// anything that isn't required.
imageDirection &= litter_sprites[litter->type].direction_mask;
imageDirection &= litter_sprites[litter->SubType].direction_mask;
uint32_t image_id = imageDirection + litter_sprites[litter->type].base_id;
uint32_t image_id = imageDirection + litter_sprites[litter->SubType].base_id;
// In the following call to PaintAddImageAsParent, we add 4 (instead of 2) to the
// bound_box_offset_z to make sure litter is drawn on top of railways

View File

@ -29,11 +29,11 @@ const uint32_t vehicle_particle_base_sprites[] = {
/**
* rct2: 0x00672AC9
*/
void misc_paint(paint_session* session, const SpriteBase* misc, int32_t imageDirection)
void misc_paint(paint_session* session, const MiscEntity* misc, int32_t imageDirection)
{
rct_drawpixelinfo* dpi = &session->DPI;
switch (static_cast<MiscEntityType>(misc->type))
switch (misc->SubType)
{
case MiscEntityType::SteamParticle: // 0
{
@ -134,9 +134,7 @@ void misc_paint(paint_session* session, const SpriteBase* misc, int32_t imageDir
isAntiClockwise = !isAntiClockwise;
}
uint32_t baseImageId = (static_cast<MiscEntityType>(jumpingFountain->type) == MiscEntityType::JumpingFountainSnow)
? 23037
: 22973;
uint32_t baseImageId = (jumpingFountain->SubType == MiscEntityType::JumpingFountainSnow) ? 23037 : 22973;
uint32_t imageId = baseImageId + ebx * 16 + jumpingFountain->frame;
constexpr std::array<CoordsXY, 2> antiClockWiseBoundingBoxes = { CoordsXY{ -COORDS_XY_STEP, -3 },
CoordsXY{ 0, -3 } };

View File

@ -115,7 +115,7 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t
break;
case SpriteIdentifier::Misc:
// TODO: Update misc_paint to take a specific sprite type
misc_paint(session, spr, image_direction);
misc_paint(session, spr->As<MiscEntity>(), image_direction);
break;
case SpriteIdentifier::Litter:
litter_paint(session, spr->As<Litter>(), image_direction);

View File

@ -17,7 +17,7 @@ struct paint_session;
void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t y);
void misc_paint(paint_session* session, const SpriteBase* misc, int32_t imageDirection);
void misc_paint(paint_session* session, const MiscEntity* misc, int32_t imageDirection);
void litter_paint(paint_session* session, const Litter* litter, int32_t imageDirection);
void peep_paint(paint_session* session, const Peep* peep, int32_t imageDirection);

View File

@ -5076,13 +5076,13 @@ void Guest::UpdateWalking()
{
if ((0xFFFF & scenario_rand()) <= 4096)
{
static constexpr const uint8_t litter_types[] = {
static constexpr const LitterType litter_types[] = {
LITTER_TYPE_EMPTY_CAN,
LITTER_TYPE_RUBBISH,
LITTER_TYPE_EMPTY_BURGER_BOX,
LITTER_TYPE_EMPTY_CUP,
};
int32_t litterType = litter_types[scenario_rand() & 0x3];
auto litterType = litter_types[scenario_rand() & 0x3];
int32_t litterX = x + (scenario_rand() & 0x7) - 3;
int32_t litterY = y + (scenario_rand() & 0x7) - 3;
Direction litterDirection = (scenario_rand() & 0x3);
@ -5097,13 +5097,13 @@ void Guest::UpdateWalking()
&& ((0xFFFF & scenario_rand()) <= 4096))
{
int32_t container = bitscanforward(GetEmptyContainerFlags());
int32_t litterType = 0;
LitterType litterType = LITTER_TYPE_SICK;
if (container != -1)
{
auto item = static_cast<ShopItem>(container);
RemoveItem(item);
litterType = GetShopItemDescriptor(item).LitterType;
litterType = LitterType(GetShopItemDescriptor(item).LitterType);
}
WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_INVENTORY;
@ -5672,7 +5672,8 @@ void Guest::UpdateUsingBin()
UpdateSpriteType();
continue;
}
uint8_t litterType = GetShopItemDescriptor(item).LitterType;
LitterType litterType = LitterType(GetShopItemDescriptor(item).LitterType);
int32_t litterX = x + (scenario_rand() & 7) - 3;
int32_t litterY = y + (scenario_rand() & 7) - 3;

View File

@ -2640,7 +2640,7 @@ static void peep_footpath_move_forward(Peep* peep, const CoordsXYE& coords, bool
continue;
litter_count++;
if (litter->type != LITTER_TYPE_SICK && litter->type != LITTER_TYPE_SICK_ALT)
if (litter->SubType != LITTER_TYPE_SICK && litter->SubType != LITTER_TYPE_SICK_ALT)
continue;
litter_count--;

View File

@ -1170,7 +1170,7 @@ private:
dst->ride_subtype = RCTEntryIndexToOpenRCT2EntryIndex(ride->subtype);
dst->vehicle_type = vehicleEntryIndex;
dst->type = src->type;
dst->SubType = Vehicle::Type(src->type);
dst->var_44 = src->var_44;
dst->remaining_distance = src->remaining_distance;
@ -1651,7 +1651,7 @@ private:
Litter* litter = reinterpret_cast<Litter*>(create_sprite(SpriteIdentifier::Litter));
litter->sprite_identifier = srcLitter->sprite_identifier;
litter->type = srcLitter->type;
litter->SubType = LitterType(srcLitter->type);
litter->x = srcLitter->x;
litter->y = srcLitter->y;
@ -1673,14 +1673,14 @@ private:
if (sprite.unknown.sprite_identifier == SpriteIdentifier::Misc)
{
rct1_unk_sprite* src = &sprite.unknown;
SpriteGeneric* dst = reinterpret_cast<SpriteGeneric*>(create_sprite(SpriteIdentifier::Misc));
MiscEntity* dst = reinterpret_cast<MiscEntity*>(create_sprite(SpriteIdentifier::Misc));
if (dst == nullptr)
{
log_warning("SV4 has too many misc entities. No more misc entities will be imported!");
break;
}
dst->sprite_identifier = src->sprite_identifier;
dst->type = src->type;
dst->SubType = MiscEntityType(src->type);
dst->flags = src->flags;
dst->sprite_direction = src->sprite_direction;
dst->sprite_width = src->sprite_width;

View File

@ -963,10 +963,10 @@ void S6Exporter::ExportSprites()
void S6Exporter::ExportSprite(RCT2Sprite* dst, const rct_sprite* src)
{
std::memset(dst, 0, sizeof(rct_sprite));
switch (src->generic.sprite_identifier)
switch (src->misc.sprite_identifier)
{
case SpriteIdentifier::Null:
ExportSpriteCommonProperties(&dst->unknown, &src->generic);
ExportSpriteCommonProperties(&dst->unknown, &src->misc);
break;
case SpriteIdentifier::Vehicle:
ExportSpriteVehicle(&dst->vehicle, &src->vehicle);
@ -975,14 +975,14 @@ void S6Exporter::ExportSprite(RCT2Sprite* dst, const rct_sprite* src)
ExportSpritePeep(&dst->peep, &src->peep);
break;
case SpriteIdentifier::Misc:
ExportSpriteMisc(&dst->unknown, &src->generic);
ExportSpriteMisc(&dst->unknown, &src->misc);
break;
case SpriteIdentifier::Litter:
ExportSpriteLitter(&dst->litter, &src->litter);
break;
default:
ExportSpriteCommonProperties(&dst->unknown, &src->generic);
log_warning("Sprite identifier %d can not be exported.", src->generic.sprite_identifier);
ExportSpriteCommonProperties(&dst->unknown, &src->misc);
log_warning("Sprite identifier %d can not be exported.", src->misc.sprite_identifier);
break;
}
}
@ -990,7 +990,6 @@ void S6Exporter::ExportSprite(RCT2Sprite* dst, const rct_sprite* src)
void S6Exporter::ExportSpriteCommonProperties(RCT12SpriteBase* dst, const SpriteBase* src)
{
dst->sprite_identifier = src->sprite_identifier;
dst->type = src->type;
dst->next_in_quadrant = src->next_in_quadrant;
dst->next = src->next;
dst->previous = src->previous;
@ -1015,6 +1014,7 @@ void S6Exporter::ExportSpriteVehicle(RCT2SpriteVehicle* dst, const Vehicle* src)
const auto* ride = src->GetRide();
ExportSpriteCommonProperties(dst, static_cast<const SpriteBase*>(src));
dst->type = EnumValue(src->SubType);
dst->vehicle_sprite_type = src->vehicle_sprite_type;
dst->bank_rotation = src->bank_rotation;
dst->remaining_distance = src->remaining_distance;
@ -1248,10 +1248,11 @@ void S6Exporter::ExportSpritePeep(RCT2SpritePeep* dst, const Peep* src)
dst->item_standard_flags = static_cast<uint32_t>(src->GetItemFlags());
}
void S6Exporter::ExportSpriteMisc(RCT12SpriteBase* cdst, const SpriteBase* csrc)
void S6Exporter::ExportSpriteMisc(RCT12SpriteBase* cdst, const MiscEntity* csrc)
{
ExportSpriteCommonProperties(cdst, csrc);
switch (static_cast<MiscEntityType>(cdst->type))
cdst->type = EnumValue(csrc->SubType);
switch (csrc->SubType)
{
case MiscEntityType::SteamParticle:
{
@ -1295,7 +1296,7 @@ void S6Exporter::ExportSpriteMisc(RCT12SpriteBase* cdst, const SpriteBase* csrc)
case MiscEntityType::ExplosionFlare:
case MiscEntityType::CrashSplash:
{
auto src = static_cast<const SpriteGeneric*>(csrc);
auto src = static_cast<const MiscEntity*>(csrc);
auto dst = static_cast<RCT12SpriteParticle*>(cdst);
dst->frame = src->frame;
break;
@ -1343,6 +1344,7 @@ void S6Exporter::ExportSpriteMisc(RCT12SpriteBase* cdst, const SpriteBase* csrc)
void S6Exporter::ExportSpriteLitter(RCT12SpriteLitter* dst, const Litter* src)
{
ExportSpriteCommonProperties(dst, src);
dst->type = EnumValue(src->SubType);
dst->creationTick = src->creationTick;
}

View File

@ -51,7 +51,7 @@ public:
void ExportSpriteCommonProperties(RCT12SpriteBase* dst, const SpriteBase* src);
void ExportSpriteVehicle(RCT2SpriteVehicle* dst, const Vehicle* src);
void ExportSpritePeep(RCT2SpritePeep* dst, const Peep* src);
void ExportSpriteMisc(RCT12SpriteBase* dst, const SpriteBase* src);
void ExportSpriteMisc(RCT12SpriteBase* dst, const MiscEntity* src);
void ExportSpriteLitter(RCT12SpriteLitter* dst, const Litter* src);
private:

View File

@ -1318,7 +1318,7 @@ public:
ImportSpritePeep(&dst->peep, &src->peep);
break;
case SpriteIdentifier::Misc:
ImportSpriteMisc(&dst->generic, &src->unknown);
ImportSpriteMisc(&dst->misc, &src->unknown);
break;
case SpriteIdentifier::Litter:
ImportSpriteLitter(&dst->litter, &src->litter);
@ -1335,6 +1335,7 @@ public:
const auto& ride = _s6.rides[src->ride];
ImportSpriteCommonProperties(static_cast<SpriteBase*>(dst), src);
dst->SubType = Vehicle::Type(src->type);
dst->vehicle_sprite_type = src->vehicle_sprite_type;
dst->bank_rotation = src->bank_rotation;
dst->remaining_distance = src->remaining_distance;
@ -1530,10 +1531,11 @@ public:
dst->FavouriteRideRating = src->favourite_ride_rating;
}
void ImportSpriteMisc(SpriteBase* cdst, const RCT12SpriteBase* csrc)
void ImportSpriteMisc(MiscEntity* cdst, const RCT12SpriteBase* csrc)
{
ImportSpriteCommonProperties(cdst, csrc);
switch (static_cast<MiscEntityType>(cdst->type))
cdst->SubType = MiscEntityType(csrc->type);
switch (cdst->SubType)
{
case MiscEntityType::SteamParticle:
{
@ -1578,7 +1580,7 @@ public:
case MiscEntityType::CrashSplash:
{
auto src = static_cast<const RCT12SpriteParticle*>(csrc);
auto dst = static_cast<SpriteGeneric*>(cdst);
auto dst = static_cast<MiscEntity*>(cdst);
dst->frame = src->frame;
break;
}
@ -1616,7 +1618,7 @@ public:
break;
}
default:
log_warning("Misc. sprite type %d can not be imported.", cdst->type);
log_warning("Misc. sprite type %d can not be imported.", cdst->SubType);
break;
}
}
@ -1624,13 +1626,13 @@ public:
void ImportSpriteLitter(Litter* dst, const RCT12SpriteLitter* src)
{
ImportSpriteCommonProperties(dst, src);
dst->SubType = LitterType(src->type);
dst->creationTick = src->creationTick;
}
void ImportSpriteCommonProperties(SpriteBase* dst, const RCT12SpriteBase* src)
{
dst->sprite_identifier = src->sprite_identifier;
dst->type = src->type;
dst->next_in_quadrant = src->next_in_quadrant;
dst->next = src->next;
dst->previous = src->previous;

View File

@ -32,7 +32,7 @@ Vehicle* cable_lift_segment_create(
{
ride.cable_lift = current->sprite_index;
}
current->type = static_cast<uint8_t>(head ? Vehicle::Type::Head : Vehicle::Type::Tail);
current->SubType = head ? Vehicle::Type::Head : Vehicle::Type::Tail;
current->var_44 = var_44;
current->remaining_distance = remaining_distance;
current->sprite_width = 10;

View File

@ -4403,7 +4403,7 @@ static Vehicle* vehicle_create_car(
vehicle->ride_subtype = ride->subtype;
vehicle->vehicle_type = vehicleEntryIndex;
vehicle->type = static_cast<uint8_t>(carIndex == 0 ? Vehicle::Type::Head : Vehicle::Type::Tail);
vehicle->SubType = carIndex == 0 ? Vehicle::Type::Head : Vehicle::Type::Tail;
vehicle->var_44 = ror32(vehicleEntry->spacing, 10) & 0xFFFF;
auto edx = vehicleEntry->spacing >> 1;
*remainingDistance -= edx;

View File

@ -7239,7 +7239,7 @@ static void steam_particle_create(const CoordsXYZ& coords)
steam->sprite_height_negative = 18;
steam->sprite_height_positive = 16;
steam->sprite_identifier = SpriteIdentifier::Misc;
steam->type = EnumValue(MiscEntityType::SteamParticle);
steam->SubType = MiscEntityType::SteamParticle;
steam->frame = 256;
steam->time_to_move = 0;
steam->MoveTo(coords);

View File

@ -198,6 +198,7 @@ struct Vehicle : SpriteBase
StoppedByBlockBrakes
};
Type SubType;
uint8_t vehicle_sprite_type;
uint8_t bank_rotation;
int32_t remaining_distance;
@ -312,7 +313,7 @@ struct Vehicle : SpriteBase
constexpr bool IsHead() const
{
return type == static_cast<uint8_t>(Vehicle::Type::Head);
return SubType == Vehicle::Type::Head;
}
void Update();
Vehicle* GetHead();

View File

@ -57,7 +57,13 @@ namespace OpenRCT2::Scripting
case SpriteIdentifier::Peep:
return "peep";
case SpriteIdentifier::Misc:
switch (static_cast<MiscEntityType>(entity->type))
{
auto misc = entity->As<MiscEntity>();
if (misc == nullptr)
{
return "unknown";
}
switch (misc->SubType)
{
case MiscEntityType::SteamParticle:
return "steam_particle";
@ -82,7 +88,8 @@ namespace OpenRCT2::Scripting
default:
break;
}
break;
}
break;
case SpriteIdentifier::Litter:
return "litter";
case SpriteIdentifier::Null:

View File

@ -99,11 +99,11 @@ namespace OpenRCT2::Scripting
std::vector<DukValue> getAllEntities(const std::string& type) const
{
EntityListId targetList{};
uint8_t targetType{};
MiscEntityType targetType{};
if (type == "balloon")
{
targetList = EntityListId::Misc;
targetType = EnumValue(MiscEntityType::Balloon);
targetType = MiscEntityType::Balloon;
}
if (type == "car")
{
@ -116,7 +116,7 @@ namespace OpenRCT2::Scripting
else if (type == "duck")
{
targetList = EntityListId::Misc;
targetType = EnumValue(MiscEntityType::Duck);
targetType = MiscEntityType::Duck;
}
else if (type == "peep")
{
@ -130,26 +130,26 @@ namespace OpenRCT2::Scripting
std::vector<DukValue> result;
for (auto sprite : EntityList(targetList))
{
// Only the misc list checks the type property
if (targetList != EntityListId::Misc || sprite->type == targetType)
if (targetList == EntityListId::Peep)
{
if (targetList == EntityListId::Peep)
{
if (sprite->Is<Staff>())
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->sprite_index)));
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;
}
}
if (sprite->Is<Staff>())
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->sprite_index)));
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>();
if (misc && misc->SubType == targetType)
{
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScEntity>(sprite->sprite_index)));
}

View File

@ -16,7 +16,8 @@
template<> bool SpriteBase::Is<Balloon>() const
{
return sprite_identifier == SpriteIdentifier::Misc && static_cast<MiscEntityType>(type) == MiscEntityType::Balloon;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::Balloon;
}
void Balloon::Update()
@ -84,9 +85,9 @@ void create_balloon(const CoordsXYZ& balloonPos, int32_t colour, bool isPopped)
rct_sprite* sprite = create_sprite(SpriteIdentifier::Misc);
if (sprite == nullptr)
return;
sprite->generic.sprite_identifier = SpriteIdentifier::Misc;
sprite->generic.type = EnumValue(MiscEntityType::Balloon);
auto balloon = sprite->generic.As<Balloon>();
sprite->misc.sprite_identifier = SpriteIdentifier::Misc;
sprite->misc.SubType = MiscEntityType::Balloon;
auto balloon = sprite->misc.As<Balloon>();
if (balloon == nullptr)
return; // can never happen

View File

@ -68,7 +68,8 @@ static constexpr const uint8_t * DuckAnimations[] =
template<> bool SpriteBase::Is<Duck>() const
{
return sprite_identifier == SpriteIdentifier::Misc && static_cast<MiscEntityType>(type) == MiscEntityType::Duck;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::Duck;
}
bool Duck::IsFlying()
@ -290,9 +291,9 @@ void create_duck(const CoordsXY& pos)
targetPos.x += offsetXY;
targetPos.y += offsetXY;
sprite->generic.sprite_identifier = SpriteIdentifier::Misc;
sprite->generic.type = EnumValue(MiscEntityType::Duck);
auto duck = sprite->generic.As<Duck>();
sprite->misc.sprite_identifier = SpriteIdentifier::Misc;
sprite->misc.SubType = MiscEntityType::Duck;
auto duck = sprite->misc.As<Duck>();
if (duck == nullptr)
return; // can never happen
duck->sprite_width = 9;

View File

@ -72,9 +72,9 @@ const uint8_t _fountainPatternFlags[] = {
template<> bool SpriteBase::Is<JumpingFountain>() const
{
const auto miscType = static_cast<MiscEntityType>(type);
return sprite_identifier == SpriteIdentifier::Misc
&& (miscType == MiscEntityType::JumpingFountainSnow || miscType == MiscEntityType::JumpingFountainWater);
auto* misc = As<MiscEntity>();
return misc
&& (misc->SubType == MiscEntityType::JumpingFountainSnow || misc->SubType == MiscEntityType::JumpingFountainWater);
}
void JumpingFountain::StartAnimation(const int32_t newType, const CoordsXY& newLoc, const TileElement* tileElement)
@ -140,8 +140,8 @@ void JumpingFountain::Create(
jumpingFountain->sprite_height_positive = 12;
jumpingFountain->sprite_identifier = SpriteIdentifier::Misc;
jumpingFountain->MoveTo(newLoc);
jumpingFountain->type = newType == JUMPING_FOUNTAIN_TYPE_SNOW ? EnumValue(MiscEntityType::JumpingFountainSnow)
: EnumValue(MiscEntityType::JumpingFountainWater);
jumpingFountain->SubType = newType == JUMPING_FOUNTAIN_TYPE_SNOW ? MiscEntityType::JumpingFountainSnow
: MiscEntityType::JumpingFountainWater;
jumpingFountain->NumTicksAlive = 0;
jumpingFountain->frame = 0;
}
@ -162,7 +162,7 @@ void JumpingFountain::Update()
Invalidate();
frame++;
switch (static_cast<MiscEntityType>(type))
switch (SubType)
{
case MiscEntityType::JumpingFountainWater:
if (frame == 11 && (FountainFlags & FOUNTAIN_FLAG::FAST))
@ -192,9 +192,8 @@ void JumpingFountain::Update()
int32_t JumpingFountain::GetType() const
{
const int32_t fountainType = static_cast<MiscEntityType>(type) == MiscEntityType::JumpingFountainSnow
? JUMPING_FOUNTAIN_TYPE_SNOW
: JUMPING_FOUNTAIN_TYPE_WATER;
const int32_t fountainType = SubType == MiscEntityType::JumpingFountainSnow ? JUMPING_FOUNTAIN_TYPE_SNOW
: JUMPING_FOUNTAIN_TYPE_WATER;
return fountainType;
}

View File

@ -13,7 +13,7 @@
#include "Map.h"
#include "SpriteBase.h"
struct JumpingFountain : SpriteGeneric
struct JumpingFountain : MiscEntity
{
uint8_t NumTicksAlive;
uint8_t FountainFlags;

View File

@ -20,7 +20,8 @@ static constexpr const CoordsXY _moneyEffectMoveOffset[] = { { 1, -1 }, { 1, 1 }
template<> bool SpriteBase::Is<MoneyEffect>() const
{
return sprite_identifier == SpriteIdentifier::Misc && static_cast<MiscEntityType>(type) == MiscEntityType::MoneyEffect;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::MoneyEffect;
}
/**
@ -43,7 +44,7 @@ void MoneyEffect::CreateAt(money32 value, const CoordsXYZ& effectPos, bool verti
moneyEffect->sprite_height_positive = 30;
moneyEffect->sprite_identifier = SpriteIdentifier::Misc;
moneyEffect->MoveTo(effectPos);
moneyEffect->type = EnumValue(MiscEntityType::MoneyEffect);
moneyEffect->SubType = MiscEntityType::MoneyEffect;
moneyEffect->NumMovements = 0;
moneyEffect->MoveDelay = 0;

View File

@ -16,13 +16,14 @@
template<> bool SpriteBase::Is<VehicleCrashParticle>() const
{
return sprite_identifier == SpriteIdentifier::Misc
&& static_cast<MiscEntityType>(type) == MiscEntityType::CrashedVehicleParticle;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::CrashedVehicleParticle;
}
template<> bool SpriteBase::Is<CrashSplashParticle>() const
{
return sprite_identifier == SpriteIdentifier::Misc && static_cast<MiscEntityType>(type) == MiscEntityType::CrashSplash;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::CrashSplash;
}
/**
*
@ -40,7 +41,7 @@ void crashed_vehicle_particle_create(rct_vehicle_colour colours, const CoordsXYZ
sprite->sprite_height_positive = 8;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(vehiclePos);
sprite->type = EnumValue(MiscEntityType::CrashedVehicleParticle);
sprite->SubType = MiscEntityType::CrashedVehicleParticle;
sprite->frame = (scenario_rand() & 0xFF) * 12;
sprite->time_to_live = (scenario_rand() & 0x7F) + 140;
@ -121,7 +122,7 @@ void VehicleCrashParticle::Update()
*/
void crash_splash_create(const CoordsXYZ& splashPos)
{
SpriteGeneric* sprite = &create_sprite(SpriteIdentifier::Misc)->generic;
MiscEntity* sprite = &create_sprite(SpriteIdentifier::Misc)->misc;
if (sprite != nullptr)
{
sprite->sprite_width = 33;
@ -129,7 +130,7 @@ void crash_splash_create(const CoordsXYZ& splashPos)
sprite->sprite_height_positive = 16;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(splashPos + CoordsXYZ{ 0, 0, 3 });
sprite->type = EnumValue(MiscEntityType::CrashSplash);
sprite->SubType = MiscEntityType::CrashSplash;
sprite->frame = 0;
}
}

View File

@ -60,19 +60,27 @@ template<> bool SpriteBase::Is<Litter>() const
return sprite_identifier == SpriteIdentifier::Litter;
}
template<> bool SpriteBase::Is<MiscEntity>() const
{
return sprite_identifier == SpriteIdentifier::Misc;
}
template<> bool SpriteBase::Is<SteamParticle>() const
{
return sprite_identifier == SpriteIdentifier::Misc && static_cast<MiscEntityType>(type) == MiscEntityType::SteamParticle;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::SteamParticle;
}
template<> bool SpriteBase::Is<ExplosionFlare>() const
{
return sprite_identifier == SpriteIdentifier::Misc && static_cast<MiscEntityType>(type) == MiscEntityType::ExplosionFlare;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::ExplosionFlare;
}
template<> bool SpriteBase::Is<ExplosionCloud>() const
{
return sprite_identifier == SpriteIdentifier::Misc && static_cast<MiscEntityType>(type) == MiscEntityType::ExplosionCloud;
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::ExplosionCloud;
}
uint16_t GetEntityListCount(EntityListId list)
@ -97,7 +105,7 @@ std::string rct_sprite_checksum::ToString() const
SpriteBase* try_get_sprite(size_t spriteIndex)
{
return spriteIndex >= MAX_SPRITES ? nullptr : &_spriteList[spriteIndex].generic;
return spriteIndex >= MAX_SPRITES ? nullptr : &_spriteList[spriteIndex].misc;
}
SpriteBase* get_sprite(size_t spriteIndex)
@ -128,7 +136,13 @@ void SpriteBase::Invalidate()
maxZoom = 2;
break;
case SpriteIdentifier::Misc:
switch (static_cast<MiscEntityType>(type))
{
auto* misc = As<MiscEntity>();
if (misc == nullptr)
{
return;
}
switch (misc->SubType)
{
case MiscEntityType::CrashedVehicleParticle:
case MiscEntityType::JumpingFountainWater:
@ -149,7 +163,8 @@ void SpriteBase::Invalidate()
default:
break;
}
break;
}
break;
case SpriteIdentifier::Litter:
maxZoom = 0;
break;
@ -283,19 +298,19 @@ rct_sprite_checksum sprite_checksum()
auto copy = *reinterpret_cast<rct_sprite*>(sprite);
// Only required for rendering/invalidation, has no meaning to the game state.
copy.generic.sprite_left = copy.generic.sprite_right = copy.generic.sprite_top = copy.generic.sprite_bottom = 0;
copy.generic.sprite_width = copy.generic.sprite_height_negative = copy.generic.sprite_height_positive = 0;
copy.misc.sprite_left = copy.misc.sprite_right = copy.misc.sprite_top = copy.misc.sprite_bottom = 0;
copy.misc.sprite_width = copy.misc.sprite_height_negative = copy.misc.sprite_height_positive = 0;
// Next in quadrant might be a misc sprite, set first non-misc sprite in quadrant.
while (auto* nextSprite = GetEntity(copy.generic.next_in_quadrant))
while (auto* nextSprite = GetEntity(copy.misc.next_in_quadrant))
{
if (nextSprite->sprite_identifier == SpriteIdentifier::Misc)
copy.generic.next_in_quadrant = nextSprite->next_in_quadrant;
copy.misc.next_in_quadrant = nextSprite->next_in_quadrant;
else
break;
}
if (copy.generic.Is<Peep>())
if (copy.misc.Is<Peep>())
{
// Name is pointer and will not be the same across clients
copy.peep.Name = {};
@ -548,7 +563,7 @@ void SteamParticle::Update()
*/
void sprite_misc_explosion_cloud_create(const CoordsXYZ& cloudPos)
{
SpriteGeneric* sprite = &create_sprite(SpriteIdentifier::Misc)->generic;
MiscEntity* sprite = &create_sprite(SpriteIdentifier::Misc)->misc;
if (sprite != nullptr)
{
sprite->sprite_width = 44;
@ -556,7 +571,7 @@ void sprite_misc_explosion_cloud_create(const CoordsXYZ& cloudPos)
sprite->sprite_height_positive = 34;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(cloudPos + CoordsXYZ{ 0, 0, 4 });
sprite->type = EnumValue(MiscEntityType::ExplosionCloud);
sprite->SubType = MiscEntityType::ExplosionCloud;
sprite->frame = 0;
}
}
@ -581,7 +596,7 @@ void ExplosionCloud::Update()
*/
void sprite_misc_explosion_flare_create(const CoordsXYZ& flarePos)
{
SpriteGeneric* sprite = &create_sprite(SpriteIdentifier::Misc)->generic;
MiscEntity* sprite = &create_sprite(SpriteIdentifier::Misc)->misc;
if (sprite != nullptr)
{
sprite->sprite_width = 25;
@ -589,7 +604,7 @@ void sprite_misc_explosion_flare_create(const CoordsXYZ& flarePos)
sprite->sprite_height_positive = 8;
sprite->sprite_identifier = SpriteIdentifier::Misc;
sprite->MoveTo(flarePos + CoordsXYZ{ 0, 0, 4 });
sprite->type = EnumValue(MiscEntityType::ExplosionFlare);
sprite->SubType = MiscEntityType::ExplosionFlare;
sprite->frame = 0;
}
}
@ -612,9 +627,9 @@ void ExplosionFlare::Update()
*
* rct2: 0x006731CD
*/
static void sprite_misc_update(SpriteBase* sprite)
static void sprite_misc_update(MiscEntity* sprite)
{
switch (static_cast<MiscEntityType>(sprite->type))
switch (sprite->SubType)
{
case MiscEntityType::SteamParticle:
sprite->As<SteamParticle>()->Update();
@ -655,7 +670,7 @@ static void sprite_misc_update(SpriteBase* sprite)
*/
void sprite_misc_update_all()
{
for (auto entity : EntityList(EntityListId::Misc))
for (auto entity : EntityList<MiscEntity>(EntityListId::Misc))
{
sprite_misc_update(entity);
}
@ -816,7 +831,7 @@ static bool litter_can_be_at(const CoordsXYZ& mapPos)
*
* rct2: 0x0067375D
*/
void litter_create(const CoordsXYZD& litterPos, int32_t type)
void litter_create(const CoordsXYZD& litterPos, LitterType type)
{
if (gCheatsDisableLittering)
return;
@ -857,7 +872,7 @@ void litter_create(const CoordsXYZD& litterPos, int32_t type)
litter->sprite_height_negative = 6;
litter->sprite_height_positive = 3;
litter->sprite_identifier = SpriteIdentifier::Litter;
litter->type = type;
litter->SubType = type;
litter->MoveTo(offsetLitterPos);
litter->creationTick = gScenarioTicks;
}

View File

@ -39,12 +39,15 @@ enum class EntityListId : uint8_t
Count,
};
enum LitterType : uint8_t;
struct Litter : SpriteBase
{
LitterType SubType;
uint32_t creationTick;
};
struct Balloon : SpriteGeneric
struct Balloon : MiscEntity
{
uint16_t popped;
uint8_t time_to_move;
@ -55,7 +58,7 @@ struct Balloon : SpriteGeneric
void Press();
};
struct Duck : SpriteGeneric
struct Duck : MiscEntity
{
enum class DuckState : uint8_t
{
@ -82,7 +85,7 @@ private:
void UpdateFlyAway();
};
struct MoneyEffect : SpriteBase
struct MoneyEffect : MiscEntity
{
uint16_t MoveDelay;
uint8_t NumMovements;
@ -97,7 +100,7 @@ struct MoneyEffect : SpriteBase
std::pair<rct_string_id, money32> GetStringId() const;
};
struct VehicleCrashParticle : SpriteGeneric
struct VehicleCrashParticle : MiscEntity
{
uint16_t time_to_live;
uint8_t colour[2];
@ -112,22 +115,22 @@ struct VehicleCrashParticle : SpriteGeneric
void Update();
};
struct ExplosionFlare : SpriteGeneric
struct ExplosionFlare : MiscEntity
{
void Update();
};
struct ExplosionCloud : SpriteGeneric
struct ExplosionCloud : MiscEntity
{
void Update();
};
struct CrashSplashParticle : SpriteGeneric
struct CrashSplashParticle : MiscEntity
{
void Update();
};
struct SteamParticle : SpriteGeneric
struct SteamParticle : MiscEntity
{
uint16_t time_to_move;
@ -142,7 +145,7 @@ struct SteamParticle : SpriteGeneric
union rct_sprite
{
uint8_t pad_00[0x200];
SpriteGeneric generic;
MiscEntity misc;
Peep peep;
Litter litter;
Vehicle vehicle;
@ -192,7 +195,7 @@ enum
SPRITE_FLAGS_PEEP_FLASHING = 1 << 9, // Deprecated: Use sprite_set_flashing/sprite_get_flashing instead.
};
enum
enum LitterType : uint8_t
{
LITTER_TYPE_SICK,
LITTER_TYPE_SICK_ALT,
@ -240,7 +243,7 @@ void sprite_clear_all_unused();
void sprite_misc_update_all();
void sprite_set_coordinates(const CoordsXYZ& spritePos, SpriteBase* sprite);
void sprite_remove(SpriteBase* sprite);
void litter_create(const CoordsXYZD& litterPos, int32_t type);
void litter_create(const CoordsXYZD& litterPos, LitterType type);
void litter_remove_at(const CoordsXYZ& litterPos);
uint16_t remove_floating_sprites();
void sprite_misc_explosion_cloud_create(const CoordsXYZ& cloudPos);

View File

@ -9,7 +9,6 @@ enum class SpriteIdentifier : uint8_t;
struct SpriteBase
{
SpriteIdentifier sprite_identifier;
uint8_t type;
uint16_t next_in_quadrant;
uint16_t next;
uint16_t previous;
@ -47,7 +46,9 @@ struct SpriteBase
}
};
struct SpriteGeneric : SpriteBase
enum class MiscEntityType : uint8_t;
struct MiscEntity : SpriteBase
{
MiscEntityType SubType;
uint16_t frame;
};

View File

@ -110,7 +110,7 @@ static std::unique_ptr<GameState_t> GetGameState(std::unique_ptr<IContext>& cont
{
rct_sprite* sprite = reinterpret_cast<rct_sprite*>(GetEntity(spriteIdx));
if (sprite == nullptr)
res->sprites[spriteIdx].generic.sprite_identifier = SpriteIdentifier::Null;
res->sprites[spriteIdx].misc.sprite_identifier = SpriteIdentifier::Null;
else
res->sprites[spriteIdx] = *sprite;
}
@ -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(type);
COMPARE_FIELD(next_in_quadrant);
COMPARE_FIELD(next);
COMPARE_FIELD(previous);
@ -271,6 +270,7 @@ static void CompareSpriteDataPeep(const Peep& left, const Peep& right)
static void CompareSpriteDataVehicle(const Vehicle& left, const Vehicle& right)
{
COMPARE_FIELD(SubType);
COMPARE_FIELD(vehicle_sprite_type);
COMPARE_FIELD(bank_rotation);
COMPARE_FIELD(remaining_distance);
@ -345,6 +345,7 @@ static void CompareSpriteDataVehicle(const Vehicle& left, const Vehicle& right)
static void CompareSpriteDataLitter(const Litter& left, const Litter& right)
{
COMPARE_FIELD(SubType);
COMPARE_FIELD(creationTick);
}
@ -404,10 +405,10 @@ static void CompareSpriteDataDuck(const Duck& left, const Duck& right)
static void CompareSpriteData(const rct_sprite& left, const rct_sprite& right)
{
CompareSpriteDataCommon(left.generic, right.generic);
if (left.generic.sprite_identifier == right.generic.sprite_identifier)
CompareSpriteDataCommon(left.misc, right.misc);
if (left.misc.sprite_identifier == right.misc.sprite_identifier)
{
switch (left.generic.sprite_identifier)
switch (left.misc.sprite_identifier)
{
case SpriteIdentifier::Peep:
CompareSpriteDataPeep(left.peep, right.peep);
@ -419,7 +420,8 @@ static void CompareSpriteData(const rct_sprite& left, const rct_sprite& right)
CompareSpriteDataLitter(left.litter, right.litter);
break;
case SpriteIdentifier::Misc:
switch (static_cast<MiscEntityType>(left.generic.type))
COMPARE_FIELD(misc.SubType);
switch (left.misc.SubType)
{
case MiscEntityType::SteamParticle:
CompareSpriteDataSteamParticle(left.steam_particle, right.steam_particle);
@ -464,8 +466,8 @@ static void CompareStates(
for (size_t spriteIdx = 0; spriteIdx < MAX_SPRITES; ++spriteIdx)
{
if (importedState->sprites[spriteIdx].generic.sprite_identifier == SpriteIdentifier::Null
&& exportedState->sprites[spriteIdx].generic.sprite_identifier == SpriteIdentifier::Null)
if (importedState->sprites[spriteIdx].misc.sprite_identifier == SpriteIdentifier::Null
&& exportedState->sprites[spriteIdx].misc.sprite_identifier == SpriteIdentifier::Null)
{
continue;
}