reorganized a lot of stuff and modified mapgen and objects slightly while doing it
authorPerttu Ahola <celeron55@gmail.com>
Sun, 26 Jun 2011 12:48:56 +0000 (15:48 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 26 Jun 2011 12:48:56 +0000 (15:48 +0300)
24 files changed:
.hgignore
data/oerkki1.png
data/oerkki1_damaged.png [new file with mode: 0644]
src/CMakeLists.txt
src/activeobject.h
src/clientobject.cpp
src/clientobject.h
src/collision.cpp
src/collision.h
src/content_cao.cpp [new file with mode: 0644]
src/content_cao.h [new file with mode: 0644]
src/content_inventory.cpp
src/content_object.h [new file with mode: 0644]
src/content_sao.cpp [new file with mode: 0644]
src/content_sao.h [new file with mode: 0644]
src/environment.cpp
src/environment.h
src/game.cpp
src/inventory.cpp
src/map.cpp
src/mapgen.cpp
src/server.cpp
src/serverobject.cpp
src/serverobject.h

index 0870e3c674d7e96310acae24938613b764ff7a65..964b22bd928c0e46c37487ecf520e95b89b4ef3c 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -9,7 +9,12 @@ src/jthread/CMakeFiles/*
 src/jthread/Makefile
 src/jthread/cmake_config.h
 src/jthread/cmake_install.cmake
+src/.*.swp
+src/sqlite/libsqlite3.a
+src/session.vim
+util/uloste.png
 minetest.conf
+debug.txt
 bin/
 CMakeCache.txt
 CPackConfig.cmake
index c32fb99dbc9381cba551ef0c96482624ec72792a..33cbac9e76114d9ce2de4006b616fe2fd17f9f21 100644 (file)
Binary files a/data/oerkki1.png and b/data/oerkki1.png differ
diff --git a/data/oerkki1_damaged.png b/data/oerkki1_damaged.png
new file mode 100644 (file)
index 0000000..9b77738
Binary files /dev/null and b/data/oerkki1_damaged.png differ
index 73a960ecc64b6a3e70dc9b7715c2719b9b89fae3..84726945691261aaacbcba5f5a772cb8af8ef42a 100644 (file)
@@ -61,6 +61,7 @@ configure_file(
 )
 
 set(common_SRCS
+       content_sao.cpp
        mapgen.cpp
        content_inventory.cpp
        content_nodemeta.cpp
@@ -102,6 +103,7 @@ set(common_SRCS
 # Client sources
 set(minetest_SRCS
        ${common_SRCS}
+       content_cao.cpp
        mapblock_mesh.cpp
        farmesh.cpp
        keycode.cpp
index 382f7f7981d329a3b751da08e44362b5f3a50df2..09ee23a14c61bec788c2a9e8d9cabd8c14b25698 100644 (file)
@@ -23,6 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "common_irrlicht.h"
 #include <string>
 
+#define ACTIVEOBJECT_TYPE_INVALID 0
+// Other types are defined in content_object.h
+
 struct ActiveObjectMessage
 {
        ActiveObjectMessage(u16 id_, bool reliable_=true, std::string data_=""):
@@ -36,12 +39,6 @@ struct ActiveObjectMessage
        std::string datastring;
 };
 
-#define ACTIVEOBJECT_TYPE_INVALID 0
-#define ACTIVEOBJECT_TYPE_TEST 1
-#define ACTIVEOBJECT_TYPE_ITEM 2
-#define ACTIVEOBJECT_TYPE_RAT 3
-#define ACTIVEOBJECT_TYPE_OERKKI1 4
-
 /*
        Parent class for ServerActiveObject and ClientActiveObject
 */
index 402535ffc974b8c232ea353f686de3eab64ad2c1..787efef294c988dae5c5e6f758e0fd0a1daf9f0a 100644 (file)
@@ -21,9 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "debug.h"
 #include "porting.h"
 #include "constants.h"
-#include "utility.h"
-#include "environment.h"
-#include "tile.h"
 
 /*
        ClientActiveObject
@@ -68,674 +65,4 @@ void ClientActiveObject::registerType(u16 type, Factory f)
        m_types.insert(type, f);
 }
 
-/*
-       TestCAO
-*/
-
-// Prototype
-TestCAO proto_TestCAO;
-
-TestCAO::TestCAO():
-       ClientActiveObject(0),
-       m_node(NULL),
-       m_position(v3f(0,10*BS,0))
-{
-       ClientActiveObject::registerType(getType(), create);
-}
-
-TestCAO::~TestCAO()
-{
-}
-
-ClientActiveObject* TestCAO::create()
-{
-       return new TestCAO();
-}
-
-void TestCAO::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();
-}
-
-void TestCAO::removeFromScene()
-{
-       if(m_node == NULL)
-               return;
-
-       m_node->remove();
-       m_node = NULL;
-}
-
-void TestCAO::updateLight(u8 light_at_pos)
-{
-}
-
-v3s16 TestCAO::getLightPosition()
-{
-       return floatToInt(m_position, BS);
-}
-
-void TestCAO::updateNodePos()
-{
-       if(m_node == NULL)
-               return;
-
-       m_node->setPosition(m_position);
-       //m_node->setRotation(v3f(0, 45, 0));
-}
-
-void TestCAO::step(float dtime, ClientEnvironment *env)
-{
-       if(m_node)
-       {
-               v3f rot = m_node->getRotation();
-               //dstream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
-               rot.Y += dtime * 180;
-               m_node->setRotation(rot);
-       }
-}
-
-void TestCAO::processMessage(const std::string &data)
-{
-       dstream<<"TestCAO: Got data: "<<data<<std::endl;
-       std::istringstream is(data, std::ios::binary);
-       u16 cmd;
-       is>>cmd;
-       if(cmd == 0)
-       {
-               v3f newpos;
-               is>>newpos.X;
-               is>>newpos.Y;
-               is>>newpos.Z;
-               m_position = newpos;
-               updateNodePos();
-       }
-}
-
-/*
-       ItemCAO
-*/
-
-#include "inventory.h"
-
-// Prototype
-ItemCAO proto_ItemCAO;
-
-ItemCAO::ItemCAO():
-       ClientActiveObject(0),
-       m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
-       m_node(NULL),
-       m_position(v3f(0,10*BS,0))
-{
-       ClientActiveObject::registerType(getType(), create);
-}
-
-ItemCAO::~ItemCAO()
-{
-}
-
-ClientActiveObject* ItemCAO::create()
-{
-       return new ItemCAO();
-}
-
-void ItemCAO::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),*/
-               video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
-               video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
-               video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
-               video::S3DVertex(BS/3.,0+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, NULL);
-       // Initialize with the stick texture
-       buf->getMaterial().setTexture
-                       (0, driver->getTexture(getTexturePath("stick.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();
-       // Set it to use the materials of the meshbuffers directly.
-       // This is needed for changing the texture in the future
-       m_node->setReadOnlyMaterials(true);
-       updateNodePos();
-}
-
-void ItemCAO::removeFromScene()
-{
-       if(m_node == NULL)
-               return;
-
-       m_node->remove();
-       m_node = NULL;
-}
-
-void ItemCAO::updateLight(u8 light_at_pos)
-{
-       if(m_node == NULL)
-               return;
-
-       u8 li = decode_light(light_at_pos);
-       video::SColor color(255,li,li,li);
-
-       scene::IMesh *mesh = m_node->getMesh();
-       if(mesh == NULL)
-               return;
-       
-       u16 mc = mesh->getMeshBufferCount();
-       for(u16 j=0; j<mc; j++)
-       {
-               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
-               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
-               u16 vc = buf->getVertexCount();
-               for(u16 i=0; i<vc; i++)
-               {
-                       vertices[i].Color = color;
-               }
-       }
-}
-
-v3s16 ItemCAO::getLightPosition()
-{
-       return floatToInt(m_position, BS);
-}
-
-void ItemCAO::updateNodePos()
-{
-       if(m_node == NULL)
-               return;
-
-       m_node->setPosition(m_position);
-}
-
-void ItemCAO::step(float dtime, ClientEnvironment *env)
-{
-       if(m_node)
-       {
-               /*v3f rot = m_node->getRotation();
-               rot.Y += dtime * 120;
-               m_node->setRotation(rot);*/
-               LocalPlayer *player = env->getLocalPlayer();
-               assert(player);
-               v3f rot = m_node->getRotation();
-               rot.Y = 180.0 - (player->getYaw());
-               m_node->setRotation(rot);
-       }
-}
-
-void ItemCAO::processMessage(const std::string &data)
-{
-       dstream<<"ItemCAO: Got message"<<std::endl;
-       std::istringstream is(data, std::ios::binary);
-       // command
-       u8 cmd = readU8(is);
-       if(cmd == 0)
-       {
-               // pos
-               m_position = readV3F1000(is);
-               updateNodePos();
-       }
-}
-
-void ItemCAO::initialize(const std::string &data)
-{
-       dstream<<"ItemCAO: Got init data"<<std::endl;
-       
-       {
-               std::istringstream is(data, std::ios::binary);
-               // version
-               u8 version = readU8(is);
-               // check version
-               if(version != 0)
-                       return;
-               // pos
-               m_position = readV3F1000(is);
-               // inventorystring
-               m_inventorystring = deSerializeString(is);
-       }
-       
-       updateNodePos();
-
-       /*
-               Update image of node
-       */
-
-       if(m_node == NULL)
-               return;
-
-       scene::IMesh *mesh = m_node->getMesh();
-
-       if(mesh == NULL)
-               return;
-       
-       scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
-
-       if(buf == NULL)
-               return;
-
-       // Create an inventory item to see what is its image
-       std::istringstream is(m_inventorystring, std::ios_base::binary);
-       video::ITexture *texture = NULL;
-       try{
-               InventoryItem *item = NULL;
-               item = InventoryItem::deSerialize(is);
-               dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
-                               <<m_inventorystring<<"\" -> item="<<item
-                               <<std::endl;
-               if(item)
-               {
-                       texture = item->getImage();
-                       delete item;
-               }
-       }
-       catch(SerializationError &e)
-       {
-               dstream<<"WARNING: "<<__FUNCTION_NAME
-                               <<": error deSerializing inventorystring \""
-                               <<m_inventorystring<<"\""<<std::endl;
-       }
-       
-       // Set meshbuffer texture
-       buf->getMaterial().setTexture(0, texture);
-       
-}
-
-/*
-       RatCAO
-*/
-
-#include "inventory.h"
-
-// Prototype
-RatCAO proto_RatCAO;
-
-RatCAO::RatCAO():
-       ClientActiveObject(0),
-       m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
-       m_node(NULL),
-       m_position(v3f(0,10*BS,0)),
-       m_yaw(0)
-{
-       ClientActiveObject::registerType(getType(), create);
-}
-
-RatCAO::~RatCAO()
-{
-}
-
-ClientActiveObject* RatCAO::create()
-{
-       return new RatCAO();
-}
-
-void RatCAO::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,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, NULL);
-       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();
-       // Set it to use the materials of the meshbuffers directly.
-       // This is needed for changing the texture in the future
-       m_node->setReadOnlyMaterials(true);
-       updateNodePos();
-}
-
-void RatCAO::removeFromScene()
-{
-       if(m_node == NULL)
-               return;
-
-       m_node->remove();
-       m_node = NULL;
-}
-
-void RatCAO::updateLight(u8 light_at_pos)
-{
-       if(m_node == NULL)
-               return;
-
-       u8 li = decode_light(light_at_pos);
-       video::SColor color(255,li,li,li);
-
-       scene::IMesh *mesh = m_node->getMesh();
-       if(mesh == NULL)
-               return;
-       
-       u16 mc = mesh->getMeshBufferCount();
-       for(u16 j=0; j<mc; j++)
-       {
-               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
-               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
-               u16 vc = buf->getVertexCount();
-               for(u16 i=0; i<vc; i++)
-               {
-                       vertices[i].Color = color;
-               }
-       }
-}
-
-v3s16 RatCAO::getLightPosition()
-{
-       return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
-}
-
-void RatCAO::updateNodePos()
-{
-       if(m_node == NULL)
-               return;
-
-       //m_node->setPosition(m_position);
-       m_node->setPosition(pos_translator.vect_show);
-
-       v3f rot = m_node->getRotation();
-       rot.Y = 180.0 - m_yaw;
-       m_node->setRotation(rot);
-}
-
-void RatCAO::step(float dtime, ClientEnvironment *env)
-{
-       pos_translator.translate(dtime);
-       updateNodePos();
-}
-
-void RatCAO::processMessage(const std::string &data)
-{
-       //dstream<<"RatCAO: Got message"<<std::endl;
-       std::istringstream is(data, std::ios::binary);
-       // command
-       u8 cmd = readU8(is);
-       if(cmd == 0)
-       {
-               // pos
-               m_position = readV3F1000(is);
-               pos_translator.update(m_position);
-               // yaw
-               m_yaw = readF1000(is);
-               updateNodePos();
-       }
-}
-
-void RatCAO::initialize(const std::string &data)
-{
-       //dstream<<"RatCAO: Got init data"<<std::endl;
-       
-       {
-               std::istringstream is(data, std::ios::binary);
-               // version
-               u8 version = readU8(is);
-               // check version
-               if(version != 0)
-                       return;
-               // pos
-               m_position = readV3F1000(is);
-               pos_translator.init(m_position);
-       }
-       
-       updateNodePos();
-}
-
-/*
-       Oerkki1CAO
-*/
-
-#include "inventory.h"
-
-// Prototype
-Oerkki1CAO proto_Oerkki1CAO;
-
-Oerkki1CAO::Oerkki1CAO():
-       ClientActiveObject(0),
-       m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
-       m_node(NULL),
-       m_position(v3f(0,10*BS,0)),
-       m_yaw(0)
-{
-       ClientActiveObject::registerType(getType(), create);
-}
-
-Oerkki1CAO::~Oerkki1CAO()
-{
-}
-
-ClientActiveObject* Oerkki1CAO::create()
-{
-       return new Oerkki1CAO();
-}
-
-void Oerkki1CAO::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,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, NULL);
-       buf->getMaterial().setTexture
-                       (0, driver->getTexture(getTexturePath("oerkki1.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();
-       // Set it to use the materials of the meshbuffers directly.
-       // This is needed for changing the texture in the future
-       m_node->setReadOnlyMaterials(true);
-       updateNodePos();
-}
-
-void Oerkki1CAO::removeFromScene()
-{
-       if(m_node == NULL)
-               return;
-
-       m_node->remove();
-       m_node = NULL;
-}
-
-void Oerkki1CAO::updateLight(u8 light_at_pos)
-{
-       if(m_node == NULL)
-               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);
-
-       scene::IMesh *mesh = m_node->getMesh();
-       if(mesh == NULL)
-               return;
-       
-       u16 mc = mesh->getMeshBufferCount();
-       for(u16 j=0; j<mc; j++)
-       {
-               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
-               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
-               u16 vc = buf->getVertexCount();
-               for(u16 i=0; i<vc; i++)
-               {
-                       vertices[i].Color = color;
-               }
-       }
-}
-
-v3s16 Oerkki1CAO::getLightPosition()
-{
-       return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
-}
-
-void Oerkki1CAO::updateNodePos()
-{
-       if(m_node == NULL)
-               return;
-
-       //m_node->setPosition(m_position);
-       m_node->setPosition(pos_translator.vect_show);
-
-       v3f rot = m_node->getRotation();
-       rot.Y = 180.0 - m_yaw + 90.0;
-       m_node->setRotation(rot);
-}
-
-void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
-{
-       pos_translator.translate(dtime);
-       updateNodePos();
-
-       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) < 3.0*BS &&
-                       objectpos_2d.getDistanceFrom(playerpos_2d) < 1.0*BS)
-       {
-               if(m_attack_interval.step(dtime, 0.5))
-               {
-                       env->damageLocalPlayer(2);
-               }
-       }
-}
-
-void Oerkki1CAO::processMessage(const std::string &data)
-{
-       //dstream<<"Oerkki1CAO: Got message"<<std::endl;
-       std::istringstream is(data, std::ios::binary);
-       // command
-       u8 cmd = readU8(is);
-       if(cmd == 0)
-       {
-               // pos
-               m_position = readV3F1000(is);
-               pos_translator.update(m_position);
-               // yaw
-               m_yaw = readF1000(is);
-               updateNodePos();
-       }
-}
-
-void Oerkki1CAO::initialize(const std::string &data)
-{
-       //dstream<<"Oerkki1CAO: Got init data"<<std::endl;
-       
-       {
-               std::istringstream is(data, std::ios::binary);
-               // version
-               u8 version = readU8(is);
-               // check version
-               if(version != 0)
-                       return;
-               // pos
-               m_position = readV3F1000(is);
-               pos_translator.init(m_position);
-       }
-       
-       updateNodePos();
-}
-
 
