]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mapblockobject.h
working good
[dragonfireclient.git] / src / mapblockobject.h
index ea0293a6f6359cfc6a0d3082f4efe2e8f85fc7cb..aee41f3ba1620cb7e48eb7f08015932ab8f59958 100644 (file)
@@ -1,5 +1,20 @@
 /*
-(c) 2010 Perttu Ahola <celeron55@gmail.com>
+Minetest-c55
+Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
 #ifndef MAPBLOCKOBJECT_HEADER
 #include "constants.h"
 #include "debug.h"
 
-enum
-{
-       MAPBLOCKOBJECT_TYPE_TEST=0,
-       MAPBLOCKOBJECT_TYPE_TEST2=1,
-       MAPBLOCKOBJECT_TYPE_SIGN=2,
-       MAPBLOCKOBJECT_TYPE_RAT=3,
-};
+#define MAPBLOCKOBJECT_TYPE_PLAYER 0
+#define MAPBLOCKOBJECT_TYPE_SIGN 2
+#define MAPBLOCKOBJECT_TYPE_RAT 3
+#define MAPBLOCKOBJECT_TYPE_ITEM 4
+// Used for handling selecting special stuff
+//#define MAPBLOCKOBJECT_TYPE_PSEUDO 1000
 
 class MapBlock;
 
@@ -67,6 +81,11 @@ class MapBlockObject
                os.write((char*)buf, 2);
        }
        
+       // Position where the object is drawn relative to block
+       virtual v3f getRelativeShowPos()
+       {
+               return m_pos;
+       }
        // Get floating point position on map
        v3f getAbsolutePos();
 
@@ -120,7 +139,15 @@ class MapBlockObject
        // Typical dtimes are 0.2 and 10000.
        // A return value of true requests deletion of the object by the caller.
        // NOTE: Only server calls this.
-       virtual bool serverStep(float dtime) { return false; };
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
+       { return false; };
+
+#ifdef SERVER
+       void clientStep(float dtime) {};
+       void addToScene(void *smgr) {};
+       void removeFromScene() {};
+       void updateLight(u8 light_at_pos) {};
+#else
        // This should do slight animations only or so
        virtual void clientStep(float dtime) {};
 
@@ -128,11 +155,15 @@ class MapBlockObject
        //       same as the current state
        // Shall add and remove relevant scene nodes for rendering the
        // object in the game world
-       virtual void addToScene(scene::ISceneManager *smgr) {};
+       virtual void addToScene(scene::ISceneManager *smgr) = 0;
        // Shall remove stuff from the scene
        // Should return silently if there is nothing to remove
        // NOTE: This has to be called before calling destructor
-       virtual void removeFromScene() {};
+       virtual void removeFromScene() = 0;
+       
+       // 0 <= light_at_pos <= LIGHT_SUN
+       virtual void updateLight(u8 light_at_pos) {};
+#endif
 
        virtual std::string infoText() { return ""; }
        
@@ -155,17 +186,22 @@ class MapBlockObject
        friend class MapBlockObjectList;
 };
 
-class TestObject : public MapBlockObject
+#if 0
+/*
+       Used for handling selections of special stuff
+*/
+class PseudoMBObject : public MapBlockObject
 {
 public:
        // The constructor of every MapBlockObject should be like this
-       TestObject(MapBlock *block, s16 id, v3f pos):
-               MapBlockObject(block, id, pos),
-               m_node(NULL)
+       PseudoMBObject(MapBlock *block, s16 id, v3f pos):
+               MapBlockObject(block, id, pos)
        {
        }
-       virtual ~TestObject()
+       virtual ~PseudoMBObject()
        {
+               if(m_selection_box)
+                       delete m_selection_box;
        }
        
        /*
@@ -173,100 +209,33 @@ class TestObject : public MapBlockObject
        */
        virtual u16 getTypeId() const
        {
-               return MAPBLOCKOBJECT_TYPE_TEST;
+               return MAPBLOCKOBJECT_TYPE_PSEUDO;
        }
        virtual void serialize(std::ostream &os, u8 version)
        {
-               serializeBase(os, version);
-
-               // Write subpos_c * 100
-               u8 buf[2];
-               writeU16(buf, m_subpos_c * 100);
-               os.write((char*)buf, 2);
+               assert(0);
        }
        virtual void update(std::istream &is, u8 version)
        {
-               // Read subpos_c * 100
-               u8 buf[2];
-               is.read((char*)buf, 2);
-               m_subpos_c = (f32)readU16(buf) / 100;
-               
-               updateNodePos();
-       }
-       virtual bool serverStep(float dtime)
-       {
-               m_subpos_c += dtime * 3.0;
-
-               updateNodePos();
-
-               return false;
-       }
-       virtual void addToScene(scene::ISceneManager *smgr)
-       {
-               if(m_node != NULL)
-                       return;
-               
-               //dstream<<"Adding to scene"<<std::endl;
-
-               video::IVideoDriver* driver = smgr->getVideoDriver();
-               
-               scene::SMesh *mesh = new scene::SMesh();
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
-               {
-                       video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
-               };
-               u16 indices[] = {0,1,2,2,3,0};
-               buf->append(vertices, 4, indices, 6);
-               // Set material
-               buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-               buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture
-                               (0, driver->getTexture("../data/player.png"));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
-               m_node = smgr->addMeshSceneNode(mesh, NULL);
-               mesh->drop();
-               m_node->setPosition(getAbsolutePos());
+               assert(0);
        }
-       virtual void removeFromScene()
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
        {
-               //dstream<<"Removing from scene"<<std::endl;
-               if(m_node != NULL)
-               {
-                       m_node->remove();
-                       m_node = NULL;
-               }
+               assert(0);
        }
 
        /*
                Special methods
        */
        
-       void updateNodePos()
+       void setSelectionBox(core::aabbox3d<f32> box)
        {
-               m_subpos = BS*2.0 * v3f(sin(m_subpos_c), sin(m_subpos_c+1.0), sin(-m_subpos_c));
-               
-               if(m_node != NULL)
-               {
-                       m_node->setPosition(getAbsolutePos() + m_subpos);
-               }
+               m_selection_box = new core::aabbox3d<f32>(box);
        }
        
 protected:
-       scene::IMeshSceneNode *m_node;
-       std::string m_text;
-
-       v3f m_subpos;
-       f32 m_subpos_c;
 };
