mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-20 13:33:02 +01:00
Start splitting Peep::Update into Staff::Update and Guest::Update
This commit is contained in:
@@ -5202,6 +5202,169 @@ void Guest::UpdateRideShopLeave()
|
||||
}
|
||||
}
|
||||
|
||||
/* From peep_update */
|
||||
static void GuestUpdateThoughts(Guest* peep)
|
||||
{
|
||||
// Thoughts must always have a gap of at least
|
||||
// 220 ticks in age between them. In order to
|
||||
// allow this when a thought is new it enters
|
||||
// a holding zone. Before it becomes fresh.
|
||||
int32_t add_fresh = 1;
|
||||
int32_t fresh_thought = -1;
|
||||
for (int32_t i = 0; i < kPeepMaxThoughts; i++)
|
||||
{
|
||||
if (peep->Thoughts[i].type == PeepThoughtType::None)
|
||||
break;
|
||||
|
||||
if (peep->Thoughts[i].freshness == 1)
|
||||
{
|
||||
add_fresh = 0;
|
||||
// If thought is fresh we wait 220 ticks
|
||||
// before allowing a new thought to become fresh.
|
||||
if (++peep->Thoughts[i].fresh_timeout >= 220)
|
||||
{
|
||||
peep->Thoughts[i].fresh_timeout = 0;
|
||||
// Thought is no longer fresh
|
||||
peep->Thoughts[i].freshness++;
|
||||
add_fresh = 1;
|
||||
}
|
||||
}
|
||||
else if (peep->Thoughts[i].freshness > 1)
|
||||
{
|
||||
if (++peep->Thoughts[i].fresh_timeout == 0)
|
||||
{
|
||||
// When thought is older than ~6900 ticks remove it
|
||||
if (++peep->Thoughts[i].freshness >= 28)
|
||||
{
|
||||
peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_THOUGHTS;
|
||||
|
||||
// Clear top thought, push others up
|
||||
if (i < kPeepMaxThoughts - 2)
|
||||
{
|
||||
memmove(&peep->Thoughts[i], &peep->Thoughts[i + 1], sizeof(PeepThought) * (kPeepMaxThoughts - i - 1));
|
||||
}
|
||||
peep->Thoughts[kPeepMaxThoughts - 1].type = PeepThoughtType::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fresh_thought = i;
|
||||
}
|
||||
}
|
||||
// If there are no fresh thoughts
|
||||
// a previously new thought can become
|
||||
// fresh.
|
||||
if (add_fresh && fresh_thought != -1)
|
||||
{
|
||||
peep->Thoughts[fresh_thought].freshness = 1;
|
||||
peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_THOUGHTS;
|
||||
}
|
||||
}
|
||||
|
||||
void Guest::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();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (!guest->PreviousRide.IsNull())
|
||||
if (++guest->PreviousRideTimeOut >= 720)
|
||||
guest->PreviousRide = RideId::GetNull();
|
||||
|
||||
GuestUpdateThoughts(guest);
|
||||
}
|
||||
|
||||
// Walking speed logic
|
||||
uint32_t stepsToTake = Energy;
|
||||
if (stepsToTake < 95 && State == PeepState::Queuing)
|
||||
stepsToTake = 95;
|
||||
if ((PeepFlags & PEEP_FLAGS_SLOW_WALK) && State != PeepState::Queuing)
|
||||
stepsToTake /= 2;
|
||||
if (IsActionWalking() && GetNextIsSloped())
|
||||
{
|
||||
stepsToTake /= 2;
|
||||
if (State == PeepState::Queuing)
|
||||
stepsToTake += stepsToTake / 2;
|
||||
}
|
||||
// Ensure guests make it across a level crossing in time
|
||||
constexpr auto minStepsForCrossing = 55;
|
||||
if (stepsToTake < minStepsForCrossing && IsOnPathBlockedByVehicle())
|
||||
stepsToTake = minStepsForCrossing;
|
||||
|
||||
uint32_t carryCheck = StepProgress + stepsToTake;
|
||||
StepProgress = carryCheck;
|
||||
if (carryCheck <= 255)
|
||||
{
|
||||
if (guest != nullptr)
|
||||
{
|
||||
guest->UpdateEasterEggInteractions();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Loc68FD2F
|
||||
switch (State)
|
||||
{
|
||||
case PeepState::Falling:
|
||||
UpdateFalling();
|
||||
break;
|
||||
case PeepState::One:
|
||||
Update1();
|
||||
break;
|
||||
case PeepState::OnRide:
|
||||
// No action
|
||||
break;
|
||||
case PeepState::Picked:
|
||||
UpdatePicked();
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (guest != nullptr)
|
||||
{
|
||||
guest->UpdateGuest();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto* staff = As<Staff>();
|
||||
if (staff != nullptr)
|
||||
{
|
||||
staff->UpdateStaff(stepsToTake);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Guest::UpdateGuest()
|
||||
{
|
||||
switch (State)
|
||||
|
||||
@@ -320,6 +320,7 @@ public:
|
||||
uint8_t FavouriteRideRating;
|
||||
uint64_t ItemFlags;
|
||||
|
||||
void Update();
|
||||
void UpdateGuest();
|
||||
void Tick128UpdateGuest(uint32_t index);
|
||||
uint64_t GetFoodOrDrinkFlags() const;
|
||||
|
||||
@@ -928,173 +928,6 @@ void Peep::UpdatePicked()
|
||||
}
|
||||
}
|
||||
|
||||
/* From peep_update */
|
||||
static void GuestUpdateThoughts(Guest* peep)
|
||||
{
|
||||
// Thoughts must always have a gap of at least
|
||||
// 220 ticks in age between them. In order to
|
||||
// allow this when a thought is new it enters
|
||||
// a holding zone. Before it becomes fresh.
|
||||
int32_t add_fresh = 1;
|
||||
int32_t fresh_thought = -1;
|
||||
for (int32_t i = 0; i < kPeepMaxThoughts; i++)
|
||||
{
|
||||
if (peep->Thoughts[i].type == PeepThoughtType::None)
|
||||
break;
|
||||
|
||||
if (peep->Thoughts[i].freshness == 1)
|
||||
{
|
||||
add_fresh = 0;
|
||||
// If thought is fresh we wait 220 ticks
|
||||
// before allowing a new thought to become fresh.
|
||||
if (++peep->Thoughts[i].fresh_timeout >= 220)
|
||||
{
|
||||
peep->Thoughts[i].fresh_timeout = 0;
|
||||
// Thought is no longer fresh
|
||||
peep->Thoughts[i].freshness++;
|
||||
add_fresh = 1;
|
||||
}
|
||||
}
|
||||
else if (peep->Thoughts[i].freshness > 1)
|
||||
{
|
||||
if (++peep->Thoughts[i].fresh_timeout == 0)
|
||||
{
|
||||
// When thought is older than ~6900 ticks remove it
|
||||
if (++peep->Thoughts[i].freshness >= 28)
|
||||
{
|
||||
peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_THOUGHTS;
|
||||
|
||||
// Clear top thought, push others up
|
||||
if (i < kPeepMaxThoughts - 2)
|
||||
{
|
||||
memmove(&peep->Thoughts[i], &peep->Thoughts[i + 1], sizeof(PeepThought) * (kPeepMaxThoughts - i - 1));
|
||||
}
|
||||
peep->Thoughts[kPeepMaxThoughts - 1].type = PeepThoughtType::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fresh_thought = i;
|
||||
}
|
||||
}
|
||||
// If there are no fresh thoughts
|
||||
// a previously new thought can become
|
||||
// fresh.
|
||||
if (add_fresh && fresh_thought != -1)
|
||||
{
|
||||
peep->Thoughts[fresh_thought].freshness = 1;
|
||||
peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_THOUGHTS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0068FC1E
|
||||
*/
|
||||
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();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (!guest->PreviousRide.IsNull())
|
||||
if (++guest->PreviousRideTimeOut >= 720)
|
||||
guest->PreviousRide = RideId::GetNull();
|
||||
|
||||
GuestUpdateThoughts(guest);
|
||||
}
|
||||
|
||||
// Walking speed logic
|
||||
uint32_t stepsToTake = Energy;
|
||||
if (stepsToTake < 95 && State == PeepState::Queuing)
|
||||
stepsToTake = 95;
|
||||
if ((PeepFlags & PEEP_FLAGS_SLOW_WALK) && State != PeepState::Queuing)
|
||||
stepsToTake /= 2;
|
||||
if (IsActionWalking() && GetNextIsSloped())
|
||||
{
|
||||
stepsToTake /= 2;
|
||||
if (State == PeepState::Queuing)
|
||||
stepsToTake += stepsToTake / 2;
|
||||
}
|
||||
// Ensure guests make it across a level crossing in time
|
||||
constexpr auto minStepsForCrossing = 55;
|
||||
if (stepsToTake < minStepsForCrossing && IsOnPathBlockedByVehicle())
|
||||
stepsToTake = minStepsForCrossing;
|
||||
|
||||
uint32_t carryCheck = StepProgress + stepsToTake;
|
||||
StepProgress = carryCheck;
|
||||
if (carryCheck <= 255)
|
||||
{
|
||||
if (guest != nullptr)
|
||||
{
|
||||
guest->UpdateEasterEggInteractions();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Loc68FD2F
|
||||
switch (State)
|
||||
{
|
||||
case PeepState::Falling:
|
||||
UpdateFalling();
|
||||
break;
|
||||
case PeepState::One:
|
||||
Update1();
|
||||
break;
|
||||
case PeepState::OnRide:
|
||||
// No action
|
||||
break;
|
||||
case PeepState::Picked:
|
||||
UpdatePicked();
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (guest != nullptr)
|
||||
{
|
||||
guest->UpdateGuest();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto* staff = As<Staff>();
|
||||
if (staff != nullptr)
|
||||
{
|
||||
staff->UpdateStaff(stepsToTake);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0069BF41
|
||||
|
||||
@@ -356,7 +356,6 @@ struct Peep : EntityBase
|
||||
uint32_t PeepFlags;
|
||||
|
||||
public: // Peep
|
||||
void Update();
|
||||
std::optional<CoordsXY> UpdateAction(int16_t& xy_distance);
|
||||
std::optional<CoordsXY> UpdateAction();
|
||||
bool UpdateActionAnimation();
|
||||
@@ -408,7 +407,7 @@ public: // Peep
|
||||
void SwitchNextAnimationType();
|
||||
[[nodiscard]] PeepAnimationType GetAnimationType();
|
||||
|
||||
private:
|
||||
protected:
|
||||
void UpdateFalling();
|
||||
void Update1();
|
||||
void UpdatePicked();
|
||||
|
||||
@@ -1680,6 +1680,104 @@ bool Staff::IsMechanic() const
|
||||
return AssignedStaffType == StaffType::Mechanic;
|
||||
}
|
||||
|
||||
void Staff::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();
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
// Walking speed logic
|
||||
uint32_t stepsToTake = Energy;
|
||||
if (stepsToTake < 95 && State == PeepState::Queuing)
|
||||
stepsToTake = 95;
|
||||
if ((PeepFlags & PEEP_FLAGS_SLOW_WALK) && State != PeepState::Queuing)
|
||||
stepsToTake /= 2;
|
||||
if (IsActionWalking() && GetNextIsSloped())
|
||||
{
|
||||
stepsToTake /= 2;
|
||||
if (State == PeepState::Queuing)
|
||||
stepsToTake += stepsToTake / 2;
|
||||
}
|
||||
// Ensure guests make it across a level crossing in time
|
||||
constexpr auto minStepsForCrossing = 55;
|
||||
if (stepsToTake < minStepsForCrossing && IsOnPathBlockedByVehicle())
|
||||
stepsToTake = minStepsForCrossing;
|
||||
|
||||
uint32_t carryCheck = StepProgress + stepsToTake;
|
||||
StepProgress = carryCheck;
|
||||
if (carryCheck <= 255)
|
||||
{
|
||||
if (guest != nullptr)
|
||||
{
|
||||
guest->UpdateEasterEggInteractions();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Loc68FD2F
|
||||
switch (State)
|
||||
{
|
||||
case PeepState::Falling:
|
||||
UpdateFalling();
|
||||
break;
|
||||
case PeepState::One:
|
||||
Update1();
|
||||
break;
|
||||
case PeepState::OnRide:
|
||||
// No action
|
||||
break;
|
||||
case PeepState::Picked:
|
||||
UpdatePicked();
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if (guest != nullptr)
|
||||
{
|
||||
guest->UpdateGuest();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto* staff = As<Staff>();
|
||||
if (staff != nullptr)
|
||||
{
|
||||
staff->UpdateStaff(stepsToTake);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Staff::UpdateStaff(uint32_t stepsToTake)
|
||||
{
|
||||
switch (State)
|
||||
|
||||
@@ -59,6 +59,7 @@ public:
|
||||
};
|
||||
uint32_t StaffBinsEmptied;
|
||||
|
||||
void Update();
|
||||
void UpdateStaff(uint32_t stepsToTake);
|
||||
void Tick128UpdateStaff();
|
||||
bool IsMechanic() const;
|
||||
|
||||
Reference in New Issue
Block a user