index 8d211fef38dde5a9f8f59443e688fcf6b61c880f..c90648483005105d11ccab1db507ac8008074256 100644 (file)
@@ -22,7 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "common_irrlicht.h"
 #include "activeobject.h"
-#include "utility.h"
 
 /*
 
@@ -36,63 +35,6 @@ Some planning
 
 */
 
-/*
-       SmoothTranslator
-*/
-
-struct SmoothTranslator
-{
-       v3f vect_old;
-       f32 anim_counter;
-       f32 anim_time;
-       f32 anim_time_counter;
-       v3f vect_show;
-       v3f vect_aim;
-
-       SmoothTranslator():
-               vect_old(0,0,0),
-               anim_counter(0),
-               anim_time(0),
-               anim_time_counter(0),
-               vect_show(0,0,0),
-               vect_aim(0,0,0)
-       {}
-
-       void init(v3f vect)
-       {
-               vect_old = vect;
-               vect_show = vect;
-               vect_aim = vect;
-       }
-
-       void update(v3f vect_new)
-       {
-               vect_old = vect_show;
-               vect_aim = vect_new;
-               if(anim_time < 0.001 || anim_time > 1.0)
-                       anim_time = anim_time_counter;
-               else
-                       anim_time = anim_time * 0.9 + anim_time_counter * 0.1;
-               anim_time_counter = 0;
-               anim_counter = 0;
-       }
-
-       void translate(f32 dtime)
-       {
-               anim_time_counter = anim_time_counter + dtime;
-               anim_counter = anim_counter + dtime;
-               v3f vect_move = vect_aim - vect_old;
-               f32 moveratio = 1.0;
-               if(anim_time > 0.001)
-                       moveratio = anim_time_counter / anim_time;
-               // Move a bit less than should, to avoid oscillation
-               moveratio = moveratio * 0.8;
-               if(moveratio > 1.5)
-                       moveratio = 1.5;
-               vect_show = vect_old + vect_move * moveratio;
-       }
-};
-
 class ClientEnvironment;
 
 class ClientActiveObject : public ActiveObject
@@ -153,164 +95,5 @@ struct DistanceSortedActiveObject
        }
 };
 
-/*
-       TestCAO
-*/
-
-class TestCAO : public ClientActiveObject
-{
-public:
-       TestCAO();
-       virtual ~TestCAO();
-       
-       u8 getType() const
-       {
-               return ACTIVEOBJECT_TYPE_TEST;
-       }
-       
-       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);
-
-private:
-       scene::IMeshSceneNode *m_node;
-       v3f m_position;
-};
-
-/*
-       ItemCAO
-*/
-
-class ItemCAO : public ClientActiveObject
-{
-public:
-       ItemCAO();
-       virtual ~ItemCAO();
-       
-       u8 getType() const
-       {
-               return ACTIVEOBJECT_TYPE_ITEM;
-       }
-       
-       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 m_position;}
-
-private:
-       core::aabbox3d<f32> m_selection_box;
-       scene::IMeshSceneNode *m_node;
-       v3f m_position;
-       std::string m_inventorystring;
-};
-
-/*
-       RatCAO
-*/
-
-class RatCAO : public ClientActiveObject
-{
-public:
-       RatCAO();
-       virtual ~RatCAO();
-       
-       u8 getType() const
-       {
-               return ACTIVEOBJECT_TYPE_RAT;
-       }
-       
-       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 m_position;}
-
-private:
-       core::aabbox3d<f32> m_selection_box;
-       scene::IMeshSceneNode *m_node;
-       v3f m_position;
-       float m_yaw;
-       SmoothTranslator pos_translator;
-};
-
-/*
-       Oerkki1CAO
-*/
-
-class Oerkki1CAO : public ClientActiveObject
-{
-public:
-       Oerkki1CAO();
-       virtual ~Oerkki1CAO();
-       
-       u8 getType() const
-       {
-               return ACTIVEOBJECT_TYPE_OERKKI1;
-       }
-       
-       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;}
-
-private:
-       IntervalLimiter m_attack_interval;
-       core::aabbox3d<f32> m_selection_box;
-       scene::IMeshSceneNode *m_node;
-       v3f m_position;
-       float m_yaw;
-       SmoothTranslator pos_translator;
-};
-
 #endif
 
index 63186a84a5e72a2b803777f4c8795d652b5097b9..01d5462847134f952626b4ea315dc83910b02286 100644 (file)
@@ -182,4 +182,58 @@ collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
        return result;
 }
 
+collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
+               const core::aabbox3d<f32> &box_0,
+               f32 dtime, v3f &pos_f, v3f &speed_f)
+{
+       collisionMoveResult final_result;
+
+       // Maximum time increment (for collision detection etc)
+       // time = distance / speed
+       f32 dtime_max_increment = pos_max_d / speed_f.getLength();
+       
+       // Maximum time increment is 10ms or lower
+       if(dtime_max_increment > 0.01)
+               dtime_max_increment = 0.01;
+       
+       // Don't allow overly huge dtime
+       if(dtime > 2.0)
+               dtime = 2.0;
+       
+       f32 dtime_downcount = dtime;
+
+       u32 loopcount = 0;
+       do
+       {
+               loopcount++;
+
+               f32 dtime_part;
+               if(dtime_downcount > dtime_max_increment)
+               {
+                       dtime_part = dtime_max_increment;
+                       dtime_downcount -= dtime_part;
+               }
+               else
+               {
+                       dtime_part = dtime_downcount;
+                       /*
+                               Setting this to 0 (no -=dtime_part) disables an infinite loop
+                               when dtime_part is so small that dtime_downcount -= dtime_part
+                               does nothing
+                       */
+                       dtime_downcount = 0;
+               }
+
+               collisionMoveResult result = collisionMoveSimple(map, pos_max_d,
+                               box_0, dtime_part, pos_f, speed_f);
+
+               if(result.touching_ground)
+                       final_result.touching_ground = true;
+       }
+       while(dtime_downcount > 0.001);
+               
+
+       return final_result;
+}
+
 
index 9c913c6a9720d52116fadc58060a4eb2bb32a744..6d167bb7be415debaa192e61a3111f46b331ed32 100644 (file)
@@ -33,10 +33,15 @@ struct collisionMoveResult
        {}
 };
 
+// Moves using a single iteration; speed should not exceed pos_max_d/dtime
 collisionMoveResult collisionMoveSimple(Map *map, f32 pos_max_d,
                const core::aabbox3d<f32> &box_0,
                f32 dtime, v3f &pos_f, v3f &speed_f);