+#endif
 
 class MovingObject : public MapBlockObject
 {
@@ -274,7 +243,10 @@ class MovingObject : public MapBlockObject
        // The constructor of every MapBlockObject should be like this
        MovingObject(MapBlock *block, s16 id, v3f pos):
                MapBlockObject(block, id, pos),
-               m_speed(0,0,0)
+               m_speed(0,0,0),
+               m_oldpos(pos),
+               m_pos_animation_time(0),
+               m_showpos(pos)
        {
                m_touching_ground = false;
        }
@@ -314,39 +286,73 @@ class MovingObject : public MapBlockObject
 
                m_speed = speed;
        }
+       
+       // Reimplementation shall call this.
+       virtual void updatePos(v3f pos)
+       {
+               m_oldpos = m_showpos;
+               m_pos = pos;
+               
+               if(m_pos_animation_time < 0.001 || m_pos_animation_time > 1.0)
+                       m_pos_animation_time = m_pos_animation_time_counter;
+               else
+                       m_pos_animation_time = m_pos_animation_time * 0.9
+                                       + m_pos_animation_time_counter * 0.1;
+               m_pos_animation_time_counter = 0;
+               m_pos_animation_counter = 0;
+       }
+       
+       // Position where the object is drawn relative to block
+       virtual v3f getRelativeShowPos()
+       {
+               return m_showpos;
+       }
+       // Returns m_showpos relative to whole map
+       v3f getAbsoluteShowPos();
 
