Some work-in-progress in hp and mobs and a frightening amount of random fixes.
[oweals/minetest.git] / src / player.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
14
15 You should have received a copy of the GNU 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 /*
21 (c) 2010 Perttu Ahola <celeron55@gmail.com>
22 */
23
24 #ifndef PLAYER_HEADER
25 #define PLAYER_HEADER
26
27 #include "common_irrlicht.h"
28 #include "inventory.h"
29 #include "collision.h"
30
31 #define PLAYERNAME_SIZE 20
32
33 #define PLAYERNAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.,"
34
35 class Map;
36
37 class Player
38 {
39 public:
40         Player();
41         virtual ~Player();
42
43         void resetInventory();
44
45         //void move(f32 dtime, Map &map);
46         virtual void move(f32 dtime, Map &map, f32 pos_max_d) = 0;
47
48         v3f getSpeed()
49         {
50                 return m_speed;
51         }
52
53         void setSpeed(v3f speed)
54         {
55                 m_speed = speed;
56         }
57         
58         // Y direction is ignored
59         void accelerate(v3f target_speed, f32 max_increase);
60
61         v3f getPosition()
62         {
63                 return m_position;
64         }
65
66         virtual void setPosition(v3f position)
67         {
68                 m_position = position;
69         }
70
71         void setPitch(f32 pitch)
72         {
73                 m_pitch = pitch;
74         }
75
76         virtual void setYaw(f32 yaw)
77         {
78                 m_yaw = yaw;
79         }
80
81         f32 getPitch()
82         {
83                 return m_pitch;
84         }
85
86         f32 getYaw()
87         {
88                 return m_yaw;
89         }
90
91         virtual void updateName(const char *name)
92         {
93                 snprintf(m_name, PLAYERNAME_SIZE, "%s", name);
94         }
95
96         const char * getName()
97         {
98                 return m_name;
99         }
100
101         virtual bool isLocal() const = 0;
102
103         virtual void updateLight(u8 light_at_pos) {};
104         
105         // NOTE: Use peer_id == 0 for disconnected
106         /*virtual bool isClientConnected() { return false; }
107         virtual void setClientConnected(bool) {}*/
108         
109         /*
110                 serialize() writes a bunch of text that can contain
111                 any characters except a '\0', and such an ending that
112                 deSerialize stops reading exactly at the right point.
113         */
114         void serialize(std::ostream &os);
115         void deSerialize(std::istream &is);
116
117         bool touching_ground;
118         // This oscillates so that the player jumps a bit above the surface
119         bool in_water;
120         // This is more stable and defines the maximum speed of the player
121         bool in_water_stable;
122         bool swimming_up;
123         
124         Inventory inventory;
125
126         bool craftresult_is_preview;
127
128         u16 hp;
129
130         u16 peer_id;
131
132 protected:
133         char m_name[PLAYERNAME_SIZE];
134         f32 m_pitch;
135         f32 m_yaw;
136         v3f m_speed;
137         v3f m_position;
138 };
139
140 /*
141         Player on the server
142 */
143
144 class ServerRemotePlayer : public Player
145 {
146 public:
147         ServerRemotePlayer()
148         {
149         }
150         virtual ~ServerRemotePlayer()
151         {
152         }
153
154         virtual bool isLocal() const
155         {
156                 return false;
157         }
158
159         virtual void move(f32 dtime, Map &map, f32 pos_max_d)
160         {
161         }
162         
163 private:
164 };
165
166 #ifndef SERVER
167
168 /*
169         All the other players on the client are these
170 */
171
172 class RemotePlayer : public Player, public scene::ISceneNode
173 {
174 public:
175         RemotePlayer(
176                 scene::ISceneNode* parent=NULL,
177                 IrrlichtDevice *device=NULL,
178                 s32 id=0);
179         
180         virtual ~RemotePlayer();
181
182         /*
183                 ISceneNode methods
184         */
185
186         virtual void OnRegisterSceneNode()
187         {
188                 if (IsVisible)
189                         SceneManager->registerNodeForRendering(this);
190
191                 ISceneNode::OnRegisterSceneNode();
192         }
193
194         virtual void render()
195         {
196                 // Do nothing
197         }
198         
199         virtual const core::aabbox3d<f32>& getBoundingBox() const
200         {
201                 return m_box;
202         }
203
204         void setPosition(v3f position)
205         {
206                 m_oldpos = m_showpos;
207                 
208                 if(m_pos_animation_time < 0.001 || m_pos_animation_time > 1.0)
209                         m_pos_animation_time = m_pos_animation_time_counter;
210                 else
211                         m_pos_animation_time = m_pos_animation_time * 0.9
212                                         + m_pos_animation_time_counter * 0.1;
213                 m_pos_animation_time_counter = 0;
214                 m_pos_animation_counter = 0;
215                 
216                 Player::setPosition(position);
217                 //ISceneNode::setPosition(position);
218         }
219
220         virtual void setYaw(f32 yaw)
221         {
222                 Player::setYaw(yaw);
223                 ISceneNode::setRotation(v3f(0, -yaw, 0));
224         }
225
226         bool isLocal() const
227         {
228                 return false;
229         }
230
231         void updateName(const char *name);
232
233         virtual void updateLight(u8 light_at_pos)
234         {
235                 if(m_node == NULL)
236                         return;
237
238                 u8 li = decode_light(light_at_pos);
239                 video::SColor color(255,li,li,li);
240
241                 scene::IMesh *mesh = m_node->getMesh();
242                 
243                 u16 mc = mesh->getMeshBufferCount();
244                 for(u16 j=0; j<mc; j++)
245                 {
246                         scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
247                         video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
248                         u16 vc = buf->getVertexCount();
249                         for(u16 i=0; i<vc; i++)
250                         {
251                                 vertices[i].Color = color;
252                         }
253                 }
254         }
255         
256         void move(f32 dtime, Map &map, f32 pos_max_d);
257
258 private:
259         scene::IMeshSceneNode *m_node;
260         scene::ITextSceneNode* m_text;
261         core::aabbox3d<f32> m_box;
262
263         v3f m_oldpos;
264         f32 m_pos_animation_counter;
265         f32 m_pos_animation_time;
266         f32 m_pos_animation_time_counter;
267         v3f m_showpos;
268 };
269
270 #endif // !SERVER
271
272 #ifndef SERVER
273 struct PlayerControl
274 {
275         PlayerControl()
276         {
277                 up = false;
278                 down = false;
279                 left = false;
280                 right = false;
281                 jump = false;
282                 aux1 = false;
283                 sneak = false;
284                 pitch = 0;
285                 yaw = 0;
286         }
287         PlayerControl(
288                 bool a_up,
289                 bool a_down,
290                 bool a_left,
291                 bool a_right,
292                 bool a_jump,
293                 bool a_aux1,
294                 bool a_sneak,
295                 float a_pitch,
296                 float a_yaw
297         )
298         {
299                 up = a_up;
300                 down = a_down;
301                 left = a_left;
302                 right = a_right;
303                 jump = a_jump;
304                 aux1 = a_aux1;
305                 sneak = a_sneak;
306                 pitch = a_pitch;
307                 yaw = a_yaw;
308         }
309         bool up;
310         bool down;
311         bool left;
312         bool right;
313         bool jump;
314         bool aux1;
315         bool sneak;
316         float pitch;
317         float yaw;
318 };
319
320 class LocalPlayer : public Player
321 {
322 public:
323         LocalPlayer();
324         virtual ~LocalPlayer();
325
326         bool isLocal() const
327         {
328                 return true;
329         }
330
331         void move(f32 dtime, Map &map, f32 pos_max_d,
332                         core::list<CollisionInfo> *collision_info);
333         void move(f32 dtime, Map &map, f32 pos_max_d);
334
335         void applyControl(float dtime);
336         
337         PlayerControl control;
338
339 private:
340         // This is used for determining the sneaking range
341         v3s16 m_sneak_node;
342         // Whether the player is allowed to sneak
343         bool m_sneak_node_exists;
344 };
345 #endif // !SERVER
346
347 #endif
348