-//{return collisionMoveResult();}
+
+// Moves using as many iterations as needed
+collisionMoveResult collisionMovePrecise(Map *map, f32 pos_max_d,
+               const core::aabbox3d<f32> &box_0,
+               f32 dtime, v3f &pos_f, v3f &speed_f);
 
 enum CollisionType
 {
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
new file mode 100644 (file)
index 0000000..ab20f1a
--- /dev/null
@@ -0,0 +1,753 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 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.
+*/
+
+#include "content_cao.h"
+#include "tile.h"
+#include "environment.h"
+
+/*
+       TestCAO
+*/
+
+// Prototype
+TestCAO proto_TestCAO;
+
+TestCAO::TestCAO():
+       ClientActiveObject(0),
+       m_node(NULL),
+       m_position(v3f(0,10*BS,0))
+{
+       ClientActiveObject::registerType(getType(), create);
+}
+
+TestCAO::~TestCAO()
+{
+}
+
+ClientActiveObject* TestCAO::create()
+{
+       return new TestCAO();
+}
+
+void TestCAO::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();
+}
+
+void TestCAO::removeFromScene()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->remove();
+       m_node = NULL;
+}
+
+void TestCAO::updateLight(u8 light_at_pos)
+{
+}
+
+v3s16 TestCAO::getLightPosition()
+{
+       return floatToInt(m_position, BS);
+}
+
+void TestCAO::updateNodePos()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->setPosition(m_position);
+       //m_node->setRotation(v3f(0, 45, 0));
+}
+
+void TestCAO::step(float dtime, ClientEnvironment *env)
+{
+       if(m_node)
+       {
+               v3f rot = m_node->getRotation();
+               //dstream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
+               rot.Y += dtime * 180;
+               m_node->setRotation(rot);
+       }
+}
+
+void TestCAO::processMessage(const std::string &data)
+{
+       dstream<<"TestCAO: Got data: "<<data<<std::endl;
+       std::istringstream is(data, std::ios::binary);
+       u16 cmd;
+       is>>cmd;
+       if(cmd == 0)
+       {
+               v3f newpos;
+               is>>newpos.X;
+               is>>newpos.Y;
+               is>>newpos.Z;
+               m_position = newpos;
+               updateNodePos();
+       }
+}
+
+/*
+       ItemCAO
+*/
+
+#include "inventory.h"
+
+// Prototype
+ItemCAO proto_ItemCAO;
+
+ItemCAO::ItemCAO():
+       ClientActiveObject(0),
+       m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
+       m_node(NULL),
+       m_position(v3f(0,10*BS,0))
+{
+       ClientActiveObject::registerType(getType(), create);
+}
+
+ItemCAO::~ItemCAO()
+{
+}
+
+ClientActiveObject* ItemCAO::create()
+{
+       return new ItemCAO();
+}
+
+void ItemCAO::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),*/
+               video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
+               video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
+               video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
+               video::S3DVertex(BS/3.,0+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, NULL);
+       // Initialize with the stick texture
+       buf->getMaterial().setTexture
+                       (0, driver->getTexture(getTexturePath("stick.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();
+       // Set it to use the materials of the meshbuffers directly.
+       // This is needed for changing the texture in the future
+       m_node->setReadOnlyMaterials(true);
+       updateNodePos();
+}
+
+void ItemCAO::removeFromScene()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->remove();
+       m_node = NULL;
+}
+
+void ItemCAO::updateLight(u8 light_at_pos)
+{
+       if(m_node == NULL)
+               return;
+
+       u8 li = decode_light(light_at_pos);
+       video::SColor color(255,li,li,li);
+
+       scene::IMesh *mesh = m_node->getMesh();
+       if(mesh == NULL)
+               return;
+       
+       u16 mc = mesh->getMeshBufferCount();
+       for(u16 j=0; j<mc; j++)
+       {
+               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+               u16 vc = buf->getVertexCount();
+               for(u16 i=0; i<vc; i++)
+               {
+                       vertices[i].Color = color;
+               }
+       }
+}
+
+v3s16 ItemCAO::getLightPosition()
+{
+       return floatToInt(m_position, BS);
+}
+
+void ItemCAO::updateNodePos()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->setPosition(m_position);
+}
+
+void ItemCAO::step(float dtime, ClientEnvironment *env)
+{
+       if(m_node)
+       {
+               /*v3f rot = m_node->getRotation();
+               rot.Y += dtime * 120;
+               m_node->setRotation(rot);*/
+               LocalPlayer *player = env->getLocalPlayer();
+               assert(player);
+               v3f rot = m_node->getRotation();
+               rot.Y = 180.0 - (player->getYaw());
+               m_node->setRotation(rot);
+       }
+}
+
+void ItemCAO::processMessage(const std::string &data)
+{
+       dstream<<"ItemCAO: Got message"<<std::endl;
+       std::istringstream is(data, std::ios::binary);
+       // command
+       u8 cmd = readU8(is);
+       if(cmd == 0)
+       {
+               // pos
+               m_position = readV3F1000(is);
+               updateNodePos();
+       }
+}
+
+void ItemCAO::initialize(const std::string &data)
+{
+       dstream<<"ItemCAO: Got init data"<<std::endl;
+       
+       {
+               std::istringstream is(data, std::ios::binary);
+               // version
+               u8 version = readU8(is);
+               // check version
+               if(version != 0)
+                       return;
+               // pos
+               m_position = readV3F1000(is);
+               // inventorystring
+               m_inventorystring = deSerializeString(is);
+       }
+       
+       updateNodePos();
+
+       /*
+               Update image of node
+       */
+
+       if(m_node == NULL)
+               return;
+
+       scene::IMesh *mesh = m_node->getMesh();
+
+       if(mesh == NULL)
+               return;
+       
+       scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
+
+       if(buf == NULL)
+               return;
+
+       // Create an inventory item to see what is its image
+       std::istringstream is(m_inventorystring, std::ios_base::binary);
+       video::ITexture *texture = NULL;
+       try{
+               InventoryItem *item = NULL;
+               item = InventoryItem::deSerialize(is);
+               dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
+                               <<m_inventorystring<<"\" -> item="<<item
+                               <<std::endl;
+               if(item)
+               {
+                       texture = item->getImage();
+                       delete item;
+               }
+       }
+       catch(SerializationError &e)
+       {
+               dstream<<"WARNING: "<<__FUNCTION_NAME
+                               <<": error deSerializing inventorystring \""
+                               <<m_inventorystring<<"\""<<std::endl;
+       }
+       
+       // Set meshbuffer texture
+       buf->getMaterial().setTexture(0, texture);
+       
+}
+
+/*
+       RatCAO
+*/
+
+#include "inventory.h"
+
+// Prototype
+RatCAO proto_RatCAO;
+
+RatCAO::RatCAO():
+       ClientActiveObject(0),
+       m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
+       m_node(NULL),
+       m_position(v3f(0,10*BS,0)),
+       m_yaw(0)
+{
+       ClientActiveObject::registerType(getType(), create);
+}
+
+RatCAO::~RatCAO()
+{
+}
+
+ClientActiveObject* RatCAO::create()
+{
+       return new RatCAO();
+}
+
+void RatCAO::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,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, NULL);
+       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();
+       // Set it to use the materials of the meshbuffers directly.
+       // This is needed for changing the texture in the future
+       m_node->setReadOnlyMaterials(true);
+       updateNodePos();
+}
+
+void RatCAO::removeFromScene()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->remove();
+       m_node = NULL;
+}
+
+void RatCAO::updateLight(u8 light_at_pos)
+{
+       if(m_node == NULL)
+               return;
+
+       u8 li = decode_light(light_at_pos);
+       video::SColor color(255,li,li,li);
+
+       scene::IMesh *mesh = m_node->getMesh();
+       if(mesh == NULL)
+               return;
+       
+       u16 mc = mesh->getMeshBufferCount();
+       for(u16 j=0; j<mc; j++)
+       {
+               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+               u16 vc = buf->getVertexCount();
+               for(u16 i=0; i<vc; i++)
+               {
+                       vertices[i].Color = color;
+               }
+       }
+}
+
+v3s16 RatCAO::getLightPosition()
+{
+       return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
+}
+
+void RatCAO::updateNodePos()
+{
+       if(m_node == NULL)
+               return;
+
+       //m_node->setPosition(m_position);
+       m_node->setPosition(pos_translator.vect_show);
+
+       v3f rot = m_node->getRotation();
+       rot.Y = 180.0 - m_yaw;
+       m_node->setRotation(rot);
+}
+
+void RatCAO::step(float dtime, ClientEnvironment *env)
+{
+       pos_translator.translate(dtime);
+       updateNodePos();
+}
+
+void RatCAO::processMessage(const std::string &data)
+{
+       //dstream<<"RatCAO: Got message"<<std::endl;
+       std::istringstream is(data, std::ios::binary);
+       // command
+       u8 cmd = readU8(is);
+       if(cmd == 0)
+       {
+               // pos
+               m_position = readV3F1000(is);
+               pos_translator.update(m_position);
+               // yaw
+               m_yaw = readF1000(is);
+               updateNodePos();
+       }
+}
+
+void RatCAO::initialize(const std::string &data)
+{
+       //dstream<<"RatCAO: Got init data"<<std::endl;
+       
+       {
+               std::istringstream is(data, std::ios::binary);
+               // version
+               u8 version = readU8(is);
+               // check version
+               if(version != 0)
+                       return;
+               // pos
+               m_position = readV3F1000(is);
+               pos_translator.init(m_position);
+       }
+       
+       updateNodePos();
+}
+
+/*
+       Oerkki1CAO
+*/
+
+#include "inventory.h"
+
+// Prototype
+Oerkki1CAO proto_Oerkki1CAO;
+
+Oerkki1CAO::Oerkki1CAO():
+       ClientActiveObject(0),
+       m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
+       m_node(NULL),
+       m_position(v3f(0,10*BS,0)),
+       m_yaw(0),
+       m_damage_visual_timer(0),
+       m_damage_texture_enabled(false)
+{
+       ClientActiveObject::registerType(getType(), create);
+}
+
+Oerkki1CAO::~Oerkki1CAO()
+{
+}
+
+ClientActiveObject* Oerkki1CAO::create()
+{
+       return new Oerkki1CAO();
+}
+
+void Oerkki1CAO::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,0,0, 0,0,0, c, 0,1),
+               video::S3DVertex(BS/2+BS,0,0, 0,0,0, c, 1,1),
+               video::S3DVertex(BS/2+BS,BS*2,0, 0,0,0, c, 1,0),
+               video::S3DVertex(-BS/2-BS,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, NULL);
+       buf->getMaterial().setTexture
+                       (0, driver->getTexture(getTexturePath("oerkki1.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();
+       // Set it to use the materials of the meshbuffers directly.
+       // This is needed for changing the texture in the future
+       m_node->setReadOnlyMaterials(true);
+       updateNodePos();
+}
+
+void Oerkki1CAO::removeFromScene()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->remove();
+       m_node = NULL;
+}
+
+void Oerkki1CAO::updateLight(u8 light_at_pos)
+{
+       if(m_node == NULL)
+               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);
+
+       scene::IMesh *mesh = m_node->getMesh();
+       if(mesh == NULL)
+               return;
+       
+       u16 mc = mesh->getMeshBufferCount();
+       for(u16 j=0; j<mc; j++)
+       {
+               scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+               video::S3DVertex *vertices = (video::S3DVertex*)buf->getVertices();
+               u16 vc = buf->getVertexCount();
+               for(u16 i=0; i<vc; i++)
+               {
+                       vertices[i].Color = color;
+               }
+       }
+}
+
+v3s16 Oerkki1CAO::getLightPosition()
+{
+       return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
+}
+
+void Oerkki1CAO::updateNodePos()
+{
+       if(m_node == NULL)
+               return;
+
+       //m_node->setPosition(m_position);
+       m_node->setPosition(pos_translator.vect_show);
+
+       v3f rot = m_node->getRotation();
+       rot.Y = 180.0 - m_yaw + 90.0;
+       m_node->setRotation(rot);
+}
+
+void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
+{
+       pos_translator.translate(dtime);
+       updateNodePos();
+
+       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) < 3.0*BS &&
+                       objectpos_2d.getDistanceFrom(playerpos_2d) < 1.5*BS)
+       {
+               if(m_attack_interval.step(dtime, 0.5))
+               {
+                       env->damageLocalPlayer(2);
+               }
+       }
+
+       if(m_damage_visual_timer > 0)
+       {
+               if(!m_damage_texture_enabled)
+               {
+                       // Enable damage texture
+                       if(m_node)
+                       {
+                               video::IVideoDriver* driver =
+                                       m_node->getSceneManager()->getVideoDriver();
+                               
+                               scene::IMesh *mesh = m_node->getMesh();
+                               if(mesh == NULL)
+                                       return;
+                               
+                               u16 mc = mesh->getMeshBufferCount();
+                               for(u16 j=0; j<mc; j++)
+                               {
+                                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                                       buf->getMaterial().setTexture(0, driver->getTexture(
+                                                       getTexturePath("oerkki1_damaged.png").c_str()));
+                               }
+                       }
+                       m_damage_texture_enabled = true;
+               }
+               m_damage_visual_timer -= dtime;
+       }
+       else
+       {
+               if(m_damage_texture_enabled)
+               {
+                       // Disable damage texture
+                       if(m_node)
+                       {
+                               video::IVideoDriver* driver =
+                                       m_node->getSceneManager()->getVideoDriver();
+                               
+                               scene::IMesh *mesh = m_node->getMesh();
+                               if(mesh == NULL)
+                                       return;
+                               
+                               u16 mc = mesh->getMeshBufferCount();
+                               for(u16 j=0; j<mc; j++)
+                               {
+                                       scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
+                                       buf->getMaterial().setTexture(0, driver->getTexture(
+                                                       getTexturePath("oerkki1.png").c_str()));
+                               }
+                       }
+                       m_damage_texture_enabled = false;
+               }
+       }
+}
+
+void Oerkki1CAO::processMessage(const std::string &data)
+{
+       //dstream<<"Oerkki1CAO: Got message"<<std::endl;
+       std::istringstream is(data, std::ios::binary);
+       // command
+       u8 cmd = readU8(is);
+       if(cmd == 0)
+       {
+               // pos
+               m_position = readV3F1000(is);
+               pos_translator.update(m_position);
+               // yaw
+               m_yaw = readF1000(is);
+               updateNodePos();
+       }
+       else if(cmd == 1)
+       {
+               u16 damage = readU8(is);
+               m_damage_visual_timer = 1.0;
+       }
+}
+
+void Oerkki1CAO::initialize(const std::string &data)
+{
+       //dstream<<"Oerkki1CAO: Got init data"<<std::endl;
+       
+       {
+               std::istringstream is(data, std::ios::binary);
+               // version
+               u8 version = readU8(is);
+               // check version
+               if(version != 0)
+                       return;
+               // pos
+               m_position = readV3F1000(is);
+               pos_translator.init(m_position);
+       }
+       
+       updateNodePos();
+}
+
+
diff --git a/src/content_cao.h b/src/content_cao.h
new file mode 100644 (file)
index 0000000..146e23b
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef CONTENT_CAO_HEADER
+#define CONTENT_CAO_HEADER
+
+#include "clientobject.h"
+#include "content_object.h"
+#include "utility.h" // For IntervalLimiter
+
+/*
+       SmoothTranslator
+*/
+
+struct SmoothTranslator
+{
+       v3f vect_old;
+       f32 anim_counter;
+       f32 anim_time;
+       f32 anim_time_counter;
+       v3f vect_show;
+       v3f vect_aim;
+
+       SmoothTranslator():
+               vect_old(0,0,0),
+               anim_counter(0),
+               anim_time(0),
+               anim_time_counter(0),
+               vect_show(0,0,0),
+               vect_aim(0,0,0)
+       {}
+
+       void init(v3f vect)
+       {
+               vect_old = vect;
+               vect_show = vect;
+               vect_aim = vect;
+       }
+
+       void update(v3f vect_new)
+       {
+               vect_old = vect_show;
+               vect_aim = vect_new;
+               if(anim_time < 0.001 || anim_time > 1.0)
+                       anim_time = anim_time_counter;
+               else
+                       anim_time = anim_time * 0.9 + anim_time_counter * 0.1;
+               anim_time_counter = 0;
+               anim_counter = 0;
+       }
+
+       void translate(f32 dtime)
+       {
+               anim_time_counter = anim_time_counter + dtime;
+               anim_counter = anim_counter + dtime;
+               v3f vect_move = vect_aim - vect_old;
+               f32 moveratio = 1.0;
+               if(anim_time > 0.001)
+                       moveratio = anim_time_counter / anim_time;
+               // Move a bit less than should, to avoid oscillation
+               moveratio = moveratio * 0.8;
+               if(moveratio > 1.5)
+                       moveratio = 1.5;
+               vect_show = vect_old + vect_move * moveratio;
+       }
+};
+
+
+/*
+       TestCAO
+*/
+
+class TestCAO : public ClientActiveObject
+{
+public:
+       TestCAO();
+       virtual ~TestCAO();
+       
+       u8 getType() const
+       {
+               return ACTIVEOBJECT_TYPE_TEST;
+       }
+       
+       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);
+
+private:
+       scene::IMeshSceneNode *m_node;
+       v3f m_position;
+};
+
+/*
+       ItemCAO
+*/
+
+class ItemCAO : public ClientActiveObject
+{
+public:
+       ItemCAO();
+       virtual ~ItemCAO();
+       
+       u8 getType() const
+       {
+               return ACTIVEOBJECT_TYPE_ITEM;
+       }
+       
+       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 m_position;}
+
+private:
+       core::aabbox3d<f32> m_selection_box;
+       scene::IMeshSceneNode *m_node;
+       v3f m_position;
+       std::string m_inventorystring;
+};
+
+/*
+       RatCAO
+*/
+
+class RatCAO : public ClientActiveObject
+{
+public:
+       RatCAO();
+       virtual ~RatCAO();
+       
+       u8 getType() const
+       {
+               return ACTIVEOBJECT_TYPE_RAT;
+       }
+       
+       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 m_position;}
+
+private:
+       core::aabbox3d<f32> m_selection_box;
+       scene::IMeshSceneNode *m_node;
+       v3f m_position;
+       float m_yaw;
+       SmoothTranslator pos_translator;
+};
+
+/*
+       Oerkki1CAO
+*/
+
+class Oerkki1CAO : public ClientActiveObject
+{
+public:
+       Oerkki1CAO();
+       virtual ~Oerkki1CAO();
+       
+       u8 getType() const
+       {
+               return ACTIVEOBJECT_TYPE_OERKKI1;
+       }
+       
+       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;}
+
+private:
+       IntervalLimiter m_attack_interval;
+       core::aabbox3d<f32> m_selection_box;
+       scene::IMeshSceneNode *m_node;
+       v3f m_position;
+       float m_yaw;
+       SmoothTranslator pos_translator;
+       float m_damage_visual_timer;
+       bool m_damage_texture_enabled;
+};
+
+
+#endif
+
index 3b72b31f1a21f72def7f4ab39b72b5c69ab29d97..ac48a619550fe414118626e9f56c515824093074 100644 (file)
@@ -19,8 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "content_inventory.h"
 #include "inventory.h"
