mobv2
authorPerttu Ahola <celeron55@gmail.com>
Fri, 14 Oct 2011 23:28:57 +0000 (02:28 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Fri, 14 Oct 2011 23:28:57 +0000 (02:28 +0300)
29 files changed:
data/dungeon_master.png [new file with mode: 0644]
data/fireball.png [new file with mode: 0644]
src/CMakeLists.txt
src/MyBillboardSceneNode.cpp [new file with mode: 0644]
src/MyBillboardSceneNode.h [new file with mode: 0644]
src/client.cpp
src/client.h
src/clientobject.cpp
src/clientobject.h
src/content_cao.cpp
src/content_cao.h
src/content_object.h
src/content_sao.cpp
src/content_sao.h
src/defaultsettings.cpp
src/environment.cpp
src/environment.h
src/game.cpp
src/inventory.cpp
src/inventory.h
src/mapblock.cpp
src/mapblock.h
src/mapblockobject.cpp [deleted file]
src/mapblockobject.h [deleted file]
src/mapgen.cpp
src/server.cpp
src/settings.h
src/tile.cpp
src/utility.h

diff --git a/data/dungeon_master.png b/data/dungeon_master.png
new file mode 100644 (file)
index 0000000..77e015c
Binary files /dev/null and b/data/dungeon_master.png differ
diff --git a/data/fireball.png b/data/fireball.png
new file mode 100644 (file)
index 0000000..5231428
Binary files /dev/null and b/data/fireball.png differ
index 1d3218bcd67c8d8cab7a6cb74ecd2a2dc630a90d..ab50394f7270850718d439980b19d7a643615e8b 100644 (file)
@@ -107,7 +107,6 @@ set(common_SRCS
        defaultsettings.cpp
        mapnode.cpp
        voxel.cpp
-       mapblockobject.cpp
        inventory.cpp
        debug.cpp
        serialization.cpp
@@ -137,6 +136,7 @@ endif()
 # Client sources
 set(minetest_SRCS
        ${common_SRCS}
+       MyBillboardSceneNode.cpp
        content_mapblock.cpp
        content_cao.cpp
        mapblock_mesh.cpp
diff --git a/src/MyBillboardSceneNode.cpp b/src/MyBillboardSceneNode.cpp
new file mode 100644 (file)
index 0000000..0dfa59b
--- /dev/null
@@ -0,0 +1,202 @@
+// Copyright (C) 2002-2010 Nikolaus Gebhardt\r
+// This file is part of the "Irrlicht Engine".\r
+// For conditions of distribution and use, see copyright notice in irrlicht.h\r
+\r
+#include "MyBillboardSceneNode.h"\r
+#include "IVideoDriver.h"\r
+#include "ISceneManager.h"\r
+#include "ICameraSceneNode.h"\r
+\r
+namespace irr\r
+{\r
+namespace scene\r
+{\r
+\r
+//! constructor\r
+MyBillboardSceneNode::MyBillboardSceneNode(ISceneNode* parent,\r
+               ISceneManager* mgr, s32 id,\r
+               const core::vector3df& position, const core::dimension2d<f32>& size)\r
+       : IBillboardSceneNode(parent, mgr, id, position)\r
+{\r
+       #ifdef _DEBUG\r
+       setDebugName("MyBillboardSceneNode");\r
+       #endif\r
+\r
+       setSize(size);\r
+\r
+       indices[0] = 0;\r
+       indices[1] = 2;\r
+       indices[2] = 1;\r
+       indices[3] = 0;\r
+       indices[4] = 3;\r
+       indices[5] = 2;\r
+\r
+       video::SColor colorTop = video::SColor(0xFFFFFFFF);\r
+       video::SColor colorBottom = video::SColor(0xFFFFFFFF);\r
+\r
+       vertices[0].TCoords.set(1.0f, 1.0f);\r
+       vertices[0].Color = colorBottom;\r
+\r
+       vertices[1].TCoords.set(1.0f, 0.0f);\r
+       vertices[1].Color = colorTop;\r
+\r
+       vertices[2].TCoords.set(0.0f, 0.0f);\r
+       vertices[2].Color = colorTop;\r
+\r
+       vertices[3].TCoords.set(0.0f, 1.0f);\r
+       vertices[3].Color = colorBottom;\r
+}\r
+\r
+\r
+//! pre render event\r
+void MyBillboardSceneNode::OnRegisterSceneNode()\r
+{\r
+       if (IsVisible)\r
+               SceneManager->registerNodeForRendering(this);\r
+\r
+       ISceneNode::OnRegisterSceneNode();\r
+}\r
+\r
+\r
+//! render\r
+void MyBillboardSceneNode::render()\r
+{\r
+       video::IVideoDriver* driver = SceneManager->getVideoDriver();\r
+       ICameraSceneNode* camera = SceneManager->getActiveCamera();\r
+\r
+       if (!camera || !driver)\r
+               return;\r
+\r
+       // make billboard look to camera\r
+\r
+       core::vector3df pos = getAbsolutePosition();\r
+\r
+       core::vector3df campos = camera->getAbsolutePosition();\r
+       core::vector3df target = camera->getTarget();\r
+       core::vector3df up = camera->getUpVector();\r
+       core::vector3df view = target - campos;\r
+       view.normalize();\r
+\r
+       core::vector3df horizontal = up.crossProduct(view);\r
+       if ( horizontal.getLength() == 0 )\r
+       {\r
+               horizontal.set(up.Y,up.X,up.Z);\r
+       }\r
+       horizontal.normalize();\r
+       horizontal *= 0.5f * Size.Width;\r
+\r
+       core::vector3df vertical = horizontal.crossProduct(view);\r
+       vertical.normalize();\r
+       vertical *= 0.5f * Size.Height;\r
+\r
+       view *= -1.0f;\r
+\r
+       for (s32 i=0; i<4; ++i)\r
+               vertices[i].Normal = view;\r
+\r
+       vertices[0].Pos = pos + horizontal + vertical;\r
+       vertices[1].Pos = pos + horizontal - vertical;\r
+       vertices[2].Pos = pos - horizontal - vertical;\r
+       vertices[3].Pos = pos - horizontal + vertical;\r
+\r
+       // draw\r
+\r
+       if ( DebugDataVisible & scene::EDS_BBOX )\r
+       {\r
+               driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);\r
+               video::SMaterial m;\r
+               m.Lighting = false;\r
+               driver->setMaterial(m);\r
+               driver->draw3DBox(BBox, video::SColor(0,208,195,152));\r
+       }\r
+\r
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);\r
+\r
+       driver->setMaterial(Material);\r
+\r
+       driver->drawIndexedTriangleList(vertices, 4, indices, 2);\r
+}\r
+\r
+\r
+//! returns the axis aligned bounding box of this node\r
+const core::aabbox3d<f32>& MyBillboardSceneNode::getBoundingBox() const\r
+{\r
+       return BBox;\r
+}\r
+\r
+\r
+//! sets the size of the billboard\r
+void MyBillboardSceneNode::setSize(const core::dimension2d<f32>& size)\r
+{\r
+       Size = size;\r
+\r
+       if (Size.Width == 0.0f)\r
+               Size.Width = 1.0f;\r
+\r
+       if (Size.Height == 0.0f )\r
+               Size.Height = 1.0f;\r
+\r
+       f32 avg = (size.Width + size.Height)/6;\r
+       BBox.MinEdge.set(-avg,-avg,-avg);\r
+       BBox.MaxEdge.set(avg,avg,avg);\r
+}\r
+\r
+\r
+video::SMaterial& MyBillboardSceneNode::getMaterial(u32 i)\r
+{\r
+       return Material;\r
+}\r
+\r
+\r
+//! returns amount of materials used by this scene node.\r
+u32 MyBillboardSceneNode::getMaterialCount() const\r
+{\r
+       return 1;\r
+}\r
+\r
+\r
+//! gets the size of the billboard\r
+const core::dimension2d<f32>& MyBillboardSceneNode::getSize() const\r
+{\r
+       return Size;\r
+}\r
+\r
+\r
+//! Set the color of all vertices of the billboard\r
+//! \param overallColor: the color to set\r
+void MyBillboardSceneNode::setColor(const video::SColor & overallColor)\r
+{\r
+       for(u32 vertex = 0; vertex < 4; ++vertex)\r
+               vertices[vertex].Color = overallColor;\r
+}\r
+\r
+\r
+//! Set the color of the top and bottom vertices of the billboard\r
+//! \param topColor: the color to set the top vertices\r
+//! \param bottomColor: the color to set the bottom vertices\r
+void MyBillboardSceneNode::setColor(const video::SColor & topColor, const video::SColor & bottomColor)\r
+{\r
+       vertices[0].Color = bottomColor;\r
+       vertices[1].Color = topColor;\r
+       vertices[2].Color = topColor;\r
+       vertices[3].Color = bottomColor;\r
+}\r
+\r
+\r
+//! Gets the color of the top and bottom vertices of the billboard\r
+//! \param[out] topColor: stores the color of the top vertices\r
+//! \param[out] bottomColor: stores the color of the bottom vertices\r
+void MyBillboardSceneNode::getColor(video::SColor & topColor, video::SColor & bottomColor) const\r
+{\r
+       bottomColor = vertices[0].Color;\r
+       topColor = vertices[1].Color;\r
+}\r
+       \r
+void MyBillboardSceneNode::setTCoords(u32 i, core::vector2d<f32> c)\r
+{\r
+       vertices[i].TCoords = c;\r
+}\r
+\r
+} // end namespace scene\r
+} // end namespace irr\r
+\r
diff --git a/src/MyBillboardSceneNode.h b/src/MyBillboardSceneNode.h
new file mode 100644 (file)
index 0000000..935993d
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright (C) 2002-2010 Nikolaus Gebhardt\r
+// This file is part of the "Irrlicht Engine".\r
+// For conditions of distribution and use, see copyright notice in irrlicht.h\r
+\r
+#ifndef __C_BILLBOARD_SCENE_NODE_H_INCLUDED__\r
+#define __C_BILLBOARD_SCENE_NODE_H_INCLUDED__\r
+\r
+#include "IBillboardSceneNode.h"\r
+#include "S3DVertex.h"\r
+\r
+namespace irr\r
+{\r
+namespace scene\r
+{\r
+\r
+//! Scene node which is a billboard. A billboard is like a 3d sprite: A 2d element,\r
+//! which always looks to the camera. \r
+class MyBillboardSceneNode : virtual public IBillboardSceneNode\r
+{\r
+public:\r
+\r
+       //! constructor\r
+       MyBillboardSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 id,\r
+               const core::vector3df& position, const core::dimension2d<f32>& size);\r
+\r
+       //! pre render event\r
+       virtual void OnRegisterSceneNode();\r
+\r
+       //! render\r
+       virtual void render();\r
+\r
+       //! returns the axis aligned bounding box of this node\r
+       virtual const core::aabbox3d<f32>& getBoundingBox() const;\r
+\r
+       //! sets the size of the billboard\r
+       virtual void setSize(const core::dimension2d<f32>& size);\r
+\r
+       //! gets the size of the billboard\r
+       virtual const core::dimension2d<f32>& getSize() const;\r
+\r
+       virtual video::SMaterial& getMaterial(u32 i);\r
+       \r
+       //! returns amount of materials used by this scene node.\r
+       virtual u32 getMaterialCount() const;\r
+       \r
+       //! Set the color of all vertices of the billboard\r
+       //! \param overallColor: the color to set\r
+       virtual void setColor(const video::SColor & overallColor);\r
+\r
+       //! Set the color of the top and bottom vertices of the billboard\r
+       //! \param topColor: the color to set the top vertices\r
+       //! \param bottomColor: the color to set the bottom vertices\r
+       virtual void setColor(const video::SColor & topColor, const video::SColor & bottomColor);\r
+\r
+       //! Gets the color of the top and bottom vertices of the billboard\r
+       //! \param[out] topColor: stores the color of the top vertices\r
+       //! \param[out] bottomColor: stores the color of the bottom vertices\r
+       virtual void getColor(video::SColor& topColor, video::SColor& bottomColor) const;\r
+\r
+       virtual void setTCoords(u32 i, core::vector2d<f32> c);\r
+\r
+private:\r
+\r
+       core::dimension2d<f32> Size;\r
+       core::aabbox3d<f32> BBox;\r
+       video::SMaterial Material;\r
+\r
+       video::S3DVertex vertices[4];\r
+       u16 indices[6];\r
+};\r
+\r
+\r
+} // end namespace scene\r
+} // end namespace irr\r
+\r
+#endif\r
+\r
index ee66e648e24bb58bab06b17fe8438607cab6eb86..1e81a464c89a22d05582c2e5a64666146d015bc1 100644 (file)
@@ -522,24 +522,6 @@ void Client::step(float dtime)
                // Step environment
                m_env.step(dtime);
                
-               /*
-                       Handle active blocks
-                       NOTE: These old objects are DEPRECATED. TODO: Remove
-               */
-               for(core::map<v3s16, bool>::Iterator
-                               i = m_active_blocks.getIterator();
-                               i.atEnd() == false; i++)
-               {
-                       v3s16 p = i.getNode()->getKey();
-
-                       MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(p);
-                       if(block == NULL)
-                               continue;
-                       
-                       // Step MapBlockObjects
-                       block->stepObjects(dtime, false, m_env.getDayNightRatio());
-               }
-
                /*
                        Get events
                */
@@ -1191,16 +1173,11 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
        }
        //DEBUG
        else if(command == TOCLIENT_OBJECTDATA)
