mirror of https://github.com/OpenRCT2/OpenRCT2.git
Reduce the use of rct_sprite (#12530)
* Reduce the use of rct_sprite * Pass the correct types in S4 importer * Add additional nullptr checks * Simplify the viewport interaction * Apply review comments * Small cleanup of GetEntity * Fix test paint
This commit is contained in:
parent
2c350fa416
commit
6d11825e1a
|
@ -53,10 +53,6 @@ static Peep* viewport_interaction_get_closest_peep(ScreenCoordsXY screenCoords,
|
|||
*/
|
||||
int32_t viewport_interaction_get_item_left(const ScreenCoordsXY& screenCoords, viewport_interaction_info* info)
|
||||
{
|
||||
TileElement* tileElement;
|
||||
rct_sprite* sprite;
|
||||
Vehicle* vehicle;
|
||||
|
||||
// No click input for scenario editor or track manager
|
||||
if (gScreenFlags & (SCREEN_FLAGS_SCENARIO_EDITOR | SCREEN_FLAGS_TRACK_MANAGER))
|
||||
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
|
@ -71,13 +67,13 @@ int32_t viewport_interaction_get_item_left(const ScreenCoordsXY& screenCoords, v
|
|||
mapCoord, &info->type, &info->tileElement, nullptr);
|
||||
info->x = mapCoord.x;
|
||||
info->y = mapCoord.y;
|
||||
tileElement = info->tileElement;
|
||||
sprite = info->sprite;
|
||||
auto tileElement = info->tileElement;
|
||||
auto sprite = info->sprite;
|
||||
|
||||
// Allows only balloons to be popped and ducks to be quacked in title screen
|
||||
if (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO)
|
||||
{
|
||||
if (info->type == VIEWPORT_INTERACTION_ITEM_SPRITE && (sprite->generic.Is<Balloon>() || sprite->generic.Is<Duck>()))
|
||||
if (info->type == VIEWPORT_INTERACTION_ITEM_SPRITE && (sprite->Is<Balloon>() || sprite->Is<Duck>()))
|
||||
return info->type;
|
||||
else
|
||||
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
|
@ -86,18 +82,30 @@ int32_t viewport_interaction_get_item_left(const ScreenCoordsXY& screenCoords, v
|
|||
switch (info->type)
|
||||
{
|
||||
case VIEWPORT_INTERACTION_ITEM_SPRITE:
|
||||
switch (sprite->generic.sprite_identifier)
|
||||
switch (sprite->sprite_identifier)
|
||||
{
|
||||
case SPRITE_IDENTIFIER_VEHICLE:
|
||||
vehicle = &(sprite->vehicle);
|
||||
if (vehicle->ride_subtype != RIDE_ENTRY_INDEX_NULL)
|
||||
{
|
||||
auto vehicle = sprite->As<Vehicle>();
|
||||
if (vehicle != nullptr && vehicle->ride_subtype != RIDE_ENTRY_INDEX_NULL)
|
||||
vehicle->SetMapToolbar();
|
||||
else
|
||||
info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SPRITE_IDENTIFIER_PEEP:
|
||||
peep_set_map_tooltip(&sprite->peep);
|
||||
break;
|
||||
{
|
||||
auto peep = sprite->As<Peep>();
|
||||
if (peep != nullptr)
|
||||
{
|
||||
peep_set_map_tooltip(peep);
|
||||
}
|
||||
else
|
||||
{
|
||||
info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VIEWPORT_INTERACTION_ITEM_RIDE:
|
||||
|
@ -121,14 +129,15 @@ int32_t viewport_interaction_get_item_left(const ScreenCoordsXY& screenCoords, v
|
|||
// If nothing is under cursor, find a close by peep
|
||||
if (info->type == VIEWPORT_INTERACTION_ITEM_NONE)
|
||||
{
|
||||
info->peep = viewport_interaction_get_closest_peep(screenCoords, 32);
|
||||
if (info->peep == nullptr)
|
||||
auto peep = viewport_interaction_get_closest_peep(screenCoords, 32);
|
||||
if (peep == nullptr)
|
||||
return VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
|
||||
info->sprite = peep;
|
||||
info->type = VIEWPORT_INTERACTION_ITEM_SPRITE;
|
||||
info->x = info->peep->x;
|
||||
info->y = info->peep->y;
|
||||
peep_set_map_tooltip(info->peep);
|
||||
info->x = peep->x;
|
||||
info->y = peep->y;
|
||||
peep_set_map_tooltip(peep);
|
||||
}
|
||||
|
||||
return info->type;
|
||||
|
@ -156,36 +165,42 @@ int32_t viewport_interaction_left_click(const ScreenCoordsXY& screenCoords)
|
|||
switch (viewport_interaction_get_item_left(screenCoords, &info))
|
||||
{
|
||||
case VIEWPORT_INTERACTION_ITEM_SPRITE:
|
||||
switch (info.sprite->generic.sprite_identifier)
|
||||
switch (info.sprite->sprite_identifier)
|
||||
{
|
||||
case SPRITE_IDENTIFIER_VEHICLE:
|
||||
{
|
||||
auto intent = Intent(WD_VEHICLE);
|
||||
intent.putExtra(INTENT_EXTRA_VEHICLE, info.vehicle);
|
||||
intent.putExtra(INTENT_EXTRA_VEHICLE, info.sprite);
|
||||
context_open_intent(&intent);
|
||||
break;
|
||||
}
|
||||
case SPRITE_IDENTIFIER_PEEP:
|
||||
{
|
||||
auto intent = Intent(WC_PEEP);
|
||||
intent.putExtra(INTENT_EXTRA_PEEP, info.peep);
|
||||
intent.putExtra(INTENT_EXTRA_PEEP, info.sprite);
|
||||
context_open_intent(&intent);
|
||||
break;
|
||||
}
|
||||
case SPRITE_IDENTIFIER_MISC:
|
||||
if (game_is_not_paused())
|
||||
{
|
||||
switch (info.sprite->generic.type)
|
||||
switch (info.sprite->type)
|
||||
{
|
||||
case SPRITE_MISC_BALLOON:
|
||||
{
|
||||
auto balloonPress = BalloonPressAction(info.sprite->generic.sprite_index);
|
||||
auto balloonPress = BalloonPressAction(info.sprite->sprite_index);
|
||||
GameActions::Execute(&balloonPress);
|
||||
}
|
||||
break;
|
||||
case SPRITE_MISC_DUCK:
|
||||
duck_press(&info.sprite->duck);
|
||||
break;
|
||||
{
|
||||
auto duck = info.sprite->As<Duck>();
|
||||
if (duck != nullptr)
|
||||
{
|
||||
duck_press(duck);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -232,15 +247,21 @@ int32_t viewport_interaction_get_item_right(const ScreenCoordsXY& screenCoords,
|
|||
info->x = mapCoord.x;
|
||||
info->y = mapCoord.y;
|
||||
tileElement = info->tileElement;
|
||||
rct_sprite* sprite = info->sprite;
|
||||
auto sprite = info->sprite;
|
||||
|
||||
switch (info->type)
|
||||
{
|
||||
case VIEWPORT_INTERACTION_ITEM_SPRITE:
|
||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || sprite->generic.sprite_identifier != SPRITE_IDENTIFIER_VEHICLE)
|
||||
{
|
||||
if ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || sprite->sprite_identifier != SPRITE_IDENTIFIER_VEHICLE)
|
||||
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
|
||||
ride = get_ride(sprite->vehicle.ride);
|
||||
auto vehicle = sprite->As<Vehicle>();
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
return info->type = VIEWPORT_INTERACTION_ITEM_NONE;
|
||||
}
|
||||
ride = get_ride(vehicle->ride);
|
||||
if (ride != nullptr && ride->status == RIDE_STATUS_CLOSED)
|
||||
{
|
||||
auto ft = Formatter::MapTooltip();
|
||||
|
@ -248,7 +269,7 @@ int32_t viewport_interaction_get_item_right(const ScreenCoordsXY& screenCoords,
|
|||
ride->FormatNameTo(ft);
|
||||
}
|
||||
return info->type;
|
||||
|
||||
}
|
||||
case VIEWPORT_INTERACTION_ITEM_RIDE:
|
||||
{
|
||||
if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR)
|
||||
|
@ -465,9 +486,14 @@ int32_t viewport_interaction_right_click(const ScreenCoordsXY& screenCoords)
|
|||
return 0;
|
||||
|
||||
case VIEWPORT_INTERACTION_ITEM_SPRITE:
|
||||
if (info.sprite->generic.sprite_identifier == SPRITE_IDENTIFIER_VEHICLE)
|
||||
if (info.sprite->sprite_identifier == SPRITE_IDENTIFIER_VEHICLE)
|
||||
{
|
||||
auto ride = get_ride(info.sprite->vehicle.ride);
|
||||
auto vehicle = info.sprite->As<Vehicle>();
|
||||
if (vehicle == nullptr)
|
||||
{
|
||||
break;
|
||||
}
|
||||
auto ride = get_ride(vehicle->ride);
|
||||
if (ride != nullptr)
|
||||
{
|
||||
ride_construct(ride);
|
||||
|
|
|
@ -613,62 +613,55 @@ static void window_title_command_editor_tool_down(
|
|||
|
||||
if (info.type == VIEWPORT_INTERACTION_ITEM_SPRITE)
|
||||
{
|
||||
uint16_t spriteIndex = info.sprite->generic.sprite_index;
|
||||
uint16_t spriteIdentifier = info.sprite->generic.sprite_identifier;
|
||||
bool validSprite = false;
|
||||
if (info.sprite->generic.Is<Peep>())
|
||||
auto peep = info.sprite->As<Peep>();
|
||||
auto vehicle = info.sprite->As<Vehicle>();
|
||||
auto litter = info.sprite->As<Litter>();
|
||||
auto duck = info.sprite->As<Duck>();
|
||||
auto balloon = info.sprite->As<Balloon>();
|
||||
if (peep != nullptr)
|
||||
{
|
||||
validSprite = true;
|
||||
auto peep = GetEntity<Peep>(spriteIndex);
|
||||
if (peep != nullptr)
|
||||
uint8_t formatArgs[32]{};
|
||||
Formatter ft(formatArgs);
|
||||
peep->FormatNameTo(ft);
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_STRINGID, &peep->Id);
|
||||
}
|
||||
else if (vehicle != nullptr)
|
||||
{
|
||||
validSprite = true;
|
||||
|
||||
auto ride = vehicle->GetRide();
|
||||
if (ride != nullptr)
|
||||
{
|
||||
uint8_t formatArgs[32]{};
|
||||
Formatter ft(formatArgs);
|
||||
peep->FormatNameTo(ft);
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_STRINGID, &peep->Id);
|
||||
ride->FormatNameTo(ft);
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_STRINGID, formatArgs);
|
||||
}
|
||||
}
|
||||
else if (spriteIdentifier == SPRITE_IDENTIFIER_VEHICLE)
|
||||
else if (litter != nullptr)
|
||||
{
|
||||
validSprite = true;
|
||||
auto vehicle = GetEntity<Vehicle>(spriteIndex);
|
||||
if (vehicle != nullptr)
|
||||
{
|
||||
auto ride = vehicle->GetRide();
|
||||
if (ride != nullptr)
|
||||
{
|
||||
uint8_t formatArgs[32]{};
|
||||
Formatter ft(formatArgs);
|
||||
ride->FormatNameTo(ft);
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_STRINGID, formatArgs);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (spriteIdentifier == SPRITE_IDENTIFIER_LITTER)
|
||||
{
|
||||
Litter* litter = GetEntity<Litter>(spriteIndex);
|
||||
if (litter != nullptr && litter->type < std::size(litterNames))
|
||||
if (litter->type < std::size(litterNames))
|
||||
{
|
||||
validSprite = true;
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, litterNames[litter->type], nullptr);
|
||||
}
|
||||
}
|
||||
else if (spriteIdentifier == SPRITE_IDENTIFIER_MISC)
|
||||
else if (balloon != nullptr)
|
||||
{
|
||||
if (info.sprite->generic.Is<Balloon>())
|
||||
{
|
||||
validSprite = true;
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_SHOP_ITEM_SINGULAR_BALLOON, nullptr);
|
||||
}
|
||||
else if (info.sprite->generic.Is<Duck>())
|
||||
{
|
||||
validSprite = true;
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_DUCK, nullptr);
|
||||
}
|
||||
validSprite = true;
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_SHOP_ITEM_SINGULAR_BALLOON, nullptr);
|
||||
}
|
||||
else if (duck != nullptr)
|
||||
{
|
||||
validSprite = true;
|
||||
format_string(command.SpriteName, USER_STRING_MAX_LENGTH, STR_DUCK, nullptr);
|
||||
}
|
||||
|
||||
if (validSprite)
|
||||
{
|
||||
command.SpriteIndex = spriteIndex;
|
||||
command.SpriteIndex = info.sprite->sprite_index;
|
||||
window_follow_sprite(w, static_cast<size_t>(command.SpriteIndex));
|
||||
tool_cancel();
|
||||
w->Invalidate();
|
||||
|
|
|
@ -21,10 +21,9 @@ struct paint_struct;
|
|||
struct rct_drawpixelinfo;
|
||||
struct Peep;
|
||||
struct TileElement;
|
||||
struct Vehicle;
|
||||
struct rct_window;
|
||||
union paint_entry;
|
||||
union rct_sprite;
|
||||
struct SpriteBase;
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -92,9 +91,7 @@ struct viewport_interaction_info
|
|||
union
|
||||
{
|
||||
TileElement* tileElement;
|
||||
rct_sprite* sprite;
|
||||
Peep* peep;
|
||||
Vehicle* vehicle;
|
||||
SpriteBase* sprite;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -29,16 +29,19 @@ const uint32_t vehicle_particle_base_sprites[] = {
|
|||
/**
|
||||
* rct2: 0x00672AC9
|
||||
*/
|
||||
void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDirection)
|
||||
void misc_paint(paint_session* session, const SpriteBase* misc, int32_t imageDirection)
|
||||
{
|
||||
rct_drawpixelinfo* dpi = &session->DPI;
|
||||
|
||||
switch (misc->generic.type)
|
||||
switch (misc->type)
|
||||
{
|
||||
case SPRITE_MISC_STEAM_PARTICLE: // 0
|
||||
{
|
||||
uint32_t imageId = 22637 + (misc->steam_particle.frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, misc->generic.z);
|
||||
auto particle = misc->As<SteamParticle>();
|
||||
if (particle == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22637 + (particle->frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -48,8 +51,9 @@ void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDir
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const MoneyEffect* moneyEffect = &misc->money_effect;
|
||||
auto moneyEffect = misc->As<MoneyEffect>();
|
||||
if (moneyEffect == nullptr)
|
||||
return;
|
||||
auto [stringId, value] = moneyEffect->GetStringId();
|
||||
paint_floating_money_effect(
|
||||
session, value, stringId, moneyEffect->y, moneyEffect->z,
|
||||
|
@ -63,35 +67,44 @@ void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDir
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
VehicleCrashParticle particle = misc->crashed_vehicle_particle;
|
||||
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
|
||||
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;
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, misc->generic.z);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case SPRITE_MISC_EXPLOSION_CLOUD: // 3
|
||||
{
|
||||
uint32_t imageId = 22878 + (misc->generic.frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, misc->generic.z);
|
||||
auto particle = misc->As<ExplosionCloud>();
|
||||
if (particle == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22878 + (particle->frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, particle->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case SPRITE_MISC_CRASH_SPLASH: // 4
|
||||
{
|
||||
CrashSplashParticle crashSplash = misc->crash_splash;
|
||||
uint32_t imageId = 22927 + (crashSplash.frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, crashSplash.z);
|
||||
auto crashSplash = misc->As<CrashSplashParticle>();
|
||||
if (crashSplash == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22927 + (crashSplash->frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, crashSplash->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case SPRITE_MISC_EXPLOSION_FLARE: // 5
|
||||
{
|
||||
// Like a flare
|
||||
uint32_t imageId = 22896 + (misc->generic.frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, misc->generic.z);
|
||||
auto flare = misc->As<ExplosionFlare>();
|
||||
if (flare == nullptr)
|
||||
return;
|
||||
uint32_t imageId = 22896 + (flare->frame / 256);
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, flare->z);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -103,15 +116,16 @@ void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDir
|
|||
return;
|
||||
}
|
||||
|
||||
JumpingFountain jumpingFountain = misc->jumping_fountain;
|
||||
|
||||
uint16_t height = jumpingFountain.z + 6;
|
||||
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);
|
||||
bool reversed = (jumpingFountain->FountainFlags & FOUNTAIN_FLAG::DIRECTION);
|
||||
// Fountain rotation
|
||||
bool rotated = (jumpingFountain.sprite_direction / 16) & 1;
|
||||
bool rotated = (jumpingFountain->sprite_direction / 16) & 1;
|
||||
bool isAntiClockwise = (ebx / 2) & 1; // Clockwise or Anti-clockwise
|
||||
|
||||
// These cancel each other out
|
||||
|
@ -120,8 +134,8 @@ void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDir
|
|||
isAntiClockwise = !isAntiClockwise;
|
||||
}
|
||||
|
||||
uint32_t baseImageId = (jumpingFountain.type == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW) ? 23037 : 22973;
|
||||
uint32_t imageId = baseImageId + ebx * 16 + jumpingFountain.frame;
|
||||
uint32_t baseImageId = (jumpingFountain->type == SPRITE_MISC_JUMPING_FOUNTAIN_SNOW) ? 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 } };
|
||||
|
@ -134,24 +148,27 @@ void misc_paint(paint_session* session, const rct_sprite* misc, int32_t imageDir
|
|||
|
||||
case SPRITE_MISC_BALLOON: // 7
|
||||
{
|
||||
Balloon balloon = misc->balloon;
|
||||
|
||||
uint32_t imageId = 22651 + (balloon.frame & 7);
|
||||
if (balloon.popped != 0)
|
||||
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;
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, balloon.z);
|
||||
imageId = imageId | (balloon->colour << 19) | IMAGE_TYPE_REMAP;
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, balloon->z);
|
||||
break;
|
||||
}
|
||||
|
||||
case SPRITE_MISC_DUCK:
|
||||
if (dpi->zoom_level <= 1)
|
||||
{
|
||||
const Duck* duck = &misc->duck;
|
||||
uint32_t imageId = duck_get_frame_image(&misc->duck, imageDirection);
|
||||
const Duck* duck = misc->As<Duck>();
|
||||
if (duck == nullptr)
|
||||
return;
|
||||
uint32_t imageId = duck->GetFrameImage(imageDirection);
|
||||
if (imageId != 0)
|
||||
{
|
||||
sub_98196C(session, imageId, 0, 0, 1, 1, 0, duck->z);
|
||||
|
|
|
@ -115,7 +115,7 @@ void sprite_paint_setup(paint_session* session, const uint16_t x, const uint16_t
|
|||
break;
|
||||
case SPRITE_IDENTIFIER_MISC:
|
||||
// TODO: Update misc_paint to take a specific sprite type
|
||||
misc_paint(session, reinterpret_cast<const rct_sprite*>(spr), image_direction);
|
||||
misc_paint(session, spr, image_direction);
|
||||
break;
|
||||
case SPRITE_IDENTIFIER_LITTER:
|
||||
litter_paint(session, spr->As<Litter>(), image_direction);
|
||||
|
|
|
@ -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 rct_sprite* misc, int32_t imageDirection);
|
||||
void misc_paint(paint_session* session, const SpriteBase* 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);
|
||||
|
||||
|
|
|
@ -1672,10 +1672,10 @@ private:
|
|||
switch (src->type)
|
||||
{
|
||||
case SPRITE_MISC_STEAM_PARTICLE:
|
||||
ImportSteamParticle(reinterpret_cast<SteamParticle*>(dst), reinterpret_cast<SteamParticle*>(src));
|
||||
ImportSteamParticle(dst->As<SteamParticle>(), reinterpret_cast<RCT12SpriteSteamParticle*>(src));
|
||||
break;
|
||||
case SPRITE_MISC_MONEY_EFFECT:
|
||||
ImportMoneyEffect(reinterpret_cast<MoneyEffect*>(dst), reinterpret_cast<MoneyEffect*>(src));
|
||||
ImportMoneyEffect(dst->As<MoneyEffect>(), reinterpret_cast<RCT12SpriteMoneyEffect*>(src));
|
||||
break;
|
||||
case SPRITE_MISC_CRASHED_VEHICLE_PARTICLE:
|
||||
break;
|
||||
|
@ -1687,13 +1687,13 @@ private:
|
|||
break;
|
||||
case SPRITE_MISC_JUMPING_FOUNTAIN_WATER:
|
||||
ImportJumpingFountainWater(
|
||||
reinterpret_cast<JumpingFountain*>(dst), reinterpret_cast<JumpingFountain*>(src));
|
||||
dst->As<JumpingFountain>(), reinterpret_cast<RCT12SpriteJumpingFountain*>(src));
|
||||
break;
|
||||
case SPRITE_MISC_BALLOON:
|
||||
ImportBalloon(reinterpret_cast<Balloon*>(dst), reinterpret_cast<Balloon*>(src));
|
||||
ImportBalloon(dst->As<Balloon>(), reinterpret_cast<RCT12SpriteBalloon*>(src));
|
||||
break;
|
||||
case SPRITE_MISC_DUCK:
|
||||
ImportDuck(reinterpret_cast<Duck*>(dst), reinterpret_cast<Duck*>(src));
|
||||
ImportDuck(dst->As<Duck>(), reinterpret_cast<RCT12SpriteDuck*>(src));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1703,30 +1703,38 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void ImportMoneyEffect(MoneyEffect* dst, MoneyEffect* src)
|
||||
void ImportMoneyEffect(MoneyEffect* dst, RCT12SpriteMoneyEffect* src)
|
||||
{
|
||||
dst->MoveDelay = src->MoveDelay;
|
||||
dst->NumMovements = src->NumMovements;
|
||||
dst->Value = src->Value;
|
||||
dst->OffsetX = src->OffsetX;
|
||||
dst->Wiggle = src->Wiggle;
|
||||
if (dst == nullptr)
|
||||
return;
|
||||
dst->MoveDelay = src->move_delay;
|
||||
dst->NumMovements = src->num_movements;
|
||||
dst->Value = src->value;
|
||||
dst->OffsetX = src->offset_x;
|
||||
dst->Wiggle = src->wiggle;
|
||||
}
|
||||
|
||||
void ImportSteamParticle(SteamParticle* dst, SteamParticle* src)
|
||||
void ImportSteamParticle(SteamParticle* dst, RCT12SpriteSteamParticle* src)
|
||||
{
|
||||
if (dst == nullptr)
|
||||
return;
|
||||
dst->frame = src->frame;
|
||||
}
|
||||
|
||||
void ImportJumpingFountainWater(JumpingFountain* dst, JumpingFountain* src)
|
||||
void ImportJumpingFountainWater(JumpingFountain* dst, RCT12SpriteJumpingFountain* src)
|
||||
{
|
||||
dst->FountainFlags = src->FountainFlags;
|
||||
dst->Iteration = src->Iteration;
|
||||
dst->NumTicksAlive = src->NumTicksAlive;
|
||||
if (dst == nullptr)
|
||||
return;
|
||||
dst->FountainFlags = src->fountain_flags;
|
||||
dst->Iteration = src->iteration;
|
||||
dst->NumTicksAlive = src->num_ticks_alive;
|
||||
dst->frame = src->frame;
|
||||
}
|
||||
|
||||
void ImportBalloon(Balloon* dst, Balloon* src)
|
||||
void ImportBalloon(Balloon* dst, RCT12SpriteBalloon* src)
|
||||
{
|
||||
if (dst == nullptr)
|
||||
return;
|
||||
// Balloons were always blue in RCT1 without AA/LL
|
||||
if (_gameVersion == FILE_VERSION_RCT1)
|
||||
{
|
||||
|
@ -1738,8 +1746,10 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void ImportDuck(Duck* dst, Duck* src)
|
||||
void ImportDuck(Duck* dst, RCT12SpriteDuck* src)
|
||||
{
|
||||
if (dst == nullptr)
|
||||
return;
|
||||
dst->frame = src->frame;
|
||||
dst->state = src->state;
|
||||
}
|
||||
|
|
|
@ -46,11 +46,11 @@ static void paint_crooked_house_structure(
|
|||
|
||||
if (ride->lifecycle_flags & RIDE_LIFECYCLE_ON_TRACK)
|
||||
{
|
||||
if (ride->vehicles[0] != SPRITE_INDEX_NULL)
|
||||
auto vehicle = GetEntity<Vehicle>(ride->vehicles[0]);
|
||||
if (vehicle != nullptr)
|
||||
{
|
||||
auto sprite = GetEntity(ride->vehicles[0]);
|
||||
session->InteractionType = VIEWPORT_INTERACTION_ITEM_SPRITE;
|
||||
session->CurrentlyDrawnItem = sprite;
|
||||
session->CurrentlyDrawnItem = vehicle;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ namespace OpenRCT2::Scripting
|
|||
auto sprite = GetEntity(spriteId);
|
||||
if (sprite != nullptr && sprite->sprite_identifier != SPRITE_IDENTIFIER_NULL)
|
||||
{
|
||||
return GetEntityAsDukValue(reinterpret_cast<rct_sprite*>(sprite));
|
||||
return GetEntityAsDukValue(sprite);
|
||||
}
|
||||
}
|
||||
duk_push_null(_context);
|
||||
|
@ -138,7 +138,7 @@ namespace OpenRCT2::Scripting
|
|||
{
|
||||
if (targetList == EntityListId::Peep)
|
||||
{
|
||||
if (sprite->As<Staff>())
|
||||
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)));
|
||||
|
@ -174,18 +174,20 @@ namespace OpenRCT2::Scripting
|
|||
}
|
||||
|
||||
private:
|
||||
DukValue GetEntityAsDukValue(const rct_sprite* sprite) const
|
||||
DukValue GetEntityAsDukValue(const SpriteBase* sprite) const
|
||||
{
|
||||
auto spriteId = sprite->generic.sprite_index;
|
||||
switch (sprite->generic.sprite_identifier)
|
||||
auto spriteId = sprite->sprite_index;
|
||||
switch (sprite->sprite_identifier)
|
||||
{
|
||||
case SPRITE_IDENTIFIER_VEHICLE:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScVehicle>(spriteId));
|
||||
case SPRITE_IDENTIFIER_PEEP:
|
||||
if (sprite->peep.AssignedPeepType == PeepType::Staff)
|
||||
{
|
||||
if (sprite->Is<Staff>())
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScStaff>(spriteId));
|
||||
else
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScGuest>(spriteId));
|
||||
}
|
||||
default:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScEntity>(spriteId));
|
||||
}
|
||||
|
|
|
@ -82,19 +82,22 @@ void Balloon::Pop()
|
|||
void create_balloon(const CoordsXYZ& balloonPos, int32_t colour, bool isPopped)
|
||||
{
|
||||
rct_sprite* sprite = create_sprite(SPRITE_IDENTIFIER_MISC);
|
||||
if (sprite != nullptr)
|
||||
{
|
||||
sprite->balloon.sprite_width = 13;
|
||||
sprite->balloon.sprite_height_negative = 22;
|
||||
sprite->balloon.sprite_height_positive = 11;
|
||||
sprite->balloon.sprite_identifier = SPRITE_IDENTIFIER_MISC;
|
||||
sprite->balloon.MoveTo(balloonPos);
|
||||
sprite->balloon.type = SPRITE_MISC_BALLOON;
|
||||
sprite->balloon.time_to_move = 0;
|
||||
sprite->balloon.frame = 0;
|
||||
sprite->balloon.colour = colour;
|
||||
sprite->balloon.popped = (isPopped ? 1 : 0);
|
||||
}
|
||||
if (sprite == nullptr)
|
||||
return;
|
||||
sprite->generic.sprite_identifier = SPRITE_IDENTIFIER_MISC;
|
||||
sprite->generic.type = SPRITE_MISC_BALLOON;
|
||||
auto balloon = sprite->generic.As<Balloon>();
|
||||
if (balloon == nullptr)
|
||||
return; // can never happen
|
||||
|
||||
balloon->sprite_width = 13;
|
||||
balloon->sprite_height_negative = 22;
|
||||
balloon->sprite_height_positive = 11;
|
||||
balloon->MoveTo(balloonPos);
|
||||
balloon->time_to_move = 0;
|
||||
balloon->frame = 0;
|
||||
balloon->colour = colour;
|
||||
balloon->popped = (isPopped ? 1 : 0);
|
||||
}
|
||||
|
||||
void balloon_update(Balloon* balloon)
|
||||
|
|
|
@ -305,13 +305,16 @@ void create_duck(const CoordsXY& pos)
|
|||
targetPos.x += offsetXY;
|
||||
targetPos.y += offsetXY;
|
||||
|
||||
sprite->duck.sprite_identifier = SPRITE_IDENTIFIER_MISC;
|
||||
sprite->duck.type = SPRITE_MISC_DUCK;
|
||||
sprite->duck.sprite_width = 9;
|
||||
sprite->duck.sprite_height_negative = 12;
|
||||
sprite->duck.sprite_height_positive = 9;
|
||||
sprite->duck.target_x = targetPos.x;
|
||||
sprite->duck.target_y = targetPos.y;
|
||||
sprite->generic.sprite_identifier = SPRITE_IDENTIFIER_MISC;
|
||||
sprite->generic.type = SPRITE_MISC_DUCK;
|
||||
auto duck = sprite->generic.As<Duck>();
|
||||
if (duck == nullptr)
|
||||
return; // can never happen
|
||||
duck->sprite_width = 9;
|
||||
duck->sprite_height_negative = 12;
|
||||
duck->sprite_height_positive = 9;
|
||||
duck->target_x = targetPos.x;
|
||||
duck->target_y = targetPos.y;
|
||||
uint8_t direction = scenario_rand() & 3;
|
||||
switch (direction)
|
||||
{
|
||||
|
@ -328,10 +331,10 @@ void create_duck(const CoordsXY& pos)
|
|||
targetPos.y = 8191 - (scenario_rand() & 0x3F);
|
||||
break;
|
||||
}
|
||||
sprite->duck.sprite_direction = direction << 3;
|
||||
sprite->duck.MoveTo({ targetPos.x, targetPos.y, 496 });
|
||||
sprite->duck.state = DUCK_STATE::FLY_TO_WATER;
|
||||
sprite->duck.frame = 0;
|
||||
duck->sprite_direction = direction << 3;
|
||||
duck->MoveTo({ targetPos.x, targetPos.y, 496 });
|
||||
duck->state = DUCK_STATE::FLY_TO_WATER;
|
||||
duck->frame = 0;
|
||||
}
|
||||
|
||||
void Duck::Update()
|
||||
|
@ -368,8 +371,3 @@ void duck_remove_all()
|
|||
duck->Remove();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t duck_get_frame_image(const Duck* duck, int32_t direction)
|
||||
{
|
||||
return duck->GetFrameImage(direction);
|
||||
}
|
||||
|
|
|
@ -98,28 +98,19 @@ std::string rct_sprite_checksum::ToString() const
|
|||
return result;
|
||||
}
|
||||
|
||||
rct_sprite* try_get_sprite(size_t spriteIndex)
|
||||
SpriteBase* try_get_sprite(size_t spriteIndex)
|
||||
{
|
||||
rct_sprite* sprite = nullptr;
|
||||
if (spriteIndex < MAX_SPRITES)
|
||||
{
|
||||
sprite = &_spriteList[spriteIndex];
|
||||
}
|
||||
return sprite;
|
||||
return spriteIndex >= MAX_SPRITES ? nullptr : &_spriteList[spriteIndex].generic;
|
||||
}
|
||||
|
||||
rct_sprite* get_sprite(size_t sprite_idx)
|
||||
SpriteBase* get_sprite(size_t spriteIndex)
|
||||
{
|
||||
if (sprite_idx == SPRITE_INDEX_NULL)
|
||||
if (spriteIndex == SPRITE_INDEX_NULL)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
openrct2_assert(sprite_idx < MAX_SPRITES, "Tried getting sprite %u", sprite_idx);
|
||||
if (sprite_idx >= MAX_SPRITES)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return &_spriteList[sprite_idx];
|
||||
openrct2_assert(spriteIndex < MAX_SPRITES, "Tried getting sprite %u", spriteIndex);
|
||||
return try_get_sprite(spriteIndex);
|
||||
}
|
||||
|
||||
uint16_t sprite_get_first_in_quadrant(const CoordsXY& spritePos)
|
||||
|
@ -782,14 +773,7 @@ void sprite_remove(SpriteBase* sprite)
|
|||
sprite->sprite_identifier = SPRITE_IDENTIFIER_NULL;
|
||||
_spriteFlashingList[sprite->sprite_index] = false;
|
||||
|
||||
size_t quadrantIndex = GetSpatialIndexOffset(sprite->x, sprite->y);
|
||||
uint16_t* spriteIndex = &gSpriteSpatialIndex[quadrantIndex];
|
||||
SpriteBase* quadrantSprite;
|
||||
while (*spriteIndex != SPRITE_INDEX_NULL && (quadrantSprite = GetEntity(*spriteIndex)) != sprite)
|
||||
{
|
||||
spriteIndex = &quadrantSprite->next_in_quadrant;
|
||||
}
|
||||
*spriteIndex = sprite->next_in_quadrant;
|
||||
SpriteSpatialRemove(sprite);
|
||||
}
|
||||
|
||||
static bool litter_can_be_at(const CoordsXYZ& mapPos)
|
||||
|
|
|
@ -201,17 +201,17 @@ enum
|
|||
LITTER_TYPE_EMPTY_BOWL_BLUE,
|
||||
};
|
||||
|
||||
rct_sprite* try_get_sprite(size_t spriteIndex);
|
||||
rct_sprite* get_sprite(size_t sprite_idx);
|
||||
SpriteBase* try_get_sprite(size_t spriteIndex);
|
||||
SpriteBase* get_sprite(size_t sprite_idx);
|
||||
template<typename T = SpriteBase> T* GetEntity(size_t sprite_idx)
|
||||
{
|
||||
auto spr = reinterpret_cast<SpriteBase*>(get_sprite(sprite_idx));
|
||||
auto spr = get_sprite(sprite_idx);
|
||||
return spr != nullptr ? spr->As<T>() : nullptr;
|
||||
}
|
||||
|
||||
template<typename T = SpriteBase> T* TryGetEntity(size_t sprite_idx)
|
||||
{
|
||||
auto spr = reinterpret_cast<SpriteBase*>(try_get_sprite(sprite_idx));
|
||||
auto spr = try_get_sprite(sprite_idx);
|
||||
return spr != nullptr ? spr->As<T>() : nullptr;
|
||||
}
|
||||
|
||||
|
@ -258,7 +258,6 @@ void create_duck(const CoordsXY& pos);
|
|||
void duck_update(Duck* duck);
|
||||
void duck_press(Duck* duck);
|
||||
void duck_remove_all();
|
||||
uint32_t duck_get_frame_image(const Duck* duck, int32_t direction);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Crash particles
|
||||
|
|
|
@ -167,10 +167,10 @@ template<> bool SpriteBase::Is<Vehicle>() const
|
|||
return sprite_identifier == SPRITE_IDENTIFIER_VEHICLE;
|
||||
}
|
||||
|
||||
rct_sprite* get_sprite(size_t sprite_idx)
|
||||
SpriteBase* get_sprite(size_t sprite_idx)
|
||||
{
|
||||
assert(sprite_idx < MAX_SPRITES);
|
||||
return &sprite_list[sprite_idx];
|
||||
return reinterpret_cast<SpriteBase*>(&sprite_list[sprite_idx]);
|
||||
}
|
||||
|
||||
bool TileElementBase::IsLastForTile() const
|
||||
|
|
Loading…
Reference in New Issue