-       virtual bool serverStep(float dtime) { return false; };
-       virtual void clientStep(float dtime) {};
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
+       { return false; };
+       virtual void clientStep(float dtime)
+       {};
        
-       virtual void addToScene(scene::ISceneManager *smgr) = 0;
-       virtual void removeFromScene() = 0;
+       /*virtual void addToScene(scene::ISceneManager *smgr) = 0;
+       virtual void removeFromScene() = 0;*/
 
        /*
                Special methods
        */
        
-       // Moves with collision detection
+       // Move with collision detection, server side
        void move(float dtime, v3f acceleration);
+
+       // Move from old position to new position, client side
+       void simpleMove(float dtime);
        
 protected:
        v3f m_speed;
        bool m_touching_ground;
+       // Client-side moving
+       v3f m_oldpos;
+       f32 m_pos_animation_counter;
+       f32 m_pos_animation_time;
+       f32 m_pos_animation_time_counter;
+       v3f m_showpos;
 };
 
-class Test2Object : public MovingObject
+class SignObject : public MapBlockObject
 {
 public:
        // The constructor of every MapBlockObject should be like this
-       Test2Object(MapBlock *block, s16 id, v3f pos):
-               MovingObject(block, id, pos),
+       SignObject(MapBlock *block, s16 id, v3f pos):
+               MapBlockObject(block, id, pos),
                m_node(NULL)
        {
-               m_collision_box = new core::aabbox3d<f32>
-                               (-BS*0.3,0,-BS*0.3, BS*0.3,BS*1.7,BS*0.3);
+               m_selection_box = new core::aabbox3d<f32>
+                               (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);
        }
-       virtual ~Test2Object()
+       virtual ~SignObject()
        {
-               delete m_collision_box;
+               delete m_selection_box;
        }
        
        /*
@@ -354,111 +360,194 @@ class Test2Object : public MovingObject
        */
        virtual u16 getTypeId() const
        {
-               return MAPBLOCKOBJECT_TYPE_TEST2;
+               return MAPBLOCKOBJECT_TYPE_SIGN;
        }
        virtual void serialize(std::ostream &os, u8 version)
        {
-               MovingObject::serialize(os, version);
+               serializeBase(os, version);
+               u8 buf[2];
+
+               // Write yaw * 10
+               writeS16(buf, m_yaw * 10);
+               os.write((char*)buf, 2);
+
+               // Write text length
+               writeU16(buf, m_text.size());
+               os.write((char*)buf, 2);
+               
+               // Write text
+               os.write(m_text.c_str(), m_text.size());
        }
        virtual void update(std::istream &is, u8 version)
        {
-               MovingObject::update(is, version);
-               
-               updateNodePos();
-       }
+               u8 buf[2];
 
-       virtual bool serverStep(float dtime)
-       {
-               m_speed.X = 2*BS;
-               m_speed.Z = 0;
+               // Read yaw * 10
+               is.read((char*)buf, 2);
+               s16 yaw_i = readS16(buf);
+               m_yaw = (f32)yaw_i / 10;
 
-               if(m_touching_ground)
+               // Read text length
+               is.read((char*)buf, 2);
+               u16 size = readU16(buf);
+
+               // Read text
+               m_text.clear();
+               for(u16 i=0; i<size; i++)
                {
-                       static float count = 0;
-                       count -= dtime;
-                       if(count < 0.0)
-                       {
-                               count += 1.0;
-                               m_speed.Y = 6.5*BS;
-                       }
+                       is.read((char*)buf, 1);
+                       m_text += buf[0];
                }
 
-               move(dtime, v3f(0, -9.81*BS, 0));
-
-               updateNodePos();
-
-               return false;
+               updateSceneNode();
        }
-       
-       virtual void clientStep(float dtime)
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
        {
-               m_pos += m_speed * dtime;
-
-               updateNodePos();
+               return false;
        }
-       
+#ifndef SERVER
        virtual void addToScene(scene::ISceneManager *smgr)
        {
                if(m_node != NULL)
                        return;
                
-               //dstream<<"Adding to scene"<<std::endl;
-
                video::IVideoDriver* driver = smgr->getVideoDriver();
                
                scene::SMesh *mesh = new scene::SMesh();
+               { // Front
                scene::IMeshBuffer *buf = new scene::SMeshBuffer();
                video::SColor c(255,255,255,255);
                video::S3DVertex vertices[4] =
                {
-                       video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
+                       video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
+                       video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
+                       video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
+                       video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),
                };
                u16 indices[] = {0,1,2,2,3,0};
                buf->append(vertices, 4, indices, 6);
                // Set material
                buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-               buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
+               //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
                buf->getMaterial().setTexture
-                               (0, driver->getTexture("../data/player.png"));
+                               (0, driver->getTexture("../data/sign.png"));
                buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
+               buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
+               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
                // Add to mesh
                mesh->addMeshBuffer(buf);
                buf->drop();
+               }
+               { // Back
+               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
+               video::SColor c(255,255,255,255);
+               video::S3DVertex vertices[4] =
+               {
+                       video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
+                       video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 1,1),
+                       video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
+                       video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
+               };
+               u16 indices[] = {0,1,2,2,3,0};
+               buf->append(vertices, 4, indices, 6);
+               // Set material
+               buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
+               //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
+               buf->getMaterial().setTexture
+                               (0, driver->getTexture("../data/sign_back.png"));
+               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
+               buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
+               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+               // Add to mesh
+               mesh->addMeshBuffer(buf);
+               buf->drop();
+               }
                m_node = smgr->addMeshSceneNode(mesh, NULL);
                mesh->drop();
