ServerRemotePlayer implements ServerActiveObject
[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         float getSendRecommendedInterval()
149         {
150                 return 0.10;
151         }
152
153         /*
154                 Save players
155         */
156         void serializePlayers(const std::string &savedir);
157         void deSerializePlayers(const std::string &savedir);
158
159         /*
160                 Save and load time of day and game timer
161         */
162         void saveMeta(const std::string &savedir);
163         void loadMeta(const std::string &savedir);
164
165         /*
166                 External ActiveObject interface
167                 -------------------------------------------
168         */
169
170         ServerActiveObject* getActiveObject(u16 id);
171
172         /*
173                 Add an active object to the environment.
174                 Environment handles deletion of object.
175                 Object may be deleted by environment immediately.
176                 If id of object is 0, assigns a free id to it.
177                 Returns the id of the object.
178                 Returns 0 if not added and thus deleted.
179         */
180         u16 addActiveObject(ServerActiveObject *object);
181         
182         /*
183                 Add an active object as a static object to the corresponding
184                 MapBlock.
185                 Caller allocates memory, ServerEnvironment frees memory.
186                 Return value: true if succeeded, false if failed.
187         */
188         bool addActiveObjectAsStatic(ServerActiveObject *object);
189         
190         /*
191                 Find out what new objects have been added to
192                 inside a radius around a position
193         */
194         void getAddedActiveObjects(v3s16 pos, s16 radius,
195                         core::map<u16, bool> &current_objects,
196                         core::map<u16, bool> &added_objects);
197
198         /*
199                 Find out what new objects have been removed from
200                 inside a radius around a position
201         */
202         void getRemovedActiveObjects(v3s16 pos, s16 radius,
203                         core::map<u16, bool> &current_objects,
204                         core::map<u16, bool> &removed_objects);
205         
206         /*
207                 Get the next message emitted by some active object.
208                 Returns a message with id=0 if no messages are available.
209         */
210         ActiveObjectMessage getActiveObjectMessage();
211
212         /*
213                 Activate objects and dynamically modify for the dtime determined
214                 from timestamp and additional_dtime
215         */
216         void activateBlock(MapBlock *block, u32 additional_dtime=0);
217
218         /*
219                 ActiveBlockModifiers (TODO)
220                 -------------------------------------------
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         // Active object list
281         core::map<u16, ServerActiveObject*> m_active_objects;
282         // Outgoing network message buffer for active objects
283         Queue<ActiveObjectMessage> m_active_object_messages;
284         // Some timers
285         float m_random_spawn_timer; // used for experimental code
286         float m_send_recommended_timer;
287         IntervalLimiter m_object_management_interval;
288         // List of active blocks
289         ActiveBlockList m_active_blocks;
290         IntervalLimiter m_active_blocks_management_interval;
291         IntervalLimiter m_active_blocks_test_interval;
292         IntervalLimiter m_active_blocks_nodemetadata_interval;
293         // Time from the beginning of the game in seconds.
294         // Incremented in step().
295         u32 m_game_time;
296         // A helper variable for incrementing the latter
297         float m_game_time_fraction_counter;
298 };
299
300 /*
301         Active block modifier interface.
302
303         These are fed into ServerEnvironment at initialization time;
304         ServerEnvironment handles deleting them.
305 */
306
307 class ActiveBlockModifier
308 {
309 public:
310         ActiveBlockModifier(){};
311         virtual ~ActiveBlockModifier(){};
312
313         //virtual core::list<u8> update(ServerEnvironment *env) = 0;
314         virtual u32 getTriggerContentCount(){ return 1;}
315         virtual u8 getTriggerContent(u32 i) = 0;
316         virtual float getActiveInterval() = 0;
317         // chance of (1 / return value), 0 is disallowed
318         virtual u32 getActiveChance() = 0;
319         // This is called usually at interval for 1/chance of the nodes
320         virtual void triggerEvent(ServerEnvironment *env, v3s16 p) = 0;
321 };
322
323 #ifndef SERVER
324
325 #include "clientobject.h"
326
327 /*
328         The client-side environment.
329
330         This is not thread-safe.
331         Must be called from main (irrlicht) thread (uses the SceneManager)
332         Client uses an environment mutex.
333 */
334
335 enum ClientEnvEventType
336 {
337         CEE_NONE,
338         CEE_PLAYER_DAMAGE
339 };
340
341 struct ClientEnvEvent
342 {
343         ClientEnvEventType type;
344         union {
345                 struct{
346                 } none;
347                 struct{
348                         u8 amount;
349                 } player_damage;
350         };
351 };
352
353 class ClientEnvironment : public Environment
354 {
355 public:
356         ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr);
357         ~ClientEnvironment();
358
359         Map & getMap()
360         {
361                 return *m_map;
362         }
363
364         ClientMap & getClientMap()
365         {
366                 return *m_map;
367         }
368
369         void step(f32 dtime);
370
371         virtual void addPlayer(Player *player);
372         LocalPlayer * getLocalPlayer();
373
374         void updateMeshes(v3s16 blockpos);
375         void expireMeshes(bool only_daynight_diffed);
376
377         void setTimeOfDay(u32 time)
378         {
379                 u32 old_dr = getDayNightRatio();
380
381                 Environment::setTimeOfDay(time);
382
383                 if(getDayNightRatio() != old_dr)
384                 {
385                         dout_client<<DTIME<<"ClientEnvironment: DayNightRatio changed"
386                                         <<" -> expiring meshes"<<std::endl;
387                         expireMeshes(true);
388                 }
389         }
390
391         /*
392                 ActiveObjects
393         */
394         
395         ClientActiveObject* getActiveObject(u16 id);
396
397         /*
398                 Adds an active object to the environment.
399                 Environment handles deletion of object.
400                 Object may be deleted by environment immediately.
401                 If id of object is 0, assigns a free id to it.
402                 Returns the id of the object.
403                 Returns 0 if not added and thus deleted.
404         */
405         u16 addActiveObject(ClientActiveObject *object);
406
407         void addActiveObject(u16 id, u8 type, const std::string &init_data);
408         void removeActiveObject(u16 id);
409
410         void processActiveObjectMessage(u16 id, const std::string &data);
411
412         /*
413                 Callbacks for activeobjects
414         */
415
416         void damageLocalPlayer(u8 damage);
417
418         /*
419                 Client likes to call these
420         */
421         
422         // Get all nearby objects
423         void getActiveObjects(v3f origin, f32 max_d,
424                         core::array<DistanceSortedActiveObject> &dest);
425         
426         // Get event from queue. CEE_NONE is returned if queue is empty.
427         ClientEnvEvent getClientEvent();
428         
429 private:
430         ClientMap *m_map;
431         scene::ISceneManager *m_smgr;
432         core::map<u16, ClientActiveObject*> m_active_objects;
433         Queue<ClientEnvEvent> m_client_event_queue;
434         IntervalLimiter m_active_object_light_update_interval;
435         IntervalLimiter m_lava_hurt_interval;
436 };
437
438 #endif
439
440 #endif
441