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 HEADER_SUPERTUX_OBJECT_PLAYER_HPP
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
31class BadGuy;
32class Portable;
33class Climbable;
34class Controller;
35class CodeController;
36
37extern const float TUX_INVINCIBLE_TIME_WARNING;
38
39class Player final : public MovingObject,
40 public ExposedObject<Player, scripting::Player>
41{
42public:
43 enum FallMode { ON_GROUND, JUMPING, TRAMPOLINE_JUMP, FALLING };
44
45public:
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
191private:
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
211private:
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
236public:
237 Direction m_dir;
238
239private:
240 Direction m_old_dir;
241
242public:
243 float m_last_ground_y;
244 FallMode m_fall_mode;
245
246private:
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
253public:
254 bool m_does_buttjump;
255 Timer m_invincible_timer;
256
257private:
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
265public:
266 Timer m_dying_timer;
267
268private:
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
295private:
296 Player(const Player&) = delete;
297 Player& operator=(const Player&) = delete;
298};
299
300#endif
301
302/* EOF */
303