-               m_node->setPosition(getAbsolutePos());
+
+               updateSceneNode();
        }
        virtual void removeFromScene()
        {
-               //dstream<<"Removing from scene"<<std::endl;
                if(m_node != NULL)
                {
                        m_node->remove();
                        m_node = NULL;
                }
        }
+       virtual void updateLight(u8 light_at_pos)
+       {
+               if(m_node == NULL)
+                       return;
+
+               u8 li = decode_light(light_at_pos);
+               video::SColor color(255,li,li,li);
+
+               scene::IMesh *mesh = m_node->getMesh();
+               
+               u16 mc = mesh->getMeshBufferCount();
+               for(u16 j=0; j<mc; j++)
+               {
+                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                       video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+                       u16 vc = buf->getVertexCount();
+                       for(u16 i=0; i<vc; i++)
+                       {
+                               vertices[i].Color = color;
+                       }
+               }
+       }
+#endif
+
+       virtual std::string infoText()
+       {
+               return std::string("\"") + m_text + "\"";
+       }
+
+       virtual std::string getInventoryString()
+       {
+               return std::string("Sign ")+m_text;
+       }
 
        /*
                Special methods
        */
-       
-       void updateNodePos()
+       void updateSceneNode()
        {
-               //m_subpos = BS*2.0 * v3f(sin(m_subpos_c), sin(m_subpos_c+1.0), sin(-m_subpos_c));
-               
+#ifndef SERVER
                if(m_node != NULL)
                {
-                       //m_node->setPosition(getAbsolutePos() + m_subpos);
                        m_node->setPosition(getAbsolutePos());
+                       m_node->setRotation(v3f(0, m_yaw, 0));
                }
+#endif
+       }
+
+       void setText(std::string text)
+       {
+               if(text.size() > SIGN_TEXT_MAX_LENGTH)
+                       text = text.substr(0, SIGN_TEXT_MAX_LENGTH);
+               m_text = text;
+
+               setBlockChanged();
+       }
+
+       std::string getText()
+       {
+               return m_text;
+       }
+
+       void setYaw(f32 yaw)
+       {
+               m_yaw = yaw;
+
+               setBlockChanged();
        }
        
 protected:
        scene::IMeshSceneNode *m_node;
+       std::string m_text;
+       f32 m_yaw;
 };
 
 class RatObject : public MovingObject