-       //else if(0)
        {
                // Strip command word and create a stringstream
                std::string datastring((char*)&data[2], datasize-2);
                std::istringstream is(datastring, std::ios_base::binary);
                
-               { //envlock
-               
-               //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
-
                u8 buf[12];
 
                /*
@@ -1250,106 +1227,16 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
 
                /*
                        Read block objects
-                       NOTE: Deprecated stuff here, TODO: Remove
+                       NOTE: Deprecated stuff
                */
 
                // Read active block count
-               is.read((char*)buf, 2);
-               u16 blockcount = readU16(buf);
-               
-               // Initialize delete queue with all active blocks
-               core::map<v3s16, bool> abs_to_delete;
-               for(core::map<v3s16, bool>::Iterator
-                               i = m_active_blocks.getIterator();
-                               i.atEnd() == false; i++)
-               {
-                       v3s16 p = i.getNode()->getKey();
-                       /*dstream<<"adding "
-                                       <<"("<<p.x<<","<<p.y<<","<<p.z<<") "
-                                       <<" to abs_to_delete"
-                                       <<std::endl;*/
-                       abs_to_delete.insert(p, true);
-               }
-
-               /*dstream<<"Initial delete queue size: "<<abs_to_delete.size()
-                               <<std::endl;*/
-               
-               for(u16 i=0; i<blockcount; i++)
-               {
-                       // Read blockpos
-                       is.read((char*)buf, 6);
-                       v3s16 p = readV3S16(buf);
-                       // Get block from somewhere
-                       MapBlock *block = NULL;
-                       try{
-                               block = m_env.getMap().getBlockNoCreate(p);
-                       }
-                       catch(InvalidPositionException &e)
-                       {
-                               //TODO: Create a dummy block?
-                       }
-                       if(block == NULL)
-                       {
-                               dstream<<"WARNING: "
-                                               <<"Could not get block at blockpos "
-                                               <<"("<<p.X<<","<<p.Y<<","<<p.Z<<") "
-                                               <<"in TOCLIENT_OBJECTDATA. Ignoring "
-                                               <<"following block object data."
-                                               <<std::endl;
-                               return;
-                       }
-
-                       /*dstream<<"Client updating objects for block "
-                                       <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
-                                       <<std::endl;*/
-
-                       // Insert to active block list
-                       m_active_blocks.insert(p, true);
-
-                       // Remove from deletion queue
-                       if(abs_to_delete.find(p) != NULL)
-                               abs_to_delete.remove(p);
-
-                       /*
-                               Update objects of block
-                               
-                               NOTE: Be sure this is done in the main thread.
-                       */
-                       block->updateObjects(is, m_server_ser_ver,
-                                       m_device->getSceneManager(), m_env.getDayNightRatio());
-               }
-               
-               /*dstream<<"Final delete queue size: "<<abs_to_delete.size()
-                               <<std::endl;*/
-               
-               // Delete objects of blocks in delete queue
-               for(core::map<v3s16, bool>::Iterator
-                               i = abs_to_delete.getIterator();
-                               i.atEnd() == false; i++)
-               {
-                       v3s16 p = i.getNode()->getKey();
-                       try
-                       {
-                               MapBlock *block = m_env.getMap().getBlockNoCreate(p);
-                               
-                               // Clear objects
-                               block->clearObjects();
-                               // Remove from active blocks list
-                               m_active_blocks.remove(p);
-                       }
-                       catch(InvalidPositionException &e)
-                       {
-                               dstream<<"WARNAING: Client: "
-                                               <<"Couldn't clear objects of active->inactive"
-                                               <<" block "
-                                               <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
-                                               <<" because block was not found"
-                                               <<std::endl;
-                               // Ignore
-                       }
+               u16 blockcount = readU16(is);
+               if(blockcount != 0){
+                       dstream<<"WARNING: TOCLIENT_OBJECTDATA: blockcount != 0 "
+                                       "not supported"<<std::endl;
+                       return;
                }
-
-               } //envlock
        }
        else if(command == TOCLIENT_TIME_OF_DAY)
        {
@@ -1636,32 +1523,6 @@ void Client::groundAction(u8 action, v3s16 nodepos_undersurface,
        Send(0, data, true);
 }
 
-void Client::clickObject(u8 button, v3s16 blockpos, s16 id, u16 item)
-{
-       if(connectedAndInitialized() == false){
-               dout_client<<DTIME<<"Client::clickObject() "
-                               "cancelled (not connected)"
-                               <<std::endl;
-               return;
-       }
-       
-       /*
-               [0] u16 command=TOSERVER_CLICK_OBJECT
-               [2] u8 button (0=left, 1=right)
-               [3] v3s16 block
-               [9] s16 id
-               [11] u16 item
-       */
-       u8 datasize = 2 + 1 + 6 + 2 + 2;
-       SharedBuffer<u8> data(datasize);
-       writeU16(&data[0], TOSERVER_CLICK_OBJECT);
-       writeU8(&data[2], button);
-       writeV3S16(&data[3], blockpos);
-       writeS16(&data[9], id);
-       writeU16(&data[11], item);
-       Send(0, data, true);
-}
-
 void Client::clickActiveObject(u8 button, u16 id, u16 item)
 {
        if(connectedAndInitialized() == false){
@@ -1687,45 +1548,6 @@ void Client::clickActiveObject(u8 button, u16 id, u16 item)
        Send(0, data, true);
 }
 
-void Client::sendSignText(v3s16 blockpos, s16 id, std::string text)
-{
-       /*
-               u16 command
-               v3s16 blockpos
-               s16 id
-               u16 textlen
-               textdata
-       */
-       std::ostringstream os(std::ios_base::binary);
-       u8 buf[12];
-       
-       // Write command
-       writeU16(buf, TOSERVER_SIGNTEXT);
-       os.write((char*)buf, 2);
-       
-       // Write blockpos
-       writeV3S16(buf, blockpos);
-       os.write((char*)buf, 6);
-
-       // Write id
-       writeS16(buf, id);
-       os.write((char*)buf, 2);
-
-       u16 textlen = text.size();
-       // Write text length
-       writeS16(buf, textlen);
-       os.write((char*)buf, 2);
-
-       // Write text
-       os.write((char*)text.c_str(), textlen);
-       
-       // Make data buffer
-       std::string s = os.str();
-       SharedBuffer<u8> data((u8*)s.c_str(), s.size());
-       // Send as reliable
-       Send(0, data, true);
-}
-       
 void Client::sendSignNodeText(v3s16 p, std::string text)
 {
        /*
@@ -2083,71 +1905,6 @@ void Client::inventoryAction(InventoryAction *a)
        sendInventoryAction(a);
 }
 
-MapBlockObject * Client::getSelectedObject(
-               f32 max_d,
-               v3f from_pos_f_on_map,
-               core::line3d<f32> shootline_on_map
-       )
-{
-       //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
-
-       core::array<DistanceSortedObject> objects;
-
-       for(core::map<v3s16, bool>::Iterator
-                       i = m_active_blocks.getIterator();
-                       i.atEnd() == false; i++)
-       {
-               v3s16 p = i.getNode()->getKey();
-
-               MapBlock *block = NULL;
-               try
-               {
-                       block = m_env.getMap().getBlockNoCreate(p);
-               }
-               catch(InvalidPositionException &e)
-               {
-                       continue;
-               }
-
-               // Calculate from_pos relative to block
-               v3s16 block_pos_i_on_map = block->getPosRelative();
-               v3f block_pos_f_on_map = intToFloat(block_pos_i_on_map, BS);
-               v3f from_pos_f_on_block = from_pos_f_on_map - block_pos_f_on_map;
-
-               block->getObjects(from_pos_f_on_block, max_d, objects);
-               //block->getPseudoObjects(from_pos_f_on_block, max_d, objects);
-       }
-
-       //dstream<<"Collected "<<objects.size()<<" nearby objects"<<std::endl;
-       
-       // Sort them.
-       // After this, the closest object is the first in the array.
-       objects.sort();
-
-       for(u32 i=0; i<objects.size(); i++)
-       {
-               MapBlockObject *obj = objects[i].obj;
-               MapBlock *block = obj->getBlock();
-
-               // Calculate shootline relative to block
-               v3s16 block_pos_i_on_map = block->getPosRelative();
-               v3f block_pos_f_on_map = intToFloat(block_pos_i_on_map, BS);
-               core::line3d<f32> shootline_on_block(
-                               shootline_on_map.start - block_pos_f_on_map,
-                               shootline_on_map.end - block_pos_f_on_map
-               );
-
-               if(obj->isSelected(shootline_on_block))
-               {
-                       //dstream<<"Returning selected object"<<std::endl;
-                       return obj;
-               }
-       }
-
-       //dstream<<"No object selected; returning NULL."<<std::endl;
-       return NULL;
-}
-
 ClientActiveObject * Client::getSelectedActiveObject(
                f32 max_d,
                v3f from_pos_f_on_map,
index 930987c02e7f676f1289626c4ad44bdb85dc5aef..87c7e328dbca8ac94762cf317b5e09a3325591be 100644 (file)
@@ -183,10 +183,8 @@ public:
 
        void groundAction(u8 action, v3s16 nodepos_undersurface,
                        v3s16 nodepos_oversurface, u16 item);
-       void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item);
        void clickActiveObject(u8 button, u16 id, u16 item);
 
-       void sendSignText(v3s16 blockpos, s16 id, std::string text);
        void sendSignNodeText(v3s16 p, std::string text);
        void sendInventoryAction(InventoryAction *a);
        void sendChatMessage(const std::wstring &message);
@@ -225,14 +223,6 @@ public:
        Inventory* getInventory(InventoryContext *c, std::string id);
        void inventoryAction(InventoryAction *a);
 
-       // Gets closest object pointed by the shootline
-       // Returns NULL if not found
-       MapBlockObject * getSelectedObject(
-                       f32 max_d,
-                       v3f from_pos_f_on_map,
-                       core::line3d<f32> shootline_on_map
-       );
-
        // Gets closest object pointed by the shootline
        // Returns NULL if not found
        ClientActiveObject * getSelectedActiveObject(
index bec9f46fdd0c8a6cb5942c92cbe2fb55fbf5e36b..ee2ad0b9fcd7cf0aa71fc6ee3ba768761abed0fe 100644 (file)
@@ -45,7 +45,7 @@ ClientActiveObject* ClientActiveObject::create(u8 type)
        {
                // If factory is not found, just return.
                dstream<<"WARNING: ClientActiveObject: No factory for type="
-                               <<type<<std::endl;
+                               <<(int)type<<std::endl;
                return NULL;
        }
 
index c90648483005105d11ccab1db507ac8008074256..6a12c718b2661ce31230f3e6ae21aea914f1d904 100644 (file)
@@ -51,6 +51,7 @@ public:
        virtual core::aabbox3d<f32>* getSelectionBox(){return NULL;}
        virtual core::aabbox3d<f32>* getCollisionBox(){return NULL;}
        virtual v3f getPosition(){return v3f(0,0,0);}
+       virtual bool doShowSelectionBox(){return true;}
        
        // Step object in time
        virtual void step(float dtime, ClientEnvironment *env){}
index b6543061aea6b38c612820d9dd2cffdf8238bbdb..88c8d58a99a1c703b72d78ae5d4d95582cc3ee14 100644 (file)
@@ -20,6 +20,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "content_cao.h"
 #include "tile.h"
 #include "environment.h"
+#include "settings.h"
+#include <ICameraSceneNode.h>
 
 core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
 
@@ -683,7 +685,7 @@ void Oerkki1CAO::processMessage(const std::string &data)
        }
        else if(cmd == 1)
        {
-               u16 damage = readU8(is);
+               //u16 damage = readU8(is);
                m_damage_visual_timer = 1.0;
        }
 }
@@ -850,3 +852,377 @@ void FireflyCAO::initialize(const std::string &data)
        
        updateNodePos();
 }
+
+/*
+       MobV2CAO
+*/
+
+// Prototype
+MobV2CAO proto_MobV2CAO;
+
+MobV2CAO::MobV2CAO():
+       ClientActiveObject(0),
+       m_selection_box(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS),
+       m_node(NULL),
+       m_position(v3f(0,10*BS,0)),
+       m_yaw(0),
+       m_walking(false),
+       m_walking_unset_timer(0),
+       m_walk_timer(0),
+       m_walk_frame(0),
+       m_damage_visual_timer(0),
+       m_last_light(0),
+       m_shooting(0),
+       m_shooting_unset_timer(0),
+       m_bright_shooting(false),
+       m_player_hit_timer(0)
+{
+       ClientActiveObject::registerType(getType(), create);
+
+       m_properties = new Settings;
+}
+
+MobV2CAO::~MobV2CAO()
+{
+       delete m_properties;
+}
+
+ClientActiveObject* MobV2CAO::create()
+{
+       return new MobV2CAO();
+}
+
+void MobV2CAO::addToScene(scene::ISceneManager *smgr)
+{
+       if(m_node != NULL)
+               return;
+       
+       std::string texture_name = m_properties->get("texture_name");
+       //dstream<<"MobV2CAO::addToScene using texture_name="<<texture_name<<std::endl;
+       std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
+       texture_string += texture_name;
+       
+       scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
+                       smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
+       bill->setMaterialTexture(0, g_texturesource->getTextureRaw(texture_string));
+       bill->setMaterialFlag(video::EMF_LIGHTING, false);
+       bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
+       bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
+       bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
+       bill->setColor(video::SColor(255,0,0,0));
+       bill->setVisible(false); /* Set visible when brightness is known */
+       bill->setSize(m_sprite_size);
+       if(m_sprite_type == "humanoid_1"){
+               const float txp = 1./192;
+               const float txs = txp*32;
+               const float typ = 1./240;
+               const float tys = typ*48;
+               bill->setTCoords(0, v2f(txs*1, tys*1));
+               bill->setTCoords(1, v2f(txs*1, tys*0));
+               bill->setTCoords(2, v2f(txs*0, tys*0));
+               bill->setTCoords(3, v2f(txs*0, tys*1));
+       } else if(m_sprite_type == "simple"){
+               const float txs = 1.0;
+               const float tys = 1.0 / m_simple_anim_frames;
+               bill->setTCoords(0, v2f(txs*1, tys*1));
+               bill->setTCoords(1, v2f(txs*1, tys*0));
+               bill->setTCoords(2, v2f(txs*0, tys*0));
+               bill->setTCoords(3, v2f(txs*0, tys*1));
+       } else {
+               dstream<<"MobV2CAO: Unknown sprite type \""<<m_sprite_type<<"\""
+                               <<std::endl;
+       }
+
+       m_node = bill;
+
+       updateNodePos();
+}
+
+void MobV2CAO::removeFromScene()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->drop();
+       m_node->remove();
+       m_node = NULL;
+}
+
+void MobV2CAO::updateLight(u8 light_at_pos)
+{
+       if(m_lock_full_brightness)
+               light_at_pos = 15;
+       
+       m_last_light = light_at_pos;
+
+       if(m_node == NULL)
+               return;
+       
+       if(m_damage_visual_timer > 0)
+               return;
+       
+       if(m_shooting && m_bright_shooting)
+               return;
+       
+       /*if(light_at_pos <= 2){
+               m_node->setVisible(false);
+               return;
+       }*/
+
+       m_node->setVisible(true);
+
+       u8 li = decode_light(light_at_pos);
+       video::SColor color(255,li,li,li);
+       m_node->setColor(color);
+}
+
+v3s16 MobV2CAO::getLightPosition()
+{
+       return floatToInt(m_position+v3f(0,0,0), BS);
+}
+
+void MobV2CAO::updateNodePos()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->setPosition(pos_translator.vect_show + m_sprite_pos);
+}
+
+void MobV2CAO::step(float dtime, ClientEnvironment *env)
+{
+       scene::MyBillboardSceneNode *bill = m_node;
+
+       pos_translator.translate(dtime);
+       
+       if(m_sprite_type == "humanoid_1"){
+               scene::ICameraSceneNode* camera = m_node->getSceneManager()->getActiveCamera();
+               v3f cam_to_mob = m_node->getAbsolutePosition() - camera->getAbsolutePosition();
+               cam_to_mob.normalize();
+               int col = 0;
+               if(cam_to_mob.Y > 0.7)
+                       col = 5;
+               else if(cam_to_mob.Y < -0.7)
+                       col = 4;
+               else{
+                       float mob_dir = atan2(cam_to_mob.Z, cam_to_mob.X) / M_PI * 180.;
+                       float dir = mob_dir - m_yaw;
+                       dir = wrapDegrees_180(dir);
+                       //dstream<<"id="<<m_id<<" dir="<<dir<<std::endl;
+                       if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
+                               col = 2;
+                       else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
+                               col = 3;
+                       else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
+                               col = 0;
+                       else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
+                               col = 1;
+                       else
+                               col = 4;
+               }
+
+               int row = 0;
+               if(m_shooting){
+                       row = 3;
+               } else if(m_walking){
+                       m_walk_timer += dtime;
+                       if(m_walk_timer >= 0.5){
+                               m_walk_frame = (m_walk_frame + 1) % 2;
+                               m_walk_timer = 0;
+                       }
+                       if(m_walk_frame == 0)
+                               row = 1;
+                       else
+                               row = 2;
+               }
+
+               const float txp = 1./192;
+               const float txs = txp*32;
+               const float typ = 1./240;
+               const float tys = typ*48;
+               bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
+               bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
+               bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
+               bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
+       } else if(m_sprite_type == "simple"){
+               m_walk_timer += dtime;
+               if(m_walk_timer >= m_simple_anim_frametime){
+                       m_walk_frame = (m_walk_frame + 1) % m_simple_anim_frames;
+                       m_walk_timer = 0;
+               }
+               int col = 0;
+               int row = m_walk_frame;
+               const float txs = 1.0;
+               const float tys = 1.0 / m_simple_anim_frames;
+               bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
+               bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
+               bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
+               bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
+       } else {
+               dstream<<"MobV2CAO::step(): Unknown sprite type \""
+                               <<m_sprite_type<<"\""<<std::endl;
+       }
+
+       updateNodePos();
+
+       /* Damage local player */
+       if(m_player_hit_damage && m_player_hit_timer <= 0.0){
+               LocalPlayer *player = env->getLocalPlayer();
+               assert(player);
+               
+               v3f playerpos = player->getPosition();
+               v2f playerpos_2d(playerpos.X,playerpos.Z);
+               v2f objectpos_2d(m_position.X,m_position.Z);
+
+               if(fabs(m_position.Y - playerpos.Y) < m_player_hit_distance*BS &&
+               objectpos_2d.getDistanceFrom(playerpos_2d) < m_player_hit_distance*BS)
+               {
+                       env->damageLocalPlayer(m_player_hit_damage);
+                       m_player_hit_timer = m_player_hit_interval;
+               }
+       }
+
+       /* Run timers */
+
+       m_player_hit_timer -= dtime;
+
+       if(m_damage_visual_timer >= 0){
+               m_damage_visual_timer -= dtime;
+               if(m_damage_visual_timer <= 0){
+                       dstream<<"id="<<m_id<<" damage visual ended"<<std::endl;
+               }
+       }
+
+       m_walking_unset_timer += dtime;
+       if(m_walking_unset_timer >= 1.0){
+               m_walking = false;
+       }
+
+       m_shooting_unset_timer -= dtime;
+       if(m_shooting_unset_timer <= 0.0){
+               if(m_bright_shooting){
+                       u8 li = decode_light(m_last_light);
+                       video::SColor color(255,li,li,li);
+                       bill->setColor(color);
+                       m_bright_shooting = false;
+               }
+               m_shooting = false;
+       }
+
+}
+
+void MobV2CAO::processMessage(const std::string &data)
+{
+       //dstream<<"MobV2CAO: Got message"<<std::endl;
+       std::istringstream is(data, std::ios::binary);
+       // command
+       u8 cmd = readU8(is);
+
+       // Move
+       if(cmd == 0)
+       {
+               // pos
+               m_position = readV3F1000(is);
+               pos_translator.update(m_position);
+               // yaw
+               m_yaw = readF1000(is);
+
+               m_walking = true;
+               m_walking_unset_timer = 0;
+
+               updateNodePos();
+       }
+       // Damage
+       else if(cmd == 1)
+       {
+               //u16 damage = readU16(is);
+
+               u8 li = decode_light(m_last_light);
+               if(li >= 100)
+                       li = 30;
+               else
+                       li = 255;
+               video::SColor color(255,li,li,li);
+               m_node->setColor(color);
+
+               m_damage_visual_timer = 0.2;
+       }
+       // Trigger shooting
+       else if(cmd == 2)
+       {
+               // length
+               m_shooting_unset_timer = readF1000(is);
+               // bright?
+               m_bright_shooting = readU8(is);
+               if(m_bright_shooting){
+                       u8 li = 255;
+                       video::SColor color(255,li,li,li);
+                       m_node->setColor(color);
+               }
+
+               m_shooting = true;
+       }
+}
+
+void MobV2CAO::initialize(const std::string &data)
+{
+       //dstream<<"MobV2CAO: Got init data"<<std::endl;
+       
+       {
+               std::istringstream is(data, std::ios::binary);
+               // version
+               u8 version = readU8(is);
+               // check version
+               if(version != 0){
+                       dstream<<__FUNCTION_NAME<<": Invalid version"<<std::endl;
+                       return;
+               }
+               
+               std::ostringstream tmp_os(std::ios::binary);
+               decompressZlib(is, tmp_os);
+               std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
+               m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
+
+               /*dstream<<"INFO: MobV2CAO::initialize(): got properties:"<<std::endl;
+               m_properties->writeLines(dstream);*/
+
+               m_properties->setDefault("texture_name", "stone.png");
+               m_properties->setDefault("yaw", "0");
+               m_properties->setDefault("pos", "(0,0,0)");
+               m_properties->setDefault("sprite_size", "(1,1)");
+               m_properties->setDefault("sprite_pos", "(0,0,0)");
+               m_properties->setDefault("selection_size", "(0.4,0.4)");
+               m_properties->setDefault("selection_y", "-0.4");
+               m_properties->setDefault("sprite_type", "humanoid_1");
+               m_properties->setDefault("simple_anim_frames", "1");
+               m_properties->setDefault("simple_anim_frametime", "0.5");
+               m_properties->setDefault("lock_full_brightness", "false");
+               m_properties->setDefault("player_hit_damage", "0");
+               m_properties->setDefault("player_hit_distance", "1.5");
+               m_properties->setDefault("player_hit_interval", "1.5");
+               
+               m_yaw = m_properties->getFloat("yaw");
+               m_position = m_properties->getV3F("pos");
+               m_sprite_size = m_properties->getV2F("sprite_size") * BS;
+               m_sprite_pos = m_properties->getV3F("sprite_pos") * BS;
+               v2f selection_size = m_properties->getV2F("selection_size") * BS;
+               float selection_y = m_properties->getFloat("selection_y") * BS;
+               m_selection_box = core::aabbox3d<f32>(
+                               -selection_size.X, selection_y, -selection_size.X,
+                               selection_size.X, selection_y+selection_size.Y,
+                               selection_size.X);
+               m_sprite_type = m_properties->get("sprite_type");
+               m_simple_anim_frames = m_properties->getS32("simple_anim_frames");
+               m_simple_anim_frametime = m_properties->getFloat("simple_anim_frametime");
+               m_lock_full_brightness = m_properties->getBool("lock_full_brightness");
+               m_player_hit_damage = m_properties->getS32("player_hit_damage");
+               m_player_hit_distance = m_properties->getFloat("player_hit_distance");
+               m_player_hit_interval = m_properties->getFloat("player_hit_interval");
+
+               pos_translator.init(m_position);
+       }
+       
+       updateNodePos();
+}
+
+
index 319f90380f6d4a3afa4fe741386507a189215b10..e240d739265fddaf5796adf3918a60d9e227a996 100644 (file)
@@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "clientobject.h"
 #include "content_object.h"
 #include "utility.h" // For IntervalLimiter
+class Settings;
+#include "MyBillboardSceneNode.h"
 
 /*
        SmoothTranslator
@@ -74,11 +76,16 @@ struct SmoothTranslator
                if(anim_time > 0.001)
                        moveratio = anim_time_counter / anim_time;
                // Move a bit less than should, to avoid oscillation
-               moveratio = moveratio * 0.8;
+               moveratio = moveratio * 0.5;
                if(moveratio > 1.5)
                        moveratio = 1.5;
                vect_show = vect_old + vect_move * moveratio;
        }
+
+       bool is_moving()
+       {
+               return ((anim_time_counter / anim_time) < 1.4);
+       }
 };
 
 
@@ -286,6 +293,72 @@ private:
        SmoothTranslator pos_translator;
 };
 
+/*
+       MobV2CAO
+*/
+
+class MobV2CAO : public ClientActiveObject
+{
+public:
+       MobV2CAO();
+       virtual ~MobV2CAO();
+       
+       u8 getType() const
+       {
+               return ACTIVEOBJECT_TYPE_MOBV2;
+       }
+       
+       static ClientActiveObject* create();
+
+       void addToScene(scene::ISceneManager *smgr);
+       void removeFromScene();
+       void updateLight(u8 light_at_pos);
+       v3s16 getLightPosition();
+       void updateNodePos();
+
+       void step(float dtime, ClientEnvironment *env);
+
+       void processMessage(const std::string &data);
+
+       void initialize(const std::string &data);
+       
+       core::aabbox3d<f32>* getSelectionBox()
+               {return &m_selection_box;}
+       v3f getPosition()
+               {return pos_translator.vect_show;}
+               //{return m_position;}
+       bool doShowSelectionBox(){return false;}
+
+private:
+       IntervalLimiter m_attack_interval;
+       core::aabbox3d<f32> m_selection_box;
+       scene::MyBillboardSceneNode *m_node;
+       v3f m_position;
+       float m_yaw;
+       SmoothTranslator pos_translator;
+       bool m_walking;
+       float m_walking_unset_timer;
+       float m_walk_timer;
+       int m_walk_frame;
+       float m_damage_visual_timer;
+       u8 m_last_light;
+       bool m_shooting;
+       float m_shooting_unset_timer;
+       v2f m_sprite_size;
+       v3f m_sprite_pos;
+       bool m_bright_shooting;
+       std::string m_sprite_type;
+       int m_simple_anim_frames;
+       float m_simple_anim_frametime;
+       bool m_lock_full_brightness;
+       int m_player_hit_damage;
+       float m_player_hit_distance;
+       float m_player_hit_interval;
+       float m_player_hit_timer;
+
+       Settings *m_properties;
+};
+
 
 #endif
 
index 47f93d7d4ad492828609f671d139613d00f2aa02..a5fea716351de6b7667d7a6dc76f26273e1be485 100644 (file)
@@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define ACTIVEOBJECT_TYPE_RAT 3
 #define ACTIVEOBJECT_TYPE_OERKKI1 4
 #define ACTIVEOBJECT_TYPE_FIREFLY 5
+#define ACTIVEOBJECT_TYPE_MOBV2 6
 
 #endif
 
index 0bb518c165149678a8747acc1b6ff96f6140aa29..8c9761740db01ab2aa89d9214f2c8591e10d3c76 100644 (file)
@@ -20,9 +20,29 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "content_sao.h"
 #include "collision.h"
 #include "environment.h"
+#include "settings.h"
 
 core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
 
+/* Some helper functions */
+
+// Y is copied, X and Z change is limited
+void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase)
+{
+       v3f d_wanted = target_speed - speed;
+       d_wanted.Y = 0;
+       f32 dl_wanted = d_wanted.getLength();
+       f32 dl = dl_wanted;
+       if(dl > max_increase)
+               dl = max_increase;
+       
+       v3f d = d_wanted.normalize() * dl;
+
+       speed.X += d.X;
+       speed.Z += d.Z;
+       speed.Y = target_speed.Y;
+}
+
 /*
        TestSAO
 */
@@ -422,23 +442,6 @@ InventoryItem* RatSAO::createPickedUpItem()
        Oerkki1SAO
 */
 
-// Y is copied, X and Z change is limited
-void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase)
-{
-       v3f d_wanted = target_speed - speed;
-       d_wanted.Y = 0;
-       f32 dl_wanted = d_wanted.getLength();
-       f32 dl = dl_wanted;
-       if(dl > max_increase)
-               dl = max_increase;
-       
-       v3f d = d_wanted.normalize() * dl;
-
-       speed.X += d.X;
-       speed.Z += d.Z;
-       speed.Y = target_speed.Y;
-}
-
 // Prototype
 Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0));
 
