]> git.lizzy.rs Git - dragonfireclient.git/blob - src/content_sao.h
Disable HW stereo for IrrLicht 1.9 (not supported anymore)
[dragonfireclient.git] / src / content_sao.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 #pragma once
21
22 #include "network/networkprotocol.h"
23 #include "util/numeric.h"
24 #include "serverobject.h"
25 #include "itemgroup.h"
26 #include "object_properties.h"
27 #include "constants.h"
28
29 class UnitSAO: public ServerActiveObject
30 {
31 public:
32         UnitSAO(ServerEnvironment *env, v3f pos);
33         virtual ~UnitSAO() = default;
34
35         virtual void setYaw(const float yaw) { m_yaw = yaw; }
36         float getYaw() const { return m_yaw; };
37         f32 getRadYaw() const { return m_yaw * core::DEGTORAD; }
38         // Deprecated
39         f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; }
40
41         s16 getHP() const { return m_hp; }
42         // Use a function, if isDead can be defined by other conditions
43         bool isDead() const { return m_hp == 0; }
44
45         inline bool isAttached() const
46         { return getParent(); }
47
48         void setArmorGroups(const ItemGroupList &armor_groups);
49         const ItemGroupList &getArmorGroups();
50         void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop);
51         void getAnimation(v2f *frame_range, float *frame_speed, float *frame_blend, bool *frame_loop);
52         void setAnimationSpeed(float frame_speed);
53         void setBonePosition(const std::string &bone, v3f position, v3f rotation);
54         void getBonePosition(const std::string &bone, v3f *position, v3f *rotation);
55         void setAttachment(int parent_id, const std::string &bone, v3f position, v3f rotation);
56         void getAttachment(int *parent_id, std::string *bone, v3f *position, v3f *rotation);
57         void clearChildAttachments();
58         void clearParentAttachment();
59         void addAttachmentChild(int child_id);
60         void removeAttachmentChild(int child_id);
61         const std::unordered_set<int> &getAttachmentChildIds();
62         ServerActiveObject *getParent() const;
63         ObjectProperties* accessObjectProperties();
64         void notifyObjectPropertiesModified();
65 protected:
66         s16 m_hp = -1;
67         float m_yaw = 0.0f;
68
69         bool m_properties_sent = true;
70         ObjectProperties m_prop;
71
72         ItemGroupList m_armor_groups;
73         bool m_armor_groups_sent = false;
74
75         v2f m_animation_range;
76         float m_animation_speed = 0.0f;
77         float m_animation_blend = 0.0f;
78         bool m_animation_loop = true;
79         bool m_animation_sent = false;
80         bool m_animation_speed_sent = false;
81
82         // Stores position and rotation for each bone name
83         std::unordered_map<std::string, core::vector2d<v3f>> m_bone_position;
84         bool m_bone_position_sent = false;
85
86         int m_attachment_parent_id = 0;
87         std::unordered_set<int> m_attachment_child_ids;
88         std::string m_attachment_bone = "";
89         v3f m_attachment_position;
90         v3f m_attachment_rotation;
91         bool m_attachment_sent = false;
92 private:
93         void onAttach(int parent_id);
94         void onDetach(int parent_id);
95 };
96
97 /*
98         LuaEntitySAO needs some internals exposed.
99 */
100
101 class LuaEntitySAO : public UnitSAO
102 {
103 public:
104         LuaEntitySAO(ServerEnvironment *env, v3f pos,
105                      const std::string &name, const std::string &state);
106         ~LuaEntitySAO();
107         ActiveObjectType getType() const
108         { return ACTIVEOBJECT_TYPE_LUAENTITY; }
109         ActiveObjectType getSendType() const
110         { return ACTIVEOBJECT_TYPE_GENERIC; }
111         virtual void addedToEnvironment(u32 dtime_s);
112         static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
113                         const std::string &data);
114         void step(float dtime, bool send_recommended);
115         std::string getClientInitializationData(u16 protocol_version);
116         bool isStaticAllowed() const
117         { return m_prop.static_save; }
118         void getStaticData(std::string *result) const;
119         int punch(v3f dir,
120                         const ToolCapabilities *toolcap=NULL,
121                         ServerActiveObject *puncher=NULL,
122                         float time_from_last_punch=1000000);
123         void rightClick(ServerActiveObject *clicker);
124         void setPos(const v3f &pos);
125         void moveTo(v3f pos, bool continuous);
126         float getMinimumSavedMovement();
127         std::string getDescription();
128         void setHP(s16 hp, const PlayerHPChangeReason &reason);
129         s16 getHP() const;
130         /* LuaEntitySAO-specific */
131         void setVelocity(v3f velocity);
132         void addVelocity(v3f velocity)
133         {
134                 m_velocity += velocity;
135         }
136         v3f getVelocity();
137         void setAcceleration(v3f acceleration);
138         v3f getAcceleration();
139
140         void setTextureMod(const std::string &mod);
141         std::string getTextureMod() const;
142         void setSprite(v2s16 p, int num_frames, float framelength,
143                         bool select_horiz_by_yawpitch);
144         std::string getName();
145         bool getCollisionBox(aabb3f *toset) const;
146         bool getSelectionBox(aabb3f *toset) const;
147         bool collideWithObjects() const;
148 private:
149         std::string getPropertyPacket();
150         void sendPosition(bool do_interpolate, bool is_movement_end);
151
152         std::string m_init_name;
153         std::string m_init_state;
154         bool m_registered = false;
155
156         v3f m_velocity;
157         v3f m_acceleration;
158
159         float m_last_sent_yaw = 0.0f;
160         v3f m_last_sent_position;
161         v3f m_last_sent_velocity;
162         float m_last_sent_position_timer = 0.0f;
163         float m_last_sent_move_precision = 0.0f;
164         std::string m_current_texture_modifier = "";
165 };
166
167 /*
168         PlayerSAO needs some internals exposed.
169 */
170
171 class LagPool
172 {
173         float m_pool = 15.0f;
174         float m_max = 15.0f;
175 public:
176         LagPool() = default;
177
178         void setMax(float new_max)
179         {
180                 m_max = new_max;
181                 if(m_pool > new_max)
182                         m_pool = new_max;
183         }
184
185         void add(float dtime)
186         {
187                 m_pool -= dtime;
188                 if(m_pool < 0)
189                         m_pool = 0;
190         }
191
192         void empty()
193         {
194                 m_pool = m_max;
195         }
196
197         bool grab(float dtime)
198         {
199                 if(dtime <= 0)
200                         return true;
201                 if(m_pool + dtime > m_max)
202                         return false;
203                 m_pool += dtime;
204                 return true;
205         }
206 };
207
208 class RemotePlayer;
209
210 class PlayerSAO : public UnitSAO
211 {
212 public:
213         PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t peer_id_,
214                         bool is_singleplayer);
215         ~PlayerSAO();
216         ActiveObjectType getType() const
217         { return ACTIVEOBJECT_TYPE_PLAYER; }
218         ActiveObjectType getSendType() const
219         { return ACTIVEOBJECT_TYPE_GENERIC; }
220         std::string getDescription();
221
222         /*
223                 Active object <-> environment interface
224         */
225
226         void addedToEnvironment(u32 dtime_s);
227         void removingFromEnvironment();
228         bool isStaticAllowed() const { return false; }
229         std::string getClientInitializationData(u16 protocol_version);
230         void getStaticData(std::string *result) const;
231         void step(float dtime, bool send_recommended);
232         void setBasePosition(const v3f &position);
233         void setPos(const v3f &pos);
234         void moveTo(v3f pos, bool continuous);
235         void setYaw(const float yaw);
236         // Data should not be sent at player initialization
237         void setYawAndSend(const float yaw);
238         void setPitch(const float pitch);
239         // Data should not be sent at player initialization
240         void setPitchAndSend(const float pitch);
241         f32 getPitch() const { return m_pitch; }
242         f32 getRadPitch() const { return m_pitch * core::DEGTORAD; }
243         // Deprecated
244         f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
245         void setFov(const float pitch);
246         f32 getFov() const { return m_fov; }
247         void setWantedRange(const s16 range);
248         s16 getWantedRange() const { return m_wanted_range; }
249
250         /*
251                 Interaction interface
252         */
253
254         int punch(v3f dir,
255                 const ToolCapabilities *toolcap,
256                 ServerActiveObject *puncher,
257                 float time_from_last_punch);
258         void rightClick(ServerActiveObject *clicker) {}
259         void setHP(s16 hp, const PlayerHPChangeReason &reason);
260         void setHPRaw(s16 hp) { m_hp = hp; }
261         s16 readDamage();
262         u16 getBreath() const { return m_breath; }
263         void setBreath(const u16 breath, bool send = true);
264
265         /*
266                 Inventory interface
267         */
268
269         Inventory* getInventory();
270         const Inventory* getInventory() const;
271         InventoryLocation getInventoryLocation() const;
272         std::string getWieldList() const;
273         ItemStack getWieldedItem() const;
274         ItemStack getWieldedItemOrHand() const;
275         bool setWieldedItem(const ItemStack &item);
276         int getWieldIndex() const;
277         void setWieldIndex(int i);
278
279         /*
280                 PlayerSAO-specific
281         */
282
283         void disconnected();
284
285         RemotePlayer *getPlayer() { return m_player; }
286         session_t getPeerID() const { return m_peer_id; }
287
288         // Cheat prevention
289
290         v3f getLastGoodPosition() const
291         {
292                 return m_last_good_position;
293         }
294         float resetTimeFromLastPunch()
295         {
296                 float r = m_time_from_last_punch;
297                 m_time_from_last_punch = 0.0;
298                 return r;
299         }
300         void noCheatDigStart(const v3s16 &p)
301         {
302                 m_nocheat_dig_pos = p;
303                 m_nocheat_dig_time = 0;
304         }
305         v3s16 getNoCheatDigPos()
306         {
307                 return m_nocheat_dig_pos;
308         }
309         float getNoCheatDigTime()
310         {
311                 return m_nocheat_dig_time;
312         }
313         void noCheatDigEnd()
314         {
315                 m_nocheat_dig_pos = v3s16(32767, 32767, 32767);
316         }
317         LagPool& getDigPool()
318         {
319                 return m_dig_pool;
320         }
321         // Returns true if cheated
322         bool checkMovementCheat();
323
324         // Other
325
326         void updatePrivileges(const std::set<std::string> &privs,
327                         bool is_singleplayer)
328         {
329                 m_privs = privs;
330                 m_is_singleplayer = is_singleplayer;
331         }
332
333         bool getCollisionBox(aabb3f *toset) const;
334         bool getSelectionBox(aabb3f *toset) const;
335         bool collideWithObjects() const { return true; }
336
337         void finalize(RemotePlayer *player, const std::set<std::string> &privs);
338
339         v3f getEyePosition() const { return m_base_position + getEyeOffset(); }
340         v3f getEyeOffset() const;
341         float getZoomFOV() const;
342
343         inline Metadata &getMeta() { return m_meta; }
344
345 private:
346         std::string getPropertyPacket();
347         void unlinkPlayerSessionAndSave();
348
349         RemotePlayer *m_player = nullptr;
350         session_t m_peer_id = 0;
351         Inventory *m_inventory = nullptr;
352         s16 m_damage = 0;
353
354         // Cheat prevention
355         LagPool m_dig_pool;
356         LagPool m_move_pool;
357         v3f m_last_good_position;
358         float m_time_from_last_teleport = 0.0f;
359         float m_time_from_last_punch = 0.0f;
360         v3s16 m_nocheat_dig_pos = v3s16(32767, 32767, 32767);
361         float m_nocheat_dig_time = 0.0f;
362
363         // Timers
364         IntervalLimiter m_breathing_interval;
365         IntervalLimiter m_drowning_interval;
366         IntervalLimiter m_node_hurt_interval;
367
368         int m_wield_index = 0;
369         bool m_position_not_sent = false;
370
371         // Cached privileges for enforcement
372         std::set<std::string> m_privs;
373         bool m_is_singleplayer;
374
375         u16 m_breath = PLAYER_MAX_BREATH_DEFAULT;
376         f32 m_pitch = 0.0f;
377         f32 m_fov = 0.0f;
378         s16 m_wanted_range = 0.0f;
379
380         Metadata m_meta;
381 public:
382         float m_physics_override_speed = 1.0f;
383         float m_physics_override_jump = 1.0f;
384         float m_physics_override_gravity = 1.0f;
385         bool m_physics_override_sneak = true;
386         bool m_physics_override_sneak_glitch = false;
387         bool m_physics_override_new_move = true;
388         bool m_physics_override_sent = false;
389 };
390
391
392 struct PlayerHPChangeReason {
393         enum Type : u8 {
394                 SET_HP,
395                 PLAYER_PUNCH,
396                 FALL,
397                 NODE_DAMAGE,
398                 DROWNING,
399                 RESPAWN
400         };
401
402         Type type = SET_HP;
403         ServerActiveObject *object;
404         bool from_mod = false;
405         int lua_reference = -1;
406
407         bool setTypeFromString(const std::string &typestr)
408         {
409                 if (typestr == "set_hp")
410                         type = SET_HP;
411                 else if (typestr == "punch")
412                         type = PLAYER_PUNCH;
413                 else if (typestr == "fall")
414                         type = FALL;
415                 else if (typestr == "node_damage")
416                         type = NODE_DAMAGE;
417                 else if (typestr == "drown")
418                         type = DROWNING;
419                 else if (typestr == "respawn")
420                         type = RESPAWN;
421                 else
422                         return false;
423
424                 return true;
425         }
426
427         std::string getTypeAsString() const
428         {
429                 switch (type) {
430                 case PlayerHPChangeReason::SET_HP:
431                         return "set_hp";
432                 case PlayerHPChangeReason::PLAYER_PUNCH:
433                         return "punch";
434                 case PlayerHPChangeReason::FALL:
435                         return "fall";
436                 case PlayerHPChangeReason::NODE_DAMAGE:
437                         return "node_damage";
438                 case PlayerHPChangeReason::DROWNING:
439                         return "drown";
440                 case PlayerHPChangeReason::RESPAWN:
441                         return "respawn";
442                 default:
443                         return "?";
444                 }
445         }
446
447         PlayerHPChangeReason(Type type, ServerActiveObject *object=NULL):
448                         type(type), object(object)
449         {}
450 };