@@ -469,12 +558,13 @@ class RatObject : public MovingObject
                m_node(NULL)
        {
                m_collision_box = new core::aabbox3d<f32>
-                               (-BS*0.3,0,-BS*0.3, BS*0.3,BS*0.5,BS*0.3);
+                               (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
                m_selection_box = new core::aabbox3d<f32>
-                               (-BS*0.3,0,-BS*0.3, BS*0.3,BS*0.5,BS*0.3);
+                               (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
 
                m_counter1 = 0;
                m_counter2 = 0;
+               m_age = 0;
        }
        virtual ~RatObject()
        {
@@ -512,8 +602,13 @@ class RatObject : public MovingObject
                updateNodePos();
        }
 
-       virtual bool serverStep(float dtime)
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
        {
+               m_age += dtime;
+               if(m_age > 60)
+                       // Die
+                       return true;
+
                v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
 
                f32 speed = 2*BS;
@@ -535,8 +630,8 @@ class RatObject : public MovingObject
                        m_counter2 -= dtime;
                        if(m_counter2 < 0.0)
                        {
-                               m_counter2 += (float)(rand()%100)/100*3.0;
-                               m_yaw += ((float)(rand()%200)-100)/100*180;
+                               m_counter2 += (float)(myrand()%100)/100*3.0;
+                               m_yaw += ((float)(myrand()%200)-100)/100*180;
                                m_yaw = wrapDegrees(m_yaw);
                        }
                }
@@ -547,59 +642,54 @@ class RatObject : public MovingObject
 
                move(dtime, v3f(0, -9.81*BS, 0));
 
-               updateNodePos();
+               //updateNodePos();
 
                return false;
        }
-       
+#ifndef SERVER
        virtual void clientStep(float dtime)
        {
-               m_pos += m_speed * dtime;
+               //m_pos += m_speed * dtime;
+               MovingObject::simpleMove(dtime);
 
                updateNodePos();
        }
        
-       virtual void addToScene(scene::ISceneManager *smgr)
+       virtual void addToScene(scene::ISceneManager *smgr);
+
+       virtual void removeFromScene()
        {
-               if(m_node != NULL)
+               if(m_node == NULL)
                        return;
-               
-               video::IVideoDriver* driver = smgr->getVideoDriver();
-               
-               scene::SMesh *mesh = new scene::SMesh();
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
-               {
-                       video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
-               };
-               u16 indices[] = {0,1,2,2,3,0};
-               buf->append(vertices, 4, indices, 6);
-               // Set material
-               buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-               buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture
-                               (0, driver->getTexture("../data/rat.png"));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
-               m_node = smgr->addMeshSceneNode(mesh, NULL);
-               mesh->drop();
-               m_node->setPosition(getAbsolutePos());
+
+               m_node->remove();
+               m_node = NULL;
        }
-       virtual void removeFromScene()
+
+       virtual void updateLight(u8 light_at_pos)
        {
-               if(m_node != NULL)
+               if(m_node == NULL)
+                       return;
+
+               u8 li = decode_light(light_at_pos);
+               video::SColor color(255,li,li,li);
+
+               scene::IMesh *mesh = m_node->getMesh();
+               
+               u16 mc = mesh->getMeshBufferCount();
+               for(u16 j=0; j<mc; j++)
                {
-                       m_node->remove();
-                       m_node = NULL;
+                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                       video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+                       u16 vc = buf->getVertexCount();
+                       for(u16 i=0; i<vc; i++)
+                       {
+                               vertices[i].Color = color;
+                       }
                }
        }
+       
+#endif
 
        virtual std::string getInventoryString()
        {
@@ -614,11 +704,11 @@ class RatObject : public MovingObject
        
        void updateNodePos()
        {
-               if(m_node != NULL)
-               {
-                       m_node->setPosition(getAbsolutePos());
-                       m_node->setRotation(v3f(0, -m_yaw+180, 0));
-               }
+               if(m_node == NULL)
+                       return;
+
+               m_node->setPosition(getAbsoluteShowPos());
+               m_node->setRotation(v3f(0, -m_yaw+180, 0));
        }
        
 protected:
@@ -627,21 +717,30 @@ class RatObject : public MovingObject
 
        float m_counter1;
        float m_counter2;
-       v3f m_oldpos;
+       float m_age;
 };
 
-class SignObject : public MapBlockObject
+/*
+       An object on the map that represents an inventory item
+*/
+
+class InventoryItem;
+
+class ItemObject : public MapBlockObject
 {
 public:
        // The constructor of every MapBlockObject should be like this
-       SignObject(MapBlock *block, s16 id, v3f pos):
+       ItemObject(MapBlock *block, s16 id, v3f pos):
                MapBlockObject(block, id, pos),
                m_node(NULL)
        {
+               /*m_selection_box = new core::aabbox3d<f32>
+                               (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);*/
                m_selection_box = new core::aabbox3d<f32>
-                               (-BS*0.4,-BS*0.5,-BS*0.4, BS*0.4,BS*0.5,BS*0.4);
+                               (-BS/3,-BS/2,-BS/3, BS/3,-BS/2+BS*2/3,BS/3);
+               m_yaw = 0.0;
        }
-       virtual ~SignObject()
+       virtual ~ItemObject()
        {
                delete m_selection_box;
        }
@@ -651,110 +750,74 @@ class SignObject : public MapBlockObject
        */
        virtual u16 getTypeId() const
        {
-               return MAPBLOCKOBJECT_TYPE_SIGN;
+               return MAPBLOCKOBJECT_TYPE_ITEM;
        }
        virtual void serialize(std::ostream &os, u8 version)
        {
                serializeBase(os, version);
                u8 buf[2];
 
-               // Write yaw * 10
-               writeS16(buf, m_yaw * 10);
-               os.write((char*)buf, 2);
-
                // Write text length
-               writeU16(buf, m_text.size());
+               writeU16(buf, m_itemstring.size());
                os.write((char*)buf, 2);
                
                // Write text
-               os.write(m_text.c_str(), m_text.size());
+               os.write(m_itemstring.c_str(), m_itemstring.size());
        }
        virtual void update(std::istream &is, u8 version)
        {
                u8 buf[2];
 
-               // Read yaw * 10
-               is.read((char*)buf, 2);
-               s16 yaw_i = readS16(buf);
-               m_yaw = (f32)yaw_i / 10;
-
                // Read text length
                is.read((char*)buf, 2);
                u16 size = readU16(buf);
 
                // Read text
-               m_text.clear();
+               std::string old_itemstring = m_itemstring;
+               m_itemstring.clear();
                for(u16 i=0; i<size; i++)
                {
                        is.read((char*)buf, 1);
-                       m_text += buf[0];
+                       m_itemstring += buf[0];
                }
-
+               
+#ifndef SERVER
+               if(m_itemstring != old_itemstring && m_node)
+               {
+                       /*
+                               Update texture
+                       */
+                       video::ITexture *texture = getItemImage();
+                       scene::IMesh *mesh = m_node->getMesh();
+                       if(mesh->getMeshBufferCount() >= 1)
+                       {
+                               scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
+                               //dstream<<"Setting texture "<<texture<<std::endl;
+                               buf->getMaterial().setTexture(0, texture);
+                       }
+               }
+               
                updateSceneNode();
+#endif
        }
-       virtual bool serverStep(float dtime)
+
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
        {
                return false;
        }
-       virtual void addToScene(scene::ISceneManager *smgr)
+
+#ifndef SERVER
+       virtual void clientStep(float dtime)
        {
-               if(m_node != NULL)
-                       return;
-               
-               video::IVideoDriver* driver = smgr->getVideoDriver();
-               
-               scene::SMesh *mesh = new scene::SMesh();
-               { // Front
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
-               {
-                       video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 0,0),
-               };
-               u16 indices[] = {0,1,2,2,3,0};
-               buf->append(vertices, 4, indices, 6);
-               // Set material
-               buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-               //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture
-                               (0, driver->getTexture("../data/sign.png"));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
-               }
-               { // Back
-               scene::IMeshBuffer *buf = new scene::SMeshBuffer();
-               video::SColor c(255,255,255,255);
-               video::S3DVertex vertices[4] =
-               {
-                       video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
-                       video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 1,1),
-                       video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
-                       video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
-               };
-               u16 indices[] = {0,1,2,2,3,0};
-               buf->append(vertices, 4, indices, 6);
-               // Set material
-               buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
-               //buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
-               buf->getMaterial().setTexture
-                               (0, driver->getTexture("../data/sign_back.png"));
-               buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-               buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
-               // Add to mesh
-               mesh->addMeshBuffer(buf);
-               buf->drop();
-               }
-               m_node = smgr->addMeshSceneNode(mesh, NULL);
-               mesh->drop();
+               m_yaw += dtime * 60;
+               if(m_yaw >= 360.)
+                       m_yaw -= 360.;
 
                updateSceneNode();
        }
