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