diff --git a/src/person.cpp b/src/person.cpp
--- a/src/person.cpp
+++ b/src/person.cpp
@@ -784,15 +784,13 @@ void Person::DeActivate(AnimateResult ar
}
/**
- * Update the animation of the guest.
+ * Update the animation of a person.
* @param delay Amount of milliseconds since the last update.
- * @return If \c false, de-activate the person.
- * @todo Merge things common to all persons to Person::OnAnimate.
+ * @return Whether to keep the person active or how to deactivate him/her.
+ * @return Result code of the visit.
*/
-AnimateResult Guest::OnAnimate(int delay)
+AnimateResult Person::OnAnimate(int delay)
{
- if (this->activity == GA_ON_RIDE) return OAR_OK; // Guest is not animated while on ride.
-
this->frame_time -= delay;
if (this->frame_time > 0) return OAR_OK;
@@ -885,16 +883,8 @@ AnimateResult Guest::OnAnimate(int delay
assert(this->x_pos >= 0 && this->x_pos < 256);
assert(this->y_pos >= 0 && this->y_pos < 256);
- /* If the guest ended up off-world, quit. */
- if (this->x_vox < 0 || this->x_vox >= _world.GetXSize() * 256 ||
- this->y_vox < 0 || this->y_vox >= _world.GetYSize() * 256) {
- return OAR_DEACTIVATE;
- }
-
- /* If the guest arrived at the 'go home' tile while going home, quit. */
- if (this->activity == GA_GO_HOME && this->x_vox == _guests.start_voxel.x && this->y_vox == _guests.start_voxel.y) {
- return OAR_DEACTIVATE;
- }
+ AnimateResult ar = this->EdgeOfWorldOnAnimate();
+ if (ar != OAR_CONTINUE) return ar;
/* Handle raising of z position. */
if (this->z_pos > 128) {
@@ -909,22 +899,10 @@ AnimateResult Guest::OnAnimate(int delay
if (instance >= SRI_FULL_RIDES) {
assert(exit_edge != INVALID_EDGE);
RideInstance *ri = _rides_manager.GetRideInstance(instance);
- if (ri->CanBeVisited(this->x_vox, this->y_vox, this->z_vox, exit_edge) && this->SelectItem(ri) != ITP_NOTHING) {
- /* All lights are green, let's try to enter the ride. */
- this->activity = GA_ON_RIDE;
- this->ride = ri;
- RideEntryResult rer = ri->EnterRide(this->id, exit_edge);
- if (rer != RER_REFUSED) {
- this->BuyItem(ri);
- /* Either the guest is already back at a path or he will be (through ExitRide). */
- return OAR_OK;
- }
+ AnimateResult ar = this->VisitRideOnAnimate(ri, exit_edge);
+ if (ar != OAR_CONTINUE) return ar;
- /* Could not enter, find another ride. */
- this->ride = nullptr;
- this->activity = GA_WANDER;
- }
- /* Ride is closed, fall-through to reversing movement. */
+ /* Ride is could not be visited, fall-through to reversing movement. */
} else if (HasValidPath(v)) {
this->AddSelf(v);
@@ -978,13 +956,6 @@ RideVisitDesire Person::WantToVisit(cons
}
/**
- * @fn AnimateResult Person::OnAnimate(int delay)
- * Update the animation of the person.
- * @param delay Amount of milliseconds since the last update.
- * @return Whether to keep the person active or how to deactivate him/her.
- */
-
-/**
* @fn bool Person::DailyUpdate()
* Daily ponderings of a person.
* @return If \c false, de-activate the person.
@@ -1038,6 +1009,58 @@ void Guest::DeActivate(AnimateResult ar)
this->Person::DeActivate(ar);
}
+AnimateResult Guest::OnAnimate(int delay)
+{
+ if (this->activity == GA_ON_RIDE) return OAR_OK; // Guest is not animated while on ride.
+ return this->Person::OnAnimate(delay);
+}
+
+/**
+ * Handle the case of a guest reaching the end of the game world.
+ * @return Result code of the visit.
+ */
+AnimateResult Guest::EdgeOfWorldOnAnimate()
+{
+ /* If the guest ended up off-world, quit. */
+ if (this->x_vox < 0 || this->x_vox >= _world.GetXSize() * 256 ||
+ this->y_vox < 0 || this->y_vox >= _world.GetYSize() * 256) {
+ return OAR_DEACTIVATE;
+ }
+
+ /* If the guest arrived at the 'go home' tile while going home, quit. */
+ if (this->activity == GA_GO_HOME && this->x_vox == _guests.start_voxel.x && this->y_vox == _guests.start_voxel.y) {
+ return OAR_DEACTIVATE;
+ }
+
+ return OAR_CONTINUE;
+}
+
+/**
+ * Handle guest ride visiting.
+ * @param ri Ride that can be visited.
+ * @param exit_edge Exit edge being examined.
+ * @return Result code of the visit.
+ */
+AnimateResult Guest::VisitRideOnAnimate(RideInstance *ri, TileEdge exit_edge)
+{
+ if (ri->CanBeVisited(this->x_vox, this->y_vox, this->z_vox, exit_edge) && this->SelectItem(ri) != ITP_NOTHING) {
+ /* All lights are green, let's try to enter the ride. */
+ this->activity = GA_ON_RIDE;
+ this->ride = ri;
+ RideEntryResult rer = ri->EnterRide(this->id, exit_edge);
+ if (rer != RER_REFUSED) {
+ this->BuyItem(ri);
+ /* Either the guest is already back at a path or he will be (through ExitRide). */
+ return OAR_OK;
+ }
+
+ /* Could not enter, find another ride. */
+ this->ride = nullptr;
+ this->activity = GA_WANDER;
+ }
+ return OAR_CONTINUE;
+}
+
/**
* Update the happiness of the guest.
* @param amount Amount of change.
diff --git a/src/person.h b/src/person.h
--- a/src/person.h
+++ b/src/person.h
@@ -73,6 +73,7 @@ struct WalkInformation {
/** Exit codes of the Person::OnAnimate call. */
enum AnimateResult {
+ OAR_CONTINUE, ///< No result yet, continue the routine.
OAR_OK, ///< All OK, keep running.
OAR_REMOVE, ///< Remove person from the person-list, and de-activate.
OAR_DEACTIVATE, ///< Person is already removed from the person-list, only de-activate.
@@ -99,7 +100,7 @@ public:
const ImageData *GetSprite(const SpriteStorage *sprites, ViewOrientation orient, const Recolouring **recolour) const override;
- virtual AnimateResult OnAnimate(int delay) = 0;
+ virtual AnimateResult OnAnimate(int delay);
virtual bool DailyUpdate() = 0;
virtual void Activate(const Point16 &start, PersonType person_type);
@@ -138,6 +139,8 @@ protected:
void StartAnimation(const WalkInformation *walk);
virtual RideVisitDesire WantToVisit(const RideInstance *ri);
+ virtual AnimateResult EdgeOfWorldOnAnimate() = 0;
+ virtual AnimateResult VisitRideOnAnimate(RideInstance *ri, TileEdge exit_edge) = 0;
};
/** Activities of the guest. */
@@ -193,6 +196,8 @@ protected:
RideVisitDesire ComputeExitDesire(TileEdge current_edge, int x, int y, int z, TileEdge exit_edge, bool *seen_wanted_ride);
uint8 GetExitDirections(const Voxel *v, TileEdge start_edge, bool *seen_wanted_ride, bool *queue_mode);
RideVisitDesire WantToVisit(const RideInstance *ri) override;
+ AnimateResult EdgeOfWorldOnAnimate() override;
+ AnimateResult VisitRideOnAnimate(RideInstance *ri, TileEdge exit_edge) override;
RideVisitDesire NeedForItem(enum ItemType it, bool use_random);
void AddItem(ItemType it);