Cataclysm-DDA icon indicating copy to clipboard operation
Cataclysm-DDA copied to clipboard

Migrate ACT_WAIT_STAMINA to the activity_actor system.

Open CLIDragon opened this issue 1 year ago • 0 comments

Summary

Infrastructure "Migrate ACT_WAIT_STAMINA to an activity_actor"

Purpose of change

Work on #40013.

Describe the solution

The dependence on moves was removed as I couldn't see how it was anything but a placeholder value - wait_stamina_do_turn completely ignored the moves left. The actor also explicitly states that it can wait until a given threshold, whereas this functionality was implicit before.

Describe alternatives you've considered

Just leaving it, I suppose?

Testing

  • [x] Waited until stamina was full.
  • [x] Waited normally, and checked that the time was correct.
  • [x] Smashed corpses until a break was needed, and checked that stamina was refilled correctly.

Additional context

I honestly thought this migration had been completed years ago.

Here's a step-by-step guide to the process for future reference.

  1. Create a new class in activity_actor_definitions.h. This has to implement certain overrided methods. I've put a template below.
  2. Create empty function definitions for the above mandatory functions in activity_actor.cpp
  3. Remove the id definition from activity_handlers.cpp and copy-pasted it into activity_actor.cpp remove the do_turn and finish functions from the do_turn_functions and finish_turn_functions maps. The definitions of these functions can be copy-pasted into the respective implementations in activity_actor.cpp.
  4. Remove the do_turn and finish functions from activity_handlers.h
  5. Migrate state from the activity object into the new activity actor. e.g. for ACT_WAIT_STAMINA, the stamina threshold and initial stamina were stored in player_activity.values. These were moved to private variables, and an initialiser taking stamina threshold was created.
  6. Search for all usages of the old function and migrate them to the new function.
  7. Implement serialize and deserialize. These are pretty easy - just write the data you need to store in serialize and read it in deserialize. If you don't need to store across save files (e.g. waiting is not stored), then you can just write null. There are plenty of other activity actor examples.
  8. TEST!!!
Activity actor generic template
class activity_name_activity_actor : public activity_actor
{

    public:
        activity_name_activity_actor() = default;

        void start( player_activity &act, Character &who ) override;
        void do_turn( player_activity &act, Character &you ) override;
        void finish( player_activity &act, Character &you ) override;

        activity_id get_type() const override {
            return activity_id( "ACT_ACTIVITY_NAME" );
        }

        std::unique_ptr<activity_actor> clone() const override {
            return std::make_unique<activity_name_activity_actor>( *this );
        }

        void serialize( JsonOut &jsout ) const override;
        static std::unique_ptr<activity_actor> deserialize( JsonValue &jsin );

    private:
     /* Any state that the activity actor needs to contain belongs here. */
};

CLIDragon avatar Sep 06 '24 06:09 CLIDragon