1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

Fix rendering balloons/hats/umbrellas held by guests

This commit is contained in:
Aaron van Geffen
2024-12-19 09:26:39 +01:00
parent 2f0af0a005
commit cc668f080e
4 changed files with 68 additions and 40 deletions

View File

@@ -578,27 +578,31 @@ namespace OpenRCT2::Ui::Windows
GfxDrawSprite(clipDpi, spriteId, screenCoords);
auto* guest = peep->As<Guest>();
if (guest != nullptr)
if (guest == nullptr)
return;
// There are only 6 walking frames available for each item.
auto itemFrame = (_guestAnimationFrame / 4) % 6;
if (guest->AnimationGroup == PeepAnimationGroup::Hat)
{
// If holding a balloon
if (animationFrame >= kPeepSpriteBalloonStateWatchRideId
&& animationFrame < kPeepSpriteBalloonStateSittingIdleId + 4)
{
GfxDrawSprite(clipDpi, ImageId(animationFrame + 32, guest->BalloonColour), screenCoords);
}
auto itemOffset = kPeepSpriteHatItemStart + 1;
auto imageId = ImageId(itemOffset + itemFrame * 4, guest->HatColour);
GfxDrawSprite(clipDpi, imageId, screenCoords);
}
// If holding umbrella
if (animationFrame >= kPeepSpriteUmbrellaStateWalkingId
&& animationFrame < kPeepSpriteUmbrellaStateSittingIdleId + 4)
{
GfxDrawSprite(clipDpi, ImageId(animationFrame + 32, guest->UmbrellaColour), screenCoords);
}
if (guest->AnimationGroup == PeepAnimationGroup::Balloon)
{
auto itemOffset = kPeepSpriteBalloonItemStart + 1;
auto imageId = ImageId(itemOffset + itemFrame * 4, guest->BalloonColour);
GfxDrawSprite(clipDpi, imageId, screenCoords);
}
// If wearing hat
if (animationFrame >= kPeepSpriteHatStateWatchRideId && animationFrame < kPeepSpriteHatStateSittingIdleId + 4)
{
GfxDrawSprite(clipDpi, ImageId(animationFrame + 32, guest->HatColour), screenCoords);
}
if (guest->AnimationGroup == PeepAnimationGroup::Umbrella)
{
auto itemOffset = kPeepSpriteUmbrellaItemStart + 1;
auto imageId = ImageId(itemOffset + itemFrame * 4, guest->UmbrellaColour);
GfxDrawSprite(clipDpi, imageId, screenCoords);
}
}

View File