-#include "serverobject.h"
 #include "content_mapnode.h"
+//#include "serverobject.h"
+#include "content_sao.h"
 
 bool item_material_is_cookable(u8 content)
 {
diff --git a/src/content_object.h b/src/content_object.h
new file mode 100644 (file)
index 0000000..ecabd8a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef CONTENT_OBJECT_HEADER
+#define CONTENT_OBJECT_HEADER
+
+#define ACTIVEOBJECT_TYPE_TEST 1
+#define ACTIVEOBJECT_TYPE_ITEM 2
+#define ACTIVEOBJECT_TYPE_RAT 3
+#define ACTIVEOBJECT_TYPE_OERKKI1 4
+
+#endif
+
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
new file mode 100644 (file)
index 0000000..fc6f208
--- /dev/null
@@ -0,0 +1,694 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 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.
+*/
+
+#include "content_sao.h"
+#include "collision.h"
+#include "environment.h"
+
+/*
+       TestSAO
+*/
+
+// Prototype
+TestSAO proto_TestSAO(NULL, 0, v3f(0,0,0));
+
+TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
+       ServerActiveObject(env, id, pos),
+       m_timer1(0),
+       m_age(0)
+{
+       ServerActiveObject::registerType(getType(), create);
+}
+
+ServerActiveObject* TestSAO::create(ServerEnvironment *env, u16 id, v3f pos,
+               const std::string &data)
+{
+       return new TestSAO(env, id, pos);
+}
+
+void TestSAO::step(float dtime, bool send_recommended)
+{
+       m_age += dtime;
+       if(m_age > 10)
+       {
+               m_removed = true;
+               return;
+       }
+
+       m_base_position.Y += dtime * BS * 2;
+       if(m_base_position.Y > 8*BS)
+               m_base_position.Y = 2*BS;
+
+       if(send_recommended == false)
+               return;
+
+       m_timer1 -= dtime;
+       if(m_timer1 < 0.0)
+       {
+               m_timer1 += 0.125;
+               //dstream<<"TestSAO: id="<<getId()<<" sending data"<<std::endl;
+
+               std::string data;
+
+               data += itos(0); // 0 = position
+               data += " ";
+               data += itos(m_base_position.X);
+               data += " ";
+               data += itos(m_base_position.Y);
+               data += " ";
+               data += itos(m_base_position.Z);
+
+               ActiveObjectMessage aom(getId(), false, data);
+               m_messages_out.push_back(aom);
+       }
+}
+
+
+/*
+       ItemSAO
+*/
+
+// Prototype
+ItemSAO proto_ItemSAO(NULL, 0, v3f(0,0,0), "");
+
+ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
+               const std::string inventorystring):
+       ServerActiveObject(env, id, pos),
+       m_inventorystring(inventorystring),
+       m_speed_f(0,0,0),
+       m_last_sent_position(0,0,0)
+{
+       ServerActiveObject::registerType(getType(), create);
+}
+
+ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
+               const std::string &data)
+{
+       std::istringstream is(data, std::ios::binary);
+       char buf[1];
+       // read version
+       is.read(buf, 1);
+       u8 version = buf[0];
+       // check if version is supported
+       if(version != 0)
+               return NULL;
+       std::string inventorystring = deSerializeString(is);
+       dstream<<"ItemSAO::create(): Creating item \""
+                       <<inventorystring<<"\""<<std::endl;
+       return new ItemSAO(env, id, pos, inventorystring);
+}
+
+void ItemSAO::step(float dtime, bool send_recommended)
+{
+       assert(m_env);
+
+       const float interval = 0.2;
+       if(m_move_interval.step(dtime, interval)==false)
+               return;
+       dtime = interval;
+       
+       core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
+       collisionMoveResult moveresult;
+       // Apply gravity
+       m_speed_f += v3f(0, -dtime*9.81*BS, 0);
+       // Maximum movement without glitches
+       f32 pos_max_d = BS*0.25;
+       // Limit speed
+       if(m_speed_f.getLength()*dtime > pos_max_d)
+               m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
+       v3f pos_f = getBasePosition();
+       v3f pos_f_old = pos_f;
+       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
+                       box, dtime, pos_f, m_speed_f);
+       
+       if(send_recommended == false)
+               return;
+
+       if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
+       {
+               setBasePosition(pos_f);
+               m_last_sent_position = pos_f;
+
+               std::ostringstream os(std::ios::binary);
+               char buf[6];
+               // command (0 = update position)
+               buf[0] = 0;
+               os.write(buf, 1);
+               // pos
+               writeS32((u8*)buf, m_base_position.X*1000);
+               os.write(buf, 4);
+               writeS32((u8*)buf, m_base_position.Y*1000);
+               os.write(buf, 4);
+               writeS32((u8*)buf, m_base_position.Z*1000);
+               os.write(buf, 4);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+}
+
+std::string ItemSAO::getClientInitializationData()
+{
+       std::ostringstream os(std::ios::binary);
+       char buf[6];
+       // version
+       buf[0] = 0;
+       os.write(buf, 1);
+       // pos
+       writeS32((u8*)buf, m_base_position.X*1000);
+       os.write(buf, 4);
+       writeS32((u8*)buf, m_base_position.Y*1000);
+       os.write(buf, 4);
+       writeS32((u8*)buf, m_base_position.Z*1000);
+       os.write(buf, 4);
+       // inventorystring
+       os<<serializeString(m_inventorystring);
+       return os.str();
+}
+
+std::string ItemSAO::getStaticData()
+{
+       dstream<<__FUNCTION_NAME<<std::endl;
+       std::ostringstream os(std::ios::binary);
+       char buf[1];
+       // version
+       buf[0] = 0;
+       os.write(buf, 1);
+       // inventorystring
+       os<<serializeString(m_inventorystring);
+       return os.str();
+}
+
+InventoryItem * ItemSAO::createInventoryItem()
+{
+       try{
+               std::istringstream is(m_inventorystring, std::ios_base::binary);
+               InventoryItem *item = InventoryItem::deSerialize(is);
+               dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
+                               <<m_inventorystring<<"\" -> item="<<item
+                               <<std::endl;
+               return item;
+       }
+       catch(SerializationError &e)
+       {
+               dstream<<__FUNCTION_NAME<<": serialization error: "
+                               <<"m_inventorystring=\""<<m_inventorystring<<"\""<<std::endl;
+               return NULL;
+       }
+}
+
+
+/*
+       RatSAO
+*/
+
+// Prototype
+RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0));
+
+RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
+       ServerActiveObject(env, id, pos),
+       m_is_active(false),
+       m_speed_f(0,0,0)
+{
+       ServerActiveObject::registerType(getType(), create);
+
+       m_oldpos = v3f(0,0,0);
+       m_last_sent_position = v3f(0,0,0);
+       m_yaw = 0;
+       m_counter1 = 0;
+       m_counter2 = 0;
+       m_age = 0;
+       m_touching_ground = false;
+}
+
+ServerActiveObject* RatSAO::create(ServerEnvironment *env, u16 id, v3f pos,
+               const std::string &data)
+{
+       std::istringstream is(data, std::ios::binary);
+       char buf[1];
+       // read version
+       is.read(buf, 1);
+       u8 version = buf[0];
+       // check if version is supported
+       if(version != 0)
+               return NULL;
+       return new RatSAO(env, id, pos);
+}
+
+void RatSAO::step(float dtime, bool send_recommended)
+{
+       assert(m_env);
+
+       if(m_is_active == false)
+       {
+               if(m_inactive_interval.step(dtime, 0.5)==false)
+                       return;
+       }
+
+       /*
+               The AI
+       */
+
+       /*m_age += dtime;
+       if(m_age > 60)
+       {
+               // Die
+               m_removed = true;
+               return;
+       }*/
+
+       // Apply gravity
+       m_speed_f.Y -= dtime*9.81*BS;
+
+       /*
+               Move around if some player is close
+       */
+       bool player_is_close = false;
+       // Check connected players
+       core::list<Player*> players = m_env->getPlayers(true);
+       core::list<Player*>::Iterator i;
+       for(i = players.begin();
+                       i != players.end(); i++)
+       {
+               Player *player = *i;
+               v3f playerpos = player->getPosition();
+               if(m_base_position.getDistanceFrom(playerpos) < BS*10.0)
+               {
+                       player_is_close = true;
+                       break;
+               }
+       }
+
+       m_is_active = player_is_close;
+       
+       if(player_is_close == false)
+       {
+               m_speed_f.X = 0;
+               m_speed_f.Z = 0;
+       }
+       else
+       {
+               // Move around
+               v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
+               f32 speed = 2*BS;
+               m_speed_f.X = speed * dir.X;
+               m_speed_f.Z = speed * dir.Z;
+
+               if(m_touching_ground && (m_oldpos - m_base_position).getLength()
+                               < dtime*speed/2)
+               {
+                       m_counter1 -= dtime;
+                       if(m_counter1 < 0.0)
+                       {
+                               m_counter1 += 1.0;
+                               m_speed_f.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_base_position;
+
+       /*
+               Move it, with collision detection
+       */
+
+       core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
+       collisionMoveResult moveresult;
+       // Maximum movement without glitches
+       f32 pos_max_d = BS*0.25;
+       // Limit speed
+       if(m_speed_f.getLength()*dtime > pos_max_d)
+               m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
+       v3f pos_f = getBasePosition();
+       v3f pos_f_old = pos_f;
+       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
+                       box, dtime, pos_f, m_speed_f);
+       m_touching_ground = moveresult.touching_ground;
+       
+       setBasePosition(pos_f);
+
+       if(send_recommended == false)
+               return;
+
+       if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
+       {
+               m_last_sent_position = pos_f;
+
+               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);
+       }
+}
+
+std::string RatSAO::getClientInitializationData()
+{
+       std::ostringstream os(std::ios::binary);
+       // version
+       writeU8(os, 0);
+       // pos
+       writeV3F1000(os, m_base_position);
+       return os.str();
+}
+
+std::string RatSAO::getStaticData()
+{
+       //dstream<<__FUNCTION_NAME<<std::endl;
+       std::ostringstream os(std::ios::binary);
+       // version
+       writeU8(os, 0);
+       return os.str();
+}
+
+InventoryItem* RatSAO::createPickedUpItem()
+{
+       std::istringstream is("CraftItem rat 1", std::ios_base::binary);
+       InventoryItem *item = InventoryItem::deSerialize(is);
+       return item;
+}
+
+/*
+       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));
+
+Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos):
+       ServerActiveObject(env, id, pos),
+       m_is_active(false),
+       m_speed_f(0,0,0)
+{
+       ServerActiveObject::registerType(getType(), create);
+
+       m_oldpos = v3f(0,0,0);
+       m_last_sent_position = v3f(0,0,0);
+       m_yaw = 0;
+       m_counter1 = 0;
+       m_counter2 = 0;
+       m_age = 0;
+       m_touching_ground = false;
+       m_hp = 20;
+       m_after_jump_timer = 0;
+}
+
+ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos,
+               const std::string &data)
+{
+       std::istringstream is(data, std::ios::binary);
+       // read version
+       u8 version = readU8(is);
+       // read hp
+       u8 hp = readU8(is);
+       // check if version is supported
+       if(version != 0)
+               return NULL;
+       Oerkki1SAO *o = new Oerkki1SAO(env, id, pos);
+       o->m_hp = hp;
+       return o;
+}
+
+void Oerkki1SAO::step(float dtime, bool send_recommended)
+{
+       assert(m_env);
+
+       if(m_is_active == false)
+       {
+               if(m_inactive_interval.step(dtime, 0.5)==false)
+                       return;
+       }
+
+       /*
+               The AI
+       */
+
+       m_age += dtime;
+       if(m_age > 120)
+       {
+               // Die
+               m_removed = true;
+               return;
+       }
+
+       m_after_jump_timer -= dtime;
+
+       v3f old_speed = m_speed_f;
+
+       // Apply gravity
+       m_speed_f.Y -= dtime*9.81*BS;
+
+       /*
+               Move around if some player is close
+       */
+       bool player_is_close = false;
+       bool player_is_too_close = false;
+       v3f near_player_pos;
+       // Check connected players
+       core::list<Player*> players = m_env->getPlayers(true);
+       core::list<Player*>::Iterator i;
+       for(i = players.begin();
+                       i != players.end(); i++)
+       {
+               Player *player = *i;
+               v3f playerpos = player->getPosition();
+               f32 dist = m_base_position.getDistanceFrom(playerpos);
+               if(dist < BS*1.45)
+               {
+                       player_is_too_close = true;
+                       near_player_pos = playerpos;
+                       break;
+               }
+               else if(dist < BS*15.0)
+               {
+                       player_is_close = true;
+                       near_player_pos = playerpos;
+               }
+       }
+
+       m_is_active = player_is_close;
+
+       v3f target_speed = m_speed_f;
+
+       if(!player_is_close)
+       {
+               target_speed = v3f(0,0,0);
+       }
+       else
+       {
+               // Move around
+
+               v3f ndir = near_player_pos - m_base_position;
+               ndir.Y = 0;
+               ndir.normalize();
+
+               f32 nyaw = 180./PI*atan2(ndir.Z,ndir.X);
+               if(nyaw < m_yaw - 180)
+                       nyaw += 360;
+               else if(nyaw > m_yaw + 180)
+                       nyaw -= 360;
+               m_yaw = 0.95*m_yaw + 0.05*nyaw;
+               m_yaw = wrapDegrees(m_yaw);
+               
+               f32 speed = 2*BS;
+
+               if((m_touching_ground || m_after_jump_timer > 0.0)
+                               && !player_is_too_close)
+               {
+                       v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
+                       target_speed.X = speed * dir.X;
+                       target_speed.Z = speed * dir.Z;
+               }
+
+               if(m_touching_ground && (m_oldpos - m_base_position).getLength()
+                               < dtime*speed/2)
+               {
+                       m_counter1 -= dtime;
+                       if(m_counter1 < 0.0)
+                       {
+                               m_counter1 += 0.2;
+                               // Jump
+                               target_speed.Y = 5.0*BS;
+                               m_after_jump_timer = 1.0;
+                       }
+               }
+
+               {
+                       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 += ((float)(myrand()%200)-100)/100*90;
+                               m_yaw = wrapDegrees(m_yaw);
+                       }
+               }
+       }
+       
+       if((m_speed_f - target_speed).getLength() > BS*4 || player_is_too_close)
+               accelerate_xz(m_speed_f, target_speed, dtime*BS*8);
+       else
+               accelerate_xz(m_speed_f, target_speed, dtime*BS*4);
+       
+       m_oldpos = m_base_position;
+
+       /*
+               Move it, with collision detection
+       */
+
+       core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*5./3.,BS/3.);
+       collisionMoveResult moveresult;
+       // Maximum movement without glitches
+       f32 pos_max_d = BS*0.25;
+       /*// Limit speed
+       if(m_speed_f.getLength()*dtime > pos_max_d)
+               m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);*/
+       v3f pos_f = getBasePosition();
+       v3f pos_f_old = pos_f;
+       moveresult = collisionMovePrecise(&m_env->getMap(), pos_max_d,
+                       box, dtime, pos_f, m_speed_f);
+       m_touching_ground = moveresult.touching_ground;
+       
+       // Do collision damage
+       float tolerance = BS*12;
+       float factor = BS*0.5;
+       v3f speed_diff = old_speed - m_speed_f;
+       // Increase effect in X and Z
+       speed_diff.X *= 2;
+       speed_diff.Z *= 2;
+       float vel = speed_diff.getLength();
+       if(vel > tolerance)
+       {
+               f32 damage_f = (vel - tolerance)/BS*factor;
+               u16 damage = (u16)(damage_f+0.5);
+               doDamage(damage);
+       }
+
+       setBasePosition(pos_f);
+
+       if(send_recommended == false && m_speed_f.getLength() < 3.0*BS)
+               return;
+
+       if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
+       {
+               m_last_sent_position = pos_f;
+
+               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);
+       }
+}
+
+std::string Oerkki1SAO::getClientInitializationData()
+{
+       std::ostringstream os(std::ios::binary);
+       // version
+       writeU8(os, 0);
+       // pos
+       writeV3F1000(os, m_base_position);
+       return os.str();
+}
+
+std::string Oerkki1SAO::getStaticData()
+{
+       //dstream<<__FUNCTION_NAME<<std::endl;
+       std::ostringstream os(std::ios::binary);
+       // version
+       writeU8(os, 0);
+       // hp
+       writeU8(os, m_hp);
+       return os.str();
+}
+
+u16 Oerkki1SAO::punch(const std::string &toolname, v3f dir)
+{
+       m_speed_f += dir*12*BS;
+
+       u16 amount = 5;
+       doDamage(amount);
+       return 65536/100;
+}
+
+void Oerkki1SAO::doDamage(u16 d)
+{
+       dstream<<"oerkki 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
+               writeU8(os, d);
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), false, os.str());
+               m_messages_out.push_back(aom);
+       }
+}
+
+
diff --git a/src/content_sao.h b/src/content_sao.h
new file mode 100644 (file)
index 0000000..030232a
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef CONTENT_SAO_HEADER
+#define CONTENT_SAO_HEADER
+
+#include "serverobject.h"
+#include "content_object.h"
+
+class TestSAO : public ServerActiveObject
+{
+public:
+       TestSAO(ServerEnvironment *env, u16 id, v3f pos);
+       u8 getType() const
+               {return ACTIVEOBJECT_TYPE_TEST;}
+       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
+                       const std::string &data);
+       void step(float dtime, bool send_recommended);
+private:
+       float m_timer1;
+       float m_age;
+};
+
+class ItemSAO : public ServerActiveObject
+{
+public:
+       ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
+                       const std::string inventorystring);
+       u8 getType() const
+               {return ACTIVEOBJECT_TYPE_ITEM;}
+       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
+                       const std::string &data);
+       void step(float dtime, bool send_recommended);
+       std::string getClientInitializationData();
+       std::string getStaticData();
+       InventoryItem* createInventoryItem();
+       InventoryItem* createPickedUpItem(){return createInventoryItem();}
+private:
+       std::string m_inventorystring;
+       v3f m_speed_f;
+       v3f m_last_sent_position;
+       IntervalLimiter m_move_interval;
+};
+
+class RatSAO : public ServerActiveObject
+{
+public:
+       RatSAO(ServerEnvironment *env, u16 id, v3f pos);
+       u8 getType() const
+               {return ACTIVEOBJECT_TYPE_RAT;}
+       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
+                       const std::string &data);
+       void step(float dtime, bool send_recommended);
+       std::string getClientInitializationData();
+       std::string getStaticData();
+       InventoryItem* createPickedUpItem();
+private:
+       bool m_is_active;
+       IntervalLimiter m_inactive_interval;
+       v3f m_speed_f;
+       v3f m_oldpos;
+       v3f m_last_sent_position;
+       float m_yaw;
+       float m_counter1;
+       float m_counter2;
+       float m_age;
+       bool m_touching_ground;
+};
+
+class Oerkki1SAO : public ServerActiveObject
+{
+public:
+       Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos);
+       u8 getType() const
+               {return ACTIVEOBJECT_TYPE_OERKKI1;}
+       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
+                       const std::string &data);
+       void step(float dtime, bool send_recommended);
+       std::string getClientInitializationData();
+       std::string getStaticData();
+       InventoryItem* createPickedUpItem(){return NULL;}
+       u16 punch(const std::string &toolname, v3f dir);
+private:
+       void doDamage(u16 d);
+
+       bool m_is_active;
+       IntervalLimiter m_inactive_interval;
+       v3f m_speed_f;
+       v3f m_oldpos;
+       v3f m_last_sent_position;
+       float m_yaw;
+       float m_counter1;
+       float m_counter2;
+       float m_age;
+       bool m_touching_ground;
+       u8 m_hp;
+       float m_after_jump_timer;
+};
+
+
+#endif
+
index 6a7c8478efdc44e076fcb3b732b57c942778fb54..d9c62978ff75700ed4cd1dd1c59e80e45c8b3b48 100644 (file)
@@ -23,6 +23,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "collision.h"
 #include "content_mapnode.h"
 #include "mapblock.h"
