1 /*
2  * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Solarus is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #ifndef SOLARUS_MOVEMENT_H
18 #define SOLARUS_MOVEMENT_H
19 
20 #include "solarus/core/Common.h"
21 #include "solarus/core/Rectangle.h"
22 #include "solarus/lua/ExportableToLua.h"
23 #include "solarus/lua/ScopedLuaRef.h"
24 #include <cstdint>
25 #include <string>
26 
27 namespace Solarus {
28 
29 class Drawable;
30 class Entity;
31 
32 /**
33  * \brief Abstract class for representing a movement.
34  *
35  * This is the parent class of all kinds of movement.
36  * An instance of Movement can be applied to a map entity during the game,
37  * to a drawable object or to some arbitrary coordinates.
38  *
39  * TODO: generalize this and allow to apply a movement to any Lua object that
40  * has a set_xy method()?
41  */
42 class SOLARUS_API Movement: public ExportableToLua {
43 
44   public:
45 
46     virtual ~Movement();
47 
48     // object controlled
49     Entity* get_entity() const;
50     void set_entity(Entity* entity);
51     Drawable* get_drawable() const;
52     void set_drawable(Drawable* drawable);
53     virtual void notify_object_controlled();
54 
55     // update
56     virtual void update(); // called repeatedly
57     bool is_suspended() const;
58     virtual void set_suspended(bool suspended);
59     bool get_ignore_suspend() const;
60     void set_ignore_suspend(bool ignore_suspend);
61 
62     // position
63     int get_x() const;
64     int get_y() const;
65     Point get_xy() const;
66     void set_x(int x);
67     void set_y(int y);
68     void set_xy(int x, int y);
69     void set_xy(const Point& xy);
70     void translate_x(int dx);
71     void translate_y(int dy);
72     void translate_xy(int dx, int dy);
73     void translate_xy(const Point& dxy);
74     virtual double get_angle() const;
75     virtual void notify_position_changed(); // called whenever x or y is changed
76     virtual void notify_obstacle_reached();
77     virtual void notify_movement_changed();
78     virtual void notify_movement_finished();
79 
80     // movement
81     bool is_stopped() const;
82     virtual bool is_started() const;
83     virtual void stop();
84     virtual bool is_finished() const;
85 
86     // obstacles
87     bool test_collision_with_obstacles(int dx, int dy) const;
88     bool test_collision_with_obstacles(const Point& dxy) const;
89     const Rectangle& get_last_collision_box_on_obstacle() const;
90     bool are_obstacles_ignored() const;
91     void set_ignore_obstacles(bool ignore_obstacles);
92     void restore_default_ignore_obstacles();
93 
94     // displaying moving objects
95     virtual int get_displayed_direction4() const;
96     virtual Point get_displayed_xy() const;
97 
98     // Lua
99     const ScopedLuaRef& get_finished_callback() const;
100     void set_finished_callback(const ScopedLuaRef& finished_callback_ref);
101     bool are_lua_notifications_enabled() const;
102     void set_lua_notifications_enabled(bool lua_notifications_enabled);
103     virtual const std::string& get_lua_type_name() const override;
104 
105   protected:
106 
107     Movement();
108     explicit Movement(bool ignore_obstacles);
109 
110     // suspended
111     uint32_t get_when_suspended() const;
112 
113     // obstacles (only when the movement is applied to an entity)
114     void set_default_ignore_obstacles(bool ignore_obstacles);
115 
116   private:
117 
118     // Object to move (can be an entity, a drawable or a point).
119     Entity* entity;                              /**< The entity controlled by this movement. */
120     Drawable* drawable;                          /**< The drawable controlled by this movement. */
121     Point xy;                                    /**< Coordinates of the point controlled by this movement. */
122 
123     uint32_t last_move_date;                     /**< Date of the last x or y move. */
124     bool finished;                               /**< true if is_finished() returns true. */
125     bool lua_notifications_enabled;              /**< Whether Lua events and callbacks should be called for this movement. */
126 
127     // suspended
128     bool suspended;                              /**< Indicates whether the movement is suspended. */
129     uint32_t when_suspended;                     /**< Indicates when the movement was suspended. */
130     bool ignore_suspend;                         /**< Whether the movement continues when the game is suspended
131                                                   * (for entity movements only). */
132 
133     // obstacles (only when the movement is applied to an entity)
134     mutable Rectangle
135         last_collision_box_on_obstacle;          /**< Copy of the entity's bounding box of the last call
136                                                   * to test_collision_with_map() returning true. */
137 
138     bool default_ignore_obstacles;               /**< Indicates that this movement normally ignores obstacles. */
139     bool current_ignore_obstacles;               /**< Indicates that this movement currently ignores obstacles. */
140 
141     ScopedLuaRef finished_callback_ref;          /**< Lua ref to a function to call when this movement finishes. */
142 
143 };
144 
145 }
146 
147 #endif
148 
149