@@ -2909,8 +2909,6 @@ void Peep::Paint(PaintSession& session, int32_t imageDirection) const
auto& objManager = GetContext()->GetObjectManager();
auto* animObj = objManager.GetLoadedObject<PeepAnimationsObject>(AnimationObjectIndex);
// In the following 4 calls to PaintAddImageAsParent/PaintAddImageAsChild, we add 5 (instead of 3) to the
// bound_box_offset_z to make sure peeps are drawn on top of railways
uint32_t baseImageId = animObj->GetPeepAnimation(AnimationGroup, actionAnimationGroup).base_image;
// Offset frame onto the base image, using rotation except for the 'picked up' state
@@ -2921,33 +2919,46 @@ void Peep::Paint(PaintSession& session, int32_t imageDirection) const
auto imageId = ImageId(baseImageId, TshirtColour, TrousersColour);
// In the following 4 calls to PaintAddImageAsParent/PaintAddImageAsChild, we add 5 (instead of 3) to the
// bound_box_offset_z to make sure peeps are drawn on top of railways
auto bb = BoundBoxXYZ{ { 0, 0, z + 5 }, { 1, 1, 11 } };
auto offset = CoordsXYZ{ 0, 0, z };
PaintAddImageAsParent(session, imageId, { 0, 0, z }, bb);
auto* guest = As<Guest>();
if (guest != nullptr)
if (guest == nullptr)
return;
// There are only 6 walking frames available for each item,
// as well as 1 sprite for sitting and 1 for standing still.
auto itemFrame = imageOffset % 6;
if (actionAnimationGroup == PeepAnimationType::WatchRide)
itemFrame = 6;
else if (actionAnimationGroup == PeepAnimationType::SittingIdle)
itemFrame = 7;
if (AnimationGroup == PeepAnimationGroup::Hat)
{
if (baseImageId >= kPeepSpriteHatStateWatchRideId && baseImageId < (kPeepSpriteHatStateSittingIdleId + 4))
{
imageId = ImageId(baseImageId + 32, guest->HatColour);
PaintAddImageAsChild(session, imageId, offset, bb);
return;
}
auto itemOffset = kPeepSpriteHatItemStart;
imageId = ImageId(itemOffset + (imageDirection >> 3) + itemFrame * 4, guest->HatColour);
PaintAddImageAsChild(session, imageId, offset, bb);
return;
}
if (baseImageId >= kPeepSpriteBalloonStateWatchRideId && baseImageId < (kPeepSpriteBalloonStateSittingIdleId + 4))
{
imageId = ImageId(baseImageId + 32, guest->BalloonColour);
PaintAddImageAsChild(session, imageId, offset, bb);
return;
}
if (AnimationGroup == PeepAnimationGroup::Balloon)
{
auto itemOffset = kPeepSpriteBalloonItemStart;
imageId = ImageId(itemOffset + (imageDirection >> 3) + itemFrame * 4, guest->BalloonColour);
PaintAddImageAsChild(session, imageId, offset, bb);
return;
}
if (baseImageId >= kPeepSpriteUmbrellaStateWalkingId && baseImageId < (kPeepSpriteUmbrellaStateSittingIdleId + 4))
{
imageId = ImageId(baseImageId + 32, guest->UmbrellaColour);
PaintAddImageAsChild(session, imageId, offset, bb);
return;
}
if (AnimationGroup == PeepAnimationGroup::Umbrella)
{
auto itemOffset = kPeepSpriteUmbrellaItemStart;
imageId = ImageId(itemOffset + (imageDirection >> 3) + itemFrame * 4, guest->UmbrellaColour);
PaintAddImageAsChild(session, imageId, offset, bb);
return;
}
}

View File

@@ -37,13 +37,23 @@ void PeepAnimationsObject::Load()
_imageOffsetId = LoadImages();
// Set loaded image offsets for all animations
for (auto& group : _animationGroups)
for (auto groupKey = 0u; groupKey < _animationGroups.size(); groupKey++)
{
auto& group = _animationGroups[groupKey];
auto& requiredAnimationMap = getAnimationsByPeepType(_peepType);
for (auto& [typeStr, typeEnum] : requiredAnimationMap)
{
group[typeEnum].base_image = _imageOffsetId + group[typeEnum].imageTableOffset;
group[typeEnum].bounds = inferMaxAnimationDimensions(group[typeEnum]);
// Balloons, hats and umbrellas are painted separately, so the inference
// algorithm doesn't account for those. We manually compensate for these here.
// Between 8-12 pixels are needed, depending on rotation, so we're generalising.
auto pag = PeepAnimationGroup(groupKey);
if (pag == PeepAnimationGroup::Balloon || pag == PeepAnimationGroup::Hat || pag == PeepAnimationGroup::Umbrella)
{
group[typeEnum].bounds.sprite_height_negative += 12;
}
}
}
}

View File

@@ -158,6 +158,7 @@ namespace OpenRCT2
kPeepSpriteBalloonStateWalkingId = 10785,
kPeepSpriteBalloonStateWatchRideId = 10781,
kPeepSpriteBalloonStateSittingIdleId = 10809,
kPeepSpriteBalloonItemStart = 10813,
kPeepSpriteCandyflossStateWalkingId = 10849,
kPeepSpriteCandyflossStateWatchRideId = 10845,
@@ -168,6 +169,7 @@ namespace OpenRCT2
kPeepSpriteUmbrellaStateWalkingId = 11197,
kPeepSpriteUmbrellaStateWatchRideId = 11221,
kPeepSpriteUmbrellaStateSittingIdleId = 11225,
kPeepSpriteUmbrellaItemStart = 11229,
kPeepSpritePizzaStateWalkingId = 7785,
kPeepSpritePizzaStateWatchRideId = 7781,
@@ -197,6 +199,7 @@ namespace OpenRCT2
kPeepSpriteHatStateWalkingId = 10721,
kPeepSpriteHatStateWatchRideId = 10717,
kPeepSpriteHatStateSittingIdleId = 10745,
kPeepSpriteHatItemStart = 10749,
kPeepSpriteHotDogStateWalkingId = 7889,
kPeepSpriteHotDogStateWatchRideId = 7885,