]> git.lizzy.rs Git - dragonfireclient.git/blob - src/utility.h
Move ClientMap to clientmap.{h,cpp}
[dragonfireclient.git] / src / utility.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 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 UTILITY_HEADER
21 #define UTILITY_HEADER
22
23 #include <iostream>
24 #include <fstream>
25 #include <string>
26 #include <sstream>
27 #include <vector>
28 #include <jthread.h>
29 #include <jmutex.h>
30 #include <jmutexautolock.h>
31 #include <cstring>
32
33 #include "common_irrlicht.h"
34 #include "debug.h"
35 #include "exceptions.h"
36 #include "porting.h"
37 #include "strfnd.h" // For trim()
38
39 extern const v3s16 g_6dirs[6];
40
41 extern const v3s16 g_26dirs[26];
42
43 // 26th is (0,0,0)
44 extern const v3s16 g_27dirs[27];
45
46 inline void writeU64(u8 *data, u64 i)
47 {
48         data[0] = ((i>>56)&0xff);
49         data[1] = ((i>>48)&0xff);
50         data[2] = ((i>>40)&0xff);
51         data[3] = ((i>>32)&0xff);
52         data[4] = ((i>>24)&0xff);
53         data[5] = ((i>>16)&0xff);
54         data[6] = ((i>> 8)&0xff);
55         data[7] = ((i>> 0)&0xff);
56 }
57
58 inline void writeU32(u8 *data, u32 i)
59 {
60         data[0] = ((i>>24)&0xff);
61         data[1] = ((i>>16)&0xff);
62         data[2] = ((i>> 8)&0xff);
63         data[3] = ((i>> 0)&0xff);
64 }
65
66 inline void writeU16(u8 *data, u16 i)
67 {
68         data[0] = ((i>> 8)&0xff);
69         data[1] = ((i>> 0)&0xff);
70 }
71
72 inline void writeU8(u8 *data, u8 i)
73 {
74         data[0] = ((i>> 0)&0xff);
75 }
76
77 inline u64 readU64(u8 *data)
78 {
79         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
80                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
81                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
82                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
83 }
84
85 inline u32 readU32(u8 *data)
86 {
87         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
88 }
89
90 inline u16 readU16(u8 *data)
91 {
92         return (data[0]<<8) | (data[1]<<0);
93 }
94
95 inline u8 readU8(u8 *data)
96 {
97         return (data[0]<<0);
98 }
99
100 inline void writeS32(u8 *data, s32 i){
101         writeU32(data, (u32)i);
102 }
103 inline s32 readS32(u8 *data){
104         return (s32)readU32(data);
105 }
106
107 inline void writeS16(u8 *data, s16 i){
108         writeU16(data, (u16)i);
109 }
110 inline s16 readS16(u8 *data){
111         return (s16)readU16(data);
112 }
113
114 inline void writeS8(u8 *data, s8 i){
115         writeU8(data, (u8)i);
116 }
117 inline s8 readS8(u8 *data){
118         return (s8)readU8(data);
119 }
120
121 inline void writeF1000(u8 *data, f32 i){
122         writeS32(data, i*1000);
123 }
124 inline f32 readF1000(u8 *data){
125         return (f32)readS32(data)/1000.;
126 }
127
128 inline void writeV3S32(u8 *data, v3s32 p)
129 {
130         writeS32(&data[0], p.X);
131         writeS32(&data[4], p.Y);
132         writeS32(&data[8], p.Z);
133 }
134 inline v3s32 readV3S32(u8 *data)
135 {
136         v3s32 p;
137         p.X = readS32(&data[0]);
138         p.Y = readS32(&data[4]);
139         p.Z = readS32(&data[8]);
140         return p;
141 }
142
143 inline void writeV3F1000(u8 *data, v3f p)
144 {
145         writeF1000(&data[0], p.X);
146         writeF1000(&data[4], p.Y);
147         writeF1000(&data[8], p.Z);
148 }
149 inline v3f readV3F1000(u8 *data)
150 {
151         v3f p;
152         p.X = (float)readF1000(&data[0]);
153         p.Y = (float)readF1000(&data[4]);
154         p.Z = (float)readF1000(&data[8]);
155         return p;
156 }
157
158 inline void writeV2F1000(u8 *data, v2f p)
159 {
160         writeF1000(&data[0], p.X);
161         writeF1000(&data[4], p.Y);
162 }
163 inline v2f readV2F1000(u8 *data)
164 {
165         v2f p;
166         p.X = (float)readF1000(&data[0]);
167         p.Y = (float)readF1000(&data[4]);
168         return p;
169 }
170
171 inline void writeV2S16(u8 *data, v2s16 p)
172 {
173         writeS16(&data[0], p.X);
174         writeS16(&data[2], p.Y);
175 }
176
177 inline v2s16 readV2S16(u8 *data)
178 {
179         v2s16 p;
180         p.X = readS16(&data[0]);
181         p.Y = readS16(&data[2]);
182         return p;
183 }
184
185 inline void writeV2S32(u8 *data, v2s32 p)
186 {
187         writeS32(&data[0], p.X);
188         writeS32(&data[2], p.Y);
189 }
190
191 inline v2s32 readV2S32(u8 *data)
192 {
193         v2s32 p;
194         p.X = readS32(&data[0]);
195         p.Y = readS32(&data[2]);
196         return p;
197 }
198
199 inline void writeV3S16(u8 *data, v3s16 p)
200 {
201         writeS16(&data[0], p.X);
202         writeS16(&data[2], p.Y);
203         writeS16(&data[4], p.Z);
204 }
205
206 inline v3s16 readV3S16(u8 *data)
207 {
208         v3s16 p;
209         p.X = readS16(&data[0]);
210         p.Y = readS16(&data[2]);
211         p.Z = readS16(&data[4]);
212         return p;
213 }
214
215 /*
216         The above stuff directly interfaced to iostream
217 */
218
219 inline void writeU8(std::ostream &os, u8 p)
220 {
221         char buf[1];
222         writeU8((u8*)buf, p);
223         os.write(buf, 1);
224 }
225 inline u8 readU8(std::istream &is)
226 {
227         char buf[1];
228         is.read(buf, 1);
229         return readU8((u8*)buf);
230 }
231
232 inline void writeU16(std::ostream &os, u16 p)
233 {
234         char buf[2];
235         writeU16((u8*)buf, p);
236         os.write(buf, 2);
237 }
238 inline u16 readU16(std::istream &is)
239 {
240         char buf[2];
241         is.read(buf, 2);
242         return readU16((u8*)buf);
243 }
244
245 inline void writeU32(std::ostream &os, u32 p)
246 {
247         char buf[4];
248         writeU32((u8*)buf, p);
249         os.write(buf, 4);
250 }
251 inline u32 readU32(std::istream &is)
252 {
253         char buf[4];
254         is.read(buf, 4);
255         return readU32((u8*)buf);
256 }
257
258 inline void writeS32(std::ostream &os, s32 p)
259 {
260         char buf[4];
261         writeS32((u8*)buf, p);
262         os.write(buf, 4);
263 }
264 inline s32 readS32(std::istream &is)
265 {
266         char buf[4];
267         is.read(buf, 4);
268         return readS32((u8*)buf);
269 }
270
271 inline void writeS16(std::ostream &os, s16 p)
272 {
273         char buf[2];
274         writeS16((u8*)buf, p);
275         os.write(buf, 2);
276 }
277 inline s16 readS16(std::istream &is)
278 {
279         char buf[2];
280         is.read(buf, 2);
281         return readS16((u8*)buf);
282 }
283
284 inline void writeS8(std::ostream &os, s8 p)
285 {
286         char buf[1];
287         writeS8((u8*)buf, p);
288         os.write(buf, 1);
289 }
290 inline s8 readS8(std::istream &is)
291 {
292         char buf[1];
293         is.read(buf, 1);
294         return readS8((u8*)buf);
295 }
296
297 inline void writeF1000(std::ostream &os, f32 p)
298 {
299         char buf[4];
300         writeF1000((u8*)buf, p);
301         os.write(buf, 4);
302 }
303 inline f32 readF1000(std::istream &is)
304 {
305         char buf[4];
306         is.read(buf, 4);
307         return readF1000((u8*)buf);
308 }
309
310 inline void writeV3F1000(std::ostream &os, v3f p)
311 {
312         char buf[12];
313         writeV3F1000((u8*)buf, p);
314         os.write(buf, 12);
315 }
316 inline v3f readV3F1000(std::istream &is)
317 {
318         char buf[12];
319         is.read(buf, 12);
320         return readV3F1000((u8*)buf);
321 }
322
323 inline void writeV2F1000(std::ostream &os, v2f p)
324 {
325         char buf[8];
326         writeV2F1000((u8*)buf, p);
327         os.write(buf, 8);
328 }
329 inline v2f readV2F1000(std::istream &is)
330 {
331         char buf[8];
332         is.read(buf, 8);
333         return readV2F1000((u8*)buf);
334 }
335
336 inline void writeV2S16(std::ostream &os, v2s16 p)
337 {
338         char buf[4];
339         writeV2S16((u8*)buf, p);
340         os.write(buf, 4);
341 }
342 inline v2s16 readV2S16(std::istream &is)
343 {
344         char buf[4];
345         is.read(buf, 4);
346         return readV2S16((u8*)buf);
347 }
348
349 inline void writeV3S16(std::ostream &os, v3s16 p)
350 {
351         char buf[6];
352         writeV3S16((u8*)buf, p);
353         os.write(buf, 6);
354 }
355 inline v3s16 readV3S16(std::istream &is)
356 {
357         char buf[6];
358         is.read(buf, 6);
359         return readV3S16((u8*)buf);
360 }
361
362 /*
363         None of these are used at the moment
364 */
365
366 template <typename T>
367 class SharedPtr
368 {
369 public:
370         SharedPtr(T *t=NULL)
371         {
372                 refcount = new int;
373                 *refcount = 1;
374                 ptr = t;
375         }
376         SharedPtr(SharedPtr<T> &t)
377         {
378                 //*this = t;
379                 drop();
380                 refcount = t.refcount;
381                 (*refcount)++;
382                 ptr = t.ptr;
383         }
384         ~SharedPtr()
385         {
386                 drop();
387         }
388         SharedPtr<T> & operator=(T *t)
389         {
390                 drop();
391                 refcount = new int;
392                 *refcount = 1;
393                 ptr = t;
394                 return *this;
395         }
396         SharedPtr<T> & operator=(SharedPtr<T> &t)
397         {
398                 drop();
399                 refcount = t.refcount;
400                 (*refcount)++;
401                 ptr = t.ptr;
402                 return *this;
403         }
404         T* operator->()
405         {
406                 return ptr;
407         }
408         T & operator*()
409         {
410                 return *ptr;
411         }
412         bool operator!=(T *t)
413         {
414                 return ptr != t;
415         }
416         bool operator==(T *t)
417         {
418                 return ptr == t;
419         }
420         T & operator[](unsigned int i)
421         {
422                 return ptr[i];
423         }
424 private:
425         void drop()
426         {
427                 assert((*refcount) > 0);
428                 (*refcount)--;
429                 if(*refcount == 0)
430                 {
431                         delete refcount;
432                         if(ptr != NULL)
433                                 delete ptr;
434                 }
435         }
436         T *ptr;
437         int *refcount;
438 };
439
440 template <typename T>
441 class Buffer
442 {
443 public:
444         Buffer()
445         {
446                 m_size = 0;
447                 data = NULL;
448         }
449         Buffer(unsigned int size)
450         {
451                 m_size = size;
452                 if(size != 0)
453                         data = new T[size];
454                 else
455                         data = NULL;
456         }
457         Buffer(const Buffer &buffer)
458         {
459                 m_size = buffer.m_size;
460                 if(m_size != 0)
461                 {
462                         data = new T[buffer.m_size];
463                         memcpy(data, buffer.data, buffer.m_size);
464                 }
465                 else
466                         data = NULL;
467         }
468         Buffer(const T *t, unsigned int size)
469         {
470                 m_size = size;
471                 if(size != 0)
472                 {
473                         data = new T[size];
474                         memcpy(data, t, size);
475                 }
476                 else
477                         data = NULL;
478         }
479         ~Buffer()
480         {
481                 drop();
482         }
483         Buffer& operator=(const Buffer &buffer)
484         {
485                 if(this == &buffer)
486                         return *this;
487                 drop();
488                 m_size = buffer.m_size;
489                 if(m_size != 0)
490                 {
491                         data = new T[buffer.m_size];
492                         memcpy(data, buffer.data, buffer.m_size);
493                 }
494                 else
495                         data = NULL;
496                 return *this;
497         }
498         T & operator[](unsigned int i) const
499         {
500                 return data[i];
501         }
502         T * operator*() const
503         {
504                 return data;
505         }
506         unsigned int getSize() const
507         {
508                 return m_size;
509         }
510 private:
511         void drop()
512         {
513                 if(data)
514                         delete[] data;
515         }
516         T *data;
517         unsigned int m_size;
518 };
519
520 template <typename T>
521 class SharedBuffer
522 {
523 public:
524         SharedBuffer()
525         {
526                 m_size = 0;
527                 data = NULL;
528                 refcount = new unsigned int;
529                 (*refcount) = 1;
530         }
531         SharedBuffer(unsigned int size)
532         {
533                 m_size = size;
534                 if(m_size != 0)
535                         data = new T[m_size];
536                 else
537                         data = NULL;
538                 refcount = new unsigned int;
539                 (*refcount) = 1;
540         }
541         SharedBuffer(const SharedBuffer &buffer)
542         {
543                 //std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
544                 m_size = buffer.m_size;
545                 data = buffer.data;
546                 refcount = buffer.refcount;
547                 (*refcount)++;
548         }
549         SharedBuffer & operator=(const SharedBuffer & buffer)
550         {
551                 //std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
552                 if(this == &buffer)
553                         return *this;
554                 drop();
555                 m_size = buffer.m_size;
556                 data = buffer.data;
557                 refcount = buffer.refcount;
558                 (*refcount)++;
559                 return *this;
560         }
561         /*
562                 Copies whole buffer
563         */
564         SharedBuffer(T *t, unsigned int size)
565         {
566                 m_size = size;
567                 if(m_size != 0)
568                 {
569                         data = new T[m_size];
570                         memcpy(data, t, m_size);
571                 }
572                 else
573                         data = NULL;
574                 refcount = new unsigned int;
575                 (*refcount) = 1;
576         }
577         /*
578                 Copies whole buffer
579         */
580         SharedBuffer(const Buffer<T> &buffer)
581         {
582                 m_size = buffer.getSize();
583                 if(m_size != 0)
584                 {
585                         data = new T[m_size];
586                         memcpy(data, *buffer, buffer.getSize());
587                 }
588                 else
589                         data = NULL;
590                 refcount = new unsigned int;
591                 (*refcount) = 1;
592         }
593         ~SharedBuffer()
594         {
595                 drop();
596         }
597         T & operator[](unsigned int i) const
598         {
599                 //assert(i < m_size)
600                 return data[i];
601         }
602         T * operator*() const
603         {
604                 return data;
605         }
606         unsigned int getSize() const
607         {
608                 return m_size;
609         }
610         operator Buffer<T>() const
611         {
612                 return Buffer<T>(data, m_size);
613         }
614 private:
615         void drop()
616         {
617                 assert((*refcount) > 0);
618                 (*refcount)--;
619                 if(*refcount == 0)
620                 {
621                         if(data)
622                                 delete[] data;
623                         delete refcount;
624                 }
625         }
626         T *data;
627         unsigned int m_size;
628         unsigned int *refcount;
629 };
630
631 inline SharedBuffer<u8> SharedBufferFromString(const char *string)
632 {
633         SharedBuffer<u8> b((u8*)string, strlen(string)+1);
634         return b;
635 }
636
637 template<typename T>
638 class MutexedVariable
639 {
640 public:
641         MutexedVariable(T value):
642                 m_value(value)
643         {
644                 m_mutex.Init();
645         }
646
647         T get()
648         {
649                 JMutexAutoLock lock(m_mutex);
650                 return m_value;
651         }
652
653         void set(T value)
654         {
655                 JMutexAutoLock lock(m_mutex);
656                 m_value = value;
657         }
658         
659         // You'll want to grab this in a SharedPtr
660         JMutexAutoLock * getLock()
661         {
662                 return new JMutexAutoLock(m_mutex);
663         }
664         
665         // You pretty surely want to grab the lock when accessing this
666         T m_value;
667
668 private:
669         JMutex m_mutex;
670 };
671
672 /*
673         TimeTaker
674 */
675
676 class TimeTaker
677 {
678 public:
679         TimeTaker(const char *name, u32 *result=NULL);
680
681         ~TimeTaker()
682         {
683                 stop();
684         }
685
686         u32 stop(bool quiet=false);
687
688         u32 getTime();
689
690 private:
691         const char *m_name;
692         u32 m_time1;
693         bool m_running;
694         u32 *m_result;
695 };
696
697 // Tests if two strings are equal, optionally case insensitive
698 inline bool str_equal(const std::wstring& s1, const std::wstring& s2,
699                 bool case_insensitive = false)
700 {
701         if(case_insensitive)
702         {
703                 if(s1.size() != s2.size())
704                         return false;
705                 for(size_t i = 0; i < s1.size(); ++i)
706                         if(tolower(s1[i]) != tolower(s2[i]))
707                                 return false;
708                 return true;
709         }
710         else
711         {
712                 return s1 == s2;
713         }
714 }
715
716 // Tests if the second string is a prefix of the first, optionally case insensitive
717 inline bool str_starts_with(const std::wstring& str, const std::wstring& prefix,
718                 bool case_insensitive = false)
719 {
720         if(str.size() < prefix.size())
721                 return false;
722         if(case_insensitive)
723         {
724                 for(size_t i = 0; i < prefix.size(); ++i)
725                         if(tolower(str[i]) != tolower(prefix[i]))
726                                 return false;
727         }
728         else
729         {
730                 for(size_t i = 0; i < prefix.size(); ++i)
731                         if(str[i] != prefix[i])
732                                 return false;
733         }
734         return true;
735 }
736
737 // Calculates the borders of a "d-radius" cube
738 inline void getFacePositions(core::list<v3s16> &list, u16 d)
739 {
740         if(d == 0)
741         {
742                 list.push_back(v3s16(0,0,0));
743                 return;
744         }
745         if(d == 1)
746         {
747                 /*
748                         This is an optimized sequence of coordinates.
749                 */
750                 list.push_back(v3s16( 0, 1, 0)); // top
751                 list.push_back(v3s16( 0, 0, 1)); // back
752                 list.push_back(v3s16(-1, 0, 0)); // left
753                 list.push_back(v3s16( 1, 0, 0)); // right
754                 list.push_back(v3s16( 0, 0,-1)); // front
755                 list.push_back(v3s16( 0,-1, 0)); // bottom
756                 // 6
757                 list.push_back(v3s16(-1, 0, 1)); // back left
758                 list.push_back(v3s16( 1, 0, 1)); // back right
759                 list.push_back(v3s16(-1, 0,-1)); // front left
760                 list.push_back(v3s16( 1, 0,-1)); // front right
761                 list.push_back(v3s16(-1,-1, 0)); // bottom left
762                 list.push_back(v3s16( 1,-1, 0)); // bottom right
763                 list.push_back(v3s16( 0,-1, 1)); // bottom back
764                 list.push_back(v3s16( 0,-1,-1)); // bottom front
765                 list.push_back(v3s16(-1, 1, 0)); // top left
766                 list.push_back(v3s16( 1, 1, 0)); // top right
767                 list.push_back(v3s16( 0, 1, 1)); // top back
768                 list.push_back(v3s16( 0, 1,-1)); // top front
769                 // 18
770                 list.push_back(v3s16(-1, 1, 1)); // top back-left
771                 list.push_back(v3s16( 1, 1, 1)); // top back-right
772                 list.push_back(v3s16(-1, 1,-1)); // top front-left
773                 list.push_back(v3s16( 1, 1,-1)); // top front-right
774                 list.push_back(v3s16(-1,-1, 1)); // bottom back-left
775                 list.push_back(v3s16( 1,-1, 1)); // bottom back-right
776                 list.push_back(v3s16(-1,-1,-1)); // bottom front-left
777                 list.push_back(v3s16( 1,-1,-1)); // bottom front-right
778                 // 26
779                 return;
780         }
781
782         // Take blocks in all sides, starting from y=0 and going +-y
783         for(s16 y=0; y<=d-1; y++)
784         {
785                 // Left and right side, including borders
786                 for(s16 z=-d; z<=d; z++)
787                 {
788                         list.push_back(v3s16(d,y,z));
789                         list.push_back(v3s16(-d,y,z));
790                         if(y != 0)
791                         {
792                                 list.push_back(v3s16(d,-y,z));
793                                 list.push_back(v3s16(-d,-y,z));
794                         }
795                 }
796                 // Back and front side, excluding borders
797                 for(s16 x=-d+1; x<=d-1; x++)
798                 {
799                         list.push_back(v3s16(x,y,d));
800                         list.push_back(v3s16(x,y,-d));
801                         if(y != 0)
802                         {
803                                 list.push_back(v3s16(x,-y,d));
804                                 list.push_back(v3s16(x,-y,-d));
805                         }
806                 }
807         }
808
809         // Take the bottom and top face with borders
810         // -d<x<d, y=+-d, -d<z<d
811         for(s16 x=-d; x<=d; x++)
812         for(s16 z=-d; z<=d; z++)
813         {
814                 list.push_back(v3s16(x,-d,z));
815                 list.push_back(v3s16(x,d,z));
816         }
817 }
818
819 class IndentationRaiser
820 {
821 public:
822         IndentationRaiser(u16 *indentation)
823         {
824                 m_indentation = indentation;
825                 (*m_indentation)++;
826         }
827         ~IndentationRaiser()
828         {
829                 (*m_indentation)--;
830         }
831 private:
832         u16 *m_indentation;
833 };
834
835 inline s16 getContainerPos(s16 p, s16 d)
836 {
837         return (p>=0 ? p : p-d+1) / d;
838 }
839
840 inline v2s16 getContainerPos(v2s16 p, s16 d)
841 {
842         return v2s16(
843                 getContainerPos(p.X, d),
844                 getContainerPos(p.Y, d)
845         );
846 }
847
848 inline v3s16 getContainerPos(v3s16 p, s16 d)
849 {
850         return v3s16(
851                 getContainerPos(p.X, d),
852                 getContainerPos(p.Y, d),
853                 getContainerPos(p.Z, d)
854         );
855 }
856
857 inline v2s16 getContainerPos(v2s16 p, v2s16 d)
858 {
859         return v2s16(
860                 getContainerPos(p.X, d.X),
861                 getContainerPos(p.Y, d.Y)
862         );
863 }
864
865 inline v3s16 getContainerPos(v3s16 p, v3s16 d)
866 {
867         return v3s16(
868                 getContainerPos(p.X, d.X),
869                 getContainerPos(p.Y, d.Y),
870                 getContainerPos(p.Z, d.Z)
871         );
872 }
873
874 inline bool isInArea(v3s16 p, s16 d)
875 {
876         return (
877                 p.X >= 0 && p.X < d &&
878                 p.Y >= 0 && p.Y < d &&
879                 p.Z >= 0 && p.Z < d
880         );
881 }
882
883 inline bool isInArea(v2s16 p, s16 d)
884 {
885         return (
886                 p.X >= 0 && p.X < d &&
887                 p.Y >= 0 && p.Y < d
888         );
889 }
890
891 inline bool isInArea(v3s16 p, v3s16 d)
892 {
893         return (
894                 p.X >= 0 && p.X < d.X &&
895                 p.Y >= 0 && p.Y < d.Y &&
896                 p.Z >= 0 && p.Z < d.Z
897         );
898 }
899
900 inline s16 rangelim(s16 i, s16 max)
901 {
902         if(i < 0)
903                 return 0;
904         if(i > max)
905                 return max;
906         return i;
907 }
908
909 #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d)>(max)?(max):(d)))
910
911 inline v3s16 arealim(v3s16 p, s16 d)
912 {
913         if(p.X < 0)
914                 p.X = 0;
915         if(p.Y < 0)
916                 p.Y = 0;
917         if(p.Z < 0)
918                 p.Z = 0;
919         if(p.X > d-1)
920                 p.X = d-1;
921         if(p.Y > d-1)
922                 p.Y = d-1;
923         if(p.Z > d-1)
924                 p.Z = d-1;
925         return p;
926 }
927
928 inline std::wstring narrow_to_wide(const std::string& mbs)
929 {
930         size_t wcl = mbs.size();
931         Buffer<wchar_t> wcs(wcl+1);
932         size_t l = mbstowcs(*wcs, mbs.c_str(), wcl);
933         if(l == (size_t)(-1))
934                 return L"<invalid multibyte string>";
935         wcs[l] = 0;
936         return *wcs;
937 }
938
939 inline std::string wide_to_narrow(const std::wstring& wcs)
940 {
941         size_t mbl = wcs.size()*4;
942         SharedBuffer<char> mbs(mbl+1);
943         size_t l = wcstombs(*mbs, wcs.c_str(), mbl);
944         if(l == (size_t)(-1))
945                 mbs[0] = 0;
946         else
947                 mbs[l] = 0;
948         return *mbs;
949 }
950
951 // Split a string using the given delimiter. Returns a vector containing
952 // the component parts.
953 inline std::vector<std::wstring> str_split(const std::wstring &str, wchar_t delimiter)
954 {
955         std::vector<std::wstring> parts;
956         std::wstringstream sstr(str);
957         std::wstring part;
958         while(std::getline(sstr, part, delimiter))
959                 parts.push_back(part);
960         return parts;
961 }
962
963
964 /*
965         See test.cpp for example cases.
966         wraps degrees to the range of -360...360
967         NOTE: Wrapping to 0...360 is not used because pitch needs negative values.
968 */
969 inline float wrapDegrees(float f)
970 {
971         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
972         // This results in
973         // 10, 720, -1, -361
974         int i = floor(f);
975         // 0, 2, 0, -1
976         int l = i / 360;
977         // NOTE: This would be used for wrapping to 0...360
978         // 0, 2, -1, -2
979         /*if(i < 0)
980                 l -= 1;*/
981         // 0, 720, 0, -360
982         int k = l * 360;
983         // 10, 0.5, -0.5, -0.5
984         f -= float(k);
985         return f;
986 }
987
988 /* Wrap to 0...360 */
989 inline float wrapDegrees_0_360(float f)
990 {
991         // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
992         // This results in
993         // 10, 720, -1, -361
994         int i = floor(f);
995         // 0, 2, 0, -1
996         int l = i / 360;
997         // Wrap to 0...360
998         // 0, 2, -1, -2
999         if(i < 0)
1000                 l -= 1;
1001         // 0, 720, 0, -360
1002         int k = l * 360;
1003         // 10, 0.5, -0.5, -0.5
1004         f -= float(k);
1005         return f;
1006 }
1007
1008 /* Wrap to -180...180 */
1009 inline float wrapDegrees_180(float f)
1010 {
1011         f += 180;
1012         f = wrapDegrees_0_360(f);
1013         f -= 180;
1014         return f;
1015 }
1016
1017 inline std::string lowercase(const std::string &s)
1018 {
1019         std::string s2;
1020         for(size_t i=0; i<s.size(); i++)
1021         {
1022                 char c = s[i];
1023                 if(c >= 'A' && c <= 'Z')
1024                         c -= 'A' - 'a';
1025                 s2 += c;
1026         }
1027         return s2;
1028 }
1029
1030 inline bool is_yes(const std::string &s)
1031 {
1032         std::string s2 = lowercase(trim(s));
1033         if(s2 == "y" || s2 == "yes" || s2 == "true" || s2 == "1")
1034                 return true;
1035         return false;
1036 }
1037
1038 inline s32 mystoi(const std::string &s, s32 min, s32 max)
1039 {
1040         s32 i = atoi(s.c_str());
1041         if(i < min)
1042                 i = min;
1043         if(i > max)
1044                 i = max;
1045         return i;
1046 }
1047
1048
1049 // MSVC2010 includes it's own versions of these
1050 //#if !defined(_MSC_VER) || _MSC_VER < 1600
1051
1052 inline s32 mystoi(std::string s)
1053 {
1054         return atoi(s.c_str());
1055 }
1056
1057 inline s32 mystoi(std::wstring s)
1058 {
1059         return atoi(wide_to_narrow(s).c_str());
1060 }
1061
1062 inline float mystof(std::string s)
1063 {
1064         float f;
1065         std::istringstream ss(s);
1066         ss>>f;
1067         return f;
1068 }
1069
1070 //#endif
1071
1072 #define stoi mystoi
1073 #define stof mystof
1074
1075 inline std::string itos(s32 i)
1076 {
1077         std::ostringstream o;
1078         o<<i;
1079         return o.str();
1080 }
1081
1082 inline std::string ftos(float f)
1083 {
1084         std::ostringstream o;
1085         o<<f;
1086         return o.str();
1087 }
1088
1089 inline void str_replace(std::string & str, std::string const & pattern,
1090                 std::string const & replacement)
1091 {
1092         std::string::size_type start = str.find(pattern, 0);
1093         while(start != str.npos)
1094         {
1095                 str.replace(start, pattern.size(), replacement);
1096                 start = str.find(pattern, start+replacement.size());
1097         }
1098 }
1099
1100 inline void str_replace_char(std::string & str, char from, char to)
1101 {
1102         for(unsigned int i=0; i<str.size(); i++)
1103         {
1104                 if(str[i] == from)
1105                         str[i] = to;
1106         }
1107 }
1108
1109 /*
1110         A base class for simple background thread implementation
1111 */
1112
1113 class SimpleThread : public JThread
1114 {
1115         bool run;
1116         JMutex run_mutex;
1117
1118 public:
1119
1120         SimpleThread():
1121                 JThread(),
1122                 run(true)
1123         {
1124                 run_mutex.Init();
1125         }
1126
1127         virtual ~SimpleThread()
1128         {}
1129
1130         virtual void * Thread() = 0;
1131
1132         bool getRun()
1133         {
1134                 JMutexAutoLock lock(run_mutex);
1135                 return run;
1136         }
1137         void setRun(bool a_run)
1138         {
1139                 JMutexAutoLock lock(run_mutex);
1140                 run = a_run;
1141         }
1142
1143         void stop()
1144         {
1145                 setRun(false);
1146                 while(IsRunning())
1147                         sleep_ms(100);
1148         }
1149 };
1150
1151 /*
1152         FIFO queue (well, actually a FILO also)
1153 */
1154 template<typename T>
1155 class Queue
1156 {
1157 public:
1158         void push_back(T t)
1159         {
1160                 m_list.push_back(t);
1161         }
1162         
1163         T pop_front()
1164         {
1165                 if(m_list.size() == 0)
1166                         throw ItemNotFoundException("Queue: queue is empty");
1167
1168                 typename core::list<T>::Iterator begin = m_list.begin();
1169                 T t = *begin;
1170                 m_list.erase(begin);
1171                 return t;
1172         }
1173         T pop_back()
1174         {
1175                 if(m_list.size() == 0)
1176                         throw ItemNotFoundException("Queue: queue is empty");
1177
1178                 typename core::list<T>::Iterator last = m_list.getLast();
1179                 T t = *last;
1180                 m_list.erase(last);
1181                 return t;
1182         }
1183
1184         u32 size()
1185         {
1186                 return m_list.size();
1187         }
1188
1189 protected:
1190         core::list<T> m_list;
1191 };
1192
1193 /*
1194         Thread-safe FIFO queue (well, actually a FILO also)
1195 */
1196
1197 template<typename T>
1198 class MutexedQueue
1199 {
1200 public:
1201         MutexedQueue()
1202         {
1203                 m_mutex.Init();
1204         }
1205         u32 size()
1206         {
1207                 JMutexAutoLock lock(m_mutex);
1208                 return m_list.size();
1209         }
1210         void push_back(T t)
1211         {
1212                 JMutexAutoLock lock(m_mutex);
1213                 m_list.push_back(t);
1214         }
1215         T pop_front(u32 wait_time_max_ms=0)
1216         {
1217                 u32 wait_time_ms = 0;
1218
1219                 for(;;)
1220                 {
1221                         {
1222                                 JMutexAutoLock lock(m_mutex);
1223
1224                                 if(m_list.size() > 0)
1225                                 {
1226                                         typename core::list<T>::Iterator begin = m_list.begin();
1227                                         T t = *begin;
1228                                         m_list.erase(begin);
1229                                         return t;
1230                                 }
1231
1232                                 if(wait_time_ms >= wait_time_max_ms)
1233                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1234                         }
1235
1236                         // Wait a while before trying again
1237                         sleep_ms(10);
1238                         wait_time_ms += 10;
1239                 }
1240         }
1241         T pop_back(u32 wait_time_max_ms=0)
1242         {
1243                 u32 wait_time_ms = 0;
1244
1245                 for(;;)
1246                 {
1247                         {
1248                                 JMutexAutoLock lock(m_mutex);
1249
1250                                 if(m_list.size() > 0)
1251                                 {
1252                                         typename core::list<T>::Iterator last = m_list.getLast();
1253                                         T t = *last;
1254                                         m_list.erase(last);
1255                                         return t;
1256                                 }
1257
1258                                 if(wait_time_ms >= wait_time_max_ms)
1259                                         throw ItemNotFoundException("MutexedQueue: queue is empty");
1260                         }
1261
1262                         // Wait a while before trying again
1263                         sleep_ms(10);
1264                         wait_time_ms += 10;
1265                 }
1266         }
1267
1268         JMutex & getMutex()
1269         {
1270                 return m_mutex;
1271         }
1272
1273         core::list<T> & getList()
1274         {
1275                 return m_list;
1276         }
1277
1278 protected:
1279         JMutex m_mutex;
1280         core::list<T> m_list;
1281 };
1282
1283 /*
1284         A single worker thread - multiple client threads queue framework.
1285 */
1286
1287 template<typename Caller, typename Data>
1288 class CallerInfo
1289 {
1290 public:
1291         Caller caller;
1292         Data data;
1293 };
1294
1295 template<typename Key, typename T, typename Caller, typename CallerData>
1296 class GetResult
1297 {
1298 public:
1299         Key key;
1300         T item;
1301         core::list<CallerInfo<Caller, CallerData> > callers;
1302 };
1303
1304 template<typename Key, typename T, typename Caller, typename CallerData>
1305 class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> >
1306 {
1307 };
1308
1309 template<typename Key, typename T, typename Caller, typename CallerData>
1310 class GetRequest
1311 {
1312 public:
1313         GetRequest()
1314         {
1315                 dest = NULL;
1316         }
1317         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest)
1318         {
1319                 dest = a_dest;
1320         }
1321         GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest,
1322                         Key a_key)
1323         {
1324                 dest = a_dest;
1325                 key = a_key;
1326         }
1327         ~GetRequest()
1328         {
1329         }
1330         
1331         Key key;
1332         ResultQueue<Key, T, Caller, CallerData> *dest;
1333         core::list<CallerInfo<Caller, CallerData> > callers;
1334 };
1335
1336 template<typename Key, typename T, typename Caller, typename CallerData>
1337 class RequestQueue
1338 {
1339 public:
1340         u32 size()
1341         {
1342                 return m_queue.size();
1343         }
1344
1345         void add(Key key, Caller caller, CallerData callerdata,
1346                         ResultQueue<Key, T, Caller, CallerData> *dest)
1347         {
1348                 JMutexAutoLock lock(m_queue.getMutex());
1349                 
1350                 /*
1351                         If the caller is already on the list, only update CallerData
1352                 */
1353                 for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator
1354                                 i = m_queue.getList().begin();
1355                                 i != m_queue.getList().end(); i++)
1356                 {
1357                         GetRequest<Key, T, Caller, CallerData> &request = *i;
1358
1359                         if(request.key == key)
1360                         {
1361                                 for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator
1362                                                 i = request.callers.begin();
1363                                                 i != request.callers.end(); i++)
1364                                 {
1365                                         CallerInfo<Caller, CallerData> &ca = *i;
1366                                         if(ca.caller == caller)
1367                                         {
1368                                                 ca.data = callerdata;
1369                                                 return;
1370                                         }
1371                                 }
1372                                 CallerInfo<Caller, CallerData> ca;
1373                                 ca.caller = caller;
1374                                 ca.data = callerdata;
1375                                 request.callers.push_back(ca);
1376                                 return;
1377                         }
1378                 }
1379
1380                 /*
1381                         Else add a new request to the queue
1382                 */
1383
1384                 GetRequest<Key, T, Caller, CallerData> request;
1385                 request.key = key;
1386                 CallerInfo<Caller, CallerData> ca;
1387                 ca.caller = caller;
1388                 ca.data = callerdata;
1389                 request.callers.push_back(ca);
1390                 request.dest = dest;
1391                 
1392                 m_queue.getList().push_back(request);
1393         }
1394
1395         GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false)
1396         {
1397                 return m_queue.pop_front(wait_if_empty);
1398         }
1399
1400 private:
1401         MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
1402 };
1403
1404 /*
1405         Pseudo-random (VC++ rand() sucks)
1406 */
1407 int myrand(void);
1408 void mysrand(unsigned seed);
1409 #define MYRAND_MAX 32767
1410
1411 int myrand_range(int min, int max);
1412
1413 /*
1414         Miscellaneous functions
1415 */
1416
1417 bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
1418                 f32 camera_fov, f32 range, f32 *distance_ptr=NULL);
1419
1420 /*
1421         Queue with unique values with fast checking of value existence
1422 */
1423
1424 template<typename Value>
1425 class UniqueQueue
1426 {
1427 public:
1428         
1429         /*
1430                 Does nothing if value is already queued.
1431                 Return value:
1432                         true: value added
1433                         false: value already exists
1434         */
1435         bool push_back(Value value)
1436         {
1437                 // Check if already exists
1438                 if(m_map.find(value) != NULL)
1439                         return false;
1440
1441                 // Add
1442                 m_map.insert(value, 0);
1443                 m_list.push_back(value);
1444                 
1445                 return true;
1446         }
1447
1448         Value pop_front()
1449         {
1450                 typename core::list<Value>::Iterator i = m_list.begin();
1451                 Value value = *i;
1452                 m_map.remove(value);
1453                 m_list.erase(i);
1454                 return value;
1455         }
1456
1457         u32 size()
1458         {
1459                 assert(m_list.size() == m_map.size());
1460                 return m_list.size();
1461         }
1462
1463 private:
1464         core::map<Value, u8> m_map;
1465         core::list<Value> m_list;
1466 };
1467
1468 #if 1
1469 template<typename Key, typename Value>
1470 class MutexedMap
1471 {
1472 public:
1473         MutexedMap()
1474         {
1475                 m_mutex.Init();
1476                 assert(m_mutex.IsInitialized());
1477         }
1478         
1479         void set(const Key &name, const Value &value)
1480         {
1481                 JMutexAutoLock lock(m_mutex);
1482
1483                 m_values[name] = value;
1484         }
1485         
1486         bool get(const Key &name, Value *result)
1487         {
1488                 JMutexAutoLock lock(m_mutex);
1489
1490                 typename core::map<Key, Value>::Node *n;
1491                 n = m_values.find(name);
1492
1493                 if(n == NULL)
1494                         return false;
1495                 
1496                 if(result != NULL)
1497                         *result = n->getValue();
1498                         
1499                 return true;
1500         }
1501
1502 private:
1503         core::map<Key, Value> m_values;
1504         JMutex m_mutex;
1505 };
1506 #endif
1507
1508 /*
1509         Generates ids for comparable values.
1510         Id=0 is reserved for "no value".
1511
1512         Is fast at:
1513         - Returning value by id (very fast)
1514         - Returning id by value
1515         - Generating a new id for a value
1516
1517         Is not able to:
1518         - Remove an id/value pair (is possible to implement but slow)
1519 */
1520 template<typename T>
1521 class MutexedIdGenerator
1522 {
1523 public:
1524         MutexedIdGenerator()
1525         {
1526                 m_mutex.Init();
1527                 assert(m_mutex.IsInitialized());
1528         }
1529         
1530         // Returns true if found
1531         bool getValue(u32 id, T &value)
1532         {
1533                 if(id == 0)
1534                         return false;
1535                 JMutexAutoLock lock(m_mutex);
1536                 if(m_id_to_value.size() < id)
1537                         return false;
1538                 value = m_id_to_value[id-1];
1539                 return true;
1540         }
1541         
1542         // If id exists for value, returns the id.
1543         // Otherwise generates an id for the value.
1544         u32 getId(const T &value)
1545         {
1546                 JMutexAutoLock lock(m_mutex);
1547                 typename core::map<T, u32>::Node *n;
1548                 n = m_value_to_id.find(value);
1549                 if(n != NULL)
1550                         return n->getValue();
1551                 m_id_to_value.push_back(value);
1552                 u32 new_id = m_id_to_value.size();
1553                 m_value_to_id.insert(value, new_id);
1554                 return new_id;
1555         }
1556
1557 private:
1558         JMutex m_mutex;
1559         // Values are stored here at id-1 position (id 1 = [0])
1560         core::array<T> m_id_to_value;
1561         core::map<T, u32> m_value_to_id;
1562 };
1563
1564 /*
1565         Checks if a string contains only supplied characters
1566 */
1567 inline bool string_allowed(const std::string &s, const std::string &allowed_chars)
1568 {
1569         for(u32 i=0; i<s.size(); i++)
1570         {
1571                 bool confirmed = false;
1572                 for(u32 j=0; j<allowed_chars.size(); j++)
1573                 {
1574                         if(s[i] == allowed_chars[j])
1575                         {
1576                                 confirmed = true;
1577                                 break;
1578                         }
1579                 }
1580                 if(confirmed == false)
1581                         return false;
1582         }
1583         return true;
1584 }
1585
1586 /*
1587         Forcefully wraps string into rows using \n
1588         (no word wrap, used for showing paths in gui)
1589 */
1590 inline std::string wrap_rows(const std::string &from, u32 rowlen)
1591 {
1592         std::string to;
1593         for(u32 i=0; i<from.size(); i++)
1594         {
1595                 if(i != 0 && i%rowlen == 0)
1596                         to += '\n';
1597                 to += from[i];
1598         }
1599         return to;
1600 }
1601
1602 /*
1603         Some helper stuff
1604 */
1605 #define MYMIN(a,b) ((a)<(b)?(a):(b))
1606 #define MYMAX(a,b) ((a)>(b)?(a):(b))
1607
1608 /*
1609         Returns nearest 32-bit integer for given floating point number.
1610         <cmath> and <math.h> in VC++ don't provide round().
1611 */
1612 inline s32 myround(f32 f)
1613 {
1614         return floor(f + 0.5);
1615 }
1616
1617 /*
1618         Returns integer position of node in given floating point position
1619 */
1620 inline v3s16 floatToInt(v3f p, f32 d)
1621 {
1622         v3s16 p2(
1623                 (p.X + (p.X>0 ? d/2 : -d/2))/d,
1624                 (p.Y + (p.Y>0 ? d/2 : -d/2))/d,
1625                 (p.Z + (p.Z>0 ? d/2 : -d/2))/d);
1626         return p2;
1627 }
1628
1629 /*
1630         Returns floating point position of node in given integer position
1631 */
1632 inline v3f intToFloat(v3s16 p, f32 d)
1633 {
1634         v3f p2(
1635                 (f32)p.X * d,
1636                 (f32)p.Y * d,
1637                 (f32)p.Z * d
1638         );
1639         return p2;
1640 }
1641
1642 /*
1643         More serialization stuff
1644 */
1645
1646 // Creates a string with the length as the first two bytes
1647 inline std::string serializeString(const std::string &plain)
1648 {
1649         //assert(plain.size() <= 65535);
1650         if(plain.size() > 65535)
1651                 throw SerializationError("String too long for serializeString");
1652         char buf[2];
1653         writeU16((u8*)&buf[0], plain.size());
1654         std::string s;
1655         s.append(buf, 2);
1656         s.append(plain);
1657         return s;
1658 }
1659
1660 // Creates a string with the length as the first two bytes from wide string
1661 inline std::string serializeWideString(const std::wstring &plain)
1662 {
1663         //assert(plain.size() <= 65535);
1664         if(plain.size() > 65535)
1665                 throw SerializationError("String too long for serializeString");
1666         char buf[2];
1667         writeU16((u8*)buf, plain.size());
1668         std::string s;
1669         s.append(buf, 2);
1670         for(u32 i=0; i<plain.size(); i++)
1671         {
1672                 writeU16((u8*)buf, plain[i]);
1673                 s.append(buf, 2);
1674         }
1675         return s;
1676 }
1677
1678 // Reads a string with the length as the first two bytes
1679 inline std::string deSerializeString(std::istream &is)
1680 {
1681         char buf[2];
1682         is.read(buf, 2);
1683         if(is.gcount() != 2)
1684                 throw SerializationError("deSerializeString: size not read");
1685         u16 s_size = readU16((u8*)buf);
1686         if(s_size == 0)
1687                 return "";
1688         Buffer<char> buf2(s_size);
1689         is.read(&buf2[0], s_size);
1690         std::string s;
1691         s.reserve(s_size);
1692         s.append(&buf2[0], s_size);
1693         return s;
1694 }
1695
1696 // Reads a wide string with the length as the first two bytes
1697 inline std::wstring deSerializeWideString(std::istream &is)
1698 {
1699         char buf[2];
1700         is.read(buf, 2);
1701         if(is.gcount() != 2)
1702                 throw SerializationError("deSerializeString: size not read");
1703         u16 s_size = readU16((u8*)buf);
1704         if(s_size == 0)
1705                 return L"";
1706         std::wstring s;
1707         s.reserve(s_size);
1708         for(u32 i=0; i<s_size; i++)
1709         {
1710                 is.read(&buf[0], 2);
1711                 wchar_t c16 = readU16((u8*)buf);
1712                 s.append(&c16, 1);
1713         }
1714         return s;
1715 }
1716
1717 // Creates a string with the length as the first four bytes
1718 inline std::string serializeLongString(const std::string &plain)
1719 {
1720         char buf[4];
1721         writeU32((u8*)&buf[0], plain.size());
1722         std::string s;
1723         s.append(buf, 4);
1724         s.append(plain);
1725         return s;
1726 }
1727
1728 // Reads a string with the length as the first four bytes
1729 inline std::string deSerializeLongString(std::istream &is)
1730 {
1731         char buf[4];
1732         is.read(buf, 4);
1733         if(is.gcount() != 4)
1734                 throw SerializationError("deSerializeLongString: size not read");
1735         u32 s_size = readU32((u8*)buf);
1736         if(s_size == 0)
1737                 return "";
1738         Buffer<char> buf2(s_size);
1739         is.read(&buf2[0], s_size);
1740         std::string s;
1741         s.reserve(s_size);
1742         s.append(&buf2[0], s_size);
1743         return s;
1744 }
1745
1746 // Creates a string encoded in JSON format (almost equivalent to a C string literal)
1747 std::string serializeJsonString(const std::string &plain);
1748
1749 // Reads a string encoded in JSON format
1750 std::string deSerializeJsonString(std::istream &is);
1751
1752 //
1753
1754 inline u32 time_to_daynight_ratio(u32 time_of_day)
1755 {
1756         s32 t = time_of_day%24000;
1757         if(t < 4500 || t >= 19500)
1758                 return 150;
1759         else if(t < 5000 || t >= 19000)
1760                 return 350;
1761         else if(t < 5500 || t >= 18500)
1762                 return 500;
1763         else if(t < 6000 || t >= 18000)
1764                 return 750;
1765         else
1766                 return 1000;
1767 }
1768
1769 // Random helper. Usually d=BS
1770 inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
1771 {
1772         return core::aabbox3d<f32>(
1773                 (float)p.X * d - 0.5*d,
1774                 (float)p.Y * d - 0.5*d,
1775                 (float)p.Z * d - 0.5*d,
1776                 (float)p.X * d + 0.5*d,
1777                 (float)p.Y * d + 0.5*d,
1778                 (float)p.Z * d + 0.5*d
1779         );
1780 }
1781         
1782 class IntervalLimiter
1783 {
1784 public:
1785         IntervalLimiter():
1786                 m_accumulator(0)
1787         {
1788         }
1789         /*
1790                 dtime: time from last call to this method
1791                 wanted_interval: interval wanted
1792                 return value:
1793                         true: action should be skipped
1794                         false: action should be done
1795         */
1796         bool step(float dtime, float wanted_interval)
1797         {
1798                 m_accumulator += dtime;
1799                 if(m_accumulator < wanted_interval)
1800                         return false;
1801                 m_accumulator -= wanted_interval;
1802                 return true;
1803         }
1804 protected:
1805         float m_accumulator;
1806 };
1807
1808 /*
1809         Splits a list into "pages". For example, the list [1,2,3,4,5] split
1810         into two pages would be [1,2,3],[4,5]. This function computes the
1811         minimum and maximum indices of a single page.
1812
1813         length: Length of the list that should be split
1814         page: Page number, 1 <= page <= pagecount
1815         pagecount: The number of pages, >= 1
1816         minindex: Receives the minimum index (inclusive).
1817         maxindex: Receives the maximum index (exclusive).
1818
1819         Ensures 0 <= minindex <= maxindex <= length.
1820 */
1821 inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxindex)
1822 {
1823         if(length < 1 || pagecount < 1 || page < 1 || page > pagecount)
1824         {
1825                 // Special cases or invalid parameters
1826                 minindex = maxindex = 0;
1827         }
1828         else if(pagecount <= length)
1829         {
1830                 // Less pages than entries in the list:
1831                 // Each page contains at least one entry
1832                 minindex = (length * (page-1) + (pagecount-1)) / pagecount;
1833                 maxindex = (length * page + (pagecount-1)) / pagecount;
1834         }
1835         else
1836         {
1837                 // More pages than entries in the list:
1838                 // Make sure the empty pages are at the end
1839                 if(page < length)
1840                 {
1841                         minindex = page-1;
1842                         maxindex = page;
1843                 }
1844                 else
1845                 {
1846                         minindex = 0;
1847                         maxindex = 0;
1848                 }
1849         }
1850 }
1851
1852 std::string translatePassword(std::string playername, std::wstring password);
1853
1854 enum PointedThingType
1855 {
1856         POINTEDTHING_NOTHING,
1857         POINTEDTHING_NODE,
1858         POINTEDTHING_OBJECT
1859 };
1860
1861 struct PointedThing
1862 {
1863         PointedThingType type;
1864         v3s16 node_undersurface;
1865         v3s16 node_abovesurface;
1866         s16 object_id;
1867
1868         PointedThing();
1869         std::string dump() const;
1870         void serialize(std::ostream &os) const;
1871         void deSerialize(std::istream &is);
1872         bool operator==(const PointedThing &pt2) const;
1873         bool operator!=(const PointedThing &pt2) const;
1874 };
1875
1876 #endif
1877