Small cleanup of hud add/remove code
[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 <list>
27
28 #define PLAYERNAME_SIZE 20
29
30 #define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
31
32 struct PlayerControl
33 {
34         PlayerControl()
35         {
36                 up = false;
37                 down = false;
38                 left = false;
39                 right = false;
40                 jump = false;
41                 aux1 = false;
42                 sneak = false;
43                 LMB = false;
44                 RMB = false;
45                 pitch = 0;
46                 yaw = 0;
47         }
48         PlayerControl(
49                 bool a_up,
50                 bool a_down,
51                 bool a_left,
52                 bool a_right,
53                 bool a_jump,
54                 bool a_aux1,
55                 bool a_sneak,
56                 bool a_LMB,
57                 bool a_RMB,
58                 float a_pitch,
59                 float a_yaw
60         )
61         {
62                 up = a_up;
63                 down = a_down;
64                 left = a_left;
65                 right = a_right;
66                 jump = a_jump;
67                 aux1 = a_aux1;
68                 sneak = a_sneak;
69                 LMB = a_LMB;
70                 RMB = a_RMB;
71                 pitch = a_pitch;
72                 yaw = a_yaw;
73         }
74         bool up;
75         bool down;
76         bool left;
77         bool right;
78         bool jump;
79         bool aux1;
80         bool sneak;
81         bool LMB;
82         bool RMB;
83         float pitch;
84         float yaw;
85 };
86
87 class Map;
88 class IGameDef;
89 struct CollisionInfo;
90 class PlayerSAO;
91 struct HudElement;
92 class Environment;
93
94 class Player
95 {
96 public:
97
98         Player(IGameDef *gamedef);
99         virtual ~Player() = 0;
100
101         virtual void move(f32 dtime, Environment *env, f32 pos_max_d)
102         {}
103         virtual void move(f32 dtime, Environment *env, f32 pos_max_d,
104                         std::list<CollisionInfo> *collision_info)
105         {}
106
107         v3f getSpeed()
108         {
109                 return m_speed;
110         }
111
112         void setSpeed(v3f speed)
113         {
114                 m_speed = speed;
115         }
116         
117         void accelerateHorizontal(v3f target_speed, f32 max_increase);
118         void accelerateVertical(v3f target_speed, f32 max_increase);
119
120         v3f getPosition()
121         {
122                 return m_position;
123         }
124
125         v3s16 getLightPosition() const;
126
127         v3f getEyeOffset()
128         {
129                 // This is at the height of the eyes of the current figure
130                 // return v3f(0, BS*1.5, 0);
131                 // This is more like in minecraft
132                 if(camera_barely_in_ceiling)
133                         return v3f(0,BS*1.5,0);
134                 else
135                         return v3f(0,BS*1.625,0);
136         }
137
138         v3f getEyePosition()
139         {
140                 return m_position + getEyeOffset();
141         }
142
143         virtual void setPosition(const v3f &position)
144         {
145                 m_position = position;
146         }
147
148         void setPitch(f32 pitch)
149         {
150                 m_pitch = pitch;
151         }
152
153         virtual void setYaw(f32 yaw)
154         {
155                 m_yaw = yaw;
156         }
157
158         f32 getPitch()
159         {
160                 return m_pitch;
161         }
162
163         f32 getYaw()
164         {
165                 return m_yaw;
166         }
167
168         u16 getBreath()
169         {
170                 return m_breath;
171         }
172
173         virtual void setBreath(u16 breath)
174         {
175                 m_breath = breath;
176         }
177
178         f32 getRadPitch()
179         {
180                 return -1.0 * m_pitch * core::DEGTORAD;
181         }
182
183         f32 getRadYaw()
184         {
185                 return (m_yaw + 90.) * core::DEGTORAD;
186         }
187
188         void updateName(const char *name)
189         {
190                 snprintf(m_name, PLAYERNAME_SIZE, "%s", name);
191         }
192
193         const char * getName() const
194         {
195                 return m_name;
196         }
197
198         core::aabbox3d<f32> getCollisionbox() {
199                 return m_collisionbox;
200         }
201
202         u32 getFreeHudID() const {
203                 size_t size = hud.size();
204                 for (size_t i = 0; i != size; i++) {
205                         if (!hud[i])
206                                 return i;
207                 }
208                 return size;
209         }
210
211         virtual bool isLocal() const
212         { return false; }
213         virtual PlayerSAO *getPlayerSAO()
214         { return NULL; }
215         virtual void setPlayerSAO(PlayerSAO *sao)
216         { assert(0); }
217
218         /*
219                 serialize() writes a bunch of text that can contain
220                 any characters except a '\0', and such an ending that
221                 deSerialize stops reading exactly at the right point.
222         */
223         void serialize(std::ostream &os);
224         void deSerialize(std::istream &is, std::string playername);
225
226         bool checkModified()
227         {
228                 if(m_last_hp != hp || m_last_pitch != m_pitch ||
229                                 m_last_pos != m_position || m_last_yaw != m_yaw ||
230                                 !(inventory == m_last_inventory))
231                 {
232                         m_last_hp = hp;
233                         m_last_pitch = m_pitch;
234                         m_last_pos = m_position;
235                         m_last_yaw = m_yaw;
236                         m_last_inventory = inventory;
237                         return true;
238                 } else {
239                         return false;
240                 }
241         }
242
243         bool touching_ground;
244         // This oscillates so that the player jumps a bit above the surface
245         bool in_liquid;
246         // This is more stable and defines the maximum speed of the player
247         bool in_liquid_stable;
248         // Gets the viscosity of water to calculate friction
249         u8 liquid_viscosity;
250         bool is_climbing;
251         bool swimming_vertical;
252         bool camera_barely_in_ceiling;
253         
254         u8 light;
255
256         Inventory inventory;
257
258         f32 movement_acceleration_default;
259         f32 movement_acceleration_air;
260         f32 movement_acceleration_fast;
261         f32 movement_speed_walk;
262         f32 movement_speed_crouch;
263         f32 movement_speed_fast;
264         f32 movement_speed_climb;
265         f32 movement_speed_jump;
266         f32 movement_liquid_fluidity;
267         f32 movement_liquid_fluidity_smooth;
268         f32 movement_liquid_sink;
269         f32 movement_gravity;
270
271         float physics_override_speed;
272         float physics_override_jump;
273         float physics_override_gravity;
274         bool physics_override_sneak;
275         bool physics_override_sneak_glitch;
276
277         v2s32 local_animations[4];
278         float local_animation_speed;
279
280         u16 hp;
281
282         float hurt_tilt_timer;
283         float hurt_tilt_strength;
284
285         u16 peer_id;
286
287         std::string inventory_formspec;
288         
289         PlayerControl control;
290         PlayerControl getPlayerControl()
291         {
292                 return control;
293         }
294         
295         u32 keyPressed;
296         
297
298         HudElement* getHud(u32 id);
299         u32         addHud(HudElement* hud);
300         HudElement* removeHud(u32 id);
301         void        clearHud();
302         u32         maxHudId() {
303                 return hud.size();
304         }
305
306         u32 hud_flags;
307         s32 hud_hotbar_itemcount;
308 protected:
309         IGameDef *m_gamedef;
310
311         char m_name[PLAYERNAME_SIZE];
312         u16 m_breath;
313         f32 m_pitch;
314         f32 m_yaw;
315         v3f m_speed;
316         v3f m_position;
317         core::aabbox3d<f32> m_collisionbox;
318
319         f32 m_last_pitch;
320         f32 m_last_yaw;
321         v3f m_last_pos;
322         u16 m_last_hp;
323         Inventory m_last_inventory;
324
325         std::vector<HudElement *> hud;
326 };
327
328
329 /*
330         Player on the server
331 */
332 class RemotePlayer : public Player
333 {
334 public:
335         RemotePlayer(IGameDef *gamedef): Player(gamedef), m_sao(0) {}
336         virtual ~RemotePlayer() {}
337
338         PlayerSAO *getPlayerSAO()
339         { return m_sao; }
340         void setPlayerSAO(PlayerSAO *sao)
341         { m_sao = sao; }
342         void setPosition(const v3f &position);
343         
344 private:
345         PlayerSAO *m_sao;
346 };
347
348 #endif
349