mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-18 20:43:04 +01:00
Merge pull request #22210 from AaronVanGeffen/peep-refactor
Introduce peep flags for fixed position and animation
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
- Feature: [#22090] [Plugin] Allow writing of paused state in non-networked settings.
|
||||
- Feature: [#22140] Add option to automatically close dropdown menus if Enlarged UI is enabled.
|
||||
- Feature: [#22150] [Plugin] Expose monthly expenditure history to the plugin API.
|
||||
- Feature: [#22210] [Plugin] Peeps can now be made stationary or completely frozen.
|
||||
- Feature: [#22210] [Plugin] The direction in which a peep is facing can now be manipulated.
|
||||
- Improved: [#19870] Allow using new colours in UI themes.
|
||||
- Improved: [#21774] The Alpine Coaster now supports using the alternative colour schemes.
|
||||
- Improved: [#21853] Dropdowns now automatically use multiple columns if they are too tall for the screen.
|
||||
|
||||
9
distribution/openrct2.d.ts
vendored
9
distribution/openrct2.d.ts
vendored
@@ -2694,6 +2694,11 @@ declare global {
|
||||
*/
|
||||
destination: CoordsXY;
|
||||
|
||||
/**
|
||||
* The peep's orthogonal direction, from 0 to 3.
|
||||
*/
|
||||
direction: Direction;
|
||||
|
||||
/**
|
||||
* How tired the guest is between 32 and 128 where lower is more tired.
|
||||
*/
|
||||
@@ -2743,7 +2748,9 @@ declare global {
|
||||
"joy" |
|
||||
"angry" |
|
||||
"iceCream" |
|
||||
"hereWeAre";
|
||||
"hereWeAre" |
|
||||
"positionFrozen" |
|
||||
"animationFrozen";
|
||||
|
||||
/**
|
||||
* @deprecated since version 34, use EntityType instead.
|
||||
|
||||
@@ -979,7 +979,10 @@ void Guest::Tick128UpdateGuest(uint32_t index)
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSpriteType();
|
||||
if (!(PeepFlags & PEEP_FLAGS_ANIMATION_FROZEN))
|
||||
{
|
||||
UpdateSpriteType();
|
||||
}
|
||||
|
||||
if (State == PeepState::OnRide || State == PeepState::EnteringRide)
|
||||
{
|
||||
@@ -1009,6 +1012,11 @@ void Guest::Tick128UpdateGuest(uint32_t index)
|
||||
}
|
||||
}
|
||||
|
||||
if (PeepFlags & PEEP_FLAGS_POSITION_FROZEN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (State == PeepState::Walking && !OutsideOfPark && !(PeepFlags & PEEP_FLAGS_LEAVING_PARK) && GuestNumRides == 0
|
||||
&& GuestHeadingToRideId.IsNull())
|
||||
{
|
||||
|
||||
@@ -428,18 +428,13 @@ std::optional<CoordsXY> Peep::UpdateAction(int16_t& xy_distance)
|
||||
return UpdateWalkingAction(differenceLoc, xy_distance);
|
||||
}
|
||||
|
||||
const PeepAnimation& peepAnimation = GetPeepAnimation(SpriteType, ActionSpriteType);
|
||||
ActionFrame++;
|
||||
|
||||
// If last frame of action
|
||||
if (ActionFrame >= peepAnimation.frame_offsets.size())
|
||||
if (!UpdateActionAnimation())
|
||||
{
|
||||
ActionSpriteImageOffset = 0;
|
||||
Action = PeepActionType::Walking;
|
||||
UpdateCurrentActionSpriteType();
|
||||
return { { x, y } };
|
||||
}
|
||||
ActionSpriteImageOffset = peepAnimation.frame_offsets[ActionFrame];
|
||||
|
||||
// Should we throw up, and are we at the frame where sick appears?
|
||||
auto* guest = As<Guest>();
|
||||
@@ -451,6 +446,21 @@ std::optional<CoordsXY> Peep::UpdateAction(int16_t& xy_distance)
|
||||
return { { x, y } };
|
||||
}
|
||||
|
||||
bool Peep::UpdateActionAnimation()
|
||||
{
|
||||
const PeepAnimation& peepAnimation = GetPeepAnimation(SpriteType, ActionSpriteType);
|
||||
ActionFrame++;
|
||||
|
||||
// If last frame of action
|
||||
if (ActionFrame >= peepAnimation.frame_offsets.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ActionSpriteImageOffset = peepAnimation.frame_offsets[ActionFrame];
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<CoordsXY> Peep::UpdateWalkingAction(const CoordsXY& differenceLoc, int16_t& xy_distance)
|
||||
{
|
||||
if (!IsActionWalking())
|
||||
@@ -489,6 +499,13 @@ std::optional<CoordsXY> Peep::UpdateWalkingAction(const CoordsXY& differenceLoc,
|
||||
CoordsXY loc = { x, y };
|
||||
loc += walkingOffsetByDirection[nextDirection];
|
||||
|
||||
UpdateWalkingAnimation();
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
void Peep::UpdateWalkingAnimation()
|
||||
{
|
||||
WalkingFrameNum++;
|
||||
const PeepAnimation& peepAnimation = GetPeepAnimation(SpriteType, ActionSpriteType);
|
||||
if (WalkingFrameNum >= peepAnimation.frame_offsets.size())
|
||||
@@ -496,8 +513,6 @@ std::optional<CoordsXY> Peep::UpdateWalkingAction(const CoordsXY& differenceLoc,
|
||||
WalkingFrameNum = 0;
|
||||
}
|
||||
ActionSpriteImageOffset = peepAnimation.frame_offsets[WalkingFrameNum];
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
void Peep::ThrowUp()
|
||||
@@ -956,6 +971,29 @@ static void GuestUpdateThoughts(Guest* peep)
|
||||
*/
|
||||
void Peep::Update()
|
||||
{
|
||||
if (PeepFlags & PEEP_FLAGS_POSITION_FROZEN)
|
||||
{
|
||||
if (!(PeepFlags & PEEP_FLAGS_ANIMATION_FROZEN))
|
||||
{
|
||||
// This is circumventing other logic, so only update every few ticks
|
||||
if ((GetGameState().CurrentTicks & 3) == 0)
|
||||
{
|
||||
if (IsActionWalking())
|
||||
UpdateWalkingAnimation();
|
||||
else
|
||||
UpdateActionAnimation();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (PeepFlags & PEEP_FLAGS_ANIMATION_FROZEN)
|
||||
{
|
||||
// Animation is frozen while position is not. This allows a peep to walk
|
||||
// around without its sprite being updated, which looks very glitchy.
|
||||
// We'll just remove the flag and continue as normal, in this case.
|
||||
PeepFlags &= ~PEEP_FLAGS_ANIMATION_FROZEN;
|
||||
}
|
||||
|
||||
auto* guest = As<Guest>();
|
||||
if (guest != nullptr)
|
||||
{
|
||||
|
||||
@@ -227,6 +227,8 @@ enum PeepFlags : uint32_t
|
||||
PEEP_FLAGS_INTAMIN_DEPRECATED = (1 << 27), // Used to make the peep think "I'm so excited - It's an Intamin ride!" while
|
||||
// riding on a Intamin ride.
|
||||
PEEP_FLAGS_HERE_WE_ARE = (1 << 28), // Makes the peep think "...and here we are on X!" while riding a ride
|
||||
PEEP_FLAGS_POSITION_FROZEN = (1 << 29), // Prevents the peep from moving around, thus keeping them in place
|
||||
PEEP_FLAGS_ANIMATION_FROZEN = (1 << 30), // Prevents the peep sprite from updating
|
||||
PEEP_FLAGS_TWITCH_DEPRECATED = (1u << 31), // Formerly used for twitch integration
|
||||
};
|
||||
|
||||
@@ -375,7 +377,9 @@ public: // Peep
|
||||
void Update();
|
||||
std::optional<CoordsXY> UpdateAction(int16_t& xy_distance);
|
||||
std::optional<CoordsXY> UpdateAction();
|
||||
bool UpdateActionAnimation();
|
||||
std::optional<CoordsXY> UpdateWalkingAction(const CoordsXY& differenceLoc, int16_t& xy_distance);
|
||||
void UpdateWalkingAnimation();
|
||||
void ThrowUp();
|
||||
void SetState(PeepState new_state);
|
||||
void Remove();
|
||||
|
||||
@@ -47,7 +47,7 @@ using namespace OpenRCT2;
|
||||
// It is used for making sure only compatible builds get connected, even within
|
||||
// single OpenRCT2 version.
|
||||
|
||||
constexpr uint8_t kNetworkStreamVersion = 2;
|
||||
constexpr uint8_t kNetworkStreamVersion = 3;
|
||||
|
||||
const std::string kNetworkStreamID = std::string(OPENRCT2_VERSION) + "-" + std::to_string(kNetworkStreamVersion);
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace OpenRCT2
|
||||
struct GameState_t;
|
||||
|
||||
// Current version that is saved.
|
||||
constexpr uint32_t PARK_FILE_CURRENT_VERSION = 33;
|
||||
constexpr uint32_t PARK_FILE_CURRENT_VERSION = 34;
|
||||
|
||||
// The minimum version that is forwards compatible with the current version.
|
||||
constexpr uint32_t PARK_FILE_MIN_VERSION = 33;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRCT2
|
||||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 93;
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 94;
|
||||
|
||||
// Versions marking breaking changes.
|
||||
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace OpenRCT2::Scripting
|
||||
{ "angry", PEEP_FLAGS_ANGRY },
|
||||
{ "iceCream", PEEP_FLAGS_ICE_CREAM },
|
||||
{ "hereWeAre", PEEP_FLAGS_HERE_WE_ARE },
|
||||
{ "positionFrozen", PEEP_FLAGS_POSITION_FROZEN },
|
||||
{ "animationFrozen", PEEP_FLAGS_ANIMATION_FROZEN },
|
||||
});
|
||||
|
||||
class ScPeep : public ScEntity
|
||||
@@ -57,6 +59,7 @@ namespace OpenRCT2::Scripting
|
||||
dukglue_register_property(ctx, &ScPeep::peepType_get, nullptr, "peepType");
|
||||
dukglue_register_property(ctx, &ScPeep::name_get, &ScPeep::name_set, "name");
|
||||
dukglue_register_property(ctx, &ScPeep::destination_get, &ScPeep::destination_set, "destination");
|
||||
dukglue_register_property(ctx, &ScPeep::direction_get, &ScPeep::direction_set, "direction");
|
||||
dukglue_register_property(ctx, &ScPeep::energy_get, &ScPeep::energy_set, "energy");
|
||||
dukglue_register_property(ctx, &ScPeep::energyTarget_get, &ScPeep::energyTarget_set, "energyTarget");
|
||||
dukglue_register_method(ctx, &ScPeep::getFlag, "getFlag");
|
||||
@@ -138,6 +141,23 @@ namespace OpenRCT2::Scripting
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t direction_get() const
|
||||
{
|
||||
auto peep = GetPeep();
|
||||
return peep != nullptr ? peep->PeepDirection : 0;
|
||||
}
|
||||
|
||||
void direction_set(const uint8_t value)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
auto peep = GetPeep();
|
||||
if (peep != nullptr && value < kNumOrthogonalDirections)
|
||||
{
|
||||
peep->PeepDirection = value;
|
||||
peep->Orientation = value << 3;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t energy_get() const
|
||||
{
|
||||
auto peep = GetPeep();
|
||||
@@ -149,6 +169,7 @@ namespace OpenRCT2::Scripting
|
||||
auto peep = GetPeep();
|
||||
if (peep != nullptr)
|
||||
{
|
||||
value = std::clamp(value, kPeepMinEnergy, kPeepMaxEnergy);
|
||||
peep->Energy = value;
|
||||
}
|
||||
}
|
||||
@@ -164,6 +185,7 @@ namespace OpenRCT2::Scripting
|
||||
auto peep = GetPeep();
|
||||
if (peep != nullptr)
|
||||
{
|
||||
value = std::clamp(value, kPeepMinEnergy, kPeepMaxEnergyTarget);
|
||||
peep->EnergyTarget = value;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user