+#include "serverobject.h"
+#include "content_sao.h"
 
 Environment::Environment():
        m_time_of_day(9000)
@@ -918,8 +920,14 @@ void ServerEnvironment::step(float dtime)
                        // Don't step if is to be removed or stored statically
                        if(obj->m_removed || obj->m_pending_deactivation)
                                continue;
-                       // Step object, putting messages directly to the queue
-                       obj->step(dtime, m_active_object_messages, send_recommended);
+                       // Step object
+                       obj->step(dtime, send_recommended);
+                       // Read messages from object
+                       while(obj->m_messages_out.size() > 0)
+                       {
+                               m_active_object_messages.push_back(
+                                               obj->m_messages_out.pop_front());
+                       }
                }
        }
        
@@ -1660,17 +1668,21 @@ void ClientEnvironment::step(float dtime)
                ClientActiveObject* obj = i.getNode()->getValue();
                // Step object
                obj->step(dtime, this);
-               // Update lighting
-               //u8 light = LIGHT_MAX;
-               u8 light = 0;
-               try{
-                       // Get node at head
-                       v3s16 p = obj->getLightPosition();
-                       MapNode n = m_map->getNode(p);
-                       light = n.getLightBlend(getDayNightRatio());
+
+               if(m_active_object_light_update_interval.step(dtime, 0.5))
+               {
+                       // Update lighting
+                       //u8 light = LIGHT_MAX;
+                       u8 light = 0;
+                       try{
+                               // Get node at head
+                               v3s16 p = obj->getLightPosition();
+                               MapNode n = m_map->getNode(p);
+                               light = n.getLightBlend(getDayNightRatio());
+                       }
+                       catch(InvalidPositionException &e) {}
+                       obj->updateLight(light);
                }
-               catch(InvalidPositionException &e) {}
-               obj->updateLight(light);
        }
 }
 
