6687ca86e6ac57a8d00210b40fce3ed35ded6ae2
[oweals/minetest.git] / src / player.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef PLAYER_HEADER
21 #define PLAYER_HEADER
22
23 #include "irrlichttypes_bloated.h"
24 #include "inventory.h"
25 #include "constants.h" // BS
26 #include "threading/mutex.h"
27 #include <list>
28
29 #define PLAYERNAME_SIZE 20
30
31 #define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
32 #define PLAYERNAME_ALLOWED_CHARS_USER_EXPL "'a' to 'z', 'A' to 'Z', '0' to '9', '-', '_'"
33
34 struct PlayerControl
35 {
36         PlayerControl()
37         {
38                 up = false;
39                 down = false;
40                 left = false;
41                 right = false;
42                 jump = false;
43                 aux1 = false;
44                 sneak = false;
45                 LMB = false;
46                 RMB = false;
47                 pitch = 0;
48                 yaw = 0;
49                 sidew_move_joystick_axis = .0f;
50                 forw_move_joystick_axis = .0f;
51         }
52         PlayerControl(
53                 bool a_up,
54                 bool a_down,
55                 bool a_left,
56                 bool a_right,
57                 bool a_jump,
58                 bool a_aux1,
59                 bool a_sneak,
60                 bool a_LMB,
61                 bool a_RMB,
62                 float a_pitch,
63                 float a_yaw,
64                 float a_sidew_move_joystick_axis,
65                 float a_forw_move_joystick_axis
66         )
67         {
68                 up = a_up;
69                 down = a_down;
70                 left = a_left;
71                 right = a_right;
72                 jump = a_jump;
73                 aux1 = a_aux1;
74                 sneak = a_sneak;
75                 LMB = a_LMB;
76                 RMB = a_RMB;
77                 pitch = a_pitch;
78                 yaw = a_yaw;
79                 sidew_move_joystick_axis = a_sidew_move_joystick_axis;
80                 forw_move_joystick_axis = a_forw_move_joystick_axis;
81         }
82         bool up;
83         bool down;
84         bool left;
85         bool right;
86         bool jump;
87         bool aux1;
88         bool sneak;
89         bool LMB;
90         bool RMB;
91         float pitch;
92         float yaw;
93         float sidew_move_joystick_axis;
94         float forw_move_joystick_axis;
95 };
96
97 class Map;
98 class IGameDef;
99 struct CollisionInfo;
100 class PlayerSAO;
101 struct HudElement;
102 class Environment;
103
104 // IMPORTANT:
105 // Do *not* perform an assignment or copy operation on a Player or
106 // RemotePlayer object!  This will copy the lock held for HUD synchronization
107 class Player
108 {
109 public:
110
111         Player(IGameDef *gamedef, const char *name);
112         virtual ~Player() = 0;
113
114         virtual void move(f32 dtime, Environment *env, f32 pos_max_d)
115         {}
116         virtual void move(f32 dtime, Environment *env, f32 pos_max_d,
117                         std::vector<CollisionInfo> *collision_info)
118         {}
119
120         v3f getSpeed()
121         {
122                 return m_speed;
123         }
124
125         void setSpeed(v3f speed)
126         {
127                 m_speed = speed;
128         }
129
130         v3f getPosition()
131         {
132                 return m_position;
133         }
134
135         v3s16 getLightPosition() const;
136
137         v3f getEyeOffset()
138         {
139                 float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f;
140                 return v3f(0, BS * eye_height, 0);
141         }
142
143         v3f getEyePosition()
144         {
145                 return m_position + getEyeOffset();
146         }
147
148         virtual void setPosition(const v3f &position)
149         {
150                 if (position != m_position)
151                         m_dirty = true;
152                 m_position = position;
153         }
154
155         void setPitch(f32 pitch)
156         {
157                 if (pitch != m_pitch)
158                         m_dirty = true;
159                 m_pitch = pitch;
160         }
161
162         virtual void setYaw(f32 yaw)
163         {
164                 if (yaw != m_yaw)
165                         m_dirty = true;
166                 m_yaw = yaw;
167         }
168
169         f32 getPitch()
170         {
171                 return m_pitch;
172         }
173
174         f32 getYaw()
175         {
176                 return m_yaw;
177         }
178
179         u16 getBreath()
180         {
181                 return m_breath;
182         }
183
184         virtual void setBreath(u16 breath)
185         {
186                 if (breath != m_breath)
187                         m_dirty = true;
188                 m_breath = breath;
189         }
190
191         f32 getRadPitch()
192         {
193                 return -1.0 * m_pitch * core::DEGTORAD;
194         }
195
196         f32 getRadYaw()
197         {
198                 return (m_yaw + 90.) * core::DEGTORAD;
199         }
200
201         const char *getName() const
202         {
203                 return m_name;
204         }
205
206         aabb3f getCollisionbox()
207         {
208                 return m_collisionbox;
209         }
210
211         u32 getFreeHudID() {
212                 size_t size = hud.size();
213                 for (size_t i = 0; i != size; i++) {
214                         if (!hud[i])
215                                 return i;
216                 }
217                 return size;
218         }
219
220         void setHotbarItemcount(s32 hotbar_itemcount)
221         {
222                 hud_hotbar_itemcount = hotbar_itemcount;
223         }
224
225         s32 getHotbarItemcount()
226         {
227                 return hud_hotbar_itemcount;
228         }
229
230         void setHotbarImage(const std::string &name)
231         {
232                 hud_hotbar_image = name;
233         }
234
235         std::string getHotbarImage()
236         {
237                 return hud_hotbar_image;
238         }
239
240         void setHotbarSelectedImage(const std::string &name)
241         {
242                 hud_hotbar_selected_image = name;
243         }
244
245         std::string getHotbarSelectedImage() {
246                 return hud_hotbar_selected_image;
247         }
248
249         void setSky(const video::SColor &bgcolor, const std::string &type,
250                 const std::vector<std::string> &params)
251         {
252                 m_sky_bgcolor = bgcolor;
253                 m_sky_type = type;
254                 m_sky_params = params;
255         }
256
257         void getSky(video::SColor *bgcolor, std::string *type,
258                 std::vector<std::string> *params)
259         {
260                 *bgcolor = m_sky_bgcolor;
261                 *type = m_sky_type;
262                 *params = m_sky_params;
263         }
264
265         void overrideDayNightRatio(bool do_override, float ratio)
266         {
267                 m_day_night_ratio_do_override = do_override;
268                 m_day_night_ratio = ratio;
269         }
270
271         void getDayNightRatio(bool *do_override, float *ratio)
272         {
273                 *do_override = m_day_night_ratio_do_override;
274                 *ratio = m_day_night_ratio;
275         }
276
277         void setLocalAnimations(v2s32 frames[4], float frame_speed)
278         {
279                 for (int i = 0; i < 4; i++)
280                         local_animations[i] = frames[i];
281                 local_animation_speed = frame_speed;
282         }
283
284         void getLocalAnimations(v2s32 *frames, float *frame_speed)
285         {
286                 for (int i = 0; i < 4; i++)
287                         frames[i] = local_animations[i];
288                 *frame_speed = local_animation_speed;
289         }
290
291         virtual bool isLocal() const
292         {
293                 return false;
294         }
295
296         virtual PlayerSAO *getPlayerSAO()
297         {
298                 return NULL;
299         }
300
301         virtual void setPlayerSAO(PlayerSAO *sao)
302         {
303                 FATAL_ERROR("FIXME");
304         }
305
306         /*
307                 serialize() writes a bunch of text that can contain
308                 any characters except a '\0', and such an ending that
309                 deSerialize stops reading exactly at the right point.
310         */
311         void serialize(std::ostream &os);
312         void deSerialize(std::istream &is, std::string playername);
313
314         bool checkModified() const
315         {
316                 return m_dirty || inventory.checkModified();
317         }
318
319         void setModified(const bool x)
320         {
321                 m_dirty = x;
322                 if (x == false)
323                         inventory.setModified(x);
324         }
325
326         // Use a function, if isDead can be defined by other conditions
327         bool isDead() { return hp == 0; }
328
329         bool got_teleported;
330         bool touching_ground;
331         // This oscillates so that the player jumps a bit above the surface
332         bool in_liquid;
333         // This is more stable and defines the maximum speed of the player
334         bool in_liquid_stable;
335         // Gets the viscosity of water to calculate friction
336         u8 liquid_viscosity;
337         bool is_climbing;
338         bool swimming_vertical;
339         bool camera_barely_in_ceiling;
340         v3f eye_offset_first;
341         v3f eye_offset_third;
342
343         Inventory inventory;
344
345         f32 movement_acceleration_default;
346         f32 movement_acceleration_air;
347         f32 movement_acceleration_fast;
348         f32 movement_speed_walk;
349         f32 movement_speed_crouch;
350         f32 movement_speed_fast;
351         f32 movement_speed_climb;
352         f32 movement_speed_jump;
353         f32 movement_liquid_fluidity;
354         f32 movement_liquid_fluidity_smooth;
355         f32 movement_liquid_sink;
356         f32 movement_gravity;
357
358         float physics_override_speed;
359         float physics_override_jump;
360         float physics_override_gravity;
361         bool physics_override_sneak;
362         bool physics_override_sneak_glitch;
363
364         v2s32 local_animations[4];
365         float local_animation_speed;
366
367         u16 hp;
368
369         float hurt_tilt_timer;
370         float hurt_tilt_strength;
371
372         u16 protocol_version;
373         u16 peer_id;
374
375         std::string inventory_formspec;
376
377         PlayerControl control;
378         PlayerControl getPlayerControl()
379         {
380                 return control;
381         }
382
383         u32 keyPressed;
384
385
386         HudElement* getHud(u32 id);
387         u32         addHud(HudElement* hud);
388         HudElement* removeHud(u32 id);
389         void        clearHud();
390         u32         maxHudId() {
391                 return hud.size();
392         }
393
394         u32 hud_flags;
395         s32 hud_hotbar_itemcount;
396         std::string hud_hotbar_image;
397         std::string hud_hotbar_selected_image;
398 protected:
399         IGameDef *m_gamedef;
400
401         char m_name[PLAYERNAME_SIZE];
402         u16 m_breath;
403         f32 m_pitch;
404         f32 m_yaw;
405         v3f m_speed;
406         v3f m_position;
407         aabb3f m_collisionbox;
408
409         bool m_dirty;
410
411         std::vector<HudElement *> hud;
412
413         std::string m_sky_type;
414         video::SColor m_sky_bgcolor;
415         std::vector<std::string> m_sky_params;
416
417         bool m_day_night_ratio_do_override;
418         float m_day_night_ratio;
419 private:
420         // Protect some critical areas
421         // hud for example can be modified by EmergeThread
422         // and ServerThread
423         Mutex m_mutex;
424 };
425
426
427 /*
428         Player on the server
429 */
430 class RemotePlayer : public Player
431 {
432 public:
433         RemotePlayer(IGameDef *gamedef, const char *name);
434         virtual ~RemotePlayer() {}
435
436         void save(std::string savedir);
437
438         PlayerSAO *getPlayerSAO()
439         { return m_sao; }
440         void setPlayerSAO(PlayerSAO *sao)
441         { m_sao = sao; }
442         void setPosition(const v3f &position);
443
444 private:
445         PlayerSAO *m_sao;
446 };
447
448 #endif
449