@@ -617,7 +620,7 @@ void Oerkki1SAO::step(float dtime, bool send_recommended)
        m_touching_ground = moveresult.touching_ground;
        
        // Do collision damage
-       float tolerance = BS*12;
+       float tolerance = BS*30;
        float factor = BS*0.5;
        v3f speed_diff = old_speed - m_speed_f;
        // Increase effect in X and Z
@@ -886,3 +889,477 @@ InventoryItem* FireflySAO::createPickedUpItem()
        InventoryItem *item = InventoryItem::deSerialize(is);
        return item;
 }
+
+/*
+       MobV2SAO
+*/
+
+// Prototype
+MobV2SAO proto_MobV2SAO(NULL, 0, v3f(0,0,0), NULL);
+
+MobV2SAO::MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
+               Settings *init_properties):
+       ServerActiveObject(env, id, pos),
+       m_move_type("ground_nodes"),
+       m_speed(0,0,0),
+       m_last_sent_position(0,0,0),
+       m_oldpos(0,0,0),
+       m_yaw(0),
+       m_counter1(0),
+       m_counter2(0),
+       m_age(0),
+       m_touching_ground(false),
+       m_hp(10),
+       m_walk_around(false),
+       m_walk_around_timer(0),
+       m_next_pos_exists(false),
+       m_shoot_reload_timer(0),
+       m_shooting(false),
+       m_shooting_timer(0),
+       m_falling(false)
+{
+       ServerActiveObject::registerType(getType(), create);
+       
+       m_properties = new Settings();
+       if(init_properties)
+               m_properties->update(*init_properties);
+       
+       m_properties->setV3F("pos", pos);
+       
+       setPropertyDefaults();
+       readProperties();
+}
+       
+MobV2SAO::~MobV2SAO()
+{
+       delete m_properties;
+}
+
+ServerActiveObject* MobV2SAO::create(ServerEnvironment *env, u16 id, v3f pos,
+               const std::string &data)
+{
+       std::istringstream is(data, std::ios::binary);
+       Settings properties;
+       properties.parseConfigLines(is, "MobArgsEnd");
+       MobV2SAO *o = new MobV2SAO(env, id, pos, &properties);
+       return o;
+}
+
+std::string MobV2SAO::getStaticData()
+{
+       updateProperties();
+
+       std::ostringstream os(std::ios::binary);
+       m_properties->writeLines(os);
+       return os.str();
+}
+
+std::string MobV2SAO::getClientInitializationData()
+{
+       //dstream<<__FUNCTION_NAME<<std::endl;
+
+       updateProperties();
+
+       std::ostringstream os(std::ios::binary);
+
+       // version
+       writeU8(os, 0);
+       
+       Settings client_properties;
+       
+       /*client_properties.set("version", "0");
+       client_properties.updateValue(*m_properties, "pos");
+       client_properties.updateValue(*m_properties, "yaw");
+       client_properties.updateValue(*m_properties, "hp");*/
+
+       // Just send everything for simplicity
+       client_properties.update(*m_properties);
+
+       std::ostringstream os2(std::ios::binary);
+       client_properties.writeLines(os2);
+       compressZlib(os2.str(), os);
+
+       return os.str();
+}
+
+bool checkFreePosition(Map *map, v3s16 p0, v3s16 size)
+{
+       for(int dx=0; dx<size.X; dx++)
+       for(int dy=0; dy<size.Y; dy++)
+       for(int dz=0; dz<size.Z; dz++){
+               v3s16 dp(dx, dy, dz);
+               v3s16 p = p0 + dp;
+               MapNode n = map->getNodeNoEx(p);
+               if(n.getContent() != CONTENT_AIR)
+                       return false;
+       }
+       return true;
+}
+
+bool checkWalkablePosition(Map *map, v3s16 p0)
+{
+       v3s16 p = p0 + v3s16(0,-1,0);
+       MapNode n = map->getNodeNoEx(p);
+       if(n.getContent() != CONTENT_AIR)
+               return true;
+       return false;
+}
+
+bool checkFreeAndWalkablePosition(Map *map, v3s16 p0, v3s16 size)
+{
+       if(!checkFreePosition(map, p0, size))
+               return false;
+       if(!checkWalkablePosition(map, p0))
+               return false;
+       return true;
+}
+
+static void get_random_u32_array(u32 a[], u32 len)
+{
+       u32 i, n;
+       for(i=0; i<len; i++)
+               a[i] = i;
+       n = len;
+       while(n > 1){
+               u32 k = myrand() % n;
+               n--;
+               u32 temp = a[n];
+               a[n] = a[k];
+               a[k] = temp;
+       }
+}
+
+#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
+
+static void explodeSquare(Map *map, v3s16 p0, v3s16 size)
+{
+       core::map<v3s16, MapBlock*> modified_blocks;
+
+       for(int dx=0; dx<size.X; dx++)
+       for(int dy=0; dy<size.Y; dy++)
+       for(int dz=0; dz<size.Z; dz++){
+               v3s16 dp(dx - size.X/2, dy - size.Y/2, dz - size.Z/2);
+               v3s16 p = p0 + dp;
+               MapNode n = map->getNodeNoEx(p);
+               if(n.getContent() == CONTENT_IGNORE)
+                       continue;
+               //map->removeNodeWithEvent(p);
+               map->removeNodeAndUpdate(p, modified_blocks);
+       }
+
+       // Send a MEET_OTHER event
+       MapEditEvent event;
+       event.type = MEET_OTHER;
+       for(core::map<v3s16, MapBlock*>::Iterator
+                 i = modified_blocks.getIterator();
+                 i.atEnd() == false; i++)
+       {
+               v3s16 p = i.getNode()->getKey();
+               event.modified_blocks.insert(p, true);
+       }
+       map->dispatchEvent(&event);
+}
+
+void MobV2SAO::step(float dtime, bool send_recommended)
+{
+       assert(m_env);
+       Map *map = &m_env->getMap();
+
+       m_age += dtime;
+
+       if(m_die_age >= 0.0 && m_age >= m_die_age){
+               m_removed = true;
+               return;
+       }
+       
+       if(!m_falling)
+       {
+               m_shooting_timer -= dtime;
+               if(m_shooting_timer <= 0.0 && m_shooting){
+                       m_shooting = false;
+                       
+                       std::string shoot_type = m_properties->get("shoot_type");
+                       v3f shoot_pos(0,0,0);
+                       shoot_pos.Y += m_properties->getFloat("shoot_y") * BS;
+                       if(shoot_type == "fireball"){
+                               v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
+                               v3f speed = dir * BS * 10.0;
+                               v3f pos = m_base_position + shoot_pos;
+                               dstream<<__FUNCTION_NAME<<": Shooting fireball from "<<PP(pos)
+                                               <<" at speed "<<PP(speed)<<std::endl;
+                               Settings properties;
+                               properties.setV3F("speed", speed);
+                               properties.setFloat("die_age", 5.0);
+                               properties.set("move_type", "constant_speed");
+                               properties.set("texture_name", "fireball.png");
+                               properties.setV3F("sprite_pos", v3f(0.0, 0.0, 0.0));
+                               properties.setV2F("sprite_size", v2f(1.0, 1.0));
+                               properties.set("sprite_type", "simple");
+                               properties.set("simple_anim_frames", "3");
+                               properties.set("simple_anim_frametime", "0.1");
+                               properties.setFloat("hp", 1000);
+                               properties.set("lock_full_brightness", "true");
+                               properties.set("player_hit_damage", "9");
+                               properties.set("player_hit_distance", "2");
+                               properties.set("player_hit_interval", "1");
+                               ServerActiveObject *obj = new MobV2SAO(m_env, 0,
+                                               pos, &properties);
+                               //m_env->addActiveObjectAsStatic(obj);
+                               m_env->addActiveObject(obj);
+                       } else {
+                               dstream<<__FUNCTION_NAME<<": Unknown shoot_type="<<shoot_type
+                                               <<std::endl;
+                       }
+               }
+
+               m_shoot_reload_timer += dtime;
+
+               if(m_shoot_reload_timer >= 5.0 && !m_next_pos_exists)
+               {
+                       m_shoot_reload_timer = 0.0;
+                       m_shooting = true;
+                       m_shooting_timer = 1.5;
+                       {
+                               std::ostringstream os(std::ios::binary);
+                               // command (2 = shooting)
+                               writeU8(os, 2);
+                               // time
+                               writeF1000(os, m_shooting_timer + 0.1);
+                               // bright?
+                               writeU8(os, true);
+                               // create message and add to list
+                               ActiveObjectMessage aom(getId(), false, os.str());
+                               m_messages_out.push_back(aom);
+                       }
+               }
+       }
+       
+       if(m_move_type == "ground_nodes")
+       {
+               if(!m_shooting){
+                       m_walk_around_timer -= dtime;
+                       if(m_walk_around_timer <= 0.0){
+                               m_walk_around = !m_walk_around;
+                               if(m_walk_around)
+                                       m_walk_around_timer = 0.1*myrand_range(10,50);
+                               else
+                                       m_walk_around_timer = 0.1*myrand_range(30,70);
+                       }
+               }
+
+               /* Move */
+               if(m_next_pos_exists){
+                       v3f pos_f = m_base_position;
+                       v3f next_pos_f = intToFloat(m_next_pos_i, BS);
+
+                       v3f v = next_pos_f - pos_f;
+                       m_yaw = atan2(v.Z, v.X) / M_PI * 180;
+                       
+                       v3f diff = next_pos_f - pos_f;
+                       v3f dir = diff;
+                       dir.normalize();
+                       float speed = BS * 0.5;
+                       if(m_falling)
+                               speed = BS * 3.0;
+                       dir *= dtime * speed;
+                       bool arrived = false;
+                       if(dir.getLength() > diff.getLength()){
+                               dir = diff;
+                               arrived = true;
+                       }
+                       pos_f += dir;
+                       m_base_position = pos_f;
+
+                       if((pos_f - next_pos_f).getLength() < 0.1 || arrived){
+                               //dstream<<"id="<<m_id<<": arrived to "<<PP(m_next_pos_i)<<std::endl;
+                               m_next_pos_exists = false;
+                       }
+               }
+
+               v3s16 pos_i = floatToInt(m_base_position, BS);
+               v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5);
+               v3s16 pos_size_off(0,0,0);
+               if(m_size.X >= 2.5){
+                       pos_size_off.X = -1;
+                       pos_size_off.Y = -1;
+               }
+               
+               if(!m_next_pos_exists){
+                       /* Check whether to drop down */
+                       if(checkFreePosition(map,
+                                       pos_i + pos_size_off + v3s16(0,-1,0), size_blocks)){
+                               m_next_pos_i = pos_i + v3s16(0,-1,0);
+                               m_next_pos_exists = true;
+                               m_falling = true;
+                       } else {
+                               m_falling = false;
+                       }
+               }
+
+               if(m_walk_around)
+               {
+                       if(!m_next_pos_exists){
+                               /* Find some position where to go next */
+                               v3s16 dps[3*3*3];
+                               int num_dps = 0;
+                               for(int dx=-1; dx<=1; dx++)
+                               for(int dy=-1; dy<=1; dy++)
+                               for(int dz=-1; dz<=1; dz++){
+                                       if(dx == 0 && dy == 0)
+                                               continue;
+                                       if(dx != 0 && dz != 0 && dy != 0)
+                                               continue;
+                                       dps[num_dps++] = v3s16(dx,dy,dz);
+                               }
+                               u32 order[3*3*3];
+                               get_random_u32_array(order, num_dps);
+                               /*dstream<<"At pos "<<PP(pos_i)<<"; Random array: ";
+                               for(int i=0; i<num_dps; i++){
+                                       dstream<<order[i]<<" ";
+                               }
+                               dstream<<std::endl;*/
+                               for(int i=0; i<num_dps; i++){
+                                       v3s16 p = dps[order[i]] + pos_i;
+                                       bool is_free = checkFreeAndWalkablePosition(map,
+                                                       p + pos_size_off, size_blocks);
+                                       //dstream<<PP(p)<<" is_free="<<is_free<<std::endl;
+                                       if(!is_free)
+                                               continue;
+                                       m_next_pos_i = p;
+                                       m_next_pos_exists = true;
+                                       break;
+                               }
+                       }
+               }
+       }
+       else if(m_move_type == "constant_speed")
+       {
+               m_base_position += m_speed * dtime;
+               
+               v3s16 pos_i = floatToInt(m_base_position, BS);
+               v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5);
+               v3s16 pos_size_off(0,0,0);
+               if(m_size.X >= 2.5){
+                       pos_size_off.X = -1;
+                       pos_size_off.Y = -1;
+               }
+               bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks);
+               if(!free){
+                       explodeSquare(map, pos_i, v3s16(3,3,3));
+                       m_removed = true;
+                       return;
+               }
+       }
+       else
+       {
+               dstream<<"MobV2SAO::step(): id="<<m_id<<" unknown move_type=\""
+                               <<m_move_type<<"\""<<std::endl;
+       }
+
+       if(send_recommended == false)
+               return;
+
+       if(m_base_position.getDistanceFrom(m_last_sent_position) > 0.05*BS)
+       {
+               m_last_sent_position = m_base_position;
+
+               std::ostringstream os(std::ios::binary);
+               // command (0 = update position)
+               writeU8(os, 0);
+               // pos
+               writeV3F1000(os, m_base_position);
+               // yaw
+               writeF1000(os, m_yaw);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+}
+
+u16 MobV2SAO::punch(const std::string &toolname, v3f dir)
+{
+       u16 amount = 2;
+       dstream<<"id="<<m_id<<": punch with \""<<toolname<<"\""<<std::endl;
+       /* See tool names in inventory.h */
+       if(toolname == "WSword")
+               amount = 4;
+       if(toolname == "STSword")
+               amount = 7;
+       if(toolname == "SteelSword")
+               amount = 10;
+       if(toolname == "STAxe")
+               amount = 3;
+       if(toolname == "SteelAxe")
+               amount = 4;
+       if(toolname == "SteelPick")
+               amount = 3;
+       doDamage(amount);
+       return 65536/100;
+}
+
+void MobV2SAO::setPropertyDefaults()
+{
+       m_properties->setDefault("move_type", "ground_nodes");
+       m_properties->setDefault("speed", "(0,0,0)");
+       m_properties->setDefault("age", "0");
+       m_properties->setDefault("yaw", "0");
+       m_properties->setDefault("pos", "(0,0,0)");
+       m_properties->setDefault("hp", "0");
+       m_properties->setDefault("die_age", "-1");
+       m_properties->setDefault("size", "(1,2)");
+       m_properties->setDefault("shoot_type", "fireball");
+       m_properties->setDefault("shoot_y", "0");
+}
+void MobV2SAO::readProperties()
+{
+       m_move_type = m_properties->get("move_type");
+       m_speed = m_properties->getV3F("speed");
+       m_age = m_properties->getFloat("age");
+       m_yaw = m_properties->getFloat("yaw");
+       m_base_position = m_properties->getV3F("pos");
+       m_hp = m_properties->getS32("hp");
+       m_die_age = m_properties->getFloat("die_age");
+       m_size = m_properties->getV2F("size");
+}
+void MobV2SAO::updateProperties()
+{
+       m_properties->set("move_type", m_move_type);
+       m_properties->setV3F("speed", m_speed);
+       m_properties->setFloat("age", m_age);
+       m_properties->setFloat("yaw", m_yaw);
+       m_properties->setV3F("pos", m_base_position);
+       m_properties->setS32("hp", m_hp);
+       m_properties->setFloat("die_age", m_die_age);
+       m_properties->setV2F("size", m_size);
+
+       m_properties->setS32("version", 0);
+}
+
+void MobV2SAO::doDamage(u16 d)
+{
+       dstream<<"MobV2 hp="<<m_hp<<" damage="<<d<<std::endl;
+       
+       if(d < m_hp)
+       {
+               m_hp -= d;
+       }
+       else
+       {
+               // Die
+               m_hp = 0;
+               m_removed = true;
+       }
+
+       {
+               std::ostringstream os(std::ios::binary);
+               // command (1 = damage)
+               writeU8(os, 1);
+               // amount
+               writeU16(os, d);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+}
+
+
index 060c18341e2479c7827173542024f07074f3ada5..078feb273f4838775ad4e44f19ec0f150b6d420e 100644 (file)
@@ -139,5 +139,52 @@ private:
        bool m_touching_ground;
 };
 
