mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 07:43:01 +01:00
Introduce PeepAnimation compilation unit (#23383)
* Move StaffType enum into Staff.h * Introduce PeepAnimation compilation unit
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../entity/Staff.h"
|
||||||
#include "GameAction.h"
|
#include "GameAction.h"
|
||||||
|
|
||||||
class StaffSetColourAction final : public GameActionBase<GameCommand::SetStaffColour>
|
class StaffSetColourAction final : public GameActionBase<GameCommand::SetStaffColour>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../world/Map.h"
|
#include "../world/Map.h"
|
||||||
#include "Peep.h"
|
#include "Staff.h"
|
||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
|||||||
@@ -36,16 +36,6 @@ namespace OpenRCT2::GameActions
|
|||||||
class Result;
|
class Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class StaffType : uint8_t
|
|
||||||
{
|
|
||||||
Handyman,
|
|
||||||
Mechanic,
|
|
||||||
Security,
|
|
||||||
Entertainer,
|
|
||||||
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class PeepState : uint8_t
|
enum class PeepState : uint8_t
|
||||||
{
|
{
|
||||||
Falling = 0, // Drowning is part of falling
|
Falling = 0, // Drowning is part of falling
|
||||||
|
|||||||
@@ -20,6 +20,16 @@ class PatrolArea;
|
|||||||
|
|
||||||
using colour_t = uint8_t;
|
using colour_t = uint8_t;
|
||||||
|
|
||||||
|
enum class StaffType : uint8_t
|
||||||
|
{
|
||||||
|
Handyman,
|
||||||
|
Mechanic,
|
||||||
|
Security,
|
||||||
|
Entertainer,
|
||||||
|
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
struct Staff : Peep
|
struct Staff : Peep
|
||||||
{
|
{
|
||||||
static constexpr auto cEntityType = EntityType::Staff;
|
static constexpr auto cEntityType = EntityType::Staff;
|
||||||
|
|||||||
@@ -329,9 +329,6 @@
|
|||||||
<ClInclude Include="object\EntranceEntry.h" />
|
<ClInclude Include="object\EntranceEntry.h" />
|
||||||
<ClInclude Include="object\EntranceObject.h" />
|
<ClInclude Include="object\EntranceObject.h" />
|
||||||
<ClInclude Include="object\FootpathEntry.h" />
|
<ClInclude Include="object\FootpathEntry.h" />
|
||||||
<ClInclude Include="object\PathAdditionEntry.h" />
|
|
||||||
<ClInclude Include="object\PathAdditionObject.h" />
|
|
||||||
<ClInclude Include="object\PeepNamesObject.h" />
|
|
||||||
<ClInclude Include="object\FootpathObject.h" />
|
<ClInclude Include="object\FootpathObject.h" />
|
||||||
<ClInclude Include="object\FootpathRailingsObject.h" />
|
<ClInclude Include="object\FootpathRailingsObject.h" />
|
||||||
<ClInclude Include="object\FootpathSurfaceObject.h" />
|
<ClInclude Include="object\FootpathSurfaceObject.h" />
|
||||||
@@ -349,6 +346,9 @@
|
|||||||
<ClInclude Include="object\ObjectRepository.h" />
|
<ClInclude Include="object\ObjectRepository.h" />
|
||||||
<ClInclude Include="object\ObjectType.h" />
|
<ClInclude Include="object\ObjectType.h" />
|
||||||
<ClInclude Include="object\ObjectTypes.h" />
|
<ClInclude Include="object\ObjectTypes.h" />
|
||||||
|
<ClInclude Include="object\PathAdditionEntry.h" />
|
||||||
|
<ClInclude Include="object\PathAdditionObject.h" />
|
||||||
|
<ClInclude Include="object\PeepNamesObject.h" />
|
||||||
<ClInclude Include="object\ResourceTable.h" />
|
<ClInclude Include="object\ResourceTable.h" />
|
||||||
<ClInclude Include="object\RideObject.h" />
|
<ClInclude Include="object\RideObject.h" />
|
||||||
<ClInclude Include="object\SceneryGroupEntry.h" />
|
<ClInclude Include="object\SceneryGroupEntry.h" />
|
||||||
@@ -391,6 +391,7 @@
|
|||||||
<ClInclude Include="peep\Guest.h" />
|
<ClInclude Include="peep\Guest.h" />
|
||||||
<ClInclude Include="peep\GuestPathfinding.h" />
|
<ClInclude Include="peep\GuestPathfinding.h" />
|
||||||
<ClInclude Include="peep\PeepAnimationData.h" />
|
<ClInclude Include="peep\PeepAnimationData.h" />
|
||||||
|
<ClInclude Include="peep\PeepAnimations.h" />
|
||||||
<ClInclude Include="peep\PeepSpriteIds.h" />
|
<ClInclude Include="peep\PeepSpriteIds.h" />
|
||||||
<ClInclude Include="peep\PeepThoughts.h" />
|
<ClInclude Include="peep\PeepThoughts.h" />
|
||||||
<ClInclude Include="peep\RideUseSystem.h" />
|
<ClInclude Include="peep\RideUseSystem.h" />
|
||||||
@@ -864,7 +865,6 @@
|
|||||||
<ClCompile Include="object\BannerObject.cpp" />
|
<ClCompile Include="object\BannerObject.cpp" />
|
||||||
<ClCompile Include="object\DefaultObjects.cpp" />
|
<ClCompile Include="object\DefaultObjects.cpp" />
|
||||||
<ClCompile Include="object\EntranceObject.cpp" />
|
<ClCompile Include="object\EntranceObject.cpp" />
|
||||||
<ClCompile Include="object\PathAdditionObject.cpp" />
|
|
||||||
<ClCompile Include="object\FootpathObject.cpp" />
|
<ClCompile Include="object\FootpathObject.cpp" />
|
||||||
<ClCompile Include="object\FootpathRailingsObject.cpp" />
|
<ClCompile Include="object\FootpathRailingsObject.cpp" />
|
||||||
<ClCompile Include="object\FootpathSurfaceObject.cpp" />
|
<ClCompile Include="object\FootpathSurfaceObject.cpp" />
|
||||||
@@ -878,11 +878,12 @@
|
|||||||
<ClCompile Include="object\ObjectManager.cpp" />
|
<ClCompile Include="object\ObjectManager.cpp" />
|
||||||
<ClCompile Include="object\ObjectRepository.cpp" />
|
<ClCompile Include="object\ObjectRepository.cpp" />
|
||||||
<ClCompile Include="object\ObjectTypes.cpp" />
|
<ClCompile Include="object\ObjectTypes.cpp" />
|
||||||
|
<ClCompile Include="object\PathAdditionObject.cpp" />
|
||||||
<ClCompile Include="object\PeepNamesObject.cpp" />
|
<ClCompile Include="object\PeepNamesObject.cpp" />
|
||||||
<ClCompile Include="object\ResourceTable.cpp" />
|
<ClCompile Include="object\ResourceTable.cpp" />
|
||||||
<ClCompile Include="object\RideObject.cpp" />
|
<ClCompile Include="object\RideObject.cpp" />
|
||||||
<ClCompile Include="object\SceneryGroupObject.cpp" />
|
|
||||||
<ClCompile Include="object\ScenarioTextObject.cpp" />
|
<ClCompile Include="object\ScenarioTextObject.cpp" />
|
||||||
|
<ClCompile Include="object\SceneryGroupObject.cpp" />
|
||||||
<ClCompile Include="object\SmallSceneryObject.cpp" />
|
<ClCompile Include="object\SmallSceneryObject.cpp" />
|
||||||
<ClCompile Include="object\StationObject.cpp" />
|
<ClCompile Include="object\StationObject.cpp" />
|
||||||
<ClCompile Include="object\StringTable.cpp" />
|
<ClCompile Include="object\StringTable.cpp" />
|
||||||
@@ -1006,6 +1007,7 @@
|
|||||||
<ClCompile Include="park\ParkFile.cpp" />
|
<ClCompile Include="park\ParkFile.cpp" />
|
||||||
<ClCompile Include="peep\GuestPathfinding.cpp" />
|
<ClCompile Include="peep\GuestPathfinding.cpp" />
|
||||||
<ClCompile Include="peep\PeepAnimationData.cpp" />
|
<ClCompile Include="peep\PeepAnimationData.cpp" />
|
||||||
|
<ClCompile Include="peep\PeepAnimations.cpp" />
|
||||||
<ClCompile Include="peep\PeepThoughts.cpp" />
|
<ClCompile Include="peep\PeepThoughts.cpp" />
|
||||||
<ClCompile Include="peep\RideUseSystem.cpp" />
|
<ClCompile Include="peep\RideUseSystem.cpp" />
|
||||||
<ClCompile Include="PlatformEnvironment.cpp" />
|
<ClCompile Include="PlatformEnvironment.cpp" />
|
||||||
|
|||||||
@@ -10,109 +10,13 @@
|
|||||||
#include "PeepAnimationData.h"
|
#include "PeepAnimationData.h"
|
||||||
|
|
||||||
#include "../drawing/Drawing.h"
|
#include "../drawing/Drawing.h"
|
||||||
|
#include "PeepAnimations.h"
|
||||||
#include "PeepSpriteIds.h"
|
#include "PeepSpriteIds.h"
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace OpenRCT2
|
namespace OpenRCT2
|
||||||
{
|
{
|
||||||
// Adapted from CarEntry.cpp
|
|
||||||
static SpriteBounds inferMaxAnimationDimensions(const PeepAnimation& anim)
|
|
||||||
{
|
|
||||||
constexpr uint8_t kWidth = 200;
|
|
||||||
constexpr uint8_t kHeight = 200;
|
|
||||||
constexpr uint8_t kCentreX = kWidth / 2;
|
|
||||||
constexpr uint8_t kCentreY = kHeight / 2;
|
|
||||||
|
|
||||||
uint8_t bitmap[kHeight][kWidth] = { 0 };
|
|
||||||
|
|
||||||
DrawPixelInfo dpi = {
|
|
||||||
.bits = reinterpret_cast<uint8_t*>(bitmap),
|
|
||||||
.x = -(kWidth / 2),
|
|
||||||
.y = -(kHeight / 2),
|
|
||||||
.width = kWidth,
|
|
||||||
.height = kHeight,
|
|
||||||
.pitch = 0,
|
|
||||||
.zoom_level = ZoomLevel{ 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto numImages = *(std::max_element(anim.frame_offsets.begin(), anim.frame_offsets.end())) + 1;
|
|
||||||
for (int32_t i = 0; i < numImages; ++i)
|
|
||||||
{
|
|
||||||
GfxDrawSpriteSoftware(dpi, ImageId(anim.base_image + i), { 0, 0 });
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t spriteWidth = -1;
|
|
||||||
for (int32_t i = kCentreX - 1; i != 0; --i)
|
|
||||||
{
|
|
||||||
for (int32_t j = 0; j < kWidth; j++)
|
|
||||||
{
|
|
||||||
if (bitmap[j][kCentreX - i] != 0)
|
|
||||||
{
|
|
||||||
spriteWidth = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spriteWidth != -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (int32_t j = 0; j < kWidth; j++)
|
|
||||||
{
|
|
||||||
if (bitmap[j][kCentreX + i] != 0)
|
|
||||||
{
|
|
||||||
spriteWidth = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spriteWidth != -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
spriteWidth++;
|
|
||||||
|
|
||||||
int32_t spriteHeightNegative = -1;
|
|
||||||
for (int32_t i = kCentreY - 1; i != 0; --i)
|
|
||||||
{
|
|
||||||
for (int32_t j = 0; j < kWidth; j++)
|
|
||||||
{
|
|
||||||
if (bitmap[kCentreY - i][j] != 0)
|
|
||||||
{
|
|
||||||
spriteHeightNegative = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spriteHeightNegative != -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
spriteHeightNegative++;
|
|
||||||
|
|
||||||
int32_t spriteHeightPositive = -1;
|
|
||||||
for (int32_t i = kCentreY - 1; i != 0; --i)
|
|
||||||
{
|
|
||||||
for (int32_t j = 0; j < kWidth; j++)
|
|
||||||
{
|
|
||||||
if (bitmap[kCentreY + i][j] != 0)
|
|
||||||
{
|
|
||||||
spriteHeightPositive = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (spriteHeightPositive != -1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
spriteHeightPositive++;
|
|
||||||
|
|
||||||
return {
|
|
||||||
.sprite_width = static_cast<uint8_t>(spriteWidth),
|
|
||||||
.sprite_height_negative = static_cast<uint8_t>(spriteHeightNegative),
|
|
||||||
.sprite_height_positive = static_cast<uint8_t>(spriteHeightPositive),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
// Define animation sequences for Normal sprites
|
// Define animation sequences for Normal sprites
|
||||||
@@ -1098,5 +1002,4 @@ namespace OpenRCT2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace OpenRCT2
|
} // namespace OpenRCT2
|
||||||
|
|||||||
@@ -2,49 +2,12 @@
|
|||||||
|
|
||||||
#include "../entity/Peep.h"
|
#include "../entity/Peep.h"
|
||||||
#include "../util/Util.h"
|
#include "../util/Util.h"
|
||||||
|
#include "PeepAnimations.h"
|
||||||
|
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
namespace OpenRCT2
|
namespace OpenRCT2
|
||||||
{
|
{
|
||||||
struct SpriteBounds
|
|
||||||
{
|
|
||||||
uint8_t sprite_width; // 0x00
|
|
||||||
uint8_t sprite_height_negative; // 0x01
|
|
||||||
uint8_t sprite_height_positive; // 0x02
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PeepAnimation
|
|
||||||
{
|
|
||||||
uint32_t base_image;
|
|
||||||
std::span<const uint8_t> frame_offsets;
|
|
||||||
SpriteBounds bounds{};
|
|
||||||
|
|
||||||
constexpr PeepAnimation() = default;
|
|
||||||
|
|
||||||
PeepAnimation(uint32_t baseImage, std::span<const uint8_t> frameOffsets)
|
|
||||||
: base_image(baseImage)
|
|
||||||
, frame_offsets(frameOffsets)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PeepAnimations
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
constexpr PeepAnimation& operator[](PeepAnimationType n)
|
|
||||||
{
|
|
||||||
return animations[EnumValue(n)];
|
|
||||||
}
|
|
||||||
constexpr const PeepAnimation& operator[](PeepAnimationType n) const
|
|
||||||
{
|
|
||||||
return animations[EnumValue(n)];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PeepAnimation animations[37]{};
|
|
||||||
};
|
|
||||||
|
|
||||||
const PeepAnimation& GetPeepAnimation(
|
const PeepAnimation& GetPeepAnimation(
|
||||||
PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::Walking);
|
PeepAnimationGroup spriteType, PeepAnimationType actionAnimationGroup = PeepAnimationType::Walking);
|
||||||
const SpriteBounds& GetSpriteBounds(
|
const SpriteBounds& GetSpriteBounds(
|
||||||
|
|||||||
203
src/openrct2/peep/PeepAnimations.cpp
Normal file
203
src/openrct2/peep/PeepAnimations.cpp
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Copyright (c) 2014-2024 OpenRCT2 developers
|
||||||
|
*
|
||||||
|
* For a complete list of all authors, please refer to contributors.md
|
||||||
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||||
|
*
|
||||||
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "PeepAnimations.h"
|
||||||
|
|
||||||
|
#include "../Context.h"
|
||||||
|
#include "../drawing/Drawing.h"
|
||||||
|
#include "../entity/Peep.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace OpenRCT2
|
||||||
|
{
|
||||||
|
static const EnumMap<PeepAnimationType> availableGuestAnimations({
|
||||||
|
{ "walking", PeepAnimationType::Walking },
|
||||||
|
{ "checkTime", PeepAnimationType::CheckTime },
|
||||||
|
{ "watchRide", PeepAnimationType::WatchRide },
|
||||||
|
{ "eatFood", PeepAnimationType::EatFood },
|
||||||
|
{ "shakeHead", PeepAnimationType::ShakeHead },
|
||||||
|
{ "emptyPockets", PeepAnimationType::EmptyPockets },
|
||||||
|
{ "holdMat", PeepAnimationType::HoldMat },
|
||||||
|
{ "sittingIdle", PeepAnimationType::SittingIdle },
|
||||||
|
{ "sittingEatFood", PeepAnimationType::SittingEatFood },
|
||||||
|
{ "sittingLookAroundLeft", PeepAnimationType::SittingLookAroundLeft },
|
||||||
|
{ "sittingLookAroundRight", PeepAnimationType::SittingLookAroundRight },
|
||||||
|
{ "hanging", PeepAnimationType::Hanging },
|
||||||
|
{ "wow", PeepAnimationType::Wow },
|
||||||
|
{ "throwUp", PeepAnimationType::ThrowUp },
|
||||||
|
{ "jump", PeepAnimationType::Jump },
|
||||||
|
{ "drowning", PeepAnimationType::Drowning },
|
||||||
|
{ "joy", PeepAnimationType::Joy },
|
||||||
|
{ "readMap", PeepAnimationType::ReadMap },
|
||||||
|
{ "wave", PeepAnimationType::Wave },
|
||||||
|
{ "wave2", PeepAnimationType::Wave2 },
|
||||||
|
{ "takePhoto", PeepAnimationType::TakePhoto },
|
||||||
|
{ "clap", PeepAnimationType::Clap },
|
||||||
|
{ "disgust", PeepAnimationType::Disgust },
|
||||||
|
{ "drawPicture", PeepAnimationType::DrawPicture },
|
||||||
|
{ "beingWatched", PeepAnimationType::BeingWatched },
|
||||||
|
{ "withdrawMoney", PeepAnimationType::WithdrawMoney },
|
||||||
|
});
|
||||||
|
|
||||||
|
static const EnumMap<PeepAnimationType> availableHandymanAnimations({
|
||||||
|
{ "walking", PeepAnimationType::Walking },
|
||||||
|
{ "watchRide", PeepAnimationType::WatchRide },
|
||||||
|
{ "hanging", PeepAnimationType::Hanging },
|
||||||
|
{ "staffMower", PeepAnimationType::StaffMower },
|
||||||
|
{ "staffSweep", PeepAnimationType::StaffSweep },
|
||||||
|
{ "drowning", PeepAnimationType::Drowning },
|
||||||
|
{ "staffWatering", PeepAnimationType::StaffWatering },
|
||||||
|
{ "staffEmptyBin", PeepAnimationType::StaffEmptyBin },
|
||||||
|
});
|
||||||
|
|
||||||
|
static const EnumMap<PeepAnimationType> availableMechanicAnimations({
|
||||||
|
{ "walking", PeepAnimationType::Walking },
|
||||||
|
{ "watchRide", PeepAnimationType::WatchRide },
|
||||||
|
{ "hanging", PeepAnimationType::Hanging },
|
||||||
|
{ "drowning", PeepAnimationType::Drowning },
|
||||||
|
{ "staffAnswerCall", PeepAnimationType::StaffAnswerCall },
|
||||||
|
{ "staffAnswerCall2", PeepAnimationType::StaffAnswerCall2 },
|
||||||
|
{ "staffCheckBoard", PeepAnimationType::StaffCheckBoard },
|
||||||
|
{ "staffFix", PeepAnimationType::StaffFix },
|
||||||
|
{ "staffFix2", PeepAnimationType::StaffFix2 },
|
||||||
|
{ "staffFixGround", PeepAnimationType::StaffFixGround },
|
||||||
|
{ "staffFix3", PeepAnimationType::StaffFix3 },
|
||||||
|
});
|
||||||
|
|
||||||
|
static const EnumMap<PeepAnimationType> availableSecurityAnimations({
|
||||||
|
{ "walking", PeepAnimationType::Walking },
|
||||||
|
{ "watchRide", PeepAnimationType::WatchRide },
|
||||||
|
{ "hanging", PeepAnimationType::Hanging },
|
||||||
|
{ "drowning", PeepAnimationType::Drowning },
|
||||||
|
});
|
||||||
|
|
||||||
|
static const EnumMap<PeepAnimationType> availableEntertainerAnimations({
|
||||||
|
{ "walking", PeepAnimationType::Walking },
|
||||||
|
{ "watchRide", PeepAnimationType::WatchRide },
|
||||||
|
{ "hanging", PeepAnimationType::Hanging },
|
||||||
|
{ "drowning", PeepAnimationType::Drowning },
|
||||||
|
{ "joy", PeepAnimationType::Joy },
|
||||||
|
{ "wave2", PeepAnimationType::Wave2 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const EnumMap<PeepAnimationType>& getAnimationsByPeepType(AnimationPeepType peepType)
|
||||||
|
{
|
||||||
|
switch (peepType)
|
||||||
|
{
|
||||||
|
case AnimationPeepType::Guest:
|
||||||
|
return availableGuestAnimations;
|
||||||
|
case AnimationPeepType::Handyman:
|
||||||
|
return availableHandymanAnimations;
|
||||||
|
case AnimationPeepType::Mechanic:
|
||||||
|
return availableMechanicAnimations;
|
||||||
|
case AnimationPeepType::Security:
|
||||||
|
return availableSecurityAnimations;
|
||||||
|
case AnimationPeepType::Entertainer:
|
||||||
|
default:
|
||||||
|
return availableEntertainerAnimations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapted from CarEntry.cpp
|
||||||
|
SpriteBounds inferMaxAnimationDimensions(const PeepAnimation& anim)
|
||||||
|
{
|
||||||
|
constexpr uint8_t kWidth = 200;
|
||||||
|
constexpr uint8_t kHeight = 200;
|
||||||
|
constexpr uint8_t kCentreX = kWidth / 2;
|
||||||
|
constexpr uint8_t kCentreY = kHeight / 2;
|
||||||
|
|
||||||
|
uint8_t bitmap[kHeight][kWidth] = { 0 };
|
||||||
|
|
||||||
|
DrawPixelInfo dpi = {
|
||||||
|
.bits = reinterpret_cast<uint8_t*>(bitmap),
|
||||||
|
.x = -(kWidth / 2),
|
||||||
|
.y = -(kHeight / 2),
|
||||||
|
.width = kWidth,
|
||||||
|
.height = kHeight,
|
||||||
|
.pitch = 0,
|
||||||
|
.zoom_level = ZoomLevel{ 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto numImages = *(std::max_element(anim.frame_offsets.begin(), anim.frame_offsets.end())) + 1;
|
||||||
|
for (int32_t i = 0; i < numImages; ++i)
|
||||||
|
{
|
||||||
|
GfxDrawSpriteSoftware(dpi, ImageId(anim.base_image + i), { 0, 0 });
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t spriteWidth = -1;
|
||||||
|
for (int32_t i = kCentreX - 1; i != 0; --i)
|
||||||
|
{
|
||||||
|
for (int32_t j = 0; j < kWidth; j++)
|
||||||
|
{
|
||||||
|
if (bitmap[j][kCentreX - i] != 0)
|
||||||
|
{
|
||||||
|
spriteWidth = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spriteWidth != -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < kWidth; j++)
|
||||||
|
{
|
||||||
|
if (bitmap[j][kCentreX + i] != 0)
|
||||||
|
{
|
||||||
|
spriteWidth = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spriteWidth != -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spriteWidth++;
|
||||||
|
|
||||||
|
int32_t spriteHeightNegative = -1;
|
||||||
|
for (int32_t i = kCentreY - 1; i != 0; --i)
|
||||||
|
{
|
||||||
|
for (int32_t j = 0; j < kWidth; j++)
|
||||||
|
{
|
||||||
|
if (bitmap[kCentreY - i][j] != 0)
|
||||||
|
{
|
||||||
|
spriteHeightNegative = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spriteHeightNegative != -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spriteHeightNegative++;
|
||||||
|
|
||||||
|
int32_t spriteHeightPositive = -1;
|
||||||
|
for (int32_t i = kCentreY - 1; i != 0; --i)
|
||||||
|
{
|
||||||
|
for (int32_t j = 0; j < kWidth; j++)
|
||||||
|
{
|
||||||
|
if (bitmap[kCentreY + i][j] != 0)
|
||||||
|
{
|
||||||
|
spriteHeightPositive = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spriteHeightPositive != -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spriteHeightPositive++;
|
||||||
|
|
||||||
|
return {
|
||||||
|
.sprite_width = static_cast<uint8_t>(spriteWidth),
|
||||||
|
.sprite_height_negative = static_cast<uint8_t>(spriteHeightNegative),
|
||||||
|
.sprite_height_positive = static_cast<uint8_t>(spriteHeightPositive),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} // namespace OpenRCT2
|
||||||
69
src/openrct2/peep/PeepAnimations.h
Normal file
69
src/openrct2/peep/PeepAnimations.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Copyright (c) 2014-2024 OpenRCT2 developers
|
||||||
|
*
|
||||||
|
* For a complete list of all authors, please refer to contributors.md
|
||||||
|
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||||
|
*
|
||||||
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../core/EnumMap.hpp"
|
||||||
|
#include "../drawing/ImageIndexType.h"
|
||||||
|
#include "../entity/Peep.h"
|
||||||
|
#include "../util/Util.h"
|
||||||
|
|
||||||
|
namespace OpenRCT2
|
||||||
|
{
|
||||||
|
enum class AnimationPeepType : uint8_t
|
||||||
|
{
|
||||||
|
Guest,
|
||||||
|
Handyman,
|
||||||
|
Mechanic,
|
||||||
|
Security,
|
||||||
|
Entertainer,
|
||||||
|
};
|
||||||
|
|
||||||
|
const EnumMap<PeepAnimationType>& getAnimationsByPeepType(AnimationPeepType peepType);
|
||||||
|
|
||||||
|
struct SpriteBounds
|
||||||
|
{
|
||||||
|
uint8_t sprite_width; // 0x00
|
||||||
|
uint8_t sprite_height_negative; // 0x01
|
||||||
|
uint8_t sprite_height_positive; // 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PeepAnimation
|
||||||
|
{
|
||||||
|
uint32_t base_image;
|
||||||
|
std::span<const uint8_t> frame_offsets;
|
||||||
|
SpriteBounds bounds{};
|
||||||
|
|
||||||
|
constexpr PeepAnimation() = default;
|
||||||
|
|
||||||
|
PeepAnimation(uint32_t baseImage, std::span<const uint8_t> frameOffsets)
|
||||||
|
: base_image(baseImage)
|
||||||
|
, frame_offsets(frameOffsets)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PeepAnimations
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr PeepAnimation& operator[](PeepAnimationType n)
|
||||||
|
{
|
||||||
|
return animations[EnumValue(n)];
|
||||||
|
}
|
||||||
|
constexpr const PeepAnimation& operator[](PeepAnimationType n) const
|
||||||
|
{
|
||||||
|
return animations[EnumValue(n)];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PeepAnimation animations[37]{};
|
||||||
|
};
|
||||||
|
|
||||||
|
SpriteBounds inferMaxAnimationDimensions(const PeepAnimation& anim);
|
||||||
|
} // namespace OpenRCT2
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "../../../entity/Guest.h"
|
#include "../../../entity/Guest.h"
|
||||||
#include "../../../localisation/Formatting.h"
|
#include "../../../localisation/Formatting.h"
|
||||||
#include "../../../peep/PeepAnimationData.h"
|
#include "../../../peep/PeepAnimationData.h"
|
||||||
|
#include "../../../peep/PeepAnimations.h"
|
||||||
#include "../../../ride/RideEntry.h"
|
#include "../../../ride/RideEntry.h"
|
||||||
|
|
||||||
namespace OpenRCT2::Scripting
|
namespace OpenRCT2::Scripting
|
||||||
@@ -147,35 +148,6 @@ namespace OpenRCT2::Scripting
|
|||||||
{ "here_we_are", PeepThoughtType::HereWeAre },
|
{ "here_we_are", PeepThoughtType::HereWeAre },
|
||||||
});
|
});
|
||||||
|
|
||||||
static const DukEnumMap<PeepAnimationType> availableGuestAnimations({
|
|
||||||
{ "walking", PeepAnimationType::Walking },
|
|
||||||
{ "checkTime", PeepAnimationType::CheckTime },
|
|
||||||
{ "watchRide", PeepAnimationType::WatchRide },
|
|
||||||
{ "eatFood", PeepAnimationType::EatFood },
|
|
||||||
{ "shakeHead", PeepAnimationType::ShakeHead },
|
|
||||||
{ "emptyPockets", PeepAnimationType::EmptyPockets },
|
|
||||||
{ "holdMat", PeepAnimationType::HoldMat },
|
|
||||||
{ "sittingIdle", PeepAnimationType::SittingIdle },
|
|
||||||
{ "sittingEatFood", PeepAnimationType::SittingEatFood },
|
|
||||||
{ "sittingLookAroundLeft", PeepAnimationType::SittingLookAroundLeft },
|
|
||||||
{ "sittingLookAroundRight", PeepAnimationType::SittingLookAroundRight },
|
|
||||||
{ "hanging", PeepAnimationType::Hanging },
|
|
||||||
{ "wow", PeepAnimationType::Wow },
|
|
||||||
{ "throwUp", PeepAnimationType::ThrowUp },
|
|
||||||
{ "jump", PeepAnimationType::Jump },
|
|
||||||
{ "drowning", PeepAnimationType::Drowning },
|
|
||||||
{ "joy", PeepAnimationType::Joy },
|
|
||||||
{ "readMap", PeepAnimationType::ReadMap },
|
|
||||||
{ "wave", PeepAnimationType::Wave },
|
|
||||||
{ "wave2", PeepAnimationType::Wave2 },
|
|
||||||
{ "takePhoto", PeepAnimationType::TakePhoto },
|
|
||||||
{ "clap", PeepAnimationType::Clap },
|
|
||||||
{ "disgust", PeepAnimationType::Disgust },
|
|
||||||
{ "drawPicture", PeepAnimationType::DrawPicture },
|
|
||||||
{ "beingWatched", PeepAnimationType::BeingWatched },
|
|
||||||
{ "withdrawMoney", PeepAnimationType::WithdrawMoney },
|
|
||||||
});
|
|
||||||
|
|
||||||
ScGuest::ScGuest(EntityId id)
|
ScGuest::ScGuest(EntityId id)
|
||||||
: ScPeep(id)
|
: ScPeep(id)
|
||||||
{
|
{
|
||||||
@@ -874,7 +846,7 @@ namespace OpenRCT2::Scripting
|
|||||||
std::vector<std::string> ScGuest::availableAnimations_get() const
|
std::vector<std::string> ScGuest::availableAnimations_get() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> availableAnimations{};
|
std::vector<std::string> availableAnimations{};
|
||||||
for (auto& animation : availableGuestAnimations)
|
for (auto& animation : getAnimationsByPeepType(AnimationPeepType::Guest))
|
||||||
{
|
{
|
||||||
availableAnimations.push_back(std::string(animation.first));
|
availableAnimations.push_back(std::string(animation.first));
|
||||||
}
|
}
|
||||||
@@ -885,6 +857,7 @@ namespace OpenRCT2::Scripting
|
|||||||
{
|
{
|
||||||
std::vector<uint32_t> spriteIds{};
|
std::vector<uint32_t> spriteIds{};
|
||||||
|
|
||||||
|
auto& availableGuestAnimations = getAnimationsByPeepType(AnimationPeepType::Guest);
|
||||||
auto animationType = availableGuestAnimations.TryGet(groupKey);
|
auto animationType = availableGuestAnimations.TryGet(groupKey);
|
||||||
if (animationType == std::nullopt)
|
if (animationType == std::nullopt)
|
||||||
{
|
{
|
||||||
@@ -894,7 +867,7 @@ namespace OpenRCT2::Scripting
|
|||||||
auto peep = GetPeep();
|
auto peep = GetPeep();
|
||||||
if (peep != nullptr)
|
if (peep != nullptr)
|
||||||
{
|
{
|
||||||
auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, *animationType);
|
const auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, *animationType);
|
||||||
for (auto frameOffset : animationGroup.frame_offsets)
|
for (auto frameOffset : animationGroup.frame_offsets)
|
||||||
{
|
{
|
||||||
auto imageId = animationGroup.base_image;
|
auto imageId = animationGroup.base_image;
|
||||||
@@ -917,6 +890,7 @@ namespace OpenRCT2::Scripting
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& availableGuestAnimations = getAnimationsByPeepType(AnimationPeepType::Guest);
|
||||||
std::string_view action = availableGuestAnimations[peep->AnimationType];
|
std::string_view action = availableGuestAnimations[peep->AnimationType];
|
||||||
|
|
||||||
// Special consideration for sitting peeps
|
// Special consideration for sitting peeps
|
||||||
@@ -931,6 +905,7 @@ namespace OpenRCT2::Scripting
|
|||||||
{
|
{
|
||||||
ThrowIfGameStateNotMutable();
|
ThrowIfGameStateNotMutable();
|
||||||
|
|
||||||
|
auto& availableGuestAnimations = getAnimationsByPeepType(AnimationPeepType::Guest);
|
||||||
auto newType = availableGuestAnimations.TryGet(groupKey);
|
auto newType = availableGuestAnimations.TryGet(groupKey);
|
||||||
if (newType == std::nullopt)
|
if (newType == std::nullopt)
|
||||||
{
|
{
|
||||||
@@ -946,7 +921,7 @@ namespace OpenRCT2::Scripting
|
|||||||
else
|
else
|
||||||
peep->AnimationFrameNum = offset;
|
peep->AnimationFrameNum = offset;
|
||||||
|
|
||||||
auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, peep->AnimationType);
|
const auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, peep->AnimationType);
|
||||||
peep->AnimationImageIdOffset = animationGroup.frame_offsets[offset];
|
peep->AnimationImageIdOffset = animationGroup.frame_offsets[offset];
|
||||||
peep->UpdateSpriteBoundingBox();
|
peep->UpdateSpriteBoundingBox();
|
||||||
}
|
}
|
||||||
@@ -971,7 +946,7 @@ namespace OpenRCT2::Scripting
|
|||||||
|
|
||||||
auto* peep = GetGuest();
|
auto* peep = GetGuest();
|
||||||
|
|
||||||
auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, peep->AnimationType);
|
const auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, peep->AnimationType);
|
||||||
auto length = animationGroup.frame_offsets.size();
|
auto length = animationGroup.frame_offsets.size();
|
||||||
offset %= length;
|
offset %= length;
|
||||||
|
|
||||||
@@ -992,7 +967,7 @@ namespace OpenRCT2::Scripting
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, peep->AnimationType);
|
const auto& animationGroup = GetPeepAnimation(peep->AnimationGroup, peep->AnimationType);
|
||||||
return static_cast<uint8_t>(animationGroup.frame_offsets.size());
|
return static_cast<uint8_t>(animationGroup.frame_offsets.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,51 +14,10 @@
|
|||||||
#include "../../../entity/PatrolArea.h"
|
#include "../../../entity/PatrolArea.h"
|
||||||
#include "../../../entity/Staff.h"
|
#include "../../../entity/Staff.h"
|
||||||
#include "../../../peep/PeepAnimationData.h"
|
#include "../../../peep/PeepAnimationData.h"
|
||||||
|
#include "../../../peep/PeepAnimations.h"
|
||||||
|
|
||||||
namespace OpenRCT2::Scripting
|
namespace OpenRCT2::Scripting
|
||||||
{
|
{
|
||||||
static const DukEnumMap<PeepAnimationType> availableHandymanAnimations({
|
|
||||||
{ "walking", PeepAnimationType::Walking },
|
|
||||||
{ "watchRide", PeepAnimationType::WatchRide },
|
|
||||||
{ "hanging", PeepAnimationType::Hanging },
|
|
||||||
{ "staffMower", PeepAnimationType::StaffMower },
|
|
||||||
{ "staffSweep", PeepAnimationType::StaffSweep },
|
|
||||||
{ "drowning", PeepAnimationType::Drowning },
|
|
||||||
{ "staffWatering", PeepAnimationType::StaffWatering },
|
|
||||||
{ "staffEmptyBin", PeepAnimationType::StaffEmptyBin },
|
|
||||||
});
|
|
||||||
|
|
||||||
static const DukEnumMap<PeepAnimationType> availableMechanicAnimations({
|
|
||||||
{ "walking", PeepAnimationType::Walking },
|
|
||||||
{ "watchRide", PeepAnimationType::WatchRide },
|
|
||||||
{ "hanging", PeepAnimationType::Hanging },
|
|
||||||
{ "drowning", PeepAnimationType::Drowning },
|
|
||||||
{ "staffAnswerCall", PeepAnimationType::StaffAnswerCall },
|
|
||||||
{ "staffAnswerCall2", PeepAnimationType::StaffAnswerCall2 },
|
|
||||||
{ "staffCheckBoard", PeepAnimationType::StaffCheckBoard },
|
|
||||||
{ "staffFix", PeepAnimationType::StaffFix },
|
|
||||||
{ "staffFix2", PeepAnimationType::StaffFix2 },
|
|
||||||
{ "staffFixGround", PeepAnimationType::StaffFixGround },
|
|
||||||
{ "staffFix3", PeepAnimationType::StaffFix3 },
|
|
||||||
});
|
|
||||||
|
|
||||||
static const DukEnumMap<PeepAnimationType> availableSecurityAnimations({
|
|
||||||
{ "walking", PeepAnimationType::Walking },
|
|
||||||
{ "watchRide", PeepAnimationType::WatchRide },
|
|
||||||
{ "hanging", PeepAnimationType::Hanging },
|
|
||||||
{ "drowning", PeepAnimationType::Drowning },
|
|
||||||
});
|
|
||||||
|
|
||||||
static const DukEnumMap<PeepAnimationType> availableEntertainerAnimations({
|
|
||||||
{ "walking", PeepAnimationType::Walking },
|
|
||||||
{ "watchRide", PeepAnimationType::WatchRide },
|
|
||||||
{ "wave", PeepAnimationType::EatFood }, // NB: this not a typo
|
|
||||||
{ "hanging", PeepAnimationType::Hanging },
|
|
||||||
{ "drowning", PeepAnimationType::Drowning },
|
|
||||||
{ "joy", PeepAnimationType::Joy },
|
|
||||||
{ "wave2", PeepAnimationType::Wave2 },
|
|
||||||
});
|
|
||||||
|
|
||||||
ScStaff::ScStaff(EntityId Id)
|
ScStaff::ScStaff(EntityId Id)
|
||||||
: ScPeep(Id)
|
: ScPeep(Id)
|
||||||
{
|
{
|
||||||
@@ -293,18 +252,23 @@ namespace OpenRCT2::Scripting
|
|||||||
|
|
||||||
const DukEnumMap<PeepAnimationType>& ScStaff::animationsByStaffType(StaffType staffType) const
|
const DukEnumMap<PeepAnimationType>& ScStaff::animationsByStaffType(StaffType staffType) const
|
||||||
{
|
{
|
||||||
|
AnimationPeepType animPeepType{};
|
||||||
switch (staffType)
|
switch (staffType)
|
||||||
{
|
{
|
||||||
case StaffType::Handyman:
|
case StaffType::Handyman:
|
||||||
return availableHandymanAnimations;
|
animPeepType = AnimationPeepType::Handyman;
|
||||||
|
break;
|
||||||
case StaffType::Mechanic:
|
case StaffType::Mechanic:
|
||||||
return availableMechanicAnimations;
|
animPeepType = AnimationPeepType::Mechanic;
|
||||||
|
break;
|
||||||
case StaffType::Security:
|
case StaffType::Security:
|
||||||
return availableSecurityAnimations;
|
animPeepType = AnimationPeepType::Security;
|
||||||
|
break;
|
||||||
case StaffType::Entertainer:
|
case StaffType::Entertainer:
|
||||||
default:
|
default:
|
||||||
return availableEntertainerAnimations;
|
animPeepType = AnimationPeepType::Entertainer;
|
||||||
}
|
}
|
||||||
|
return getAnimationsByPeepType(animPeepType);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> ScStaff::availableAnimations_get() const
|
std::vector<std::string> ScStaff::availableAnimations_get() const
|
||||||
|
|||||||
Reference in New Issue
Block a user