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