index eac69d222af38b49a7642632a2e8db04b9f7f6fc..ce6b5ae1e76bb1c6912f99198b259ea2c8746789 100644 (file)
@@ -36,6 +36,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "map.h"
 #include <ostream>
 #include "utility.h"
+#include "activeobject.h"
+
+class Server;
+class ActiveBlockModifier;
+class ServerActiveObject;
 
 class Environment
 {
@@ -118,11 +123,6 @@ private:
        This is not thread-safe. Server uses an environment mutex.
 */
 
-#include "serverobject.h"
-
-class Server;
-class ActiveBlockModifier;
-
 class ServerEnvironment : public Environment
 {
 public:
@@ -412,6 +412,7 @@ private:
        scene::ISceneManager *m_smgr;
        core::map<u16, ClientActiveObject*> m_active_objects;
        Queue<ClientEnvEvent> m_client_event_queue;
+       IntervalLimiter m_active_object_light_update_interval;
 };
 
 #endif
index aa1cf4a70a657d192905c9c885862cbb66462e84..59f14d37dc0126eb5941a03d3f54195e2b0484b2 100644 (file)
@@ -661,7 +661,9 @@ void the_game(
        screensize = driver->getScreenSize();
 
        const s32 hotbar_itemcount = 8;
-       const s32 hotbar_imagesize = 36;
+       //const s32 hotbar_imagesize = 36;
+       //const s32 hotbar_imagesize = 64;
+       s32 hotbar_imagesize = 48;
        
        // The color of the sky
 
@@ -967,6 +969,14 @@ void the_game(
                screensize = driver->getScreenSize();
                v2s32 displaycenter(screensize.X/2,screensize.Y/2);
                //bool screensize_changed = screensize != last_screensize;
+
+               // Resize hotbar
+               if(screensize.Y <= 600)
+                       hotbar_imagesize = 32;
+               else if(screensize.Y <= 1024)
+                       hotbar_imagesize = 48;
+               else
+                       hotbar_imagesize = 64;
                
                // Hilight boxes collected during the loop and displayed
                core::list< core::aabbox3d<f32> > hilightboxes;
index 0c76ed84555ff4ed436d787a602937a297bb70ce..fec51a759e581617db89f43eef9bb494ef82f949 100644 (file)
@@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "serverobject.h"
 #include "content_mapnode.h"
 #include "content_inventory.h"
+#include "content_sao.h"
 
 /*
        InventoryItem
index 3164028b7b1d2e9a7403b32ad2afdab2b744f43b..a20cd9910e45952aed21ab91cda324bc58f30860 100644 (file)
@@ -26,10 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "utility.h"
 #include "voxel.h"
 #include "porting.h"
-#include "mineral.h"
-#include "noise.h"
-#include "serverobject.h"
-#include "content_mapnode.h"
 #include "mapgen.h"
 #include "nodemetadata.h"
 
@@ -901,7 +897,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n,
        {
        }
 
-#if 1
+#if 0
        /*
                If the new node is solid and there is grass below, change it to mud
        */
@@ -2869,10 +2865,10 @@ MapSector* ServerMap::loadSectorMeta(std::string sectordir, bool save_after_load
                // format. Just go ahead and create the sector.
                if(fs::PathExists(sectordir))
                {
-                       dstream<<"ServerMap::loadSectorMeta(): Sector metafile "
+                       /*dstream<<"ServerMap::loadSectorMeta(): Sector metafile "
                                        <<fullpath<<" doesn't exist but directory does."
                                        <<" Continuing with a sector with no metadata."
-                                       <<std::endl;
+                                       <<std::endl;*/
                        sector = new ServerMapSector(this, p2d);
                        m_sectors.insert(p2d, sector);
                }
index 801dd72b10650d5603a03dffd8874d90de96056e..285f76781495b3b33d2249d85bad8c6b7866815e 100644 (file)
@@ -23,8 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "noise.h"
 #include "mapblock.h"
 #include "map.h"
-#include "serverobject.h"
 #include "mineral.h"
+//#include "serverobject.h"
+#include "content_sao.h"
 
 namespace mapgen
 {
@@ -503,7 +504,7 @@ static void make_corridor(VoxelManipulator &vmanip, v3s16 doorplace,
        else
                length = random.range(1,6);
        length = random.range(1,13);
-       u32 partlength = random.range(1,length);
+       u32 partlength = random.range(1,13);
        u32 partcount = 0;
        s16 make_stairs = 0;
        if(random.next()%2 == 0 && partlength >= 3)
@@ -672,14 +673,63 @@ public:
                                continue;
                        v3s16 roomplace;
                        // X east, Z north, Y up
+#if 0
+                       if(doordir == v3s16(1,0,0)) // X+
+                               roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2+
+                                               m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
+                       if(doordir == v3s16(-1,0,0)) // X-
+                               roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2
+                                               +m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
+                       if(doordir == v3s16(0,0,1)) // Z+
+                               roomplace = doorplace + v3s16(-roomsize.X/2
+                                               +m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,0);
+                       if(doordir == v3s16(0,0,-1)) // Z-
+                               roomplace = doorplace + v3s16(-roomsize.X/2
+                                               +m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,
+                                                               -roomsize.Z+1);
+#endif
+#if 0
+                       if(doordir == v3s16(1,0,0)) // X+
+                               roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2+
+                                               m_random.range(-roomsize.Z/2+(roomsize.Z%2==0?2:1),
+                                                               roomsize.Z/2-1));
+                       if(doordir == v3s16(-1,0,0)) // X-
+                               roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2
+                                               +m_random.range(-roomsize.Z/2+(roomsize.Z%2==0?2:1),
+                                                               roomsize.Z/2-1));
+                       if(doordir == v3s16(0,0,1)) // Z+
+                               roomplace = doorplace + v3s16(-roomsize.X/2
+                                               +m_random.range(-roomsize.X/2+(roomsize.X%2==0?2:1),
+                                                               roomsize.X/2-1),-1,0);
+                       if(doordir == v3s16(0,0,-1)) // Z-
+                               roomplace = doorplace + v3s16(-roomsize.X/2
+                                               +m_random.range(-roomsize.X/2+(roomsize.X%2==0?2:1),
+                                                               roomsize.X/2-1),-1, -roomsize.Z+1);
+#endif
+#if 1
+                       if(doordir == v3s16(1,0,0)) // X+
+                               roomplace = doorplace +
+                                               v3s16(0,-1,m_random.range(-roomsize.Z+1,-2));
+                       if(doordir == v3s16(-1,0,0)) // X-
+                               roomplace = doorplace +
+                                               v3s16(-roomsize.X+1,-1,m_random.range(-roomsize.Z+1,-2));
+                       if(doordir == v3s16(0,0,1)) // Z+
+                               roomplace = doorplace +
+                                               v3s16(m_random.range(-roomsize.X+1,-2),-1,0);
+                       if(doordir == v3s16(0,0,-1)) // Z-
+                               roomplace = doorplace +
+                                               v3s16(m_random.range(-roomsize.X+1,-2),-1,-roomsize.Z+1);
+#endif
+#if 0
                        if(doordir == v3s16(1,0,0)) // X+
-                               roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2+m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
+                               roomplace = doorplace + v3s16(0,-1,-roomsize.Z/2);
                        if(doordir == v3s16(-1,0,0)) // X-
-                               roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2+m_random.range(-roomsize.Z/2+1,roomsize.Z/2-1));
+                               roomplace = doorplace + v3s16(-roomsize.X+1,-1,-roomsize.Z/2);
                        if(doordir == v3s16(0,0,1)) // Z+
-                               roomplace = doorplace + v3s16(-roomsize.X/2+m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,0);
+                               roomplace = doorplace + v3s16(-roomsize.X/2,-1,0);
                        if(doordir == v3s16(0,0,-1)) // Z-
-                               roomplace = doorplace + v3s16(-roomsize.X/2+m_random.range(-roomsize.X/2+1,roomsize.X/2-1),-1,-roomsize.Z+1);
+                               roomplace = doorplace + v3s16(-roomsize.X/2,-1,-roomsize.Z+1);
+#endif
                        
                        // Check fit
                        bool fits = true;
@@ -790,7 +840,7 @@ static void make_dungeon1(VoxelManipulator &vmanip, PseudoRandom &random)
                
                // Determine walker start position
 
-               bool start_in_last_room = (random.range(0,1)==0);
+               bool start_in_last_room = (random.range(0,2)!=0);
                //bool start_in_last_room = true;
 
                v3s16 walker_start_place;
@@ -858,7 +908,9 @@ NoiseParams get_cave_noise1_params(u64 seed)
 {
        /*return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 5, 0.7,
                        200, CAVE_NOISE_SCALE);*/
-       return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 4, 0.7,
+       /*return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 4, 0.7,
+                       100, CAVE_NOISE_SCALE);*/
+       return NoiseParams(NOISE_PERLIN_CONTOUR, seed+52534, 5, 0.6,
                        100, CAVE_NOISE_SCALE);
 }
 
@@ -866,7 +918,9 @@ NoiseParams get_cave_noise2_params(u64 seed)
 {
        /*return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 5, 0.7,
                        200, CAVE_NOISE_SCALE);*/
-       return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 4, 0.7,
+       /*return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 4, 0.7,
+                       100, CAVE_NOISE_SCALE);*/
+       return NoiseParams(NOISE_PERLIN_CONTOUR_FLIP_YZ, seed+10325, 5, 0.6,
                        100, CAVE_NOISE_SCALE);
 }
 
@@ -1054,6 +1108,7 @@ double get_sector_maximum_ground_level(u64 seed, v2s16 sectorpos, double p)
        v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
        v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
        double a = -31000;
+       // Corners
        a = MYMAX(a, find_ground_level_from_noise(seed,
                        v2s16(node_min.X, node_min.Y), p));
        a = MYMAX(a, find_ground_level_from_noise(seed,
@@ -1062,8 +1117,18 @@ double get_sector_maximum_ground_level(u64 seed, v2s16 sectorpos, double p)
                        v2s16(node_max.X, node_max.Y), p));
        a = MYMAX(a, find_ground_level_from_noise(seed,
                        v2s16(node_min.X, node_min.Y), p));
+       // Center
        a = MYMAX(a, find_ground_level_from_noise(seed,
                        v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y+MAP_BLOCKSIZE/2), p));
+       // Side middle points
+       a = MYMAX(a, find_ground_level_from_noise(seed,
+                       v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y), p));
+       a = MYMAX(a, find_ground_level_from_noise(seed,
+                       v2s16(node_min.X+MAP_BLOCKSIZE/2, node_max.Y), p));
+       a = MYMAX(a, find_ground_level_from_noise(seed,
+                       v2s16(node_min.X, node_min.Y+MAP_BLOCKSIZE/2), p));
+       a = MYMAX(a, find_ground_level_from_noise(seed,
+                       v2s16(node_max.X, node_min.Y+MAP_BLOCKSIZE/2), p));
        return a;
 }
 
