]> git.lizzy.rs Git - minetest.git/blob - src/environment.h
Rename --do-unittests to --run-unittests as @Zeno- and @sfan5 requested
[minetest.git] / src / environment.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 ENVIRONMENT_HEADER
21 #define ENVIRONMENT_HEADER
22
23 /*
24         This class is the game's environment.
25         It contains:
26         - The map
27         - Players
28         - Other objects
29         - The current time in the game
30         - etc.
31 */
32
33 #include <set>
34 #include <list>
35 #include <map>
36 #include "irr_v3d.h"
37 #include "activeobject.h"
38 #include "util/numeric.h"
39 #include "mapnode.h"
40 #include "mapblock.h"
41 #include "jthread/jmutex.h"
42
43 class ServerEnvironment;
44 class ActiveBlockModifier;
45 class ServerActiveObject;
46 class ITextureSource;
47 class IGameDef;
48 class Map;
49 class ServerMap;
50 class ClientMap;
51 class GameScripting;
52 class Player;
53
54 class Environment
55 {
56 public:
57         // Environment will delete the map passed to the constructor
58         Environment();
59         virtual ~Environment();
60
61         /*
62                 Step everything in environment.
63                 - Move players
64                 - Step mobs
65                 - Run timers of map
66         */
67         virtual void step(f32 dtime) = 0;
68
69         virtual Map & getMap() = 0;
70
71         virtual void addPlayer(Player *player);
72         void removePlayer(u16 peer_id);
73         void removePlayer(const char *name);
74         Player * getPlayer(u16 peer_id);
75         Player * getPlayer(const char *name);
76         Player * getRandomConnectedPlayer();
77         Player * getNearestConnectedPlayer(v3f pos);
78         std::vector<Player*> getPlayers();
79         std::vector<Player*> getPlayers(bool ignore_disconnected);
80
81         u32 getDayNightRatio();
82
83         // 0-23999
84         virtual void setTimeOfDay(u32 time)
85         {
86                 m_time_of_day = time;
87                 m_time_of_day_f = (float)time / 24000.0;
88         }
89
90         u32 getTimeOfDay()
91         { return m_time_of_day; }
92
93         float getTimeOfDayF()
94         { return m_time_of_day_f; }
95
96         void stepTimeOfDay(float dtime);
97
98         void setTimeOfDaySpeed(float speed);
99
100         float getTimeOfDaySpeed();
101
102         void setDayNightRatioOverride(bool enable, u32 value)
103         {
104                 m_enable_day_night_ratio_override = enable;
105                 m_day_night_ratio_override = value;
106         }
107
108         // counter used internally when triggering ABMs
109         u32 m_added_objects;
110
111 protected:
112         // peer_ids in here should be unique, except that there may be many 0s
113         std::vector<Player*> m_players;
114         // Time of day in milli-hours (0-23999); determines day and night
115         u32 m_time_of_day;
116         // Time of day in 0...1
117         float m_time_of_day_f;
118         float m_time_of_day_speed;
119         // Used to buffer dtime for adding to m_time_of_day
120         float m_time_counter;
121         // Overriding the day-night ratio is useful for custom sky visuals
122         bool m_enable_day_night_ratio_override;
123         u32 m_day_night_ratio_override;
124
125         /* TODO: Add a callback function so these can be updated when a setting
126          *       changes.  At this point in time it doesn't matter (e.g. /set
127          *       is documented to change server settings only)
128          *
129          * TODO: Local caching of settings is not optimal and should at some stage
130          *       be updated to use a global settings object for getting thse values
131          *       (as opposed to the this local caching). This can be addressed in
132          *       a later release.
133          */
134         bool m_cache_enable_shaders;
135
136 private:
137         JMutex m_lock;
138
139 };
140
141 /*
142         Active block modifier interface.
143
144         These are fed into ServerEnvironment at initialization time;
145         ServerEnvironment handles deleting them.
146 */
147
148 class ActiveBlockModifier
149 {
150 public:
151         ActiveBlockModifier(){};
152         virtual ~ActiveBlockModifier(){};
153
154         // Set of contents to trigger on
155         virtual std::set<std::string> getTriggerContents()=0;
156         // Set of required neighbors (trigger doesn't happen if none are found)
157         // Empty = do not check neighbors
158         virtual std::set<std::string> getRequiredNeighbors()
159         { return std::set<std::string>(); }
160         // Trigger interval in seconds
161         virtual float getTriggerInterval() = 0;
162         // Random chance of (1 / return value), 0 is disallowed
163         virtual u32 getTriggerChance() = 0;
164         // This is called usually at interval for 1/chance of the nodes
165         virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n){};
166         virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
167                         u32 active_object_count, u32 active_object_count_wider){};
168 };
169
170 struct ABMWithState
171 {
172         ActiveBlockModifier *abm;
173         float timer;
174
175         ABMWithState(ActiveBlockModifier *abm_);
176 };
177
178 /*
179         List of active blocks, used by ServerEnvironment
180 */
181
182 class ActiveBlockList
183 {
184 public:
185         void update(std::vector<v3s16> &active_positions,
186                         s16 radius,
187                         std::set<v3s16> &blocks_removed,
188                         std::set<v3s16> &blocks_added);
189
190         bool contains(v3s16 p){
191                 return (m_list.find(p) != m_list.end());
192         }
193
194         void clear(){
195                 m_list.clear();
196         }
197
198         std::set<v3s16> m_list;
199         std::set<v3s16> m_forceloaded_list;
200
201 private:
202 };
203
204 /*
205         The server-side environment.
206
207         This is not thread-safe. Server uses an environment mutex.
208 */
209
210 class ServerEnvironment : public Environment
211 {
212 public:
213         ServerEnvironment(ServerMap *map, GameScripting *scriptIface,
214                         IGameDef *gamedef, const std::string &path_world);
215         ~ServerEnvironment();
216
217         Map & getMap();
218
219         ServerMap & getServerMap();
220
221         //TODO find way to remove this fct!
222         GameScripting* getScriptIface()
223                 { return m_script; }
224
225         IGameDef *getGameDef()
226                 { return m_gamedef; }
227
228         float getSendRecommendedInterval()
229                 { return m_recommended_send_interval; }
230
231         // Save players
232         void saveLoadedPlayers();
233         void savePlayer(const std::string &playername);
234         Player *loadPlayer(const std::string &playername);
235
236         /*
237                 Save and load time of day and game timer
238         */
239         void saveMeta();
240         void loadMeta();
241
242         /*
243                 External ActiveObject interface
244                 -------------------------------------------
245         */
246
247         ServerActiveObject* getActiveObject(u16 id);
248
249         /*
250                 Add an active object to the environment.
251                 Environment handles deletion of object.
252                 Object may be deleted by environment immediately.
253                 If id of object is 0, assigns a free id to it.
254                 Returns the id of the object.
255                 Returns 0 if not added and thus deleted.
256         */
257         u16 addActiveObject(ServerActiveObject *object);
258
259         /*
260                 Add an active object as a static object to the corresponding
261                 MapBlock.
262                 Caller allocates memory, ServerEnvironment frees memory.
263                 Return value: true if succeeded, false if failed.
264                 (note:  not used, pending removal from engine)
265         */
266         //bool addActiveObjectAsStatic(ServerActiveObject *object);
267
268         /*
269                 Find out what new objects have been added to
270                 inside a radius around a position
271         */
272         void getAddedActiveObjects(v3s16 pos, s16 radius,
273                         s16 player_radius,
274                         std::set<u16> &current_objects,
275                         std::set<u16> &added_objects);
276
277         /*
278                 Find out what new objects have been removed from
279                 inside a radius around a position
280         */
281         void getRemovedActiveObjects(v3s16 pos, s16 radius,
282                         s16 player_radius,
283                         std::set<u16> &current_objects,
284                         std::set<u16> &removed_objects);
285
286         /*
287                 Get the next message emitted by some active object.
288                 Returns a message with id=0 if no messages are available.
289         */
290         ActiveObjectMessage getActiveObjectMessage();
291
292         /*
293                 Activate objects and dynamically modify for the dtime determined
294                 from timestamp and additional_dtime
295         */
296         void activateBlock(MapBlock *block, u32 additional_dtime=0);
297
298         /*
299                 ActiveBlockModifiers
300                 -------------------------------------------
301         */
302
303         void addActiveBlockModifier(ActiveBlockModifier *abm);
304
305         /*
306                 Other stuff
307                 -------------------------------------------
308         */
309
310         // Script-aware node setters
311         bool setNode(v3s16 p, const MapNode &n);
312         bool removeNode(v3s16 p);
313         bool swapNode(v3s16 p, const MapNode &n);
314
315         // Find all active objects inside a radius around a point
316         std::set<u16> getObjectsInsideRadius(v3f pos, float radius);
317
318         // Clear all objects, loading and going through every MapBlock
319         void clearAllObjects();
320
321         // This makes stuff happen
322         void step(f32 dtime);
323
324         //check if there's a line of sight between two positions
325         bool line_of_sight(v3f pos1, v3f pos2, float stepsize=1.0, v3s16 *p=NULL);
326
327         u32 getGameTime() { return m_game_time; }
328
329         void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; }
330         float getMaxLagEstimate() { return m_max_lag_estimate; }
331
332         std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; };
333
334 private:
335
336         /*
337                 Internal ActiveObject interface
338                 -------------------------------------------
339         */
340
341         /*
342                 Add an active object to the environment.
343
344                 Called by addActiveObject.
345
346                 Object may be deleted by environment immediately.
347                 If id of object is 0, assigns a free id to it.
348                 Returns the id of the object.
349                 Returns 0 if not added and thus deleted.
350         */
351         u16 addActiveObjectRaw(ServerActiveObject *object, bool set_changed, u32 dtime_s);
352
353         /*
354                 Remove all objects that satisfy (m_removed && m_known_by_count==0)
355         */
356         void removeRemovedObjects();
357
358         /*
359                 Convert stored objects from block to active
360         */
361         void activateObjects(MapBlock *block, u32 dtime_s);
362
363         /*
364                 Convert objects that are not in active blocks to static.
365
366                 If m_known_by_count != 0, active object is not deleted, but static
367                 data is still updated.
368
369                 If force_delete is set, active object is deleted nevertheless. It
370                 shall only be set so in the destructor of the environment.
371         */
372         void deactivateFarObjects(bool force_delete);
373
374         /*
375                 Member variables
376         */
377
378         // The map
379         ServerMap *m_map;
380         // Lua state
381         GameScripting* m_script;
382         // Game definition
383         IGameDef *m_gamedef;
384         // World path
385         const std::string m_path_world;
386         // Active object list
387         std::map<u16, ServerActiveObject*> m_active_objects;
388         // Outgoing network message buffer for active objects
389         std::list<ActiveObjectMessage> m_active_object_messages;
390         // Some timers
391         float m_send_recommended_timer;
392         IntervalLimiter m_object_management_interval;
393         // List of active blocks
394         ActiveBlockList m_active_blocks;
395         IntervalLimiter m_active_blocks_management_interval;
396         IntervalLimiter m_active_block_modifier_interval;
397         IntervalLimiter m_active_blocks_nodemetadata_interval;
398         int m_active_block_interval_overload_skip;
399         // Time from the beginning of the game in seconds.
400         // Incremented in step().
401         u32 m_game_time;
402         // A helper variable for incrementing the latter
403         float m_game_time_fraction_counter;
404         std::list<ABMWithState> m_abms;
405         // An interval for generally sending object positions and stuff
406         float m_recommended_send_interval;
407         // Estimate for general maximum lag as determined by server.
408         // Can raise to high values like 15s with eg. map generation mods.
409         float m_max_lag_estimate;
410 };
411
412 #ifndef SERVER
413
414 #include "clientobject.h"
415 class ClientSimpleObject;
416
417 /*
418         The client-side environment.
419
420         This is not thread-safe.
421         Must be called from main (irrlicht) thread (uses the SceneManager)
422         Client uses an environment mutex.
423 */
424
425 enum ClientEnvEventType
426 {
427         CEE_NONE,
428         CEE_PLAYER_DAMAGE,
429         CEE_PLAYER_BREATH
430 };
431
432 struct ClientEnvEvent
433 {
434         ClientEnvEventType type;
435         union {
436                 //struct{
437                 //} none;
438                 struct{
439                         u8 amount;
440                         bool send_to_server;
441                 } player_damage;
442                 struct{
443                         u16 amount;
444                 } player_breath;
445         };
446 };
447
448 class ClientEnvironment : public Environment
449 {
450 public:
451         ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr,
452                         ITextureSource *texturesource, IGameDef *gamedef,
453                         IrrlichtDevice *device);
454         ~ClientEnvironment();
455
456         Map & getMap();
457         ClientMap & getClientMap();
458
459         IGameDef *getGameDef()
460         { return m_gamedef; }
461
462         void step(f32 dtime);
463
464         virtual void addPlayer(Player *player);
465         LocalPlayer * getLocalPlayer();
466
467         /*
468                 ClientSimpleObjects
469         */
470
471         void addSimpleObject(ClientSimpleObject *simple);
472
473         /*
474                 ActiveObjects
475         */
476
477         ClientActiveObject* getActiveObject(u16 id);
478
479         /*
480                 Adds an active object to the environment.
481                 Environment handles deletion of object.
482                 Object may be deleted by environment immediately.
483                 If id of object is 0, assigns a free id to it.
484                 Returns the id of the object.
485                 Returns 0 if not added and thus deleted.
486         */
487         u16 addActiveObject(ClientActiveObject *object);
488
489         void addActiveObject(u16 id, u8 type, const std::string &init_data);
490         void removeActiveObject(u16 id);
491
492         void processActiveObjectMessage(u16 id, const std::string &data);
493
494         /*
495                 Callbacks for activeobjects
496         */
497
498         void damageLocalPlayer(u8 damage, bool handle_hp=true);
499         void updateLocalPlayerBreath(u16 breath);
500
501         /*
502                 Client likes to call these
503         */
504
505         // Get all nearby objects
506         void getActiveObjects(v3f origin, f32 max_d,
507                         std::vector<DistanceSortedActiveObject> &dest);
508
509         // Get event from queue. CEE_NONE is returned if queue is empty.
510         ClientEnvEvent getClientEvent();
511
512         u16 m_attachements[USHRT_MAX];
513
514         std::list<std::string> getPlayerNames()
515         { return m_player_names; }
516         void addPlayerName(std::string name)
517         { m_player_names.push_back(name); }
518         void removePlayerName(std::string name)
519         { m_player_names.remove(name); }
520         void updateCameraOffset(v3s16 camera_offset)
521         { m_camera_offset = camera_offset; }
522         v3s16 getCameraOffset()
523         { return m_camera_offset; }
524
525 private:
526         ClientMap *m_map;
527         scene::ISceneManager *m_smgr;
528         ITextureSource *m_texturesource;
529         IGameDef *m_gamedef;
530         IrrlichtDevice *m_irr;
531         std::map<u16, ClientActiveObject*> m_active_objects;
532         std::list<ClientSimpleObject*> m_simple_objects;
533         std::list<ClientEnvEvent> m_client_event_queue;
534         IntervalLimiter m_active_object_light_update_interval;
535         IntervalLimiter m_lava_hurt_interval;
536         IntervalLimiter m_drowning_interval;
537         IntervalLimiter m_breathing_interval;
538         std::list<std::string> m_player_names;
539         v3s16 m_camera_offset;
540 };
541
542 #endif
543
544 #endif
545