mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-23 23:04:36 +01:00
Refactor paint entity (#14342)
This commit is contained in:
@@ -65,7 +65,7 @@ static constexpr const litter_sprite litter_sprites[] = {
|
||||
* Litter Paint Setup
|
||||
* rct2: 0x006736FC
|
||||
*/
|
||||
void litter_paint(paint_session* session, const Litter* litter, int32_t imageDirection)
|
||||
template<> void PaintEntity(paint_session* session, const Litter* litter, int32_t imageDirection)
|
||||
{
|
||||
rct_drawpixelinfo* dpi;
|
||||
|
||||
|
||||
@@ -26,154 +26,128 @@ const uint32_t vehicle_particle_base_sprites[] = {
|
||||
22577, 22589, 22601, 22613, 22625,
|
||||
};
|
||||
|
||||
/**
|
||||
* rct2: 0x00672AC9
|
||||
*/
|
||||
void misc_paint(paint_session* session, const MiscEntity* misc, int32_t imageDirection)
|
||||
template<> void PaintEntity(paint_session* session, const SteamParticle* particle, int32_t imageDirection)
|
||||
{
|
||||
uint32_t imageId = 22637 + (particle->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const MoneyEffect* moneyEffect, int32_t imageDirection)
|
||||
{
|
||||
rct_drawpixelinfo* dpi = &session->DPI;
|
||||
|
||||
switch (misc->SubType)
|
||||
if (dpi->zoom_level > 0)
|
||||
{
|
||||
case MiscEntityType::SteamParticle: // 0
|
||||
return;
|
||||
}
|
||||
if (moneyEffect == nullptr)
|
||||
return;
|
||||
auto [stringId, value] = moneyEffect->GetStringId();
|
||||
PaintFloatingMoneyEffect(
|
||||
session, value, stringId, moneyEffect->y, moneyEffect->z, const_cast<int8_t*>(&money_wave[moneyEffect->Wiggle % 22]),
|
||||
moneyEffect->OffsetX, session->CurrentRotation);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const VehicleCrashParticle* particle, int32_t imageDirection)
|
||||
{
|
||||
rct_drawpixelinfo* dpi = &session->DPI;
|
||||
if (dpi->zoom_level > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (particle == nullptr)
|
||||
return;
|
||||
uint32_t imageId = vehicle_particle_base_sprites[particle->crashed_sprite_base] + particle->frame / 256;
|
||||
imageId = imageId | (particle->colour[0] << 19) | (particle->colour[1] << 24) | IMAGE_TYPE_REMAP | IMAGE_TYPE_REMAP_2_PLUS;
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const ExplosionCloud* particle, int32_t imageDirection)
|
||||
{
|
||||
if (particle == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22878 + (particle->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const CrashSplashParticle* crashSplash, int32_t imageDirection)
|
||||
{
|
||||
if (crashSplash == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22927 + (crashSplash->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, crashSplash->z);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const ExplosionFlare* flare, int32_t imageDirection)
|
||||
{
|
||||
// Like a flare
|
||||
if (flare == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22896 + (flare->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, flare->z);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const JumpingFountain* jumpingFountain, int32_t imageDirection)
|
||||
{
|
||||
rct_drawpixelinfo* dpi = &session->DPI;
|
||||
if (dpi->zoom_level > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (jumpingFountain == nullptr)
|
||||
return;
|
||||
uint16_t height = jumpingFountain->z + 6;
|
||||
int32_t ebx = imageDirection / 8;
|
||||
|
||||
// Fountain is firing anti clockwise
|
||||
bool reversed = (jumpingFountain->FountainFlags & FOUNTAIN_FLAG::DIRECTION);
|
||||
// Fountain rotation
|
||||
bool rotated = (jumpingFountain->sprite_direction / 16) & 1;
|
||||
bool isAntiClockwise = (ebx / 2) & 1; // Clockwise or Anti-clockwise
|
||||
|
||||
// These cancel each other out
|
||||
if (reversed != rotated)
|
||||
{
|
||||
isAntiClockwise = !isAntiClockwise;
|
||||
}
|
||||
|
||||
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 } };
|
||||
constexpr std::array<CoordsXY, 2> clockWiseBoundingBoxes = { CoordsXY{ -COORDS_XY_STEP, 3 }, CoordsXY{ 0, 3 } };
|
||||
|
||||
auto bb = isAntiClockwise ? antiClockWiseBoundingBoxes : clockWiseBoundingBoxes;
|
||||
|
||||
PaintAddImageAsParentRotated(session, ebx, imageId, 0, 0, 32, 1, 3, height, bb[ebx & 1].x, bb[ebx & 1].y, height);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const Balloon* balloon, int32_t imageDirection)
|
||||
{
|
||||
if (balloon == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22651 + (balloon->frame & 7);
|
||||
if (balloon->popped != 0)
|
||||
{
|
||||
imageId += 8;
|
||||
}
|
||||
|
||||
imageId = imageId | (balloon->colour << 19) | IMAGE_TYPE_REMAP;
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, balloon->z);
|
||||
}
|
||||
|
||||
template<> void PaintEntity(paint_session* session, const Duck* duck, int32_t imageDirection)
|
||||
{
|
||||
rct_drawpixelinfo* dpi = &session->DPI;
|
||||
if (dpi->zoom_level <= 1)
|
||||
{
|
||||
if (duck == nullptr)
|
||||
return;
|
||||
uint32_t imageId = duck->GetFrameImage(imageDirection);
|
||||
if (imageId != 0)
|
||||
{
|
||||
auto particle = misc->As<SteamParticle>();
|
||||
if (particle == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22637 + (particle->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
break;
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, duck->z);
|
||||
}
|
||||
|
||||
case MiscEntityType::MoneyEffect: // 1
|
||||
{
|
||||
if (dpi->zoom_level > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto moneyEffect = misc->As<MoneyEffect>();
|
||||
if (moneyEffect == nullptr)
|
||||
return;
|
||||
auto [stringId, value] = moneyEffect->GetStringId();
|
||||
PaintFloatingMoneyEffect(
|
||||
session, value, stringId, moneyEffect->y, moneyEffect->z,
|
||||
const_cast<int8_t*>(&money_wave[moneyEffect->Wiggle % 22]), moneyEffect->OffsetX, session->CurrentRotation);
|
||||
break;
|
||||
}
|
||||
|
||||
case MiscEntityType::CrashedVehicleParticle: // 2
|
||||
{
|
||||
if (dpi->zoom_level > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto particle = misc->As<VehicleCrashParticle>();
|
||||
if (particle == nullptr)
|
||||
return;
|
||||
uint32_t imageId = vehicle_particle_base_sprites[particle->crashed_sprite_base] + particle->frame / 256;
|
||||
imageId = imageId | (particle->colour[0] << 19) | (particle->colour[1] << 24) | IMAGE_TYPE_REMAP
|
||||
| IMAGE_TYPE_REMAP_2_PLUS;
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case MiscEntityType::ExplosionCloud: // 3
|
||||
{
|
||||
auto particle = misc->As<ExplosionCloud>();
|
||||
if (particle == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22878 + (particle->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case MiscEntityType::CrashSplash: // 4
|
||||
{
|
||||
auto crashSplash = misc->As<CrashSplashParticle>();
|
||||
if (crashSplash == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22927 + (crashSplash->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, crashSplash->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case MiscEntityType::ExplosionFlare: // 5
|
||||
{
|
||||
// Like a flare
|
||||
auto flare = misc->As<ExplosionFlare>();
|
||||
if (flare == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22896 + (flare->frame / 256);
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, flare->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case MiscEntityType::JumpingFountainWater: // 6
|
||||
case MiscEntityType::JumpingFountainSnow: // 9
|
||||
{
|
||||
if (dpi->zoom_level > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto jumpingFountain = misc->As<JumpingFountain>();
|
||||
if (jumpingFountain == nullptr)
|
||||
return;
|
||||
uint16_t height = jumpingFountain->z + 6;
|
||||
int32_t ebx = imageDirection / 8;
|
||||
|
||||
// Fountain is firing anti clockwise
|
||||
bool reversed = (jumpingFountain->FountainFlags & FOUNTAIN_FLAG::DIRECTION);
|
||||
// Fountain rotation
|
||||
bool rotated = (jumpingFountain->sprite_direction / 16) & 1;
|
||||
bool isAntiClockwise = (ebx / 2) & 1; // Clockwise or Anti-clockwise
|
||||
|
||||
// These cancel each other out
|
||||
if (reversed != rotated)
|
||||
{
|
||||
isAntiClockwise = !isAntiClockwise;
|
||||
}
|
||||
|
||||
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 } };
|
||||
constexpr std::array<CoordsXY, 2> clockWiseBoundingBoxes = { CoordsXY{ -COORDS_XY_STEP, 3 }, CoordsXY{ 0, 3 } };
|
||||
|
||||
auto bb = isAntiClockwise ? antiClockWiseBoundingBoxes : clockWiseBoundingBoxes;
|
||||
|
||||
PaintAddImageAsParentRotated(session, ebx, imageId, 0, 0, 32, 1, 3, height, bb[ebx & 1].x, bb[ebx & 1].y, height);
|
||||
break;
|
||||
}
|
||||
|
||||
case MiscEntityType::Balloon: // 7
|
||||
{
|
||||
auto balloon = misc->As<Balloon>();
|
||||
if (balloon == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22651 + (balloon->frame & 7);
|
||||
if (balloon->popped != 0)
|
||||
{
|
||||
imageId += 8;
|
||||
}
|
||||
|
||||
imageId = imageId | (balloon->colour << 19) | IMAGE_TYPE_REMAP;
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, balloon->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case MiscEntityType::Duck:
|
||||
if (dpi->zoom_level <= 1)
|
||||
{
|
||||
const Duck* duck = misc->As<Duck>();
|
||||
if (duck == nullptr)
|
||||
return;
|
||||
uint32_t imageId = duck->GetFrameImage(imageDirection);
|
||||
if (imageId != 0)
|
||||
{
|
||||
PaintAddImageAsParent(session, imageId, 0, 0, 1, 1, 0, duck->z);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*
|
||||
* rct2: 0x0068F0FB
|
||||
*/
|
||||
void peep_paint(paint_session* session, const Peep* peep, int32_t imageDirection)
|
||||
template<> void PaintEntity(paint_session* session, const Peep* peep, int32_t imageDirection)
|
||||
{
|
||||
#ifdef __ENABLE_LIGHTFX__
|
||||
if (lightfx_is_available())
|
||||
|
||||
@@ -103,7 +103,7 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t
|
||||
switch (spr->Type)
|
||||
{
|
||||
case EntityType::Vehicle:
|
||||
vehicle_paint(session, spr->As<Vehicle>(), image_direction);
|
||||
PaintEntity(session, spr->As<Vehicle>(), image_direction);
|
||||
#ifdef __ENABLE_LIGHTFX__
|
||||
if (lightfx_for_vehicles_is_available())
|
||||
{
|
||||
@@ -113,22 +113,37 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t
|
||||
break;
|
||||
case EntityType::Guest:
|
||||
case EntityType::Staff:
|
||||
peep_paint(session, spr->As<Peep>(), image_direction);
|
||||
PaintEntity(session, spr->As<Peep>(), image_direction);
|
||||
break;
|
||||
case EntityType::SteamParticle:
|
||||
PaintEntity(session, spr->As<SteamParticle>(), image_direction);
|
||||
break;
|
||||
case EntityType::MoneyEffect:
|
||||
PaintEntity(session, spr->As<MoneyEffect>(), image_direction);
|
||||
break;
|
||||
case EntityType::CrashedVehicleParticle:
|
||||
PaintEntity(session, spr->As<VehicleCrashParticle>(), image_direction);
|
||||
break;
|
||||
case EntityType::ExplosionCloud:
|
||||
PaintEntity(session, spr->As<ExplosionCloud>(), image_direction);
|
||||
break;
|
||||
case EntityType::CrashSplash:
|
||||
PaintEntity(session, spr->As<CrashSplashParticle>(), image_direction);
|
||||
break;
|
||||
case EntityType::ExplosionFlare:
|
||||
PaintEntity(session, spr->As<ExplosionFlare>(), image_direction);
|
||||
break;
|
||||
case EntityType::JumpingFountain:
|
||||
PaintEntity(session, spr->As<JumpingFountain>(), image_direction);
|
||||
break;
|
||||
case EntityType::Balloon:
|
||||
PaintEntity(session, spr->As<Balloon>(), image_direction);
|
||||
break;
|
||||
case EntityType::Duck:
|
||||
// TODO: Update misc_paint to take a specific sprite type
|
||||
misc_paint(session, spr->As<MiscEntity>(), image_direction);
|
||||
PaintEntity(session, spr->As<Duck>(), image_direction);
|
||||
break;
|
||||
case EntityType::Litter:
|
||||
litter_paint(session, spr->As<Litter>(), image_direction);
|
||||
PaintEntity(session, spr->As<Litter>(), image_direction);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
|
||||
@@ -13,15 +13,10 @@
|
||||
#include "../../common.h"
|
||||
|
||||
struct paint_session;
|
||||
struct Litter;
|
||||
struct MiscEntity;
|
||||
struct Peep;
|
||||
|
||||
void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t y);
|
||||
|
||||
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);
|
||||
template<typename T> void PaintEntity(paint_session* session, const T* entity, int32_t imageDirection);
|
||||
|
||||
extern const uint32_t vehicle_particle_base_sprites[5];
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "../drawing/LightFX.h"
|
||||
#include "../interface/Viewport.h"
|
||||
#include "../paint/Paint.h"
|
||||
#include "../paint/sprite/Paint.Sprite.h"
|
||||
#include "../ride/RideData.h"
|
||||
#include "../world/Sprite.h"
|
||||
#include "Track.h"
|
||||
@@ -3131,7 +3132,7 @@ void vehicle_visual_default(
|
||||
*
|
||||
* rct2: 0x006D4244
|
||||
*/
|
||||
void vehicle_paint(paint_session* session, const Vehicle* vehicle, int32_t imageDirection)
|
||||
template<> void PaintEntity(paint_session* session, const Vehicle* vehicle, int32_t imageDirection)
|
||||
{
|
||||
const rct_ride_entry_vehicle* vehicleEntry;
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ struct vehicle_boundbox
|
||||
|
||||
extern const vehicle_boundbox VehicleBoundboxes[16][224];
|
||||
|
||||
void vehicle_paint(paint_session* session, const Vehicle* vehicle, int32_t imageDirection);
|
||||
|
||||
void vehicle_visual_default(
|
||||
paint_session* session, int32_t imageDirection, int32_t z, const Vehicle* vehicle,
|
||||
const rct_ride_entry_vehicle* vehicleEntry);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "../../interface/Viewport.h"
|
||||
#include "../../paint/Paint.h"
|
||||
#include "../../paint/Supports.h"
|
||||
#include "../../paint/sprite/Paint.Sprite.h"
|
||||
#include "../../world/Sprite.h"
|
||||
#include "../Track.h"
|
||||
#include "../TrackPaint.h"
|
||||
@@ -1269,6 +1270,6 @@ void vehicle_visual_splash_boats_or_water_coaster(
|
||||
imageDirection = ((session->CurrentRotation * 8) + vehicle->sprite_direction) & 0x1F;
|
||||
session->SpritePosition.x = vehicle->x;
|
||||
session->SpritePosition.y = vehicle->y;
|
||||
vehicle_paint(session, vehicle, imageDirection);
|
||||
PaintEntity(session, vehicle, imageDirection);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user