@@ -1074,6 +1139,7 @@ double get_sector_minimum_ground_level(u64 seed, v2s16 sectorpos, double p)
        v2s16 node_min = sectorpos*MAP_BLOCKSIZE;
        v2s16 node_max = (sectorpos+v2s16(1,1))*MAP_BLOCKSIZE-v2s16(1,1);
        double a = 31000;
+       // Corners
        a = MYMIN(a, find_ground_level_from_noise(seed,
                        v2s16(node_min.X, node_min.Y), p));
        a = MYMIN(a, find_ground_level_from_noise(seed,
@@ -1082,8 +1148,18 @@ double get_sector_minimum_ground_level(u64 seed, v2s16 sectorpos, double p)
                        v2s16(node_max.X, node_max.Y), p));
        a = MYMIN(a, find_ground_level_from_noise(seed,
                        v2s16(node_min.X, node_min.Y), p));
+       // Center
        a = MYMIN(a, find_ground_level_from_noise(seed,
                        v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y+MAP_BLOCKSIZE/2), p));
+       // Side middle points
+       a = MYMIN(a, find_ground_level_from_noise(seed,
+                       v2s16(node_min.X+MAP_BLOCKSIZE/2, node_min.Y), p));
+       a = MYMIN(a, find_ground_level_from_noise(seed,
+                       v2s16(node_min.X+MAP_BLOCKSIZE/2, node_max.Y), p));
+       a = MYMIN(a, find_ground_level_from_noise(seed,
+                       v2s16(node_min.X, node_min.Y+MAP_BLOCKSIZE/2), p));
+       a = MYMIN(a, find_ground_level_from_noise(seed,
+                       v2s16(node_max.X, node_min.Y+MAP_BLOCKSIZE/2), p));
        return a;
 }
 
@@ -1328,7 +1404,7 @@ void make_block(BlockMakeData *data)
                If block is deep underground, this is set to true and ground
                density noise is not generated, for speed optimization.
        */
-       bool all_is_ground_except_caves = (minimum_ground_depth > 16);
+       bool all_is_ground_except_caves = (minimum_ground_depth > 40);
        
        /*
                Create a block-specific seed
index 16346b870d0e26fb24a40b2e49a1f42f0c631503..18357e19dc45f682be94d7cce15e0e8825263330 100644 (file)
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "content_craft.h"
 #include "content_nodemeta.h"
 #include "mapblock.h"
+#include "serverobject.h"
 
 #define BLOCK_EMERGE_FLAG_FROMDISK (1<<0)
 
@@ -2411,8 +2412,12 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                                        toolname = titem->getToolName();
                                                }
                                        }
+
+                                       v3f playerpos = player->getPosition();
+                                       v3f objpos = obj->getBasePosition();
+                                       v3f dir = (objpos - playerpos).normalize();
                                        
-                                       u16 wear = obj->punch(toolname);
+                                       u16 wear = obj->punch(toolname, dir);
                                        
                                        if(titem)
                                        {
index d31e9a31cdc7fd7cd6e9f6a66b85e1ea2c3275f1..8acb35f6db84fefd601d03e8f4496dbb050f5c2c 100644 (file)
@@ -19,9 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "serverobject.h"
 #include <fstream>
-#include "environment.h"
 #include "inventory.h"
-#include "collision.h"
 
 core::map<u16, ServerActiveObject::Factory> ServerActiveObject::m_types;
 
@@ -71,600 +69,4 @@ void ServerActiveObject::registerType(u16 type, Factory f)
 }
 
 
-/*
-       TestSAO
-*/
-
-// Prototype
-TestSAO proto_TestSAO(NULL, 0, v3f(0,0,0));
-
-TestSAO::TestSAO(ServerEnvironment *env, u16 id, v3f pos):
-       ServerActiveObject(env, id, pos),
-       m_timer1(0),
-       m_age(0)
-{
-       ServerActiveObject::registerType(getType(), create);
-}
-
-ServerActiveObject* TestSAO::create(ServerEnvironment *env, u16 id, v3f pos,
-               const std::string &data)
-{
-       return new TestSAO(env, id, pos);
-}
-
-void TestSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
-               bool send_recommended)
-{
-       m_age += dtime;
-       if(m_age > 10)
-       {
-               m_removed = true;
-               return;
-       }
-
-       m_base_position.Y += dtime * BS * 2;
-       if(m_base_position.Y > 8*BS)
-               m_base_position.Y = 2*BS;
-
-       if(send_recommended == false)
-               return;
-
-       m_timer1 -= dtime;
-       if(m_timer1 < 0.0)
-       {
-               m_timer1 += 0.125;
-               //dstream<<"TestSAO: id="<<getId()<<" sending data"<<std::endl;
-
-               std::string data;
-
-               data += itos(0); // 0 = position
-               data += " ";
-               data += itos(m_base_position.X);
-               data += " ";
-               data += itos(m_base_position.Y);
-               data += " ";
-               data += itos(m_base_position.Z);
-
-               ActiveObjectMessage aom(getId(), false, data);
-               messages.push_back(aom);
-       }
-}
-
-
-/*
-       ItemSAO
-*/
-
-// Prototype
-ItemSAO proto_ItemSAO(NULL, 0, v3f(0,0,0), "");
-
-ItemSAO::ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
-               const std::string inventorystring):
-       ServerActiveObject(env, id, pos),
-       m_inventorystring(inventorystring),
-       m_speed_f(0,0,0),
-       m_last_sent_position(0,0,0)
-{
-       ServerActiveObject::registerType(getType(), create);
-}
-
-ServerActiveObject* ItemSAO::create(ServerEnvironment *env, u16 id, v3f pos,
-               const std::string &data)
-{
-       std::istringstream is(data, std::ios::binary);
-       char buf[1];
-       // read version
-       is.read(buf, 1);
-       u8 version = buf[0];
-       // check if version is supported
-       if(version != 0)
-               return NULL;
-       std::string inventorystring = deSerializeString(is);
-       dstream<<"ItemSAO::create(): Creating item \""
-                       <<inventorystring<<"\""<<std::endl;
-       return new ItemSAO(env, id, pos, inventorystring);
-}
-
-void ItemSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
-               bool send_recommended)
-{
-       assert(m_env);
-
-       const float interval = 0.2;
-       if(m_move_interval.step(dtime, interval)==false)
-               return;
-       dtime = interval;
-       
-       core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
-       collisionMoveResult moveresult;
-       // Apply gravity
-       m_speed_f += v3f(0, -dtime*9.81*BS, 0);
-       // Maximum movement without glitches
-       f32 pos_max_d = BS*0.25;
-       // Limit speed
-       if(m_speed_f.getLength()*dtime > pos_max_d)
-               m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
-       v3f pos_f = getBasePosition();
-       v3f pos_f_old = pos_f;
-       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
-                       box, dtime, pos_f, m_speed_f);
-       
-       if(send_recommended == false)
-               return;
-
-       if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
-       {
-               setBasePosition(pos_f);
-               m_last_sent_position = pos_f;
-
-               std::ostringstream os(std::ios::binary);
-               char buf[6];
-               // command (0 = update position)
-               buf[0] = 0;
-               os.write(buf, 1);
-               // pos
-               writeS32((u8*)buf, m_base_position.X*1000);
-               os.write(buf, 4);
-               writeS32((u8*)buf, m_base_position.Y*1000);
-               os.write(buf, 4);
-               writeS32((u8*)buf, m_base_position.Z*1000);
-               os.write(buf, 4);
-               // create message and add to list
-               ActiveObjectMessage aom(getId(), false, os.str());
-               messages.push_back(aom);
-       }
-}
-
-std::string ItemSAO::getClientInitializationData()
-{
-       std::ostringstream os(std::ios::binary);
-       char buf[6];
-       // version
-       buf[0] = 0;
-       os.write(buf, 1);
-       // pos
-       writeS32((u8*)buf, m_base_position.X*1000);
-       os.write(buf, 4);
-       writeS32((u8*)buf, m_base_position.Y*1000);
-       os.write(buf, 4);
-       writeS32((u8*)buf, m_base_position.Z*1000);
-       os.write(buf, 4);
-       // inventorystring
-       os<<serializeString(m_inventorystring);
-       return os.str();
-}
-
-std::string ItemSAO::getStaticData()
-{
-       dstream<<__FUNCTION_NAME<<std::endl;
-       std::ostringstream os(std::ios::binary);
-       char buf[1];
-       // version
-       buf[0] = 0;
-       os.write(buf, 1);
-       // inventorystring
-       os<<serializeString(m_inventorystring);
-       return os.str();
-}
-
-InventoryItem * ItemSAO::createInventoryItem()
-{
-       try{
-               std::istringstream is(m_inventorystring, std::ios_base::binary);
-               InventoryItem *item = InventoryItem::deSerialize(is);
-               dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
-                               <<m_inventorystring<<"\" -> item="<<item
-                               <<std::endl;
-               return item;
-       }
-       catch(SerializationError &e)
-       {
-               dstream<<__FUNCTION_NAME<<": serialization error: "
-                               <<"m_inventorystring=\""<<m_inventorystring<<"\""<<std::endl;
-               return NULL;
-       }
-}
-
-
-/*
-       RatSAO
-*/
-
-// Prototype
-RatSAO proto_RatSAO(NULL, 0, v3f(0,0,0));
-
-RatSAO::RatSAO(ServerEnvironment *env, u16 id, v3f pos):
-       ServerActiveObject(env, id, pos),
-       m_is_active(false),
-       m_speed_f(0,0,0)
-{
-       ServerActiveObject::registerType(getType(), create);
-
-       m_oldpos = v3f(0,0,0);
-       m_last_sent_position = v3f(0,0,0);
-       m_yaw = 0;
-       m_counter1 = 0;
-       m_counter2 = 0;
-       m_age = 0;
-       m_touching_ground = false;
-}
-
-ServerActiveObject* RatSAO::create(ServerEnvironment *env, u16 id, v3f pos,
-               const std::string &data)
-{
-       std::istringstream is(data, std::ios::binary);
-       char buf[1];
-       // read version
-       is.read(buf, 1);
-       u8 version = buf[0];
-       // check if version is supported
-       if(version != 0)
-               return NULL;
-       return new RatSAO(env, id, pos);
-}
-
-void RatSAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
-               bool send_recommended)
-{
-       assert(m_env);
-
-       if(m_is_active == false)
-       {
-               if(m_inactive_interval.step(dtime, 0.5)==false)
-                       return;
-       }
-
-       /*
-               The AI
-       */
-
-       /*m_age += dtime;
-       if(m_age > 60)
-       {
-               // Die
-               m_removed = true;
-               return;
-       }*/
-
-       // Apply gravity
-       m_speed_f.Y -= dtime*9.81*BS;
-
-       /*
-               Move around if some player is close
-       */
-       bool player_is_close = false;
-       // Check connected players
-       core::list<Player*> players = m_env->getPlayers(true);
-       core::list<Player*>::Iterator i;
-       for(i = players.begin();
-                       i != players.end(); i++)
-       {
-               Player *player = *i;
-               v3f playerpos = player->getPosition();
-               if(m_base_position.getDistanceFrom(playerpos) < BS*10.0)
-               {
-                       player_is_close = true;
-                       break;
-               }
-       }
-
-       m_is_active = player_is_close;
-       
-       if(player_is_close == false)
-       {
-               m_speed_f.X = 0;
-               m_speed_f.Z = 0;
-       }
-       else
-       {
-               // Move around
-               v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
-               f32 speed = 2*BS;
-               m_speed_f.X = speed * dir.X;
-               m_speed_f.Z = speed * dir.Z;
-
-               if(m_touching_ground && (m_oldpos - m_base_position).getLength()
-                               < dtime*speed/2)
-               {
-                       m_counter1 -= dtime;
-                       if(m_counter1 < 0.0)
-                       {
-                               m_counter1 += 1.0;
-                               m_speed_f.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_base_position;
-
-       /*
-               Move it, with collision detection
-       */
-
-       core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.);
-       collisionMoveResult moveresult;
-       // Maximum movement without glitches
-       f32 pos_max_d = BS*0.25;
-       // Limit speed
-       if(m_speed_f.getLength()*dtime > pos_max_d)
-               m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
-       v3f pos_f = getBasePosition();
-       v3f pos_f_old = pos_f;
-       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
-                       box, dtime, pos_f, m_speed_f);
-       m_touching_ground = moveresult.touching_ground;
-       
-       setBasePosition(pos_f);
-
-       if(send_recommended == false)
-               return;
-
-       if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
-       {
-               m_last_sent_position = pos_f;
-
-               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());
-               messages.push_back(aom);
-       }
-}
-
-std::string RatSAO::getClientInitializationData()
-{
-       std::ostringstream os(std::ios::binary);
-       // version
-       writeU8(os, 0);
-       // pos
-       writeV3F1000(os, m_base_position);
-       return os.str();
-}
-
-std::string RatSAO::getStaticData()
-{
-       //dstream<<__FUNCTION_NAME<<std::endl;
-       std::ostringstream os(std::ios::binary);
-       // version
-       writeU8(os, 0);
-       return os.str();
-}
-
-InventoryItem* RatSAO::createPickedUpItem()
-{
-       std::istringstream is("CraftItem rat 1", std::ios_base::binary);
-       InventoryItem *item = InventoryItem::deSerialize(is);
-       return item;
-}
-
-/*
-       Oerkki1SAO
-*/
-
-// Prototype
-Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0));
-
-Oerkki1SAO::Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos):
-       ServerActiveObject(env, id, pos),
-       m_is_active(false),
-       m_speed_f(0,0,0)
-{
-       ServerActiveObject::registerType(getType(), create);
-
-       m_oldpos = v3f(0,0,0);
-       m_last_sent_position = v3f(0,0,0);
-       m_yaw = 0;
-       m_counter1 = 0;
-       m_counter2 = 0;
-       m_age = 0;
-       m_touching_ground = false;
-       m_hp = 20;
-}
-
-ServerActiveObject* Oerkki1SAO::create(ServerEnvironment *env, u16 id, v3f pos,
-               const std::string &data)
-{
-       std::istringstream is(data, std::ios::binary);
-       // read version
-       u8 version = readU8(is);
-       // read hp
-       u8 hp = readU8(is);
-       // check if version is supported
-       if(version != 0)
-               return NULL;
-       Oerkki1SAO *o = new Oerkki1SAO(env, id, pos);
-       o->m_hp = hp;
-       return o;
-}
-
-void Oerkki1SAO::step(float dtime, Queue<ActiveObjectMessage> &messages,
-               bool send_recommended)
-{
-       assert(m_env);
-
-       if(m_is_active == false)
-       {
-               if(m_inactive_interval.step(dtime, 0.5)==false)
-                       return;
-       }
-
-       /*
-               The AI
-       */
-
-       m_age += dtime;
-       if(m_age > 120)
-       {
-               // Die
-               m_removed = true;
-               return;
-       }
-
-       // Apply gravity
-       m_speed_f.Y -= dtime*9.81*BS;
-
-       /*
-               Move around if some player is close
-       */
-       bool player_is_close = false;
-       v3f near_player_pos;
-       // Check connected players
-       core::list<Player*> players = m_env->getPlayers(true);
-       core::list<Player*>::Iterator i;
-       for(i = players.begin();
-                       i != players.end(); i++)
-       {
-               Player *player = *i;
-               v3f playerpos = player->getPosition();
-               if(m_base_position.getDistanceFrom(playerpos) < BS*15.0)
-               {
-                       player_is_close = true;
-                       near_player_pos = playerpos;
-                       break;
-               }
-       }
-
-       m_is_active = player_is_close;
-       
-       if(player_is_close == false)
-       {
-               m_speed_f.X = 0;
-               m_speed_f.Z = 0;
-       }
-       else
-       {
-               // Move around
-
-               v3f ndir = near_player_pos - m_base_position;
-               ndir.Y = 0;
-               ndir /= ndir.getLength();
-               f32 nyaw = 180./PI*atan2(ndir.Z,ndir.X);
-               if(nyaw < m_yaw - 180)
-                       nyaw += 360;
-               else if(nyaw > m_yaw + 180)
-                       nyaw -= 360;
-               m_yaw = 0.95*m_yaw + 0.05*nyaw;
-               m_yaw = wrapDegrees(m_yaw);
-
-               v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
-               f32 speed = 2*BS;
-               m_speed_f.X = speed * dir.X;
-               m_speed_f.Z = speed * dir.Z;
-
-               if(m_touching_ground && (m_oldpos - m_base_position).getLength()
-                               < dtime*speed/2)
-               {
-                       m_counter1 -= dtime;
-                       if(m_counter1 < 0.0)
-                       {
-                               m_counter1 += 1.0;
-                               // Jump
-                               m_speed_f.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 += ((float)(myrand()%200)-100)/100*90;
-                               m_yaw = wrapDegrees(m_yaw);
-                       }
-               }
-       }
-       
-       m_oldpos = m_base_position;
-
-       /*
-               Move it, with collision detection
-       */
-
-       core::aabbox3d<f32> box(-BS/3.,0.0,-BS/3., BS/3.,BS*5./3.,BS/3.);
-       collisionMoveResult moveresult;
-       // Maximum movement without glitches
-       f32 pos_max_d = BS*0.25;
-       // Limit speed
-       if(m_speed_f.getLength()*dtime > pos_max_d)
-               m_speed_f *= pos_max_d / (m_speed_f.getLength()*dtime);
-       v3f pos_f = getBasePosition();
-       v3f pos_f_old = pos_f;
-       moveresult = collisionMoveSimple(&m_env->getMap(), pos_max_d,
-                       box, dtime, pos_f, m_speed_f);
-       m_touching_ground = moveresult.touching_ground;
-       
-       setBasePosition(pos_f);
-
-       if(send_recommended == false)
-               return;
-
-       if(pos_f.getDistanceFrom(m_last_sent_position) > 0.05*BS)
-       {
-               m_last_sent_position = pos_f;
-
-               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());
-               messages.push_back(aom);
-       }
-}
-
-std::string Oerkki1SAO::getClientInitializationData()
-{
-       std::ostringstream os(std::ios::binary);
-       // version
-       writeU8(os, 0);
-       // pos
-       writeV3F1000(os, m_base_position);
-       return os.str();
-}
-
-std::string Oerkki1SAO::getStaticData()
-{
-       //dstream<<__FUNCTION_NAME<<std::endl;
-       std::ostringstream os(std::ios::binary);
-       // version
-       writeU8(os, 0);
-       // hp
-       writeU8(os, m_hp);
-       return os.str();
-}
-
-u16 Oerkki1SAO::punch(const std::string &toolname)
-{
-       u16 amount = 5;
-       if(amount < m_hp)
-       {
-               m_hp -= amount;
-       }
-       else
-       {
-               // Die
-               m_removed = true;
-       }
-       return 65536/100;
-}
-
 