+       
+       virtual void addToScene(scene::ISceneManager *smgr);
+       
        virtual void removeFromScene()
        {
                if(m_node != NULL)
@@ -763,21 +826,49 @@ class SignObject : public MapBlockObject
                        m_node = NULL;
                }
        }
+       virtual void updateLight(u8 light_at_pos)
+       {
+               if(m_node == NULL)
+                       return;
+
+               u8 li = decode_light(light_at_pos);
+               video::SColor color(255,li,li,li);
+
+               scene::IMesh *mesh = m_node->getMesh();
+               
+               u16 mc = mesh->getMeshBufferCount();
+               for(u16 j=0; j<mc; j++)
+               {
+                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                       video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+                       u16 vc = buf->getVertexCount();
+                       for(u16 i=0; i<vc; i++)
+                       {
+                               vertices[i].Color = color;
+                       }
+               }
+       }
+#endif
 
        virtual std::string infoText()
        {
-               return std::string("\"") + m_text + "\"";
+               return std::string("\"") + m_itemstring + "\"";
        }
 
        virtual std::string getInventoryString()
        {
-               return std::string("Sign ")+m_text;
+               return std::string("ItemObj ")+m_itemstring;
        }
 
        /*
                Special methods
        */
 
+       InventoryItem * createInventoryItem();
+       
+#ifndef SERVER
+       video::ITexture * getItemImage();
+
        void updateSceneNode()
        {
                if(m_node != NULL)
@@ -786,27 +877,143 @@ class SignObject : public MapBlockObject
                        m_node->setRotation(v3f(0, m_yaw, 0));
                }
        }
