Create framework for getting rid of global definitions of node/tool/item/whatever...
[oweals/minetest.git] / src / environment.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 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 <list>
34 #include "common_irrlicht.h"
35 #include "player.h"
36 #include "map.h"
37 #include <ostream>
38 #include "utility.h"
39 #include "activeobject.h"
40
41 class Server;
42 class ActiveBlockModifier;
43 class ServerActiveObject;
44 typedef struct lua_State lua_State;
45 class ITextureSource;
46 class IGameDef;
47
48 class Environment
49 {
50 public:
51         // Environment will delete the map passed to the constructor
52         Environment();
53         virtual ~Environment();
54
55         /*
56                 Step everything in environment.
57                 - Move players
58                 - Step mobs
59                 - Run timers of map
60         */
61         virtual void step(f32 dtime) = 0;
62
63         virtual Map & getMap() = 0;
64
65         virtual void addPlayer(Player *player);
66         void removePlayer(u16 peer_id);
67         Player * getPlayer(u16 peer_id);
68         Player * getPlayer(const char *name);
69         Player * getRandomConnectedPlayer();
70         Player * getNearestConnectedPlayer(v3f pos);
71         core::list<Player*> getPlayers();
72         core::list<Player*> getPlayers(bool ignore_disconnected);
73         void printPlayers(std::ostream &o);
74         
75         //void setDayNightRatio(u32 r);
76         u32 getDayNightRatio();
77         
78         // 0-23999
79         virtual void setTimeOfDay(u32 time)
80         {
81                 m_time_of_day = time;
82         }
83
84         u32 getTimeOfDay()
85         {
86                 return m_time_of_day;
87         }
88
89 protected:
90         // peer_ids in here should be unique, except that there may be many 0s
91         core::list<Player*> m_players;
92         // Brightness
93         //u32 m_daynight_ratio;
94         // Time of day in milli-hours (0-23999); determines day and night
95         u32 m_time_of_day;
96 };
97
98 /*
99         List of active blocks, used by ServerEnvironment
100 */
101
102 class ActiveBlockList
103 {
104 public:
105         void update(core::list<v3s16> &active_positions,
106                         s16 radius,
107                         core::map<v3s16, bool> &blocks_removed,
108                         core::map<v3s16, bool> &blocks_added);
109
110         bool contains(v3s16 p){
111                 return (m_list.find(p) != NULL);
112         }
113
114         void clear(){
115                 m_list.clear();
116         }
117
118         core::map<v3s16, bool> m_list;
119
120 private:
121 };
122
123 /*
124         The server-side environment.
125
126         This is not thread-safe. Server uses an environment mutex.
127 */
128
129 class ServerEnvironment : public Environment
130 {
131 public:
132         ServerEnvironment(ServerMap *map, lua_State *L, IGameDef *gamedef);
133         ~ServerEnvironment();
134
135         Map & getMap()
136                 { return *m_map; }
137
138         ServerMap & getServerMap()
139                 { return *m_map; }
140
141         lua_State* getLua()
142                 { return m_lua; }
143
144         IGameDef *getGameDef()
145                 { return m_gamedef; }
146
147         float getSendRecommendedInterval()
148         {
149                 return 0.10;
150         }
151
152         /*
153                 Save players
154         */
155         void serializePlayers(const std::string &savedir);
156         void deSerializePlayers(const std::string &savedir);
157
158         /*
159                 Save and load time of day and game timer
160         */
161         void saveMeta(const std::string &savedir);
162         void loadMeta(const std::string &savedir);
163
164         /*
165                 External ActiveObject interface
166                 -------------------------------------------
167         */
168
169         ServerActiveObject* getActiveObject(u16 id);
170
171         /*
172                 Add an active object to the environment.
173                 Environment handles deletion of object.
174                 Object may be deleted by environment immediately.
175                 If id of object is 0, assigns a free id to it.
176                 Returns the id of the object.
177                 Returns 0 if not added and thus deleted.
178         */
179         u16 addActiveObject(ServerActiveObject *object);
180         
181         /*
182                 Add an active object as a static object to the corresponding
183                 MapBlock.
184                 Caller allocates memory, ServerEnvironment frees memory.
185                 Return value: true if succeeded, false if failed.
186         */
187         bool addActiveObjectAsStatic(ServerActiveObject *object);
188         
189         /*
190                 Find out what new objects have been added to
191                 inside a radius around a position
192         */
193         void getAddedActiveObjects(v3s16 pos, s16 radius,
194                         core::map<u16, bool> &current_objects,
195                         core::map<u16, bool> &added_objects);
196
197         /*
198                 Find out what new objects have been removed from
199                 inside a radius around a position
200         */
201         void getRemovedActiveObjects(v3s16 pos, s16 radius,
202                         core::map<u16, bool> &current_objects,
203                         core::map<u16, bool> &removed_objects);
204         
205         /*
206                 Get the next message emitted by some active object.
207                 Returns a message with id=0 if no messages are available.
208         */
209         ActiveObjectMessage getActiveObjectMessage();
210
211         /*
212                 Activate objects and dynamically modify for the dtime determined
213                 from timestamp and additional_dtime
214         */
215         void activateBlock(MapBlock *block, u32 additional_dtime=0);
216
217         /*
218                 ActiveBlockModifiers (TODO)
219                 -------------------------------------------
220                 NOTE: Not used currently (TODO: Use or remove)
221         */
222
223         void addActiveBlockModifier(ActiveBlockModifier *abm);
224
225         /* Other stuff */
226         
227         // Clear all objects, loading and going through every MapBlock
228         void clearAllObjects();
229         
230         void step(f32 dtime);
231         
232 private:
233
234         /*
235                 Internal ActiveObject interface
236                 -------------------------------------------
237         */
238
239         /*
240                 Add an active object to the environment.
241
242                 Called by addActiveObject.
243
244                 Object may be deleted by environment immediately.
245                 If id of object is 0, assigns a free id to it.
246                 Returns the id of the object.
247                 Returns 0 if not added and thus deleted.
248         */
249         u16 addActiveObjectRaw(ServerActiveObject *object, bool set_changed);
250         
251         /*
252                 Remove all objects that satisfy (m_removed && m_known_by_count==0)
253         */
254         void removeRemovedObjects();
255         
256         /*
257                 Convert stored objects from block to active
258         */
259         void activateObjects(MapBlock *block);
260         
261         /*
262                 Convert objects that are not in active blocks to static.
263
264                 If m_known_by_count != 0, active object is not deleted, but static
265                 data is still updated.
266
267                 If force_delete is set, active object is deleted nevertheless. It
268                 shall only be set so in the destructor of the environment.
269         */
270         void deactivateFarObjects(bool force_delete);
271
272         /*
273                 Member variables
274         */
275         
276         // The map
277         ServerMap *m_map;
278         // Lua state
279         lua_State *m_lua;
280         // Game definition
281         IGameDef *m_gamedef;
282         // Active object list
283         core::map<u16, ServerActiveObject*> m_active_objects;
284         // Outgoing network message buffer for active objects
285         Queue<ActiveObjectMessage> m_active_object_messages;
286         // Some timers
287         float m_random_spawn_timer; // used for experimental code
288         float m_send_recommended_timer;
289         IntervalLimiter m_object_management_interval;
290         // List of active blocks
291         ActiveBlockList m_active_blocks;
292         IntervalLimiter m_active_blocks_management_interval;
293         IntervalLimiter m_active_blocks_test_interval;
294         IntervalLimiter m_active_blocks_nodemetadata_interval;
295         // Time from the beginning of the game in seconds.
296         // Incremented in step().
297         u32 m_game_time;
298         // A helper variable for incrementing the latter
299         float m_game_time_fraction_counter;
300 };
301
302 /*
303         Active block modifier interface.
304
305         These are fed into ServerEnvironment at initialization time;
306         ServerEnvironment handles deleting them.
307
308         NOTE: Not used currently (TODO: Use or remove)
309 */
310
311 class ActiveBlockModifier
312 {
313 public:
314         ActiveBlockModifier(){};
315         virtual ~ActiveBlockModifier(){};
316
317         //virtual core::list<u8> update(ServerEnvironment *env) = 0;
318         virtual u32 getTriggerContentCount(){ return 1;}
319         virtual u8 getTriggerContent(u32 i) = 0;
320         virtual float getActiveInterval() = 0;
321         // chance of (1 / return value), 0 is disallowed
322         virtual u32 getActiveChance() = 0;
323         // This is called usually at interval for 1/chance of the nodes
324         virtual void triggerEvent(ServerEnvironment *env, v3s16 p) = 0;
325 };
326
327 #ifndef SERVER
328
329 #include "clientobject.h"
330
331 /*
332         The client-side environment.
333
334         This is not thread-safe.
335         Must be called from main (irrlicht) thread (uses the SceneManager)
336         Client uses an environment mutex.
337 */
338
339 enum ClientEnvEventType
340 {
341         CEE_NONE,
342         CEE_PLAYER_DAMAGE
343 };
344
345 struct ClientEnvEvent
346 {
347         ClientEnvEventType type;
348         union {
349                 struct{
350                 } none;
351                 struct{
352                         u8 amount;
353                 } player_damage;
354         };
355 };
356
357 class ClientEnvironment : public Environment
358 {
359 public:
360         ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr,
361                         ITextureSource *texturesource, IGameDef *gamedef);
362         ~ClientEnvironment();
363
364         Map & getMap()
365         {
366                 return *m_map;
367         }
368
369         ClientMap & getClientMap()
370         {
371                 return *m_map;
372         }
373
374         void step(f32 dtime);
375
376         virtual void addPlayer(Player *player);
377         LocalPlayer * getLocalPlayer();
378         
379         // Slightly deprecated
380         void updateMeshes(v3s16 blockpos, ITextureSource *tsrc);
381         void expireMeshes(bool only_daynight_diffed);
382
383         void setTimeOfDay(u32 time)
384         {
385                 u32 old_dr = getDayNightRatio();
386
387                 Environment::setTimeOfDay(time);
388
389                 if(getDayNightRatio() != old_dr)
390                 {
391                         /*infostream<<"ClientEnvironment: DayNightRatio changed"
392                                         <<" -> expiring meshes"<<std::endl;*/
393                         expireMeshes(true);
394                 }
395         }
396
397         /*
398                 ActiveObjects
399         */
400         
401         ClientActiveObject* getActiveObject(u16 id);
402
403         /*
404                 Adds an active object to the environment.
405                 Environment handles deletion of object.
406                 Object may be deleted by environment immediately.
407                 If id of object is 0, assigns a free id to it.
408                 Returns the id of the object.
409                 Returns 0 if not added and thus deleted.
410         */
411         u16 addActiveObject(ClientActiveObject *object);
412
413         void addActiveObject(u16 id, u8 type, const std::string &init_data);
414         void removeActiveObject(u16 id);
415
416         void processActiveObjectMessage(u16 id, const std::string &data);
417
418         /*
419                 Callbacks for activeobjects
420         */
421
422         void damageLocalPlayer(u8 damage);
423
424         /*
425                 Client likes to call these
426         */
427         
428         // Get all nearby objects
429         void getActiveObjects(v3f origin, f32 max_d,
430                         core::array<DistanceSortedActiveObject> &dest);
431         
432         // Get event from queue. CEE_NONE is returned if queue is empty.
433         ClientEnvEvent getClientEvent();
434         
435 private:
436         ClientMap *m_map;
437         scene::ISceneManager *m_smgr;
438         ITextureSource *m_texturesource;
439         IGameDef *m_gamedef;
440         core::map<u16, ClientActiveObject*> m_active_objects;
441         Queue<ClientEnvEvent> m_client_event_queue;
442         IntervalLimiter m_active_object_light_update_interval;
443         IntervalLimiter m_lava_hurt_interval;
444 };
445
446 #endif
447
448 #endif
449