1 | // SuperTux |
2 | // Copyright (C) 2006 Matthias Braun <matze@braunis.de> |
3 | // |
4 | // This program 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 | // This program 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 |
15 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | |
17 | #ifndef HEADER_SUPERTUX_OBJECT_PLAYER_HPP |
18 | #define |
19 | |
20 | #include "scripting/player.hpp" |
21 | #include "sprite/sprite_ptr.hpp" |
22 | #include "squirrel/exposed_object.hpp" |
23 | #include "supertux/direction.hpp" |
24 | #include "supertux/moving_object.hpp" |
25 | #include "supertux/physic.hpp" |
26 | #include "supertux/player_status.hpp" |
27 | #include "supertux/sequence.hpp" |
28 | #include "supertux/timer.hpp" |
29 | #include "video/surface_ptr.hpp" |
30 | |
31 | class BadGuy; |
32 | class Portable; |
33 | class Climbable; |
34 | class Controller; |
35 | class CodeController; |
36 | |
37 | extern const float TUX_INVINCIBLE_TIME_WARNING; |
38 | |
39 | class Player final : public MovingObject, |
40 | public ExposedObject<Player, scripting::Player> |
41 | { |
42 | public: |
43 | enum FallMode { ON_GROUND, JUMPING, TRAMPOLINE_JUMP, FALLING }; |
44 | |
45 | public: |
46 | Player(PlayerStatus& player_status, const std::string& name); |
47 | virtual ~Player(); |
48 | |
49 | virtual void update(float dt_sec) override; |
50 | virtual void draw(DrawingContext& context) override; |
51 | virtual void collision_solid(const CollisionHit& hit) override; |
52 | virtual HitResponse collision(GameObject& other, const CollisionHit& hit) override; |
53 | virtual void collision_tile(uint32_t tile_attributes) override; |
54 | virtual bool is_saveable() const override { return false; } |
55 | virtual bool is_singleton() const override { return true; } |
56 | |
57 | void set_controller(const Controller* controller); |
58 | /** Level solved. Don't kill Tux any more. */ |
59 | void set_winning(); |
60 | bool is_winning() const { return m_winning; } |
61 | |
62 | // Tux can only go this fast. If set to 0 no special limit is used, only the default limits. |
63 | void set_speedlimit(float newlimit); |
64 | float get_speedlimit() const; |
65 | |
66 | const Controller& get_controller() const { return *m_controller; } |
67 | |
68 | void use_scripting_controller(bool use_or_release); |
69 | void do_scripting_controller(const std::string& control, bool pressed); |
70 | |
71 | void make_invincible(); |
72 | |
73 | bool is_invincible() const { return m_invincible_timer.started(); } |
74 | bool is_dying() const { return m_dying; } |
75 | |
76 | Direction peeking_direction_x() const { return m_peekingX; } |
77 | Direction peeking_direction_y() const { return m_peekingY; } |
78 | |
79 | void kill(bool completely); |
80 | void move(const Vector& vector); |
81 | |
82 | bool add_bonus(const std::string& bonus); |
83 | bool set_bonus(const std::string& bonus); |
84 | void add_coins(int count); |
85 | int get_coins() const; |
86 | |
87 | /** picks up a bonus, taking care not to pick up lesser bonus items than we already have |
88 | |
89 | @returns true if the bonus has been set (or was already good enough) |
90 | false if the bonus could not be set (for example no space for big tux) */ |
91 | bool add_bonus(BonusType type, bool animate = false); |
92 | |
93 | /** like add_bonus, but can also downgrade the bonus items carried */ |
94 | bool set_bonus(BonusType type, bool animate = false); |
95 | |
96 | PlayerStatus& get_status() const { return m_player_status; } |
97 | |
98 | /** set kick animation */ |
99 | void kick(); |
100 | |
101 | /** play cheer animation. |
102 | This might need some space and behave in an unpredictable way. |
103 | Best to use this at level end. */ |
104 | void do_cheer(); |
105 | |
106 | /** duck down if possible. |
107 | this won't last long as long as input is enabled. */ |
108 | void do_duck(); |
109 | |
110 | /** stand back up if possible. */ |
111 | void do_standup(); |
112 | |
113 | /** do a backflip if possible. */ |
114 | void do_backflip(); |
115 | |
116 | /** jump in the air if possible |
117 | sensible values for yspeed are negative - unless we want to jump |
118 | into the ground of course */ |
119 | void do_jump(float yspeed); |
120 | |
121 | /** Adds velocity to the player (be careful when using this) */ |
122 | void add_velocity(const Vector& velocity); |
123 | |
124 | /** Adds velocity to the player until given end speed is reached */ |
125 | void add_velocity(const Vector& velocity, const Vector& end_speed); |
126 | |
127 | /** Returns the current velocity of the player */ |
128 | Vector get_velocity() const; |
129 | |
130 | void bounce(BadGuy& badguy); |
131 | |
132 | bool is_dead() const { return m_dead; } |
133 | bool is_big() const; |
134 | bool is_stone() const { return m_stone; } |
135 | |
136 | void set_visible(bool visible); |
137 | bool get_visible() const; |
138 | |
139 | bool on_ground() const; |
140 | |
141 | Portable* get_grabbed_object() const { return m_grabbed_object; } |
142 | void stop_grabbing() { m_grabbed_object = nullptr; } |
143 | |
144 | /** Checks whether the player has grabbed a certain object |
145 | @param name Name of the object to check */ |
146 | bool has_grabbed(const std::string& object_name) const; |
147 | |
148 | /** Switches ghost mode on/off. |
149 | Lets Tux float around and through solid objects. */ |
150 | void set_ghost_mode(bool enable); |
151 | |
152 | /** Switches edit mode on/off. |
153 | In edit mode, Tux will enter ghost_mode instead of dying. */ |
154 | void set_edit_mode(bool enable); |
155 | |
156 | /** Returns whether ghost mode is currently enabled */ |
157 | bool get_ghost_mode() const { return m_ghost_mode; } |
158 | |
159 | /** Changes height of bounding box. |
160 | Returns true if successful, false otherwise */ |
161 | bool adjust_height(float new_height); |
162 | |
163 | /** Orders the current GameSession to start a sequence |
164 | @param sequence_name Name of the sequence to start |
165 | @param data Custom additional sequence data */ |
166 | void trigger_sequence(const std::string& sequence_name, const SequenceData* data = nullptr); |
167 | |
168 | /** Orders the current GameSession to start a sequence |
169 | @param sequence Sequence to start |
170 | @param data Custom additional sequence data */ |
171 | void trigger_sequence(Sequence seq, const SequenceData* data = nullptr); |
172 | |
173 | /** Requests that the player start climbing the given Climbable */ |
174 | void start_climbing(Climbable& climbable); |
175 | |
176 | /** Requests that the player stop climbing the given Climbable */ |
177 | void stop_climbing(Climbable& climbable); |
178 | |
179 | Physic& get_physic() { return m_physic; } |
180 | |
181 | void activate(); |
182 | void deactivate(); |
183 | |
184 | void walk(float speed); |
185 | void set_dir(bool right); |
186 | void stop_backflipping(); |
187 | |
188 | void position_grabbed_object(); |
189 | void try_grab(); |
190 | |
191 | private: |
192 | void handle_input(); |
193 | void handle_input_ghost(); /**< input handling while in ghost mode */ |
194 | void handle_input_climbing(); /**< input handling while climbing */ |
195 | |
196 | void handle_horizontal_input(); |
197 | void handle_vertical_input(); |
198 | |
199 | void do_jump_apex(); |
200 | void early_jump_apex(); |
201 | |
202 | bool slightly_above_ground() const; |
203 | |
204 | BonusType string_to_bonus(const std::string& bonus) const; |
205 | |
206 | /** slows Tux down a little, based on where he's standing */ |
207 | void apply_friction(); |
208 | |
209 | void check_bounds(); |
210 | |
211 | private: |
212 | bool m_deactivated; |
213 | |
214 | const Controller* m_controller; |
215 | std::unique_ptr<CodeController> m_scripting_controller; /**< This controller is used when the Player is controlled via scripting */ |
216 | PlayerStatus& m_player_status; |
217 | bool m_duck; |
218 | bool m_dead; |
219 | bool m_dying; |
220 | bool m_winning; |
221 | bool m_backflipping; |
222 | int m_backflip_direction; |
223 | Direction m_peekingX; |
224 | Direction m_peekingY; |
225 | float m_ability_time; |
226 | bool m_stone; |
227 | bool m_swimming; |
228 | float m_speedlimit; |
229 | const Controller* m_scripting_controller_old; /**< Saves the old controller while the scripting_controller is used */ |
230 | bool m_jump_early_apex; |
231 | bool m_on_ice; |
232 | bool m_ice_this_frame; |
233 | SpritePtr m_lightsprite; |
234 | SpritePtr m_powersprite; |
235 | |
236 | public: |
237 | Direction m_dir; |
238 | |
239 | private: |
240 | Direction m_old_dir; |
241 | |
242 | public: |
243 | float m_last_ground_y; |
244 | FallMode m_fall_mode; |
245 | |
246 | private: |
247 | bool m_on_ground_flag; |
248 | bool m_jumping; |
249 | bool m_can_jump; |
250 | Timer m_jump_button_timer; /**< started when player presses the jump button; runs until Tux jumps or JUMP_GRACE_TIME runs out */ |
251 | bool m_wants_buttjump; |
252 | |
253 | public: |
254 | bool m_does_buttjump; |
255 | Timer m_invincible_timer; |
256 | |
257 | private: |
258 | Timer m_skidding_timer; |
259 | Timer m_safe_timer; |
260 | Timer m_kick_timer; |
261 | Timer m_shooting_timer; // used to show the arm when Tux is shooting |
262 | Timer m_ability_timer; // maximum lengh of time that special abilities can last |
263 | Timer m_cooldown_timer; // minimum time period between successive uses of a special ability |
264 | |
265 | public: |
266 | Timer m_dying_timer; |
267 | |
268 | private: |
269 | Timer m_second_growup_sound_timer; |
270 | bool m_growing; |
271 | Timer m_backflip_timer; |
272 | |
273 | Physic m_physic; |
274 | |
275 | bool m_visible; |
276 | |
277 | Portable* m_grabbed_object; |
278 | |
279 | SpritePtr m_sprite; /**< The main sprite representing Tux */ |
280 | |
281 | SurfacePtr m_airarrow; /**< arrow indicating Tux' position when he's above the camera */ |
282 | |
283 | Vector m_floor_normal; |
284 | |
285 | bool m_ghost_mode; /**< indicates if Tux should float around and through solid objects */ |
286 | bool m_edit_mode; /**< indicates if Tux should switch to ghost mode rather than dying */ |
287 | |
288 | Timer m_unduck_hurt_timer; /**< if Tux wants to stand up again after ducking and cannot, this timer is started */ |
289 | |
290 | Timer m_idle_timer; |
291 | unsigned int m_idle_stage; |
292 | |
293 | Climbable* m_climbing; /**< Climbable object we are currently climbing, null if none */ |
294 | |
295 | private: |
296 | Player(const Player&) = delete; |
297 | Player& operator=(const Player&) = delete; |
298 | }; |
299 | |
300 | #endif |
301 | |
302 | /* EOF */ |
303 | |