+#endif
 
-       void setText(std::string text)
+       void setItemString(std::string inventorystring)
        {
-               if(text.size() > SIGN_TEXT_MAX_LENGTH)
-                       text = text.substr(0, SIGN_TEXT_MAX_LENGTH);
-               m_text = text;
-
+               m_itemstring = inventorystring;
                setBlockChanged();
        }
 
-       void setYaw(f32 yaw)
+       std::string getItemString()
        {
-               m_yaw = yaw;
+               return m_itemstring;
+       }
 
-               setBlockChanged();
+protected:
+       scene::IMeshSceneNode *m_node;
+       std::string m_itemstring;
+       f32 m_yaw;
+};
+
+/*
+       NOTE: Not used.
+*/
+class PlayerObject : public MovingObject
+{
+public:
+       PlayerObject(MapBlock *block, s16 id, v3f pos):
+               MovingObject(block, id, pos),
+               m_node(NULL)
+       {
+               m_collision_box = new core::aabbox3d<f32>
+                               (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);
+               /*m_selection_box = new core::aabbox3d<f32>
+                               (-BS*0.3,-BS*.25,-BS*0.3, BS*0.3,BS*0.25,BS*0.3);*/
+       }
+       virtual ~PlayerObject()
+       {
+               if(m_collision_box)
+                       delete m_collision_box;
+               if(m_selection_box)
+                       delete m_selection_box;
+       }
+       
+       /*
+               Implementation interface
+       */
+       virtual u16 getTypeId() const
+       {
+               return MAPBLOCKOBJECT_TYPE_PLAYER;
+       }
+       virtual void serialize(std::ostream &os, u8 version)
+       {
+               // Object data is generated from actual player
+       }
+       virtual void update(std::istream &is, u8 version)
+       {
+               MovingObject::update(is, version);
+               u8 buf[2];
+               
+               // Read yaw * 10
+               is.read((char*)buf, 2);
+               s16 yaw_i = readS16(buf);
+               m_yaw = (f32)yaw_i / 10;
+
+               updateNodePos();
+       }
+
+       virtual bool serverStep(float dtime, u32 daynight_ratio)
+       {
+               // Player is handled elsewhere.
+               // Die.
+               //return true;
+               // Actually, fail very loudly:
+               assert(0);
+       }
+
+#ifndef SERVER
+       virtual void clientStep(float dtime)
+       {
+               MovingObject::simpleMove(dtime);
+
+               updateNodePos();
+       }
+       
+       virtual void addToScene(scene::ISceneManager *smgr);
+
+       virtual void removeFromScene()
+       {
+               if(m_node == NULL)
+                       return;
+
+               m_node->remove();
+               m_node = NULL;
+       }
+
+       virtual void updateLight(u8 light_at_pos)
+       {
+               if(m_node == NULL)
+                       return;
+
+               u8 li = decode_light(light_at_pos);
+               video::SColor color(255,li,li,li);
+
+               scene::IMesh *mesh = m_node->getMesh();
+               
+               u16 mc = mesh->getMeshBufferCount();
+               for(u16 j=0; j<mc; j++)
+               {
+                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                       video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+                       u16 vc = buf->getVertexCount();
+                       for(u16 i=0; i<vc; i++)
+                       {
+                               vertices[i].Color = color;
+                       }
+               }
+       }
+       
+#endif
+
+       /*
+               Special methods
+       */
+       
+       void updateNodePos()
+       {
+               if(m_node == NULL)
+                       return;
+
+               m_node->setPosition(getAbsoluteShowPos());
+               m_node->setRotation(v3f(0, -m_yaw+180, 0));
        }
        
 protected:
        scene::IMeshSceneNode *m_node;
-       std::string m_text;
-       f32 m_yaw;
+       float m_yaw;
+
+       v3f m_oldpos;
 };
 
 struct DistanceSortedObject