+class Settings;
+
+class MobV2SAO : public ServerActiveObject
+{
+public:
+       MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
+                       Settings *init_properties);
+       virtual ~MobV2SAO();
+       u8 getType() const
+               {return ACTIVEOBJECT_TYPE_MOBV2;}
+       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
+                       const std::string &data);
+       std::string getStaticData();
+       std::string getClientInitializationData();
+       void step(float dtime, bool send_recommended);
+       InventoryItem* createPickedUpItem(){return NULL;}
+       u16 punch(const std::string &toolname, v3f dir);
+private:
+       void setPropertyDefaults();
+       void readProperties();
+       void updateProperties();
+       void doDamage(u16 d);
+       
+       std::string m_move_type;
+       v3f m_speed;
+       v3f m_last_sent_position;
+       v3f m_oldpos;
+       float m_yaw;
+       float m_counter1;
+       float m_counter2;
+       float m_age;
+       bool m_touching_ground;
+       int m_hp;
+       bool m_walk_around;
+       float m_walk_around_timer;
+       bool m_next_pos_exists;
+       v3s16 m_next_pos_i;
+       float m_shoot_reload_timer;
+       bool m_shooting;
+       float m_shooting_timer;
+       float m_die_age;
+       v2f m_size;
+       bool m_falling;
+       
+       Settings *m_properties;
+};
+
 #endif
 
index e25bc90e985507bd29582554cf341acbcba38345..05b0611e9b78c136332eb6cc5b22272bbb508b6a 100644 (file)
@@ -89,7 +89,8 @@ void set_default_settings(Settings *settings)
        settings->setDefault("fixed_map_seed", "");
 
        settings->setDefault("objectdata_interval", "0.2");
-       settings->setDefault("active_object_range", "2");
+       settings->setDefault("active_object_send_range_blocks", "3");
+       settings->setDefault("active_block_range", "5");
        //settings->setDefault("max_simultaneous_block_sends_per_client", "1");
        // This causes frametime jitter on client side, or does it?
        settings->setDefault("max_simultaneous_block_sends_per_client", "2");
index e1e0f8255761d9dbca5800135e479d5703c7d387..124e5631c026d3d24dc604e4196454f2ec9d0588 100644 (file)
@@ -643,6 +643,24 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
        }
 }
 
+static void getMob_dungeon_master(Settings &properties)
+{
+       properties.set("texture_name", "dungeon_master.png");
+       properties.setV3F("sprite_pos", v3f(0.0, 0.85, 0.0));
+       properties.setV2F("sprite_size", v2f(2.0, 3.0));
+       properties.setFloat("selection_y", -0.4);
+       properties.setV2F("selection_size", v2f(0.4, 2.6));
+       properties.setFloat("yaw", 1.57);
+       properties.setFloat("hp", 20);
+       properties.setBool("bright_shooting", true);
+       properties.set("shoot_type", "fireball");
+       properties.set("shoot_y", "0.7");
+       properties.set("sprite_type", "humanoid_1");
+       properties.set("player_hit_damage", "1");
+       properties.set("player_hit_distance", "1.0");
+       properties.set("player_hit_interval", "0.5");
+}
+
 void ServerEnvironment::step(float dtime)
 {
        DSTACK(__FUNCTION_NAME);
@@ -725,7 +743,7 @@ void ServerEnvironment::step(float dtime)
                /*
                        Update list of active blocks, collecting changes
                */
-               const s16 active_block_range = 5;
+               const s16 active_block_range = g_settings->getS16("active_block_range");
                core::map<v3s16, bool> blocks_removed;
                core::map<v3s16, bool> blocks_added;
                m_active_blocks.update(players_blockpos, active_block_range,
@@ -926,14 +944,52 @@ void ServerEnvironment::step(float dtime)
                                        }
                                }
                                /*
-                                       Make trees from saplings!
+                                       Fun things spawn in caves and dungeons
+                               */
+                               if(n.getContent() == CONTENT_STONE ||
+                                               n.getContent() == CONTENT_MOSSYCOBBLE)
+                               {
+                                       if(myrand()%200 == 0 && active_object_count_wider == 0)
+                                       {
+                                               v3s16 p1 = p + v3s16(0,1,0);
+                                               MapNode n1a = m_map->getNodeNoEx(p1+v3s16(0,0,0));
+                                               if(n1a.getLightBlend(getDayNightRatio()) <= 3){
+                                                       MapNode n1b = m_map->getNodeNoEx(p1+v3s16(0,1,0));
+                                                       if(n1a.getContent() == CONTENT_AIR &&
+                                                                       n1b.getContent() == CONTENT_AIR)
+                                                       {
+                                                               v3f pos = intToFloat(p1, BS);
+                                                               int i = myrand()%5;
+                                                               if(i == 0 || i == 1){
+                                                                       Settings properties;
+                                                                       getMob_dungeon_master(properties);
+                                                                       ServerActiveObject *obj = new MobV2SAO(
+                                                                                       this, 0, pos, &properties);
+                                                                       addActiveObject(obj);
+                                                               } else if(i == 2 || i == 3){
+                                                                       for(int j=0; j<3; j++){
+                                                                               ServerActiveObject *obj = new RatSAO(
+                                                                                               this, 0, pos);
+                                                                               addActiveObject(obj);
+                                                                       }
+                                                               } else {
+                                                                       ServerActiveObject *obj = new Oerkki1SAO(
+                                                                                       this, 0, pos);
+                                                                       addActiveObject(obj);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                               /*
+                                       Make trees from saplings!
                                */
                                if(n.getContent() == CONTENT_SAPLING)
                                {
-                                       if(myrand()%50 == 0)
+                                       if(myrand()%50 == 0)
                                        {
-                                               core::map<v3s16, MapBlock*> modified_blocks;
-                                               v3s16 tree_p = p;
+                                               core::map<v3s16, MapBlock*> modified_blocks;
+                                               v3s16 tree_p = p;
                                                ManualMapVoxelManipulator vmanip(m_map);
                                                v3s16 tree_blockp = getNodeBlockPos(tree_p);
                                                vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
@@ -944,8 +1000,8 @@ void ServerEnvironment::step(float dtime)
                                                // update lighting
                                                core::map<v3s16, MapBlock*> lighting_modified_blocks;
                                                for(core::map<v3s16, MapBlock*>::Iterator
-                                                     i = modified_blocks.getIterator();
-                                                     i.atEnd() == false; i++)
+                                                       i = modified_blocks.getIterator();
+                                                       i.atEnd() == false; i++)
                                                {
                                                        lighting_modified_blocks.insert(i.getNode()->getKey(), i.getNode()->getValue());
                                                }
@@ -955,16 +1011,15 @@ void ServerEnvironment::step(float dtime)
                                                MapEditEvent event;
                                                event.type = MEET_OTHER;
                                                for(core::map<v3s16, MapBlock*>::Iterator
-                                                     i = modified_blocks.getIterator();
-                                                     i.atEnd() == false; i++)
-                                               {
-                                                       v3s16 p = i.getNode()->getKey();
+                                                       i = modified_blocks.getIterator();
+                                                       i.atEnd() == false; i++)
+                                               {
+                                                       v3s16 p = i.getNode()->getKey();
                                                        event.modified_blocks.insert(p, true);
                                                }
                                                m_map->dispatchEvent(&event);
                                        }
                                }
-                                               
                        }
                }
        }
@@ -978,7 +1033,7 @@ void ServerEnvironment::step(float dtime)
                // This helps the objects to send data at the same time
                bool send_recommended = false;
                m_send_recommended_timer += dtime;
-               if(m_send_recommended_timer > 0.15)
+               if(m_send_recommended_timer > 0.10)
                {
                        m_send_recommended_timer = 0;
                        send_recommended = true;
@@ -1020,7 +1075,7 @@ void ServerEnvironment::step(float dtime)
        /*
                TEST CODE
        */
-#if 1
+#if 0
        m_random_spawn_timer -= dtime;
        if(m_random_spawn_timer < 0)
        {
@@ -1042,7 +1097,7 @@ void ServerEnvironment::step(float dtime)
                        pos = player->getPosition();
                pos += v3f(
                        myrand_range(-3,3)*BS,
-                       0,
+                       5,
                        myrand_range(-3,3)*BS
                );
 
@@ -1054,7 +1109,14 @@ void ServerEnvironment::step(float dtime)
                //ServerActiveObject *obj = new ItemSAO(this, 0, pos, "CraftItem Stick 1");
                //ServerActiveObject *obj = new RatSAO(this, 0, pos);
                //ServerActiveObject *obj = new Oerkki1SAO(this, 0, pos);
-               ServerActiveObject *obj = new FireflySAO(this, 0, pos);
+               //ServerActiveObject *obj = new FireflySAO(this, 0, pos);
+
+               dstream<<DTIME<<"INFO: Server: Spawning MobV2SAO at "
+                               <<"("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"<<std::endl;
+               
+               Settings properties;
+               getMob_dungeon_master(properties);
+               ServerActiveObject *obj = new MobV2SAO(this, 0, pos, &properties);
                addActiveObject(obj);
        }
 #endif
@@ -1110,6 +1172,47 @@ u16 ServerEnvironment::addActiveObject(ServerActiveObject *object)
        return id;
 }
 
+bool ServerEnvironment::addActiveObjectAsStatic(ServerActiveObject *obj)
+{
+       assert(obj);
+
+       v3f objectpos = obj->getBasePosition(); 
+
+       // The block in which the object resides in
+       v3s16 blockpos_o = getNodeBlockPos(floatToInt(objectpos, BS));
+
+       /*
+               Update the static data
+       */
+
+       // Create new static object
+       std::string staticdata = obj->getStaticData();
+       StaticObject s_obj(obj->getType(), objectpos, staticdata);
+       // Add to the block where the object is located in
+       v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS));
+       // Get or generate the block
+       MapBlock *block = m_map->emergeBlock(blockpos);
+
+       bool succeeded = false;
+
+       if(block)
+       {
+               block->m_static_objects.insert(0, s_obj);
+               block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD);
+               succeeded = true;
+       }
+       else{
+               dstream<<"WARNING: ServerEnvironment::addActiveObjectAsStatic: "
+                               <<"Could not find or generate "
+                               <<"a block for storing static object"<<std::endl;
+               succeeded = false;
+       }
+
+       delete obj;
+
+       return succeeded;
+}
+
 /*
        Finds out what new objects have been added to
        inside a radius around a position
@@ -1894,9 +1997,9 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
        
        obj->setId(id);
 
-       addActiveObject(obj);
-
        obj->initialize(init_data);
+       
+       addActiveObject(obj);
 }
 
 void ClientEnvironment::removeActiveObject(u16 id)
index 055e2b1f68c0fc5ab78e4082ffab09e779c3f5ae..d93caac3bd49d6b49f6de90e10405627cf13fb9a 100644 (file)
@@ -175,6 +175,14 @@ public:
        */
        u16 addActiveObject(ServerActiveObject *object);
        
+       /*
+               Add an active object as a static object to the corresponding
+               MapBlock.
+               Caller allocates memory, ServerEnvironment frees memory.
+               Return value: true if succeeded, false if failed.
+       */
+       bool addActiveObjectAsStatic(ServerActiveObject *object);
+       
        /*
                Find out what new objects have been added to
                inside a radius around a position
index 9e54e6ad311909671db0e6cfa5a8cf1ede9bc7cf..e8d0238a3742a0c946e3b93329fd57f8a84a0868 100644 (file)
@@ -89,27 +89,6 @@ u16 g_selected_item = 0;
        Text input system
 */
 
