1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-28 17:24:47 +01:00

Entity type 2: Remove sprite_identifier (#14334)

* Start changing the underlying type

* Further work

* Complete refactor

* Further cleanup

* Remove pointless check

* Increment network and plugin versions

* Add defaults

* Further defaults

* Fix test paint

* Update replays
This commit is contained in:
Duncan
2021-03-17 08:04:41 +00:00
committed by GitHub
parent 6ec379cd0e
commit df7a284822
30 changed files with 435 additions and 501 deletions

View File

@@ -75,30 +75,41 @@ template<> bool SpriteBase::Is<SpriteBase>() const
template<> bool SpriteBase::Is<Litter>() const
{
return sprite_identifier == SpriteIdentifier::Litter;
return Type == EntityType::Litter;
}
template<> bool SpriteBase::Is<MiscEntity>() const
{
return sprite_identifier == SpriteIdentifier::Misc;
switch (Type)
{
case EntityType::SteamParticle:
case EntityType::MoneyEffect:
case EntityType::CrashedVehicleParticle:
case EntityType::ExplosionCloud:
case EntityType::CrashSplash:
case EntityType::ExplosionFlare:
case EntityType::JumpingFountain:
case EntityType::Balloon:
case EntityType::Duck:
return true;
default:
return false;
}
}
template<> bool SpriteBase::Is<SteamParticle>() const
{
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::SteamParticle;
return Type == EntityType::SteamParticle;
}
template<> bool SpriteBase::Is<ExplosionFlare>() const
{
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::ExplosionFlare;
return Type == EntityType::ExplosionFlare;
}
template<> bool SpriteBase::Is<ExplosionCloud>() const
{
auto* misc = As<MiscEntity>();
return misc && misc->SubType == MiscEntityType::ExplosionCloud;
return Type == EntityType::ExplosionCloud;
}
uint16_t GetEntityListCount(EntityType type)
@@ -152,43 +163,29 @@ void SpriteBase::Invalidate()
return;
int32_t maxZoom = 0;
switch (sprite_identifier)
switch (Type)
{
case SpriteIdentifier::Vehicle:
case SpriteIdentifier::Peep:
case EntityType::Vehicle:
case EntityType::Guest:
case EntityType::Staff:
maxZoom = 2;
break;
case SpriteIdentifier::Misc:
{
auto* misc = As<MiscEntity>();
if (misc == nullptr)
{
return;
}
switch (misc->SubType)
{
case MiscEntityType::CrashedVehicleParticle:
case MiscEntityType::JumpingFountainWater:
case MiscEntityType::JumpingFountainSnow:
maxZoom = 0;
break;
case MiscEntityType::Duck:
maxZoom = 1;
break;
case MiscEntityType::SteamParticle:
case MiscEntityType::MoneyEffect:
case MiscEntityType::ExplosionCloud:
case MiscEntityType::CrashSplash:
case MiscEntityType::ExplosionFlare:
case MiscEntityType::Balloon:
maxZoom = 2;
break;
default:
break;
}
}
break;
case SpriteIdentifier::Litter:
case EntityType::CrashedVehicleParticle:
case EntityType::JumpingFountain:
maxZoom = 0;
break;
case EntityType::Duck:
maxZoom = 1;
break;
case EntityType::SteamParticle:
case EntityType::MoneyEffect:
case EntityType::ExplosionCloud:
case EntityType::CrashSplash:
case EntityType::ExplosionFlare:
case EntityType::Balloon:
maxZoom = 2;
break;
case EntityType::Litter:
maxZoom = 0;
break;
default:
@@ -198,71 +195,6 @@ void SpriteBase::Invalidate()
viewports_invalidate(sprite_left, sprite_top, sprite_right, sprite_bottom, maxZoom);
}
constexpr EntityType EntityBaseToEntityType(const SpriteBase& base)
{
EntityType type = EntityType::Count;
switch (base.sprite_identifier)
{
case SpriteIdentifier::Vehicle:
type = EntityType::Vehicle;
break;
case SpriteIdentifier::Peep:
if (base.Is<Guest>())
{
type = EntityType::Guest;
}
else
{
type = EntityType::Staff;
}
break;
case SpriteIdentifier::Misc:
if (base.Is<SteamParticle>())
{
type = EntityType::SteamParticle;
}
else if (base.Is<MoneyEffect>())
{
type = EntityType::MoneyEffect;
}
else if (base.Is<VehicleCrashParticle>())
{
type = EntityType::CrashedVehicleParticle;
}
else if (base.Is<ExplosionCloud>())
{
type = EntityType::ExplosionCloud;
}
else if (base.Is<CrashSplashParticle>())
{
type = EntityType::CrashSplash;
}
else if (base.Is<ExplosionFlare>())
{
type = EntityType::ExplosionFlare;
}
else if (base.Is<JumpingFountain>())
{
type = EntityType::JumpingFountain;
}
else if (base.Is<Balloon>())
{
type = EntityType::Balloon;
}
else if (base.Is<Duck>())
{
type = EntityType::Duck;
}
break;
case SpriteIdentifier::Litter:
type = EntityType::Litter;
break;
default:
break;
}
return type;
}
constexpr SpriteIdentifier EntityTypeToSpriteIdentifier(const EntityType type)
{
switch (type)
@@ -285,6 +217,7 @@ constexpr SpriteIdentifier EntityTypeToSpriteIdentifier(const EntityType type)
case EntityType::Balloon:
case EntityType::Duck:
return SpriteIdentifier::Misc;
case EntityType::Null:
case EntityType::Count:
return SpriteIdentifier::Null;
}
@@ -302,14 +235,13 @@ void RebuildEntityLists()
for (auto& ent : _spriteList)
{
if (ent.misc.sprite_identifier == SpriteIdentifier::Null)
if (ent.misc.Type == EntityType::Null)
{
_freeIdList.push_back(ent.misc.sprite_index);
}
else
{
auto listId = EntityBaseToEntityType(ent.misc);
gEntityLists[EnumValue(listId)].push_back(ent.misc.sprite_index);
gEntityLists[EnumValue(ent.misc.Type)].push_back(ent.misc.sprite_index);
}
}
// List needs to be back to front to simplify removing
@@ -337,7 +269,7 @@ void reset_sprite_list()
continue;
}
spr->sprite_identifier = SpriteIdentifier::Null;
spr->Type = EntityType::Null;
spr->sprite_index = i;
_spriteFlashingList[i] = false;
@@ -363,7 +295,7 @@ void reset_sprite_spatial_index()
for (size_t i = 0; i < MAX_ENTITIES; i++)
{
auto* spr = GetEntity(i);
if (spr != nullptr && spr->sprite_identifier != SpriteIdentifier::Null)
if (spr != nullptr && spr->Type != EntityType::Null)
{
SpriteSpatialInsert(spr, { spr->x, spr->y });
}
@@ -394,8 +326,7 @@ rct_sprite_checksum sprite_checksum()
{
// TODO create a way to copy only the specific type
auto sprite = GetEntity(i);
if (sprite != nullptr && sprite->sprite_identifier != SpriteIdentifier::Null
&& sprite->sprite_identifier != SpriteIdentifier::Misc)
if (sprite != nullptr && sprite->Type != EntityType::Null && !sprite->Is<MiscEntity>())
{
// Upconvert it to rct_sprite so that the full size is copied.
auto copy = *reinterpret_cast<rct_sprite*>(sprite);
@@ -447,7 +378,7 @@ static void sprite_reset(SpriteBase* sprite)
std::memset(sprite, 0, sizeof(rct_sprite));
sprite->sprite_index = sprite_index;
sprite->sprite_identifier = SpriteIdentifier::Null;
sprite->Type = EntityType::Null;
}
/**
@@ -472,8 +403,7 @@ void sprite_clear_all_unused()
static constexpr uint16_t MAX_MISC_SPRITES = 300;
static void AddToEntityList(SpriteBase* entity)
{
auto listId = EntityBaseToEntityType(*entity);
auto& list = gEntityLists[EnumValue(listId)];
auto& list = gEntityLists[EnumValue(entity->Type)];
// 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);
}
@@ -486,8 +416,7 @@ static void AddToFreeList(uint16_t index)
static void RemoveFromEntityList(SpriteBase* entity)
{
auto listId = EntityBaseToEntityType(*entity);
auto& list = gEntityLists[EnumValue(listId)];
auto& list = gEntityLists[EnumValue(entity->Type)];
auto ptr = std::lower_bound(std::begin(list), std::end(list), entity->sprite_index);
if (ptr != std::end(list) && *ptr == entity->sprite_index)
{
@@ -507,70 +436,6 @@ uint16_t GetMiscEntityCount()
return count;
}
static void SetLegacyFields(SpriteBase& base, EntityType type)
{
auto spriteIdentifier = EntityTypeToSpriteIdentifier(type);
base.sprite_identifier = spriteIdentifier;
switch (spriteIdentifier)
{
case SpriteIdentifier::Peep:
{
Peep* peep = base.As<Peep>();
if (peep != nullptr)
{
if (type == EntityType::Guest)
{
peep->AssignedPeepType = PeepType::Guest;
}
else
{
peep->AssignedPeepType = PeepType::Staff;
}
}
break;
}
case SpriteIdentifier::Misc:
{
MiscEntity* misc = base.As<MiscEntity>();
switch (type)
{
case EntityType::SteamParticle:
misc->SubType = MiscEntityType::SteamParticle;
break;
case EntityType::MoneyEffect:
misc->SubType = MiscEntityType::MoneyEffect;
break;
case EntityType::CrashedVehicleParticle:
misc->SubType = MiscEntityType::CrashedVehicleParticle;
break;
case EntityType::ExplosionCloud:
misc->SubType = MiscEntityType::ExplosionCloud;
break;
case EntityType::CrashSplash:
misc->SubType = MiscEntityType::CrashSplash;
break;
case EntityType::ExplosionFlare:
misc->SubType = MiscEntityType::ExplosionFlare;
break;
case EntityType::JumpingFountain:
misc->SubType = MiscEntityType::JumpingFountainWater;
break;
case EntityType::Balloon:
misc->SubType = MiscEntityType::Balloon;
break;
case EntityType::Duck:
misc->SubType = MiscEntityType::Duck;
break;
default:
break;
}
break;
}
default:
break;
}
}
rct_sprite* create_sprite(EntityType type)
{
if (_freeIdList.size() == 0)
@@ -603,7 +468,7 @@ rct_sprite* create_sprite(EntityType type)
// may contain garbage and cause a desync later on.
sprite_reset(sprite);
SetLegacyFields(*sprite, type);
sprite->Type = type;
AddToEntityList(sprite);
sprite->x = LOCATION_NULL;
@@ -1009,7 +874,7 @@ void EntityTweener::PostTick()
void EntityTweener::RemoveEntity(SpriteBase* entity)
{
if (entity->sprite_identifier != SpriteIdentifier::Peep && entity->sprite_identifier != SpriteIdentifier::Vehicle)
if (!entity->Is<Peep>() && !entity->Is<Vehicle>())
{
// Only peeps and vehicles are tweened, bail if type is incorrect.
return;