index 955969819e2befa9fb9eb348fb08f5fad9c5aef5..c008bf93eebfa24e5a042518e3f910f5481c26d7 100644 (file)
@@ -78,8 +78,7 @@ public:
                        same time so that the data can be combined in a single
                        packet.
        */
-       virtual void step(float dtime, Queue<ActiveObjectMessage> &messages,
-                       bool send_recommended){}
+       virtual void step(float dtime, bool send_recommended){}
        
        /*
                The return value of this is passed to the client-side object
@@ -104,7 +103,8 @@ public:
                If the object doesn't return an item, this will be called.
                Return value is tool wear.
        */
-       virtual u16 punch(const std::string &toolname){return 0;}
+       virtual u16 punch(const std::string &toolname, v3f dir)
+       {return 0;}
        
        /*
                Number of players which know about this object. Object won't be
@@ -144,6 +144,11 @@ public:
        */
        v3s16 m_static_block;
        
+       /*
+               Queue of messages to be sent to the client
+       */
+       Queue<ActiveObjectMessage> m_messages_out;
+       
 protected:
        // Used for creating objects based on type
        typedef ServerActiveObject* (*Factory)
@@ -159,96 +164,5 @@ private:
        static core::map<u16, Factory> m_types;
 };
 
-class TestSAO : public ServerActiveObject
-{
-public:
-       TestSAO(ServerEnvironment *env, u16 id, v3f pos);
-       u8 getType() const
-               {return ACTIVEOBJECT_TYPE_TEST;}
-       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
-                       const std::string &data);
-       void step(float dtime, Queue<ActiveObjectMessage> &messages,
-                       bool send_recommended);
-private:
-       float m_timer1;
-       float m_age;
-};
-
-class ItemSAO : public ServerActiveObject
-{
-public:
-       ItemSAO(ServerEnvironment *env, u16 id, v3f pos,
-                       const std::string inventorystring);
-       u8 getType() const
-               {return ACTIVEOBJECT_TYPE_ITEM;}
-       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
-                       const std::string &data);
-       void step(float dtime, Queue<ActiveObjectMessage> &messages,
-                       bool send_recommended);
-       std::string getClientInitializationData();
-       std::string getStaticData();
-       InventoryItem* createInventoryItem();
-       InventoryItem* createPickedUpItem(){return createInventoryItem();}
-private:
-       std::string m_inventorystring;
-       v3f m_speed_f;
-       v3f m_last_sent_position;
-       IntervalLimiter m_move_interval;
-};
-
-class RatSAO : public ServerActiveObject
-{
-public:
-       RatSAO(ServerEnvironment *env, u16 id, v3f pos);
-       u8 getType() const
-               {return ACTIVEOBJECT_TYPE_RAT;}
-       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
-                       const std::string &data);
-       void step(float dtime, Queue<ActiveObjectMessage> &messages,
-                       bool send_recommended);
-       std::string getClientInitializationData();
-       std::string getStaticData();
-       InventoryItem* createPickedUpItem();
-private:
-       bool m_is_active;
-       IntervalLimiter m_inactive_interval;
-       v3f m_speed_f;
-       v3f m_oldpos;
-       v3f m_last_sent_position;
-       float m_yaw;
-       float m_counter1;
-       float m_counter2;
-       float m_age;
-       bool m_touching_ground;
-};
-
-class Oerkki1SAO : public ServerActiveObject
-{
-public:
-       Oerkki1SAO(ServerEnvironment *env, u16 id, v3f pos);
-       u8 getType() const
-               {return ACTIVEOBJECT_TYPE_OERKKI1;}
-       static ServerActiveObject* create(ServerEnvironment *env, u16 id, v3f pos,
-                       const std::string &data);
-       void step(float dtime, Queue<ActiveObjectMessage> &messages,
-                       bool send_recommended);
-       std::string getClientInitializationData();
-       std::string getStaticData();
-       InventoryItem* createPickedUpItem(){return NULL;}
-       u16 punch(const std::string &toolname);
-private:
-       bool m_is_active;
-       IntervalLimiter m_inactive_interval;
-       v3f m_speed_f;
-       v3f m_oldpos;
-       v3f m_last_sent_position;
-       float m_yaw;
-       float m_counter1;
-       float m_counter2;
-       float m_age;
-       bool m_touching_ground;
-       u8 m_hp;
-};
-
 #endif