-struct TextDestSign : public TextDest
-{
-       TextDestSign(v3s16 blockpos, s16 id, Client *client)
-       {
-               m_blockpos = blockpos;
-               m_id = id;
-               m_client = client;
-       }
-       void gotText(std::wstring text)
-       {
-               std::string ntext = wide_to_narrow(text);
-               dstream<<"Changing text of a sign object: "
-                               <<ntext<<std::endl;
-               m_client->sendSignText(m_blockpos, m_id, ntext);
-       }
-
-       v3s16 m_blockpos;
-       s16 m_id;
-       Client *m_client;
-};
-
 struct TextDestChat : public TextDest
 {
        TextDestChat(Client *client)
@@ -298,7 +277,7 @@ void getPointedNode(Client *client, v3f player_position,
        
        v3s16 pos_i = floatToInt(player_position, BS);
 
-       /*std::cout<<"pos_i=("<<pos_i.X<<","<<pos_i.Y<<","<<pos_i.Z<<")"
+       /*dstream<<"pos_i=("<<pos_i.X<<","<<pos_i.Y<<","<<pos_i.Z<<")"
                        <<std::endl;*/
 
        s16 a = d;
@@ -705,7 +684,7 @@ void the_game(
        SharedPtr<Server> server;
        if(address == ""){
                draw_load_screen(L"Creating server...", driver, font);
-               std::cout<<DTIME<<"Creating server"<<std::endl;
+               dstream<<DTIME<<"Creating server"<<std::endl;
                server = new Server(map_dir, configpath);
                server->start(port);
        }
@@ -715,7 +694,7 @@ void the_game(
        */
 
        draw_load_screen(L"Creating client...", driver, font);
-       std::cout<<DTIME<<"Creating client"<<std::endl;
+       dstream<<DTIME<<"Creating client"<<std::endl;
        MapDrawControl draw_control;
        Client client(device, playername.c_str(), password, draw_control);
                        
@@ -730,7 +709,7 @@ void the_game(
        }
        catch(ResolveError &e)
        {
-               std::cout<<DTIME<<"Couldn't resolve address"<<std::endl;
+               dstream<<DTIME<<"Couldn't resolve address"<<std::endl;
                //return 0;
                error_message = L"Couldn't resolve address";
                //gui_loadingtext->remove();
@@ -799,12 +778,12 @@ void the_game(
                {
                        error_message = L"Access denied. Reason: "
                                        +client.accessDeniedReason();
-                       std::cout<<DTIME<<wide_to_narrow(error_message)<<std::endl;
+                       dstream<<DTIME<<wide_to_narrow(error_message)<<std::endl;
                }
                else
                {
                        error_message = L"Connection timed out.";
-                       std::cout<<DTIME<<"Timed out."<<std::endl;
+                       dstream<<DTIME<<"Timed out."<<std::endl;
                }
                //gui_loadingtext->remove();
                return;
@@ -924,8 +903,16 @@ void the_game(
 
        core::list<float> frametime_log;
 
+       float nodig_delay_counter = 0.0;
+       float dig_time = 0.0;
+       u16 dig_index = 0;
+       v3s16 nodepos_old(-32768,-32768,-32768);
+
        float damage_flash_timer = 0;
        s16 farmesh_range = 20*MAP_BLOCKSIZE;
+
+       const float object_hit_delay = 0.5;
+       float object_hit_delay_timer = 0.0;
        
        bool invert_mouse = g_settings->getBool("invert_mouse");
 
@@ -952,7 +939,7 @@ void the_game(
                {
                        error_message = L"Access denied. Reason: "
                                        +client.accessDeniedReason();
-                       std::cout<<DTIME<<wide_to_narrow(error_message)<<std::endl;
+                       dstream<<DTIME<<wide_to_narrow(error_message)<<std::endl;
                        break;
                }
 
@@ -1018,7 +1005,7 @@ void the_game(
                        busytime = busytime_u32 / 1000.0;
                }
 
-               //std::cout<<"busytime_u32="<<busytime_u32<<std::endl;
+               //dstream<<"busytime_u32="<<busytime_u32<<std::endl;
        
                // Necessary for device->getTimer()->getTime()
                device->run();
@@ -1053,6 +1040,10 @@ void the_game(
                        dtime = 0;
                lasttime = time;
 
+               /* Run timers */
+
+               object_hit_delay_timer -= dtime;
+
                /*
                        Log frametime for visualization
                */
@@ -1067,8 +1058,8 @@ void the_game(
                        Visualize frametime in terminal
                */
                /*for(u32 i=0; i<dtime*400; i++)
-                       std::cout<<"X";
-               std::cout<<std::endl;*/
+                       dstream<<"X";
+               dstream<<std::endl;*/
 
                /*
                        Time average and jitter calculation
@@ -1133,7 +1124,7 @@ void the_game(
                        if(counter < 0)
                        {
                                counter = 30.0;
-                               client.printDebugInfo(std::cout);
+                               client.printDebugInfo(dstream);
                        }
                }
 
@@ -1359,7 +1350,7 @@ void the_game(
                        }
 
                        if(first_loop_after_window_activation){
-                               //std::cout<<"window active, first loop"<<std::endl;
+                               //dstream<<"window active, first loop"<<std::endl;
                                first_loop_after_window_activation = false;
                        }
                        else{
@@ -1367,7 +1358,7 @@ void the_game(
                                s32 dy = input->getMousePos().Y - displaycenter.Y;
                                if(invert_mouse)
                                        dy = -dy;
-                               //std::cout<<"window active, pos difference "<<dx<<","<<dy<<std::endl;
+                               //dstream<<"window active, pos difference "<<dx<<","<<dy<<std::endl;
                                
                                /*const float keyspeed = 500;
                                if(input->isKeyDown(irr::KEY_UP))
@@ -1391,7 +1382,7 @@ void the_game(
                        if(device->getCursorControl()->isVisible() == false)
                                device->getCursorControl()->setVisible(true);
 
-                       //std::cout<<"window inactive"<<std::endl;
+                       //dstream<<"window inactive"<<std::endl;
                        first_loop_after_window_activation = true;
                }
 
@@ -1500,71 +1491,23 @@ void the_game(
                core::line3d<f32> shootline(camera_position,
                                camera_position + camera_direction * BS * (d+1));
 
-               MapBlockObject *selected_object = client.getSelectedObject
-                               (d*BS, camera_position, shootline);
-
                ClientActiveObject *selected_active_object
                                = client.getSelectedActiveObject
                                        (d*BS, camera_position, shootline);
+               
+               bool left_punch = false;
+               bool left_punch_muted = false;
 
-               if(selected_object != NULL)
+               if(selected_active_object != NULL)
                {
-                       //dstream<<"Client returned selected_object != NULL"<<std::endl;
-
-                       core::aabbox3d<f32> box_on_map
-                                       = selected_object->getSelectionBoxOnMap();
-
-                       hilightboxes.push_back(box_on_map);
-
-                       infotext = narrow_to_wide(selected_object->infoText());
-
-                       if(input->getLeftClicked())
+                       /* Clear possible cracking animation */
+                       if(nodepos_old != v3s16(-32768,-32768,-32768))
                        {
-                               std::cout<<DTIME<<"Left-clicked object"<<std::endl;
-                               client.clickObject(0, selected_object->getBlock()->getPos(),
-                                               selected_object->getId(), g_selected_item);
+                               client.clearTempMod(nodepos_old);
+                               dig_time = 0.0;
+                               nodepos_old = v3s16(-32768,-32768,-32768);
                        }
-                       else if(input->getRightClicked())
-                       {
-                               std::cout<<DTIME<<"Right-clicked object"<<std::endl;
-                               /*
-                                       Check if we want to modify the object ourselves
-                               */
-                               if(selected_object->getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN)
-                               {
-                                       dstream<<"Sign object right-clicked"<<std::endl;
-                                       
-                                       if(random_input == false)
-                                       {
-                                               // Get a new text for it
-
-                                               TextDest *dest = new TextDestSign(
-                                                               selected_object->getBlock()->getPos(),
-                                                               selected_object->getId(),
-                                                               &client);
 
-                                               SignObject *sign_object = (SignObject*)selected_object;
-
-                                               std::wstring wtext =
-                                                               narrow_to_wide(sign_object->getText());
-
-                                               (new GUITextInputMenu(guienv, guiroot, -1,
-                                                               &g_menumgr, dest,
-                                                               wtext))->drop();
-                                       }
-                               }
-                               /*
-                                       Otherwise pass the event to the server as-is
-                               */
-                               else
-                               {
-                                       client.clickObject(1, selected_object->getBlock()->getPos(),
-                                                       selected_object->getId(), g_selected_item);
-                               }
-                       }
-               }
-               else if(selected_active_object != NULL)
-               {
                        //dstream<<"Client returned selected_active_object != NULL"<<std::endl;
                        
                        core::aabbox3d<f32> *selection_box
@@ -1579,21 +1522,31 @@ void the_game(
                                        selection_box->MinEdge + pos,
                                        selection_box->MaxEdge + pos
                        );
-
-                       hilightboxes.push_back(box_on_map);
+                       
+                       if(selected_active_object->doShowSelectionBox())
+                               hilightboxes.push_back(box_on_map);
 
                        //infotext = narrow_to_wide("A ClientActiveObject");
                        infotext = narrow_to_wide(selected_active_object->infoText());
 
-                       if(input->getLeftClicked())
+                       //if(input->getLeftClicked())
+                       if(input->getLeftState())
                        {
-                               std::cout<<DTIME<<"Left-clicked object"<<std::endl;
-                               client.clickActiveObject(0,
-                                               selected_active_object->getId(), g_selected_item);
+                               if(object_hit_delay_timer <= 0.0){
+                                       dstream<<DTIME<<"Left-clicked object"<<std::endl;
+                                       client.clickActiveObject(0,
+                                                       selected_active_object->getId(), g_selected_item);
+                                       object_hit_delay_timer = object_hit_delay;
+                                       left_punch = true;
+                               } else {
+                                       dstream<<DTIME<<"Left-clicked object faster than allowed"
+                                                       <<std::endl;
+                                       left_punch_muted = true;
+                               }
                        }
                        else if(input->getRightClicked())
                        {
-                               std::cout<<DTIME<<"Right-clicked object"<<std::endl;
+                               dstream<<DTIME<<"Right-clicked object"<<std::endl;
                                client.clickActiveObject(1,
                                                selected_active_object->getId(), g_selected_item);
                        }
@@ -1616,15 +1569,14 @@ void the_game(
                                nodepos, neighbourpos,
                                nodehilightbox, d);
        
-               static float nodig_delay_counter = 0.0;
-
-               if(nodefound)
-               {
-                       static v3s16 nodepos_old(-32768,-32768,-32768);
-
-                       static float dig_time = 0.0;
-                       static u16 dig_index = 0;
-                       
+               if(!nodefound){
+                       if(nodepos_old != v3s16(-32768,-32768,-32768))
+                       {
+                               client.clearTempMod(nodepos_old);
+                               dig_time = 0.0;
+                               nodepos_old = v3s16(-32768,-32768,-32768);
+                       }
+               } else {
                        /*
                                Visualize selection
                        */
@@ -1661,13 +1613,14 @@ void the_game(
                        {
                                if(nodepos != nodepos_old)
                                {
-                                       std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","
+                                       dstream<<DTIME<<"Pointing at ("<<nodepos.X<<","
                                                        <<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;
 
                                        if(nodepos_old != v3s16(-32768,-32768,-32768))
                                        {
                                                client.clearTempMod(nodepos_old);
                                                dig_time = 0.0;
+                                               nodepos_old = v3s16(-32768,-32768,-32768);
                                        }
                                }
 
@@ -1771,7 +1724,7 @@ void the_game(
                        
                        if(input->getRightClicked())
                        {
-                               std::cout<<DTIME<<"Ground right-clicked"<<std::endl;
+                               dstream<<DTIME<<"Ground right-clicked"<<std::endl;
                                
                                // If metadata provides an inventory view, activate it
                                if(meta && meta->getInventoryDrawSpecString() != "" && !random_input)
@@ -1836,7 +1789,7 @@ void the_game(
 
                } // selected_object == NULL
                
-               if(input->getLeftClicked())
+               if(left_punch || (input->getLeftClicked() && !left_punch_muted))
                {
                        camera.setDigging(0); // left click animation
                }
@@ -1846,13 +1799,13 @@ void the_game(
                
                if(input->getLeftReleased())
                {
-                       std::cout<<DTIME<<"Left button released (stopped digging)"
+                       dstream<<DTIME<<"Left button released (stopped digging)"
                                        <<std::endl;
                        client.groundAction(2, v3s16(0,0,0), v3s16(0,0,0), 0);
                }
                if(input->getRightReleased())
                {
-                       //std::cout<<DTIME<<"Right released"<<std::endl;
+                       //dstream<<DTIME<<"Right released"<<std::endl;
                        // Nothing here
                }
                
@@ -2097,7 +2050,7 @@ void the_game(
                {
                        client.selectPlayerItem(g_selected_item);
                        old_selected_item = g_selected_item;
-                       //std::cout<<"Updating local inventory"<<std::endl;
+                       //dstream<<"Updating local inventory"<<std::endl;
                        client.getLocalInventory(local_inventory);
 
                        // Update wielded tool
@@ -2136,7 +2089,7 @@ void the_game(
                
                //timer3.stop();
                
-               //std::cout<<DTIME<<"smgr->drawAll()"<<std::endl;
+               //dstream<<DTIME<<"smgr->drawAll()"<<std::endl;
                
                {
                        TimeTaker timer("smgr");
@@ -2162,7 +2115,7 @@ void the_game(
                for(core::list< core::aabbox3d<f32> >::Iterator i=hilightboxes.begin();
                                i != hilightboxes.end(); i++)
                {
-                       /*std::cout<<"hilightbox min="
+                       /*dstream<<"hilightbox min="
                                        <<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
                                        <<" max="
                                        <<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
index a3e35c92cd15234efab6b33c7e9bb99c54a7550b..b8afbc81f32b3f60b8d897f5cded51014af43cf7 100644 (file)
@@ -97,7 +97,7 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is)
        {
                std::string inventorystring;
                std::getline(is, inventorystring, '|');
-               return new MapBlockObjectItem(inventorystring);
+               throw SerializationError("MBOItem not supported anymore");
        }
        else if(name == "CraftItem")
        {
@@ -219,77 +219,6 @@ bool CraftItem::use(ServerEnvironment *env, Player *player)
        return false;
 }
 
-/*
-       MapBlockObjectItem DEPRECATED
-       TODO: Remove
-*/
-#ifndef SERVER
-video::ITexture * MapBlockObjectItem::getImage() const
-{
-       if(m_inventorystring.substr(0,3) == "Rat")
-               return g_texturesource->getTextureRaw("rat.png");
-       
-       if(m_inventorystring.substr(0,4) == "Sign")
-               return g_texturesource->getTextureRaw("sign.png");
-
-       return NULL;
-}
-#endif
-std::string MapBlockObjectItem::getText()
-{
-       if(m_inventorystring.substr(0,3) == "Rat")
-               return "";
-       
-       if(m_inventorystring.substr(0,4) == "Sign")
-               return "";
-
-       return "obj";
-}
-
-MapBlockObject * MapBlockObjectItem::createObject
-               (v3f pos, f32 player_yaw, f32 player_pitch)
-{
-       std::istringstream is(m_inventorystring);
-       std::string name;
-       std::getline(is, name, ' ');
-       
-       if(name == "None")
-       {
-               return NULL;
-       }
-       else if(name == "Sign")
-       {
-               std::string text;
-               std::getline(is, text, '|');
-               SignObject *obj = new SignObject(NULL, -1, pos);
-               obj->setText(text);
-               obj->setYaw(-player_yaw);
-               return obj;
-       }
-       else if(name == "Rat")
-       {
-               RatObject *obj = new RatObject(NULL, -1, pos);
-               return obj;
-       }
-       else if(name == "ItemObj")
-       {
-               /*
-                       Now we are an inventory item containing the serialization
-                       string of an object that contains the serialization
-                       string of an inventory item. Fuck this.
-               */
-               //assert(0);
-               dstream<<__FUNCTION_NAME<<": WARNING: Ignoring ItemObj "
-                               <<"because an item-object should never be inside "
-                               <<"an object-item."<<std::endl;
-               return NULL;
-       }
-       else
-       {
-               return NULL;
-       }
-}
-
 /*
        Inventory
 */
index 3e05015efb6d7b9660be0f187427a49812867e3e..490cab73ef9eb239ae43241cbdf0954c998b0ea6 100644 (file)
@@ -29,7 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <string>
 #include "common_irrlicht.h"
 #include "debug.h"
-#include "mapblockobject.h"
 #include "main.h" // For g_materials
 #include "mapnode.h" // For content_t
 
@@ -196,56 +195,6 @@ private:
        content_t m_content;
 };
 
-//TODO: Remove
-class MapBlockObjectItem : public InventoryItem
-{
-public:
-       MapBlockObjectItem(std::string inventorystring):
-               InventoryItem(1)
-       {
-               m_inventorystring = inventorystring;
-       }
-       
-       /*
-               Implementation interface
-       */
-       virtual const char* getName() const
-       {
-               return "MBOItem";
-       }
-       virtual void serialize(std::ostream &os) const
-       {
-               std::string sane_string(m_inventorystring);
-               str_replace_char(sane_string, '|', '?');
-               os<<getName();
-               os<<" ";
-               os<<sane_string;
-               os<<"|";
-       }
-       virtual InventoryItem* clone()
-       {
-               return new MapBlockObjectItem(m_inventorystring);
-       }
-
-#ifndef SERVER
-       video::ITexture * getImage() const;
-#endif
-       std::string getText();
-
-       /*
-               Special methods
-       */
-       std::string getInventoryString()
-       {
-               return m_inventorystring;
-       }
-
-       MapBlockObject * createObject(v3f pos, f32 player_yaw, f32 player_pitch);
-
-private:
-       std::string m_inventorystring;
-};
-
 /*
        An item that is used as a mid-product when crafting.
        Subnames:
index 6613f388a2ecbfd0d7b4b549700af39813470fa2..dd47c6ffc28aa4c01c8ad6c1b66ae91bd5e776c1 100644 (file)
@@ -36,7 +36,6 @@ MapBlock::MapBlock(Map *parent, v3s16 pos, bool dummy):
                m_lighting_expired(true),
                m_day_night_differs(false),
                m_generated(false),
-               m_objects(this),
                m_timestamp(BLOCK_TIMESTAMP_UNDEFINED),
                m_usage_timer(0)
 {
@@ -434,18 +433,6 @@ void MapBlock::copyFrom(VoxelManipulator &dst)
                        getPosRelative(), data_size);
 }
 
-void MapBlock::stepObjects(float dtime, bool server, u32 daynight_ratio)
-{
-       /*
-               Step objects
-       */
-       m_objects.step(dtime, server, daynight_ratio);
-
-       //setChangedFlag();
-       raiseModified(MOD_STATE_WRITE_AT_UNLOAD);
-}
-
-
 void MapBlock::updateDayNightDiff()
 {
        if(data == NULL)
@@ -818,10 +805,9 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
 
 void MapBlock::serializeDiskExtra(std::ostream &os, u8 version)
 {
-       // Versions up from 9 have block objects.
+       // Versions up from 9 have block objects. (DEPRECATED)
        if(version >= 9)
        {
-               //serializeObjects(os, version); // DEPRECATED
                // count=0
                writeU16(os, 0);
        }
@@ -842,11 +828,17 @@ void MapBlock::serializeDiskExtra(std::ostream &os, u8 version)
 void MapBlock::deSerializeDiskExtra(std::istream &is, u8 version)
 {
        /*
-               Versions up from 9 have block objects.
+               Versions up from 9 have block objects. (DEPRECATED)
        */
        if(version >= 9)
        {
-               updateObjects(is, version, NULL, 0);
+               u16 count = readU16(is);
+               // Not supported and length not known if count is not 0
+               if(count != 0){
+                       dstream<<"WARNING: MapBlock::deSerializeDiskExtra(): "
+                                       <<"Ignoring stuff coming at and after MBOs"<<std::endl;
+                       return;
+               }
        }
 
        /*
index 368290065458be02fa6b3602e01a5588dc2c80a8..22b3b7db6189d986c947d9ac50c393f4f53fe909 100644 (file)
@@ -29,7 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "exceptions.h"
 #include "serialization.h"
 #include "constants.h"
-#include "mapblockobject.h"
 #include "voxel.h"
 #include "nodemetadata.h"
 #include "staticobject.h"
@@ -423,68 +422,6 @@ public:
        // Copies data from VoxelManipulator getPosRelative()
        void copyFrom(VoxelManipulator &dst);
 
-       /*
-               MapBlockObject stuff
-               DEPRECATED
-       */
-       
-       /*void serializeObjects(std::ostream &os, u8 version)
-       {
-               m_objects.serialize(os, version);
-       }*/
-       // If smgr!=NULL, new objects are added to the scene
-       void updateObjects(std::istream &is, u8 version,
-                       scene::ISceneManager *smgr, u32 daynight_ratio)
-       {
-               m_objects.update(is, version, smgr, daynight_ratio);
-
-               raiseModified(MOD_STATE_WRITE_NEEDED);
-       }
-       void clearObjects()
-       {
-               m_objects.clear();
-
-               raiseModified(MOD_STATE_WRITE_NEEDED);
-       }
-       void addObject(MapBlockObject *object)
-                       throw(ContainerFullException, AlreadyExistsException)
-       {
-               m_objects.add(object);
-
-               raiseModified(MOD_STATE_WRITE_NEEDED);
-       }
-       void removeObject(s16 id)
-       {
-               m_objects.remove(id);
-
-               raiseModified(MOD_STATE_WRITE_NEEDED);
-       }
-       MapBlockObject * getObject(s16 id)
-       {
-               return m_objects.get(id);
-       }
-       JMutexAutoLock * getObjectLock()
-       {
-               return m_objects.getLock();
-       }
-
-       /*
-               Moves objects, deletes objects and spawns new objects
-       */
-       void stepObjects(float dtime, bool server, u32 daynight_ratio);
-
-       // origin is relative to block
-       void getObjects(v3f origin, f32 max_d,
-                       core::array<DistanceSortedObject> &dest)
-       {
-               m_objects.getObjects(origin, max_d, dest);
-       }
-
-       s32 getObjectCount()
-       {
-               return m_objects.getCount();
-       }
-
 #ifndef SERVER // Only on client
        /*
                Methods for setting temporary modifications to nodes for
@@ -688,9 +625,6 @@ private:
 
        bool m_generated;
        
-       // DEPRECATED
-       MapBlockObjectList m_objects;
-
 #ifndef SERVER // Only on client
        /*
                Set to true if the mesh has been ordered to be updated
diff --git a/src/mapblockobject.cpp b/src/mapblockobject.cpp
deleted file mode 100644 (file)
index 071a14b..0000000
+++ /dev/null
@@ -1,939 +0,0 @@
-/*
-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.
-*/
-
-// This file contains the DEPRECATED MapBlockObject system
-
-#include "mapblockobject.h"
-#include "mapblock.h"
-// For object wrapping
-#include "map.h"
-#include "inventory.h"
-#include "utility.h"
-#include "mapblock.h"
-
-/*
-       MapBlockObject
-*/
-
-// This is here because it uses the MapBlock
-v3f MapBlockObject::getAbsolutePos()
-{
-       if(m_block == NULL)
-               return m_pos;
-       
-       // getPosRelative gets nodepos relative to map origin
-       v3f blockpos = intToFloat(m_block->getPosRelative(), BS);
-       return blockpos + m_pos;
-}
-
-void MapBlockObject::setBlockChanged()
-{
-       if(m_block)
-               m_block->setChangedFlag();
-}
-
-/*
-       MovingObject
-*/
-
-v3f MovingObject::getAbsoluteShowPos()
-{
-       if(m_block == NULL)
-               return m_pos;
-       
-       // getPosRelative gets nodepos relative to map origin
-       v3f blockpos = intToFloat(m_block->getPosRelative(), BS);
-       return blockpos + m_showpos;
-}
-
-void MovingObject::move(float dtime, v3f acceleration)
-{
-       DSTACKF("%s: typeid=%i, pos=(%f,%f,%f), speed=(%f,%f,%f)"
-                       ", dtime=%f, acc=(%f,%f,%f)",
-                       __FUNCTION_NAME,
-                       getTypeId(),
-                       m_pos.X, m_pos.Y, m_pos.Z,
-                       m_speed.X, m_speed.Y, m_speed.Z,
-                       dtime,
-                       acceleration.X, acceleration.Y, acceleration.Z
-                       );
-       
-       v3s16 oldpos_i = floatToInt(m_pos, BS);
-       
-       if(m_block->isValidPosition(oldpos_i) == false)
-       {
-               // Should have wrapped, cancelling further movement.
-               return;
-       }
-
-       // No collisions if there is no collision box
-       if(m_collision_box == NULL)
-       {
-               m_speed += dtime * acceleration;
-               m_pos += m_speed * dtime;
-               return;
-       }
-       
-       // Set insane speed to zero
-       // Otherwise there will be divides by zero and other silly stuff
-       if(m_speed.getLength() > 1000.0*BS)
-               m_speed = v3f(0,0,0);
-               
-       // Limit speed to a reasonable value
-       float speed_limit = 20.0*BS;
-       if(m_speed.getLength() > speed_limit)
-               m_speed = m_speed * (speed_limit / m_speed.getLength());
-
-       v3f position = m_pos;
-       v3f oldpos = position;
-
-       /*std::cout<<"oldpos_i=("<<oldpos_i.X<<","<<oldpos_i.Y<<","
-                       <<oldpos_i.Z<<")"<<std::endl;*/
-
-       // Maximum time increment (for collision detection etc)
-       // Allow 0.1 blocks per increment
-       // time = distance / speed
-       // NOTE: In the loop below collisions are detected at 0.15*BS radius
-       float speedlength = m_speed.getLength();
-       f32 dtime_max_increment;
-       if(fabs(speedlength) > 0.001)
-               dtime_max_increment = 0.05*BS / speedlength;
-       else
-               dtime_max_increment = 0.5;
-       
-       m_touching_ground = false;
-               
-       u32 loopcount = 0;
-       do
-       {
-               loopcount++;
-
-               f32 dtime_part;
-               if(dtime > dtime_max_increment)
-                       dtime_part = dtime_max_increment;
-               else
-                       dtime_part = dtime;
-               dtime -= dtime_part;
-
-               // Begin of dtime limited code
-               
-               m_speed += acceleration * dtime_part;
-               position += m_speed * dtime_part;
-
-               /*
-                       Collision detection
-               */
-               
-               v3s16 pos_i = floatToInt(position, BS);
-               
-               // The loop length is limited to the object moving a distance
-               f32 d = (float)BS * 0.15;
-
-               core::aabbox3d<f32> objectbox(
-                               m_collision_box->MinEdge + position,
-                               m_collision_box->MaxEdge + position
-               );
-               
-               core::aabbox3d<f32> objectbox_old(
-                               m_collision_box->MinEdge + oldpos,
-                               m_collision_box->MaxEdge + oldpos
-               );
-               
-               //TODO: Get these ranges from somewhere
-               for(s16 y = oldpos_i.Y - 1; y <= oldpos_i.Y + 2; y++)
-               for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++)
-               for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
-               {
-                       try{
-                               MapNode n = m_block->getNodeParent(v3s16(x,y,z));
-                               if(content_features(n).walkable == false)
-                                       continue;
-                       }
-                       catch(InvalidPositionException &e)
-                       {
-                               // Doing nothing here will block the object from
-                               // walking over map borders
-                       }
-
-                       core::aabbox3d<f32> nodebox = getNodeBox(v3s16(x,y,z), BS);
-                       
-                       // See if the object is touching ground
-                       if(
-                                       fabs(nodebox.MaxEdge.Y-objectbox.MinEdge.Y) < d
-                                       && nodebox.MaxEdge.X-d > objectbox.MinEdge.X
-                                       && nodebox.MinEdge.X+d < objectbox.MaxEdge.X
-                                       && nodebox.MaxEdge.Z-d > objectbox.MinEdge.Z
-                                       && nodebox.MinEdge.Z+d < objectbox.MaxEdge.Z
-                       ){
-                               m_touching_ground = true;
-                       }
-                       
-                       if(objectbox.intersectsWithBox(nodebox))
-                       {
-                                       
-               v3f dirs[3] = {
-                       v3f(0,0,1), // back
-                       v3f(0,1,0), // top
-                       v3f(1,0,0), // right
-               };
-               for(u16 i=0; i<3; i++)
-               {
-                       f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[i]);
-                       f32 nodemin = nodebox.MinEdge.dotProduct(dirs[i]);
-                       f32 playermax = objectbox.MaxEdge.dotProduct(dirs[i]);
-                       f32 playermin = objectbox.MinEdge.dotProduct(dirs[i]);
-                       f32 playermax_old = objectbox_old.MaxEdge.dotProduct(dirs[i]);
-                       f32 playermin_old = objectbox_old.MinEdge.dotProduct(dirs[i]);
-
-                       bool main_edge_collides = 
-                               ((nodemax > playermin && nodemax <= playermin_old + d
-                                       && m_speed.dotProduct(dirs[i]) < 0)
-                               ||
-                               (nodemin < playermax && nodemin >= playermax_old - d
-                                       && m_speed.dotProduct(dirs[i]) > 0));
-
-                       bool other_edges_collide = true;
-                       for(u16 j=0; j<3; j++)
-                       {
-                               if(j == i)
-                                       continue;
-                               f32 nodemax = nodebox.MaxEdge.dotProduct(dirs[j]);
-                               f32 nodemin = nodebox.MinEdge.dotProduct(dirs[j]);
-                               f32 playermax = objectbox.MaxEdge.dotProduct(dirs[j]);
-                               f32 playermin = objectbox.MinEdge.dotProduct(dirs[j]);
-                               if(!(nodemax - d > playermin && nodemin + d < playermax))
-                               {
-                                       other_edges_collide = false;
-                                       break;
-                               }
-                       }
-                       
-                       if(main_edge_collides && other_edges_collide)
-                       {
-                               m_speed -= m_speed.dotProduct(dirs[i]) * dirs[i];
-                               position -= position.dotProduct(dirs[i]) * dirs[i];
-                               position += oldpos.dotProduct(dirs[i]) * dirs[i];
-                       }
-               
-               }
-               
-                       } // if(objectbox.intersectsWithBox(nodebox))
-               } // for y
-
-       } // End of dtime limited loop
-       while(dtime > 0.001);
-
-       m_pos = position;
-}
-
-void MovingObject::simpleMove(float dtime)
-{
-       m_pos_animation_time_counter += dtime;
-       m_pos_animation_counter += dtime;
-       v3f movevector = m_pos - m_oldpos;
-       f32 moveratio;
-       if(m_pos_animation_time < 0.001)
-               moveratio = 1.0;
-       else
-               moveratio = m_pos_animation_counter / m_pos_animation_time;
-       if(moveratio > 1.5)
-               moveratio = 1.5;
-       m_showpos = m_oldpos + movevector * moveratio;
-}
-
-#ifndef SERVER
-/*
-       RatObject
-*/
-void RatObject::addToScene(scene::ISceneManager *smgr)
-{
-       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,-BS/4,0, 0,0,0, c, 0,1),
-               video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
-               video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
-               video::S3DVertex(-BS/2,BS/4,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(getTexturePath("rat.png").c_str()));
-       buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-       buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
-       buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-       // Add to mesh
-       mesh->addMeshBuffer(buf);
-       buf->drop();
-       m_node = smgr->addMeshSceneNode(mesh, NULL);
-       mesh->drop();
-       updateNodePos();
-}
-#endif
-
-/*
-       ItemObject
-*/
-#ifndef SERVER
-void ItemObject::addToScene(scene::ISceneManager *smgr)
-{
-       if(m_node != NULL)
-               return;
-       
-       //video::IVideoDriver* driver = smgr->getVideoDriver();
-       
-       // Get image of item for showing
-       video::ITexture *texture = getItemImage();
-
-       /*
-               Create a mesh
-       */
-
-       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,-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),*/
-               video::S3DVertex(BS/3,-BS/2,0, 0,0,0, c, 0,1),
-               video::S3DVertex(-BS/3,-BS/2,0, 0,0,0, c, 1,1),
-               video::S3DVertex(-BS/3,-BS/2+BS*2/3,0, 0,0,0, c, 1,0),
-               video::S3DVertex(BS/3,-BS/2+BS*2/3,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, texture);
-       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);
-       // Set it to use the materials of the meshbuffers directly.
-       // This is needed for changing the texture in the future
-       ((scene::IMeshSceneNode*)m_node)->setReadOnlyMaterials(true);
-       mesh->drop();
-
-       updateSceneNode();
-}
-
-video::ITexture * ItemObject::getItemImage()
-{
-       /*
-               Create an inventory item to see what is its image
-       */
-       video::ITexture *texture = NULL;
-       InventoryItem *item = createInventoryItem();
-       if(item)
-               texture = item->getImage();
-       if(item)
-               delete item;
-       return texture;
-}
-
-#endif
-
-InventoryItem * ItemObject::createInventoryItem()
-{
-       try{
-               std::istringstream is(m_itemstring, std::ios_base::binary);
-               InventoryItem *item = InventoryItem::deSerialize(is);
-               dstream<<__FUNCTION_NAME<<": m_itemstring=\""
-                               <<m_itemstring<<"\" -> item="<<item
-                               <<std::endl;
-               return item;
-       }
-       catch(SerializationError &e)
-       {
-               dstream<<__FUNCTION_NAME<<": serialization error: "
-                               <<"m_itemstring=\""<<m_itemstring<<"\""<<std::endl;
-               return NULL;
-       }
-}
-
-/*
-       PlayerObject
-*/
-#ifndef SERVER
-void PlayerObject::addToScene(scene::ISceneManager *smgr)
-{
-       if(m_node != NULL)
-               return;
-       
-       video::IVideoDriver* driver = smgr->getVideoDriver();
-
-       // Attach a simple mesh to the player for showing an image
-       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),
-       };
-       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(getTexturePath("player.png").c_str()));
-       buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
-       buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
-       //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
-       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,0,0, 0,0,0, c, 1,1),
-               video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
-               video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
-               video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,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(getTexturePath("player_back.png").c_str()));
-       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();
-       updateNodePos();
-}
-#endif
-
-/*
-       MapBlockObjectList
-*/
-
-MapBlockObjectList::MapBlockObjectList(MapBlock *block):
-       m_block(block)
-{
-       m_mutex.Init();
-}
-
-MapBlockObjectList::~MapBlockObjectList()
-{
-       clear();
-}
-
-/*
-       The serialization format:
-       [0] u16 number of entries
-       [2] entries (id, typeId, parameters)
-*/
-
-void MapBlockObjectList::serialize(std::ostream &os, u8 version)
-{
-       JMutexAutoLock lock(m_mutex);
-
-       u8 buf[2];
-       writeU16(buf, m_objects.size());
-       os.write((char*)buf, 2);
-
-       for(core::map<s16, MapBlockObject*>::Iterator
-                       i = m_objects.getIterator();
-                       i.atEnd() == false; i++)
-       {
-               i.getNode()->getValue()->serialize(os, version);
-       }
-}
-
-void MapBlockObjectList::update(std::istream &is, u8 version,
-               scene::ISceneManager *smgr, u32 daynight_ratio)
-{
-       JMutexAutoLock lock(m_mutex);
-
-       /*
-               Collect all existing ids to a set.
-
-               As things are updated, they are removed from this.
-
-               All remaining ones are deleted.
-       */
-       core::map<s16, bool> ids_to_delete;
-       for(core::map<s16, MapBlockObject*>::Iterator
-                       i = m_objects.getIterator();
-                       i.atEnd() == false; i++)
-       {
-               ids_to_delete.insert(i.getNode()->getKey(), true);
-       }
-       
-       u8 buf[6];
-       
-       is.read((char*)buf, 2);
-       u16 count = readU16(buf);
-
-       for(u16 i=0; i<count; i++)
-       {
-               // Read id
-               is.read((char*)buf, 2);
-               s16 id = readS16(buf);
-               
-               // Read position
-               // stored as x1000/BS v3s16
-               is.read((char*)buf, 6);
-               v3s16 pos_i = readV3S16(buf);
-               v3f pos((f32)pos_i.X/1000*BS,
-                               (f32)pos_i.Y/1000*BS,
-                               (f32)pos_i.Z/1000*BS);
-
-               // Read typeId
-               is.read((char*)buf, 2);
-               u16 type_id = readU16(buf);
-               
-               bool create_new = false;
-
-               // Find an object with the id
-               core::map<s16, MapBlockObject*>::Node *n;
-               n = m_objects.find(id);
-               // If no entry is found for id
-               if(n == NULL)
-               {
-                       // Insert dummy pointer node
-                       m_objects.insert(id, NULL);
-                       // Get node
-                       n = m_objects.find(id);
-                       // A new object will be created at this node
-                       create_new = true;
-               }
-               // If type_id differs
-               else if(n->getValue()->getTypeId() != type_id)
-               {
-                       // Delete old object
-                       delete n->getValue();
-                       // A new object will be created at this node
-                       create_new = true;
-               }
-
-               MapBlockObject *obj = NULL;
-
-               if(create_new)
-               {
-                       /*dstream<<"MapBlockObjectList adding new object"
-                                       " id="<<id
-                                       <<std::endl;*/
-
-                       if(type_id == MAPBLOCKOBJECT_TYPE_SIGN)
-                       {
-                               obj = new SignObject(m_block, id, pos);
-                       }
-                       else if(type_id == MAPBLOCKOBJECT_TYPE_RAT)
-                       {
-                               obj = new RatObject(m_block, id, pos);
-                       }
-                       else if(type_id == MAPBLOCKOBJECT_TYPE_ITEM)
-                       {
-                               obj = new ItemObject(m_block, id, pos);
-                       }
-                       else
-                       {
-                               // This is fatal because we cannot know the length
-                               // of the object's data
-                               throw SerializationError
-                               ("MapBlockObjectList::update(): Unknown MapBlockObject type");
-                       }
-
-                       if(smgr != NULL)
-                               //obj->addToScene(smgr, daynight_ratio);
-                               obj->addToScene(smgr);
-
-                       n->setValue(obj);
-               }
-               else
-               {
-                       obj = n->getValue();
-                       obj->updatePos(pos);
-                       /*if(daynight_ratio != m_last_update_daynight_ratio)
-                       {
-                               obj->removeFromScene();
-                               obj->addToScene(smgr, daynight_ratio);
-                       }*/
-               }
-
-               // Now there is an object in obj.
-               // Update it.
-               
-               obj->update(is, version);
-               
-               /*
-                       Update light on client
-               */
-               if(smgr != NULL)
-               {
-                       u8 light = LIGHT_MAX;
-                       try{
-                               v3s16 relpos_i = floatToInt(obj->m_pos, BS);
-                               MapNode n = m_block->getNodeParent(relpos_i);
-                               light = n.getLightBlend(daynight_ratio);
-                       }
-                       catch(InvalidPositionException &e) {}
-                       obj->updateLight(light);
-               }
-               
-               // Remove from deletion list
-               if(ids_to_delete.find(id) != NULL)
-                       ids_to_delete.remove(id);
-       }
-
-       // Delete all objects whose ids_to_delete remain in ids_to_delete
-       for(core::map<s16, bool>::Iterator
-                       i = ids_to_delete.getIterator();
-                       i.atEnd() == false; i++)
-       {
-               s16 id = i.getNode()->getKey();
-
-               /*dstream<<"MapBlockObjectList deleting object"
-                               " id="<<id
-                               <<std::endl;*/
-
-               MapBlockObject *obj = m_objects[id];
-               obj->removeFromScene();
-               delete obj;
-               m_objects.remove(id);
-       }
-
-       m_last_update_daynight_ratio = daynight_ratio;
-}
-
-s16 MapBlockObjectList::getFreeId() throw(ContainerFullException)
-{
-       s16 id = 0;
-       for(;;)
-       {
-               if(m_objects.find(id) == NULL)
-                       return id;
-               if(id == 32767)
-                       throw ContainerFullException
-                                       ("MapBlockObjectList doesn't fit more objects");
-               id++;
-       }
-}
-
-void MapBlockObjectList::add(MapBlockObject *object)
-               throw(ContainerFullException, AlreadyExistsException)
-{
-       if(object == NULL)
-       {
-               dstream<<"MapBlockObjectList::add(): NULL object"<<std::endl;
-               return;
-       }
-
-       JMutexAutoLock lock(m_mutex);
-
-       // Create unique id if id==-1
-       if(object->m_id == -1)
-       {
-               object->m_id = getFreeId();
-       }
-
-       if(m_objects.find(object->m_id) != NULL)
-       {
-               dstream<<"MapBlockObjectList::add(): "
-                               "object with same id already exists"<<std::endl;
-               throw AlreadyExistsException
-                               ("MapBlockObjectList already has given id");
-       }
-       
-       object->m_block = m_block;
-       
-       /*v3f p = object->m_pos;
-       dstream<<"MapBlockObjectList::add(): "
-                       <<"m_block->getPos()=("
-                       <<m_block->getPos().X<<","
-                       <<m_block->getPos().Y<<","
-                       <<m_block->getPos().Z<<")"
-                       <<" inserting object with id="<<object->m_id
-                       <<" pos="
-                       <<"("<<p.X<<","<<p.Y<<","<<p.Z<<")"
-                       <<std::endl;*/
-       
-       m_objects.insert(object->m_id, object);
-}
-
-void MapBlockObjectList::clear()
-{
-       JMutexAutoLock lock(m_mutex);
-
-       for(core::map<s16, MapBlockObject*>::Iterator
-                       i = m_objects.getIterator();
-                       i.atEnd() == false; i++)
-       {
-               MapBlockObject *obj = i.getNode()->getValue();
-               //FIXME: This really shouldn't be NULL at any time,
-               //       but this condition was added because it was.
-               if(obj != NULL)
-               {
-                       obj->removeFromScene();
-                       delete obj;
-               }
-       }
-
-       m_objects.clear();
-}
-
-void MapBlockObjectList::remove(s16 id)
-{
-       JMutexAutoLock lock(m_mutex);
-
-       core::map<s16, MapBlockObject*>::Node *n;
-       n = m_objects.find(id);
-       if(n == NULL)
-               return;
-       
-       n->getValue()->removeFromScene();
-       delete n->getValue();
-       m_objects.remove(id);
-}
-
-MapBlockObject * MapBlockObjectList::get(s16 id)
-{
-       core::map<s16, MapBlockObject*>::Node *n;
-       n = m_objects.find(id);
-       if(n == NULL)
-               return NULL;
-       else
-               return n->getValue();
-}
-
-void MapBlockObjectList::step(float dtime, bool server, u32 daynight_ratio)
-{
-       DSTACK(__FUNCTION_NAME);
-       
-       JMutexAutoLock lock(m_mutex);
-       
-       core::map<s16, bool> ids_to_delete;
-
-       {
-               DSTACKF("%s: stepping objects", __FUNCTION_NAME);
-
-               for(core::map<s16, MapBlockObject*>::Iterator
-                               i = m_objects.getIterator();
-                               i.atEnd() == false; i++)
-               {
-                       MapBlockObject *obj = i.getNode()->getValue();
-                       
-                       DSTACKF("%s: stepping object type %i", __FUNCTION_NAME,
-                                       obj->getTypeId());
-
-                       if(server)
-                       {
-                               // Update light
-                               u8 light = LIGHT_MAX;
-                               try{
-                                       v3s16 relpos_i = floatToInt(obj->m_pos, BS);
-                                       MapNode n = m_block->getNodeParent(relpos_i);
-                                       light = n.getLightBlend(daynight_ratio);
-                               }
-                               catch(InvalidPositionException &e) {}
-                               obj->updateLight(light);
-                               
-                               bool to_delete = obj->serverStep(dtime, daynight_ratio);
-
-                               if(to_delete)
-                                       ids_to_delete.insert(obj->m_id, true);
-                       }
-                       else
-                       {
-                               obj->clientStep(dtime);
-                       }
-               }
-       }
-
-       {
-               DSTACKF("%s: deleting objects", __FUNCTION_NAME);
-
-               // Delete objects in delete queue
-               for(core::map<s16, bool>::Iterator
-                               i = ids_to_delete.getIterator();
-                               i.atEnd() == false; i++)
-               {
-                       s16 id = i.getNode()->getKey();
-
-                       MapBlockObject *obj = m_objects[id];
-                       obj->removeFromScene();
-                       delete obj;
-                       m_objects.remove(id);
-               }
-       }
-       
-       /*
-               Wrap objects on server
-       */
-
-       if(server == false)
-               return;
-       
-       {
-               DSTACKF("%s: object wrap loop", __FUNCTION_NAME);
-
-               for(core::map<s16, MapBlockObject*>::Iterator
-                               i = m_objects.getIterator();
-                               i.atEnd() == false; i++)
-               {
-                       MapBlockObject *obj = i.getNode()->getValue();
-
-                       v3s16 pos_i = floatToInt(obj->m_pos, BS);
-
-                       if(m_block->isValidPosition(pos_i))
-                       {
-                               // No wrap
-                               continue;
-                       }
-
-                       bool impossible = wrapObject(obj);
-
-                       if(impossible)
-                       {
-                               // No wrap
-                               continue;
-                       }
-
-                       // Restart find
-                       i = m_objects.getIterator();
-               }
-       }
-}
-
-bool MapBlockObjectList::wrapObject(MapBlockObject *object)
-{
-       DSTACK(__FUNCTION_NAME);
-       
-       // No lock here; this is called so that the lock is already locked.
-       //JMutexAutoLock lock(m_mutex);
-
-       assert(object->m_block == m_block);
-       assert(m_objects.find(object->m_id) != NULL);
-       assert(m_objects[object->m_id] == object);
-
-       Map *map = m_block->getParent();
-       
-       // Calculate blockpos on map
-       v3s16 oldblock_pos_i_on_map = m_block->getPosRelative();
-       v3f pos_f_on_oldblock = object->m_pos;
-       v3s16 pos_i_on_oldblock = floatToInt(pos_f_on_oldblock, BS);
-       v3s16 pos_i_on_map = pos_i_on_oldblock + oldblock_pos_i_on_map;
-       v3s16 pos_blocks_on_map = getNodeBlockPos(pos_i_on_map);
-
-       // Get new block
-       MapBlock *newblock;
-       try{
-               newblock = map->getBlockNoCreate(pos_blocks_on_map);
-       }
-       catch(InvalidPositionException &e)
-       {
-               // Couldn't find block -> not wrapping
-               /*dstream<<"WARNING: Wrapping object not possible: "
-                               <<"could not find new block"
-                               <<"("<<pos_blocks_on_map.X
-                               <<","<<pos_blocks_on_map.Y
-                               <<","<<pos_blocks_on_map.Z
-                               <<")"<<std::endl;*/
-               /*dstream<<"pos_f_on_oldblock=("
-                               <<pos_f_on_oldblock.X<<","
-                               <<pos_f_on_oldblock.Y<<","
-                               <<pos_f_on_oldblock.Z<<")"
-                               <<std::endl;*/
-               return true;
-       }
-
-       if(newblock == m_block)
-       {
-               dstream<<"WARNING: Wrapping object not possible: "
-                               "newblock == oldblock"<<std::endl;
-               return true;
-       }
-       
-       // Calculate position on new block
-       v3f oldblock_pos_f_on_map = intToFloat(oldblock_pos_i_on_map, BS);
-       v3s16 newblock_pos_i_on_map = newblock->getPosRelative();
-       v3f newblock_pos_f_on_map = intToFloat(newblock_pos_i_on_map, BS);
-       v3f pos_f_on_newblock = pos_f_on_oldblock
-                       - newblock_pos_f_on_map + oldblock_pos_f_on_map;
-
-       // Remove object from this block
-       m_objects.remove(object->m_id);
-       
-       // Add object to new block
-       object->m_pos = pos_f_on_newblock;
-       object->m_id = -1;
-       object->m_block = NULL;
-       newblock->addObject(object);
-
-       //dstream<<"NOTE: Wrapped object"<<std::endl;
-
-       return false;
-}
-
-void MapBlockObjectList::getObjects(v3f origin, f32 max_d,
-               core::array<DistanceSortedObject> &dest)
-{
-       for(core::map<s16, MapBlockObject*>::Iterator
-                       i = m_objects.getIterator();
-                       i.atEnd() == false; i++)
-       {
-               MapBlockObject *obj = i.getNode()->getValue();
-
-               f32 d = (obj->getRelativeShowPos() - origin).getLength();
-
-               if(d > max_d)
-                       continue;
-
-               DistanceSortedObject dso(obj, d);
-
-               dest.push_back(dso);
-       }
-}
-
-//END
diff --git a/src/mapblockobject.h b/src/mapblockobject.h
deleted file mode 100644 (file)
index 406c32f..0000000
+++ /dev/null
@@ -1,1091 +0,0 @@
-/*
-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.
-*/
-
-// This file contains the DEPRECATED MapBlockObject system
-
-#ifndef MAPBLOCKOBJECT_HEADER
-#define MAPBLOCKOBJECT_HEADER
-
-#include "common_irrlicht.h"
-#include <math.h>
-#include <string>
-#include "serialization.h"
-#include "mapnode.h"
-#include "constants.h"
-#include "debug.h"
-
-#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;
-
-class MapBlockObject
-{
-public:
-       MapBlockObject(MapBlock *block, s16 id, v3f pos):
-               m_collision_box(NULL),
-               m_selection_box(NULL),
-               m_block(block),
-               m_id(id),
-               m_pos(pos)
-       {
-       }
-       virtual ~MapBlockObject()
-       {
-       }
-
-       s16 getId()
-       {
-               return m_id;
-       }
-       MapBlock* getBlock()
-       {
-               return m_block;
-       }
-       
-       // Writes id, pos and typeId
-       void serializeBase(std::ostream &os, u8 version)
-       {
-               u8 buf[6];
-
-               // id
-               writeS16(buf, m_id);
-               os.write((char*)buf, 2);
-               
-               // position
-               // stored as x1000/BS v3s16
-               v3s16 pos_i(m_pos.X*1000/BS, m_pos.Y*1000/BS, m_pos.Z*1000/BS);
-               writeV3S16(buf, pos_i);
-               os.write((char*)buf, 6);
-
-               // typeId
-               writeU16(buf, getTypeId());
-               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();
-
-       void setBlockChanged();
-
-       // Shootline is relative to block
-       bool isSelected(core::line3d<f32> shootline)
-       {
-               if(m_selection_box == NULL)
-                       return false;
-
-               core::aabbox3d<f32> offsetted_box(
-                               m_selection_box->MinEdge + m_pos,
-                               m_selection_box->MaxEdge + m_pos
-               );
-
-               return offsetted_box.intersectsWithLine(shootline);
-       }
-
-       core::aabbox3d<f32> getSelectionBoxOnMap()
-       {
-               v3f absolute_pos = getAbsolutePos();
-
-               core::aabbox3d<f32> box(
-                               m_selection_box->MinEdge + absolute_pos,
-                               m_selection_box->MaxEdge + absolute_pos
-               );
-
-               return box;
-       }
-       
-       /*
-               Implementation interface
-       */
-
-       virtual u16 getTypeId() const = 0;
-       // Shall call serializeBase and then write the parameters
-       virtual void serialize(std::ostream &os, u8 version) = 0;
-       // Shall read parameters from stream
-       virtual void update(std::istream &is, u8 version) = 0;
-
-       virtual std::string getInventoryString() { return "None"; }
-       
-       // Reimplementation shall call this.
-       virtual void updatePos(v3f pos)
-       {
-               m_pos = pos;
-       }
-       
-       // Shall move the object around, modify it and possibly delete it.
-       // 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, 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) {};
-
-       // NOTE: These functions should do nothing if the asked state is
-       //       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) = 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() = 0;
-       
-       // 0 <= light_at_pos <= LIGHT_SUN
-       virtual void updateLight(u8 light_at_pos) {};
-#endif
-
-       virtual std::string infoText() { return ""; }
-       
-       // Shall be left NULL if doesn't collide
-       // Position is relative to m_pos in block
-       core::aabbox3d<f32> * m_collision_box;
-       
-       // Shall be left NULL if can't be selected
-       core::aabbox3d<f32> * m_selection_box;
-
-protected:
-       MapBlock *m_block;
-       // This differentiates the instance of the object
-       // Not same as typeId.
-       s16 m_id;
-       // Position of the object inside the block
-       // Units is node coordinates * BS
-       v3f m_pos;
-
-       friend class MapBlockObjectList;
-};
-
-#if 0
-/*
-       Used for handling selections of special stuff
-*/
-class PseudoMBObject : public MapBlockObject
-{
-public:
-       // The constructor of every MapBlockObject should be like this
-       PseudoMBObject(MapBlock *block, s16 id, v3f pos):
-               MapBlockObject(block, id, pos)
-       {
-       }
-       virtual ~PseudoMBObject()
-       {
-               if(m_selection_box)
-                       delete m_selection_box;
-       }
-       
-       /*
-               Implementation interface
-       */
-       virtual u16 getTypeId() const
-       {
-               return MAPBLOCKOBJECT_TYPE_PSEUDO;
-       }
-       virtual void serialize(std::ostream &os, u8 version)
-       {
-               assert(0);
-       }
-       virtual void update(std::istream &is, u8 version)
-       {
-               assert(0);
-       }
-       virtual bool serverStep(float dtime, u32 daynight_ratio)
-       {
-               assert(0);
-       }
-
-       /*
-               Special methods
-       */
-       
-       void setSelectionBox(core::aabbox3d<f32> box)
-       {
-               m_selection_box = new core::aabbox3d<f32>(box);
-       }
-       
-protected:
-};
-#endif
-
-class MovingObject : public MapBlockObject
-{
-public:
-       // 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_oldpos(pos),
-               m_pos_animation_time(0),
-               m_showpos(pos)
-       {
-               m_touching_ground = false;
-       }
-       virtual ~MovingObject()
-       {
-       }
-       
-       /*
-               Implementation interface
-       */
-       
-       virtual u16 getTypeId() const = 0;
-
-       virtual void serialize(std::ostream &os, u8 version)
-       {
-               serializeBase(os, version);
-
-               u8 buf[6];
-
-               // Write speed
-               // stored as x100/BS v3s16
-               v3s16 speed_i(m_speed.X*100/BS, m_speed.Y*100/BS, m_speed.Z*100/BS);
-               writeV3S16(buf, speed_i);
-               os.write((char*)buf, 6);
-       }
-       virtual void update(std::istream &is, u8 version)
-       {
-               u8 buf[6];
-               
-               // Read speed
-               // stored as x100/BS v3s16
-               is.read((char*)buf, 6);
-               v3s16 speed_i = readV3S16(buf);
-               v3f speed((f32)speed_i.X/100*BS,
-                               (f32)speed_i.Y/100*BS,
-                               (f32)speed_i.Z/100*BS);
-
-               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, u32 daynight_ratio)
-       { return false; };
-       virtual void clientStep(float dtime)
-       {};
-       
-       /*virtual void addToScene(scene::ISceneManager *smgr) = 0;
-       virtual void removeFromScene() = 0;*/
-
-       /*
-               Special methods
-       */
-       
-       // 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 SignObject : public MapBlockObject
-{
-public:
-       // The constructor of every MapBlockObject should be like this
-       SignObject(MapBlock *block, s16 id, v3f pos):
-               MapBlockObject(block, id, pos)
-#ifndef SERVER
-               ,m_node(NULL)
-#endif
-       {
-               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 ~SignObject()
-       {
-               delete m_selection_box;
-       }
-       
-       /*
-               Implementation interface
-       */
-       virtual u16 getTypeId() const
-       {
-               return MAPBLOCKOBJECT_TYPE_SIGN;
-       }
-       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());
-               os.write((char*)buf, 2);
-               
-               // Write text
-               os.write(m_text.c_str(), m_text.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();
-               for(u16 i=0; i<size; i++)
-               {
-                       is.read((char*)buf, 1);
-                       m_text += buf[0];
-               }
-
-               updateSceneNode();
-       }
-       virtual bool serverStep(float dtime, u32 daynight_ratio)
-       {
-               return false;
-       }
-#ifndef SERVER
-       virtual void addToScene(scene::ISceneManager *smgr)
-       {
-               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(getTexturePath("sign.png").c_str()));
-               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();
-               }
-               { // 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(getTexturePath("sign_back.png").c_str()));
-               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();
-
-               updateSceneNode();
-       }
-       virtual void removeFromScene()
-       {
-               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);
-               setMeshVerticesColor(m_node->getMesh(), color);
-       }
-#endif
-
-       virtual std::string infoText()
-       {
-               return std::string("\"") + m_text + "\"";
-       }
-
-       virtual std::string getInventoryString()
-       {
-               return std::string("Sign ")+m_text;
-       }
-
-       /*
-               Special methods
-       */
-       void updateSceneNode()
-       {
-#ifndef SERVER
-               if(m_node != NULL)
-               {
-                       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:
-#ifndef SERVER
-       scene::IMeshSceneNode *m_node;
-#endif
-       std::string m_text;
-       f32 m_yaw;
-};
-
-class RatObject : public MovingObject
-{
-public:
-       RatObject(MapBlock *block, s16 id, v3f pos):
-               MovingObject(block, id, pos)
-#ifndef SERVER
-               ,m_node(NULL)
-#endif
-       {
-               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);
-               
-               m_yaw = 0;
-               m_counter1 = 0;
-               m_counter2 = 0;
-               m_age = 0;
-       }
-       virtual ~RatObject()
-       {
-               delete m_collision_box;
-               delete m_selection_box;
-       }
-       
-       /*
-               Implementation interface
-       */
-       virtual u16 getTypeId() const
-       {
-               return MAPBLOCKOBJECT_TYPE_RAT;
-       }
-       virtual void serialize(std::ostream &os, u8 version)
-       {
-               MovingObject::serialize(os, version);
-               u8 buf[2];
-
-               // Write yaw * 10
-               writeS16(buf, m_yaw * 10);
-               os.write((char*)buf, 2);
-
-       }
-       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)
-       {
-               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;
-
-               m_speed.X = speed * dir.X;
-               m_speed.Z = speed * dir.Z;
-
-               if(m_touching_ground && (m_oldpos - m_pos).getLength() < dtime*speed/2)
-               {
-                       m_counter1 -= dtime;
-                       if(m_counter1 < 0.0)
-                       {
-                               m_counter1 += 1.0;
-                               m_speed.Y = 5.0*BS;
-                       }
-               }
-
-               {
-                       m_counter2 -= dtime;
-                       if(m_counter2 < 0.0)
-                       {
-                               m_counter2 += (float)(myrand()%100)/100*3.0;
-                               m_yaw += ((float)(myrand()%200)-100)/100*180;
-                               m_yaw = wrapDegrees(m_yaw);
-                       }
-               }
-
-               m_oldpos = m_pos;
-
-               //m_yaw += dtime*90;
-
-               move(dtime, v3f(0, -9.81*BS, 0));
-
-               //updateNodePos();
-
-               return false;
-       }
-#ifndef SERVER
-       virtual void clientStep(float dtime)
-       {
-               //m_pos += m_speed * 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);
-               setMeshVerticesColor(m_node->getMesh(), color);
-       }
-       
-#endif
-
-       virtual std::string getInventoryString()
-       {
-               // There must be a space after the name
-               // Or does there?
-               return std::string("Rat ");
-       }
-
-       /*
-               Special methods
-       */
-       
-       void updateNodePos()
-       {
-#ifndef SERVER
-               if(m_node == NULL)
-                       return;
-
-               m_node->setPosition(getAbsoluteShowPos());
-               m_node->setRotation(v3f(0, -m_yaw+180, 0));
-#endif
-       }
-       
-protected:
-#ifndef SERVER
-       scene::IMeshSceneNode *m_node;
-#endif
-       float m_yaw;
-
-       float m_counter1;
-       float m_counter2;
-       float m_age;
-};
-
-/*
-       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
-       ItemObject(MapBlock *block, s16 id, v3f pos):
-               MapBlockObject(block, id, pos)
-#ifndef SERVER
-               ,m_node(NULL)
-#endif
-       {
-               /*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/3,-BS/2,-BS/3, BS/3,-BS/2+BS*2/3,BS/3);
-               m_yaw = 0.0;
-       }
-       virtual ~ItemObject()
-       {
-               delete m_selection_box;
-       }
-       
-       /*
-               Implementation interface
-       */
-       virtual u16 getTypeId() const
-       {
-               return MAPBLOCKOBJECT_TYPE_ITEM;
-       }
-       virtual void serialize(std::ostream &os, u8 version)
-       {
-               serializeBase(os, version);
-               u8 buf[2];
-
-               // Write text length
-               writeU16(buf, m_itemstring.size());
-               os.write((char*)buf, 2);
-               
-               // Write text
-               os.write(m_itemstring.c_str(), m_itemstring.size());
-       }
-       virtual void update(std::istream &is, u8 version)
-       {
-               u8 buf[2];
-
-               // Read text length
-               is.read((char*)buf, 2);
-               u16 size = readU16(buf);
-
-               // Read text
-               std::string old_itemstring = m_itemstring;
-               m_itemstring.clear();
-               for(u16 i=0; i<size; i++)
-               {
-                       is.read((char*)buf, 1);
-                       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, u32 daynight_ratio)
-       {
-               return false;
-       }
-
-#ifndef SERVER
-       virtual void clientStep(float dtime)
-       {
-               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)
-               {
-                       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);
-               setMeshVerticesColor(m_node->getMesh(), color);
-       }
-#endif
-
-       virtual std::string infoText()
-       {
-               return std::string("\"") + m_itemstring + "\"";
-       }
-
-       virtual std::string getInventoryString()
-       {
-               return std::string("ItemObj ")+m_itemstring;
-       }
-
-       /*
-               Special methods
-       */
-
-       InventoryItem * createInventoryItem();
-       
-#ifndef SERVER
-       video::ITexture * getItemImage();
-
-       void updateSceneNode()
-       {
-               if(m_node != NULL)
-               {
-                       m_node->setPosition(getAbsolutePos());
-                       m_node->setRotation(v3f(0, m_yaw, 0));
-               }
-       }
-#endif
-
-       void setItemString(std::string inventorystring)
-       {
-               m_itemstring = inventorystring;
-               setBlockChanged();
-       }
-
-       std::string getItemString()
-       {
-               return m_itemstring;
-       }
-
-protected:
-#ifndef SERVER
-       scene::IMeshSceneNode *m_node;
-#endif
-       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),
-#ifndef SERVER
-               m_node(NULL),
-#endif
-               m_yaw(0)
-       {
-               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);
-               setMeshVerticesColor(m_node->getMesh(), color);
-       }
-       
-#endif
-
-       /*
-               Special methods
-       */
-       
-       void updateNodePos()
-       {
-#ifndef SERVER
-               if(m_node == NULL)
-                       return;
-
-               m_node->setPosition(getAbsoluteShowPos());
-               m_node->setRotation(v3f(0, -m_yaw+180, 0));
-#endif
-       }
-       
-protected:
-#ifndef SERVER
-       scene::IMeshSceneNode *m_node;
-#endif
-       float m_yaw;
-
-       v3f m_oldpos;
-};
-
-struct DistanceSortedObject
-{
-       DistanceSortedObject(MapBlockObject *a_obj, f32 a_d)
-       {
-               obj = a_obj;
-               d = a_d;
-       }
-       
-       MapBlockObject *obj;
-       f32 d;
-
-       bool operator < (DistanceSortedObject &other)
-       {
-               return d < other.d;
-       }
-};
-
-namespace irr{
-namespace scene{
-       class ISceneManager;
-}
-}
-using namespace irr;
-
-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,
-                       u32 daynight_ratio);
-
-       // Finds a new unique id
-       s16 getFreeId() throw(ContainerFullException);
-       /*
-               Adds an object.
-               Set id to -1 to have this set it to a suitable one.
-               The block pointer member is set to this block.
-       */
-       void add(MapBlockObject *object)
-                       throw(ContainerFullException, AlreadyExistsException);
-
-       // Deletes and removes all objects
-       void clear();
-
-       /*
-               Removes an object.
-               Ignores inexistent objects
-       */
-       void remove(s16 id);
-       /*
-               References an object.
-               The object will not be valid after step() or of course if
-               it is removed.
-               Grabbing the lock is recommended while processing.
-       */
-       MapBlockObject * get(s16 id);
-
-       // You'll want to grab this in a SharedPtr
-       JMutexAutoLock * getLock()
-       {
-               return new JMutexAutoLock(m_mutex);
-       }
-
-       // Steps all objects and if server==true, removes those that
-       // want to be removed
-       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
-       bool wrapObject(MapBlockObject *object);
-       
-       // origin is relative to block
-       void getObjects(v3f origin, f32 max_d,
-                       core::array<DistanceSortedObject> &dest);
-       
-       // Number of objects
-       s32 getCount()
-       {
-               return m_objects.size();
-       }
-
-private:
-       JMutex m_mutex;
-       // Key is id
-       core::map<s16, MapBlockObject*> m_objects;
-       MapBlock *m_block;
-
-       u32 m_last_update_daynight_ratio;
-};
-
-
-#endif
-
index 9a7c7ba9020ff3e610dc5071800b6bc6f2ce7b46..a74a91eebfc6faafbb5cf042ee643ad5fbd3f05e 100644 (file)
@@ -1405,6 +1405,7 @@ bool get_have_sand(u64 seed, v2s16 p2d)
 */
 void add_random_objects(MapBlock *block)
 {
+#if 0
        for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
        for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
        {
@@ -1465,6 +1466,7 @@ void add_random_objects(MapBlock *block)
                }
        }
        block->setChangedFlag();
+#endif
 }
 
 void make_block(BlockMakeData *data)
index 5b9903f5ad42f0bf970f5b2a0430ffede1312ebe..d78a00ea3cacd848f2d7a9490c51489fabbaf74e 100644 (file)
@@ -860,107 +860,10 @@ void RemoteClient::SendObjectData(
        v3s16 center_nodepos = floatToInt(playerpos, BS);
        v3s16 center = getNodeBlockPos(center_nodepos);
 
-       s16 d_max = g_settings->getS16("active_object_range");
-       
-       // Number of blocks whose objects were written to bos
-       u16 blockcount = 0;
-
-       std::ostringstream bos(std::ios_base::binary);
-
-       for(s16 d = 0; d <= d_max; d++)
-       {
-               core::list<v3s16> list;
-               getFacePositions(list, d);
-               
-               core::list<v3s16>::Iterator li;
-               for(li=list.begin(); li!=list.end(); li++)
-               {
-                       v3s16 p = *li + center;
-
-                       /*
-                               Ignore blocks that haven't been sent to the client
-                       */
-                       {
-                               if(m_blocks_sent.find(p) == NULL)
-                                       continue;
-                       }
-                       
-                       // Try stepping block and add it to a send queue
-                       try
-                       {
-
-                       // Get block
-                       MapBlock *block = server->m_env.getMap().getBlockNoCreate(p);
-
-                       /*
-                               Step block if not in stepped_blocks and add to stepped_blocks.
-                       */
-                       if(stepped_blocks.find(p) == NULL)
-                       {
-                               block->stepObjects(dtime, true, server->m_env.getDayNightRatio());
-                               stepped_blocks.insert(p, true);
-                               //block->setChangedFlag();
-                       }
-
-                       // Skip block if there are no objects
-                       if(block->getObjectCount() == 0)
-                               continue;
-                       
-                       /*
-                               Write objects
-                       */
-
-                       // Write blockpos
-                       writeV3S16(buf, p);
-                       bos.write((char*)buf, 6);
-
-                       // Write objects
-                       //block->serializeObjects(bos, serialization_version); // DEPRECATED
-                       // count=0
-                       writeU16(bos, 0);
-
-                       blockcount++;
-
-                       /*
-                               Stop collecting objects if data is already too big
-                       */
-                       // Sum of player and object data sizes
-                       s32 sum = (s32)os.tellp() + 2 + (s32)bos.tellp();
-                       // break out if data too big
-                       if(sum > MAX_OBJECTDATA_SIZE)
-                       {
-                               goto skip_subsequent;
-                       }
-                       
-                       } //try
-                       catch(InvalidPositionException &e)
-                       {
-                               // Not in memory
-                               // Add it to the emerge queue and trigger the thread.
-                               // Fetch the block only if it is on disk.
-                               
-                               // Grab and increment counter
-                               /*SharedPtr<JMutexAutoLock> lock
-                                               (m_num_blocks_in_emerge_queue.getLock());
-                               m_num_blocks_in_emerge_queue.m_value++;*/
-                               
-                               // Add to queue as an anonymous fetch from disk
-                               u8 flags = BLOCK_EMERGE_FLAG_FROMDISK;
-                               server->m_emerge_queue.addBlock(0, p, flags);
-                               server->m_emergethread.trigger();
-                       }
-               }
-       }
-
-skip_subsequent:
-
        // Write block count
-       writeU16(buf, blockcount);
+       writeU16(buf, 0);
        os.write((char*)buf, 2);
 
-       // Write block objects
-       os<<bos.str();
-
        /*
                Send data
        */
@@ -1431,7 +1334,8 @@ void Server::AsyncRunStep()
                ScopeProfiler sp(g_profiler, "Server: checking added and deleted objects");
 
                // Radius inside which objects are active
-               s16 radius = 32;
+               s16 radius = g_settings->getS16("active_object_send_range_blocks");
+               radius *= MAP_BLOCKSIZE;
 
                for(core::map<u16, RemoteClient*>::Iterator
                        i = m_clients.getIterator();
@@ -2343,87 +2247,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
        }
        else if(command == TOSERVER_CLICK_OBJECT)
        {
-               if(datasize < 13)
-                       return;
-
-               if((getPlayerPrivs(player) & PRIV_BUILD) == 0)
-                       return;
-
-               /*
-                       [0] u16 command
-                       [2] u8 button (0=left, 1=right)
-                       [3] v3s16 block
-                       [9] s16 id
-                       [11] u16 item
-               */
-               u8 button = readU8(&data[2]);
-               v3s16 p;
-               p.X = readS16(&data[3]);
-               p.Y = readS16(&data[5]);
-               p.Z = readS16(&data[7]);
-               s16 id = readS16(&data[9]);
-               //u16 item_i = readU16(&data[11]);
-
-               MapBlock *block = NULL;
-               try
-               {
-                       block = m_env.getMap().getBlockNoCreate(p);
-               }
-               catch(InvalidPositionException &e)
-               {
-                       derr_server<<"CLICK_OBJECT block not found"<<std::endl;
-                       return;
-               }
-
-               MapBlockObject *obj = block->getObject(id);
-
-               if(obj == NULL)
-               {
-                       derr_server<<"CLICK_OBJECT object not found"<<std::endl;
-                       return;
-               }
-
-               //TODO: Check that object is reasonably close
-               
-               // Left click
-               if(button == 0)
-               {
-                       InventoryList *ilist = player->inventory.getList("main");
-                       if(g_settings->getBool("creative_mode") == false && ilist != NULL)
-                       {
-                       
-                               // Skip if inventory has no free space
-                               if(ilist->getUsedSlots() == ilist->getSize())
-                               {
-                                       dout_server<<"Player inventory has no free space"<<std::endl;
-                                       return;
-                               }
-                               
-                               /*
-                                       Create the inventory item
-                               */
-                               InventoryItem *item = NULL;
-                               // If it is an item-object, take the item from it
-                               if(obj->getTypeId() == MAPBLOCKOBJECT_TYPE_ITEM)
-                               {
-                                       item = ((ItemObject*)obj)->createInventoryItem();
-                               }
-                               // Else create an item of the object
-                               else
-                               {
-                                       item = new MapBlockObjectItem
-                                                       (obj->getInventoryString());
-                               }
-                               
-                               // Add to inventory and send inventory
-                               ilist->addItem(item);
-                               UpdateCrafting(player->peer_id);
-                               SendInventory(player->peer_id);
-                       }
-
-                       // Remove from block
-                       block->removeObject(id);
-               }
+               derr_server<<"Server: CLICK_OBJECT not supported anymore"<<std::endl;
+               return;
        }
        else if(command == TOSERVER_CLICK_ACTIVEOBJECT)
        {
@@ -2442,7 +2267,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                */
                u8 button = readU8(&data[2]);
                u16 id = readS16(&data[3]);
-               u16 item_i = readU16(&data[11]);
+               u16 item_i = readU16(&data[5]);
        
                ServerActiveObject *obj = m_env.getActiveObject(id);
 
@@ -3076,62 +2901,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 #endif
        else if(command == TOSERVER_SIGNTEXT)
        {
-               if((getPlayerPrivs(player) & PRIV_BUILD) == 0)
-                       return;
-               /*
-                       u16 command
-                       v3s16 blockpos
-                       s16 id
-                       u16 textlen
-                       textdata
-               */
-               std::string datastring((char*)&data[2], datasize-2);
-               std::istringstream is(datastring, std::ios_base::binary);
-               u8 buf[6];
-               // Read stuff
-               is.read((char*)buf, 6);
-               v3s16 blockpos = readV3S16(buf);
-               is.read((char*)buf, 2);
-               s16 id = readS16(buf);
-               is.read((char*)buf, 2);
-               u16 textlen = readU16(buf);
-               std::string text;
-               for(u16 i=0; i<textlen; i++)
-               {
-                       is.read((char*)buf, 1);
-                       text += (char)buf[0];
-               }
-
-               MapBlock *block = NULL;
-               try
-               {
-                       block = m_env.getMap().getBlockNoCreate(blockpos);
-               }
-               catch(InvalidPositionException &e)
-               {
-                       derr_server<<"Error while setting sign text: "
-                                       "block not found"<<std::endl;
-                       return;
-               }
-
-               MapBlockObject *obj = block->getObject(id);
-               if(obj == NULL)
-               {
-                       derr_server<<"Error while setting sign text: "
-                                       "object not found"<<std::endl;
-                       return;
-               }
-               
-               if(obj->getTypeId() != MAPBLOCKOBJECT_TYPE_SIGN)
-               {
-                       derr_server<<"Error while setting sign text: "
-                                       "object is not a sign"<<std::endl;
-                       return;
-               }
-
-               ((SignObject*)obj)->setText(text);
-
-               obj->getBlock()->setChangedFlag();
+               derr_server<<"Server: TOSERVER_SIGNTEXT not supported anymore"
+                               <<std::endl;
+               return;
        }
        else if(command == TOSERVER_SIGNNODETEXT)
        {
index f972ce3ece1ce8528d97eb2c82514ca9e5aef550..e8f376938676ecee172f247e189325098ac47c06 100644 (file)
@@ -102,6 +102,22 @@ public:
                return true;
        }
 
+       void parseConfigLines(std::istream &is, const std::string &endstring)
+       {
+               for(;;){
+                       if(is.eof())
+                               break;
+                       std::string line;
+                       std::getline(is, line);
+                       std::string trimmedline = trim(line);
+                       if(endstring != ""){
+                               if(trimmedline == endstring)
+                                       break;
+                       }
+                       parseConfigLine(line);
+               }
+       }
+
        // Returns false on EOF
        bool parseConfigObject(std::istream &is)
        {
@@ -481,6 +497,16 @@ public:
                return value;
        }
 
+       v2f getV2F(std::string name)
+       {
+               v2f value;
+               Strfnd f(get(name));
+               f.next("(");
+               value.X = stof(f.next(","));
+               value.Y = stof(f.next(")"));
+               return value;
+       }
+
        u64 getU64(std::string name)
        {
                u64 value = 0;
@@ -515,6 +541,13 @@ public:
                set(name, os.str());
        }
 
+       void setV2F(std::string name, v2f value)
+       {
+               std::ostringstream os;
+               os<<"("<<value.X<<","<<value.Y<<")";
+               set(name, os.str());
+       }
+
        void setU64(std::string name, u64 value)
        {
                std::ostringstream os;
@@ -530,6 +563,47 @@ public:
                m_defaults.clear();
        }
 
+       void updateValue(Settings &other, const std::string &name)
+       {
+               JMutexAutoLock lock(m_mutex);
+               
+               if(&other == this)
+                       return;
+
+               try{
+                       std::string val = other.get(name);
+                       m_settings[name] = val;
+               } catch(SettingNotFoundException &e){
+               }
+
+               return;
+       }
+
+       void update(Settings &other)
+       {
+               JMutexAutoLock lock(m_mutex);
+               JMutexAutoLock lock2(other.m_mutex);
+               
+               if(&other == this)
+                       return;
+
+               for(core::map<std::string, std::string>::Iterator
+                               i = other.m_settings.getIterator();
+                               i.atEnd() == false; i++)
+               {
+                       m_settings[i.getNode()->getKey()] = i.getNode()->getValue();
+               }
+               
+               for(core::map<std::string, std::string>::Iterator
+                               i = other.m_defaults.getIterator();
+                               i.atEnd() == false; i++)
+               {
+                       m_defaults[i.getNode()->getKey()] = i.getNode()->getValue();
+               }
+
+               return;
+       }
+
        Settings & operator+=(Settings &other)
        {
                JMutexAutoLock lock(m_mutex);
index ac5965e9feb3f8e8f7a5a1517cd0b05e69deae9e..986d6bbf11b034721b564a3d072f79183c1115ee 100644 (file)
@@ -1054,6 +1054,120 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
                                image->drop();
                        }
                }
+               /*
+                       "[makealpha:R,G,B:filename.png"
+                       Use an image with converting one color to transparent.
+               */
+               else if(part_of_name.substr(0,11) == "[makealpha:")
+               {
+                       if(baseimg != NULL)
+                       {
+                               dstream<<"WARNING: generate_image(): baseimg!=NULL "
+                                               <<"for part_of_name=\""<<part_of_name
+                                               <<"\", cancelling."<<std::endl;
+                               return false;
+                       }
+
+                       Strfnd sf(part_of_name.substr(11));
+                       u32 r1 = stoi(sf.next(","));
+                       u32 g1 = stoi(sf.next(","));
+                       u32 b1 = stoi(sf.next(":"));
+                       std::string filename = sf.next("");
+
+                       std::string path = getTexturePath(filename.c_str());
+
+                       dstream<<"INFO: generate_image(): Loading path \""<<path
+                                       <<"\""<<std::endl;
+                       
+                       video::IImage *image = driver->createImageFromFile(path.c_str());
+                       
+                       if(image == NULL)
+                       {
+                               dstream<<"WARNING: generate_image(): Loading path \""
+                                               <<path<<"\" failed"<<std::endl;
+                       }
+                       else
+                       {
+                               core::dimension2d<u32> dim = image->getDimension();
+                               baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
+                               
+                               for(u32 y=0; y<dim.Height; y++)
+                               for(u32 x=0; x<dim.Width; x++)
+                               {
+                                       video::SColor c = image->getPixel(x,y);
+                                       u32 r = c.getRed();
+                                       u32 g = c.getGreen();
+                                       u32 b = c.getBlue();
+                                       if(!(r == r1 && g == g1 && b == b1))
+                                               continue;
+                                       c.setAlpha(0);
+                                       image->setPixel(x,y,c);
+                               }
+                               // Blit
+                               image->copyTo(baseimg);
+
+                               image->drop();
+                       }
+               }
+               /*
+                       "[makealpha2:R,G,B;R2,G2,B2:filename.png"
+                       Use an image with converting two colors to transparent.
+               */
+               else if(part_of_name.substr(0,12) == "[makealpha2:")
+               {
+                       if(baseimg != NULL)
+                       {
+                               dstream<<"WARNING: generate_image(): baseimg!=NULL "
+                                               <<"for part_of_name=\""<<part_of_name
+                                               <<"\", cancelling."<<std::endl;
+                               return false;
+                       }
+
+                       Strfnd sf(part_of_name.substr(12));
+                       u32 r1 = stoi(sf.next(","));
+                       u32 g1 = stoi(sf.next(","));
+                       u32 b1 = stoi(sf.next(";"));
+                       u32 r2 = stoi(sf.next(","));
+                       u32 g2 = stoi(sf.next(","));
+                       u32 b2 = stoi(sf.next(":"));
+                       std::string filename = sf.next("");
+
+                       std::string path = getTexturePath(filename.c_str());
+
+                       dstream<<"INFO: generate_image(): Loading path \""<<path
+                                       <<"\""<<std::endl;
+                       
+                       video::IImage *image = driver->createImageFromFile(path.c_str());
+                       
+                       if(image == NULL)
+                       {
+                               dstream<<"WARNING: generate_image(): Loading path \""
+                                               <<path<<"\" failed"<<std::endl;
+                       }
+                       else
+                       {
+                               core::dimension2d<u32> dim = image->getDimension();
+                               baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
+                               
+                               for(u32 y=0; y<dim.Height; y++)
+                               for(u32 x=0; x<dim.Width; x++)
+                               {
+                                       video::SColor c = image->getPixel(x,y);
+                                       u32 r = c.getRed();
+                                       u32 g = c.getGreen();
+                                       u32 b = c.getBlue();
+                                       if(!(r == r1 && g == g1 && b == b1) &&
+                                          !(r == r2 && g == g2 && b == b2))
+                                               continue;
+                                       c.setAlpha(0);
+                                       image->setPixel(x,y,c);
+                               }
+                               // Blit
+                               image->copyTo(baseimg);
+
+                               image->drop();
+                       }
+               }
                /*
                        [inventorycube{topimage{leftimage{rightimage
                        In every subimage, replace ^ with &.
index f8cc3498444265da15fe88259a86d32be0a327a2..255b75c08c695bf44da49a014f6a35d15b4f4469 100644 (file)
@@ -810,6 +810,35 @@ inline float wrapDegrees(float f)
        return f;
 }
 
+/* Wrap to 0...360 */
+inline float wrapDegrees_0_360(float f)
+{
+       // Take examples of f=10, f=720.5, f=-0.5, f=-360.5
+       // This results in
+       // 10, 720, -1, -361
+       int i = floor(f);
+       // 0, 2, 0, -1
+       int l = i / 360;
+       // Wrap to 0...360
+       // 0, 2, -1, -2
+       if(i < 0)
+               l -= 1;
+       // 0, 720, 0, -360
+       int k = l * 360;
+       // 10, 0.5, -0.5, -0.5
+       f -= float(k);
+       return f;
+}
+
+/* Wrap to -180...180 */
+inline float wrapDegrees_180(float f)
+{
+       f += 180;
+       f = wrapDegrees_0_360(f);
+       f -= 180;
+       return f;
+}
+
 inline std::string lowercase(const std::string &s)
 {
        std::string s2;