+ fireflies
authorNils Dagsson Moskopp <nils@dieweltistgarnichtso.net>
Wed, 20 Jul 2011 20:04:24 +0000 (22:04 +0200)
committerNils Dagsson Moskopp <nils@dieweltistgarnichtso.net>
Wed, 20 Jul 2011 20:05:57 +0000 (22:05 +0200)
data/firefly.png [new file with mode: 0644]
src/content_cao.cpp
src/content_cao.h
src/content_inventory.cpp
src/content_object.h
src/content_sao.cpp
src/content_sao.h
src/environment.cpp

diff --git a/data/firefly.png b/data/firefly.png
new file mode 100644 (file)
index 0000000..d5a444b
Binary files /dev/null and b/data/firefly.png differ
index dc5ac400f5da3f05f400291ade4911ab7f220866..dfeaea85ab09babf8d62f7a07b22a058046ea353 100644 (file)
@@ -752,4 +752,161 @@ void Oerkki1CAO::initialize(const std::string &data)
        updateNodePos();
 }
 
+/*
+       FireflyCAO
+*/
+
+// Prototype
+FireflyCAO proto_FireflyCAO;
+
+FireflyCAO::FireflyCAO():
+       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);
+}
 
+FireflyCAO::~FireflyCAO()
+{
+}
+
+ClientActiveObject* FireflyCAO::create()
+{
+       return new FireflyCAO();
+}
+
+void FireflyCAO::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(0,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(0,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("firefly.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 FireflyCAO::removeFromScene()
+{
+       if(m_node == NULL)
+               return;
+
+       m_node->remove();
+       m_node = NULL;
+}
+
+void FireflyCAO::updateLight(u8 light_at_pos)
+{
+       if(m_node == NULL)
+               return;
+
+       u8 li = 255;
+       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 FireflyCAO::getLightPosition()
+{
+       return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
+}
+
+void FireflyCAO::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 FireflyCAO::step(float dtime, ClientEnvironment *env)
+{
+       pos_translator.translate(dtime);
+       updateNodePos();
+}
+
+void FireflyCAO::processMessage(const std::string &data)
+{
+       //dstream<<"FireflyCAO: 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 FireflyCAO::initialize(const std::string &data)
+{
+       //dstream<<"FireflyCAO: 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 146e23b0c985f0db3bd7f5fa0071866bbd88e543..b984be1361cb79d98fbf016659058cec538f65dd 100644 (file)
@@ -243,6 +243,48 @@ private:
        bool m_damage_texture_enabled;
 };
 
+/*
+       FireflyCAO
+*/
+
+class FireflyCAO : public ClientActiveObject
+{
+public:
+       FireflyCAO();
+       virtual ~FireflyCAO();
+       
+       u8 getType() const
+       {
+               return ACTIVEOBJECT_TYPE_FIREFLY;
+       }
+       
+       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;
+};
+
 
 #endif
 
index 7d995cb5f1e7893f32a94c0a25f38a4630805913..1068defb5e8772a3289704fcef077aba8b5dfd03 100644 (file)
@@ -65,6 +65,8 @@ std::string item_craft_get_image_name(const std::string &subname)
                return "clay_brick.png";
        else if(subname == "rat")
                return "rat.png";
+       else if(subname == "firefly")
+               return "firefly.png";
        else
                return "cloud.png"; // just something
 }
@@ -77,13 +79,18 @@ ServerActiveObject* item_craft_create_object(const std::string &subname,
                ServerActiveObject *obj = new RatSAO(env, id, pos);
                return obj;
        }
+       else if(subname == "firefly")
+       {
+               ServerActiveObject *obj = new FireflySAO(env, id, pos);
+               return obj;
+       }
 
        return NULL;
 }
 
 s16 item_craft_get_drop_count(const std::string &subname)
 {
-       if(subname == "rat")
+       if(subname == "rat" || subname == "firefly")
                return 1;
 
        return -1;
index ecabd8a3877ab5eaf850857564df86a5b06a3ee0..47f93d7d4ad492828609f671d139613d00f2aa02 100644 (file)
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define ACTIVEOBJECT_TYPE_ITEM 2
 #define ACTIVEOBJECT_TYPE_RAT 3
 #define ACTIVEOBJECT_TYPE_OERKKI1 4
+#define ACTIVEOBJECT_TYPE_FIREFLY 5
 
 #endif
 
index c41f4ed784297e0aaf08efb5ac6dc1f0bba0a07c..aeeafc2f88d649cecd6e8825a22d007a36d11098 100644 (file)
@@ -693,4 +693,179 @@ void Oerkki1SAO::doDamage(u16 d)
        }
 }
 
+/*
+       FireflySAO
+*/
+
+// Prototype
+FireflySAO proto_FireflySAO(NULL, 0, v3f(0,0,0));
+
+FireflySAO::FireflySAO(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* FireflySAO::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 FireflySAO(env, id, pos);
+}
+
+void FireflySAO::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
+       */
+
+       // Apply (less) gravity
+       m_speed_f.Y -= dtime*3*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 = BS/2;
+               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 FireflySAO::getClientInitializationData()
+{
+       std::ostringstream os(std::ios::binary);
+       // version
+       writeU8(os, 0);
+       // pos
+       writeV3F1000(os, m_base_position);
+       return os.str();
+}
+
+std::string FireflySAO::getStaticData()
+{
+       //dstream<<__FUNCTION_NAME<<std::endl;
+       std::ostringstream os(std::ios::binary);
+       // version
+       writeU8(os, 0);
+       return os.str();
+}
+
+InventoryItem* FireflySAO::createPickedUpItem()
+{
+       std::istringstream is("CraftItem firefly 1", std::ios_base::binary);
+       InventoryItem *item = InventoryItem::deSerialize(is);
+       return item;
+}
index 030232a9ee05317fc8e0173d1a58984968645041..e5b1223d466c68c54bf221d6ceff5c1beb2dde85 100644 (file)
@@ -113,6 +113,30 @@ private:
        float m_after_jump_timer;
 };
 
+class FireflySAO : public ServerActiveObject
+{
+public:
+       FireflySAO(ServerEnvironment *env, u16 id, v3f pos);
+       u8 getType() const
+               {return ACTIVEOBJECT_TYPE_FIREFLY;}
+       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;
+};
 
 #endif
 
index d55aa38d172bc96eda77f07c0e217687afa10778..df41dc63f24fc40feb39300b772853bd5799ce49 100644 (file)
@@ -976,7 +976,8 @@ void ServerEnvironment::step(float dtime)
                //TestSAO *obj = new TestSAO(this, 0, pos);
                //ServerActiveObject *obj = new ItemSAO(this, 0, pos, "CraftItem Stick 1");
                //ServerActiveObject *obj = new RatSAO(this, 0, pos);
-               ServerActiveObject *obj = new Oerkki1SAO(this, 0, pos);
+               //ServerActiveObject *obj = new Oerkki1SAO(this, 0, pos);
+               ServerActiveObject *obj = new FireflySAO(this, 0, pos);
                addActiveObject(obj);
        }
 #endif