1 #pragma once
2 #ifndef CATA_SRC_ACTIVITY_ACTOR_H
3 #define CATA_SRC_ACTIVITY_ACTOR_H
4 
5 #include <iosfwd>
6 #include <memory>
7 #include <unordered_map>
8 
9 #include "activity_type.h"
10 #include "clone_ptr.h"
11 #include "type_id.h"
12 
13 class Character;
14 class JsonIn;
15 class JsonOut;
16 class player_activity;
17 
18 class activity_actor
19 {
20     private:
21         /**
22          * Returns true if `this` activity is resumable, and `this` and @p other
23          * are "equivalent" i.e. similar enough that `this` activity
24          * can be resumed instead of starting @p other.
25          * Many activities are not resumable, so the default is returning
26          * false.
27          * @pre @p other is the same type of actor as `this`
28          */
can_resume_with_internal(const activity_actor &,const Character &)29         virtual bool can_resume_with_internal( const activity_actor &,
30                                                const Character & ) const {
31             return false;
32         }
33 
34     public:
35         virtual ~activity_actor() = default;
36 
37         /**
38          * Should return the activity id of the corresponding activity
39          */
40         virtual activity_id get_type() const = 0;
41 
42         /**
43          * Called once at the start of the activity.
44          * This may be used to preform setup actions and/or set
45          * player_activity::moves_left/moves_total.
46          */
47         virtual void start( player_activity &act, Character &who ) = 0;
48 
49         /**
50          * Called on every turn of the activity
51          * It may be used to stop the activity prematurely by setting it to null.
52          */
53         virtual void do_turn( player_activity &act, Character &who ) = 0;
54 
55         /**
56          * Called when the activity runs out of moves, assuming that it has not
57          * already been set to null
58          */
59         virtual void finish( player_activity &act, Character &who ) = 0;
60 
61         /**
62          * Called just before Character::cancel_activity() executes.
63          * This may be used to perform cleanup
64          */
canceled(player_activity &,Character &)65         virtual void canceled( player_activity &/*act*/, Character &/*who*/ ) {}
66 
67         /**
68          * Called in player_activity::can_resume_with
69          * which allows suspended activities to be resumed instead of
70          * starting a new activity in certain cases.
71          * Checks that @p other has the same type as `this` so that
72          * `can_resume_with_internal` can safely `static_cast` @p other.
73          */
can_resume_with(const activity_actor & other,const Character & who)74         bool can_resume_with( const activity_actor &other, const Character &who ) const {
75             if( other.get_type() == get_type() ) {
76                 return can_resume_with_internal( other, who );
77             }
78 
79             return false;
80         }
81 
82         /**
83          * Used to generate the progress display at the top of the screen
84          */
85         virtual std::string get_progress_message( const player_activity &act ) const;
86 
87         /**
88          * Called every turn, in player_activity::do_turn
89          * (with some indirection through player_activity::exertion_level)
90          * How strenuous this activity level is
91          */
exertion_level()92         virtual float exertion_level() const {
93             return get_type()->exertion_level();
94         }
95 
96         /**
97          * Returns a deep copy of this object. Example implementation:
98          * \code
99          * class my_activity_actor {
100          *     std::unique_ptr<activity_actor> clone() const override {
101          *         return std::make_unique<my_activity_actor>( *this );
102          *     }
103          * };
104          * \endcode
105          * The returned value should behave like the original item and must have the same type.
106          */
107         virtual std::unique_ptr<activity_actor> clone() const = 0;
108 
109         /**
110          * Must write any custom members of the derived class to json
111          * Note that a static member function for deserialization must also be created and
112          * added to the `activity_actor_deserializers` hashmap in activity_actor.cpp
113          */
114         virtual void serialize( JsonOut &jsout ) const = 0;
115 };
116 
117 void serialize( const cata::clone_ptr<activity_actor> &actor, JsonOut &jsout );
118 void deserialize( cata::clone_ptr<activity_actor> &actor, JsonIn &jsin );
119 
120 namespace activity_actors
121 {
122 
123 // defined in activity_actor.cpp
124 extern const std::unordered_map<activity_id, std::unique_ptr<activity_actor>( * )( JsonIn & )>
125 deserialize_functions;
126 
127 } // namespace activity_actors
128 
129 #endif // CATA_SRC_ACTIVITY_ACTOR_H
130