@@ -831,12 +1038,16 @@ class MapBlockObjectList
 public:
        MapBlockObjectList(MapBlock *block);
        ~MapBlockObjectList();
+
        // Writes the count, id, the type id and the parameters of all objects
        void serialize(std::ostream &os, u8 version);
+
        // Reads ids, type_ids and parameters.
        // Creates, updates and deletes objects.
        // If smgr!=NULL, new objects are added to the scene
-       void update(std::istream &is, u8 version, scene::ISceneManager *smgr);
+       void update(std::istream &is, u8 version, scene::ISceneManager *smgr,
+                       u32 daynight_ratio);
+
        // Finds a new unique id
        s16 getFreeId() throw(ContainerFullException);
        /*
@@ -871,7 +1082,7 @@ class MapBlockObjectList
 
        // Steps all objects and if server==true, removes those that
        // want to be removed
-       void step(float dtime, bool server);
+       void step(float dtime, bool server, u32 daynight_ratio);
 
        // Wraps an object that wants to move onto this block from an another
        // Returns true if wrapping was impossible
@@ -892,6 +1103,8 @@ class MapBlockObjectList
        // Key is id
        core::map<s16, MapBlockObject*> m_objects;
        MapBlock *m_block;
+
+       u32 m_last_update_daynight_ratio;
 };