3 Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "content_cao.h"
22 #include "environment.h"
24 #include <ICameraSceneNode.h>
25 #include "serialization.h" // For decompressZlib
27 core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
34 TestCAO proto_TestCAO(NULL);
36 TestCAO::TestCAO(IGameDef *gamedef):
37 ClientActiveObject(0, gamedef),
39 m_position(v3f(0,10*BS,0))
41 ClientActiveObject::registerType(getType(), create);
48 ClientActiveObject* TestCAO::create(IGameDef *gamedef)
50 return new TestCAO(gamedef);
53 void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
58 video::IVideoDriver* driver = smgr->getVideoDriver();
60 scene::SMesh *mesh = new scene::SMesh();
61 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
62 video::SColor c(255,255,255,255);
63 video::S3DVertex vertices[4] =
65 video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
66 video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
67 video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
68 video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),
70 u16 indices[] = {0,1,2,2,3,0};
71 buf->append(vertices, 4, indices, 6);
73 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
74 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
75 buf->getMaterial().setTexture
76 (0, driver->getTexture(getTexturePath("rat.png").c_str()));
77 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
78 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
79 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
81 mesh->addMeshBuffer(buf);
83 m_node = smgr->addMeshSceneNode(mesh, NULL);
88 void TestCAO::removeFromScene()
97 void TestCAO::updateLight(u8 light_at_pos)
101 v3s16 TestCAO::getLightPosition()
103 return floatToInt(m_position, BS);
106 void TestCAO::updateNodePos()
111 m_node->setPosition(m_position);
112 //m_node->setRotation(v3f(0, 45, 0));
115 void TestCAO::step(float dtime, ClientEnvironment *env)
119 v3f rot = m_node->getRotation();
120 //infostream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
121 rot.Y += dtime * 180;
122 m_node->setRotation(rot);
126 void TestCAO::processMessage(const std::string &data)
128 infostream<<"TestCAO: Got data: "<<data<<std::endl;
129 std::istringstream is(data, std::ios::binary);
147 #include "inventory.h"
150 ItemCAO proto_ItemCAO(NULL);
152 ItemCAO::ItemCAO(IGameDef *gamedef):
153 ClientActiveObject(0, gamedef),
154 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
156 m_position(v3f(0,10*BS,0))
158 ClientActiveObject::registerType(getType(), create);
165 ClientActiveObject* ItemCAO::create(IGameDef *gamedef)
167 return new ItemCAO(gamedef);
170 void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
175 video::IVideoDriver* driver = smgr->getVideoDriver();
177 scene::SMesh *mesh = new scene::SMesh();
178 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
179 video::SColor c(255,255,255,255);
180 video::S3DVertex vertices[4] =
182 /*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
183 video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
184 video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
185 video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
186 video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
187 video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
188 video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
189 video::S3DVertex(BS/3.,0+BS*2./3.,0, 0,0,0, c, 0,0),
191 u16 indices[] = {0,1,2,2,3,0};
192 buf->append(vertices, 4, indices, 6);
194 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
195 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
196 //buf->getMaterial().setTexture(0, NULL);
197 // Initialize with the stick texture
198 buf->getMaterial().setTexture
199 (0, driver->getTexture(getTexturePath("stick.png").c_str()));
200 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
201 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
202 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
204 mesh->addMeshBuffer(buf);
206 m_node = smgr->addMeshSceneNode(mesh, NULL);
208 // Set it to use the materials of the meshbuffers directly.
209 // This is needed for changing the texture in the future
210 m_node->setReadOnlyMaterials(true);
217 // Create an inventory item to see what is its image
218 std::istringstream is(m_inventorystring, std::ios_base::binary);
219 video::ITexture *texture = NULL;
221 InventoryItem *item = NULL;
222 item = InventoryItem::deSerialize(is, m_gamedef);
223 infostream<<__FUNCTION_NAME<<": m_inventorystring=\""
224 <<m_inventorystring<<"\" -> item="<<item
228 texture = item->getImage(tsrc);
232 catch(SerializationError &e)
234 infostream<<"WARNING: "<<__FUNCTION_NAME
235 <<": error deSerializing inventorystring \""
236 <<m_inventorystring<<"\""<<std::endl;
239 // Set meshbuffer texture
240 buf->getMaterial().setTexture(0, texture);
243 void ItemCAO::removeFromScene()
252 void ItemCAO::updateLight(u8 light_at_pos)
257 u8 li = decode_light(light_at_pos);
258 video::SColor color(255,li,li,li);
259 setMeshVerticesColor(m_node->getMesh(), color);
262 v3s16 ItemCAO::getLightPosition()
264 return floatToInt(m_position, BS);
267 void ItemCAO::updateNodePos()
272 m_node->setPosition(m_position);
275 void ItemCAO::step(float dtime, ClientEnvironment *env)
279 /*v3f rot = m_node->getRotation();
280 rot.Y += dtime * 120;
281 m_node->setRotation(rot);*/
282 LocalPlayer *player = env->getLocalPlayer();
284 v3f rot = m_node->getRotation();
285 rot.Y = 180.0 - (player->getYaw());
286 m_node->setRotation(rot);
290 void ItemCAO::processMessage(const std::string &data)
292 infostream<<"ItemCAO: Got message"<<std::endl;
293 std::istringstream is(data, std::ios::binary);
299 m_position = readV3F1000(is);
304 void ItemCAO::initialize(const std::string &data)
306 infostream<<"ItemCAO: Got init data"<<std::endl;
309 std::istringstream is(data, std::ios::binary);
311 u8 version = readU8(is);
316 m_position = readV3F1000(is);
318 m_inventorystring = deSerializeString(is);
328 #include "inventory.h"
331 RatCAO proto_RatCAO(NULL);
333 RatCAO::RatCAO(IGameDef *gamedef):
334 ClientActiveObject(0, gamedef),
335 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
337 m_position(v3f(0,10*BS,0)),
340 ClientActiveObject::registerType(getType(), create);
347 ClientActiveObject* RatCAO::create(IGameDef *gamedef)
349 return new RatCAO(gamedef);
352 void RatCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
357 video::IVideoDriver* driver = smgr->getVideoDriver();
359 scene::SMesh *mesh = new scene::SMesh();
360 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
361 video::SColor c(255,255,255,255);
362 video::S3DVertex vertices[4] =
364 video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
365 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
366 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
367 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
369 u16 indices[] = {0,1,2,2,3,0};
370 buf->append(vertices, 4, indices, 6);
372 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
373 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
374 //buf->getMaterial().setTexture(0, NULL);
375 buf->getMaterial().setTexture
376 (0, driver->getTexture(getTexturePath("rat.png").c_str()));
377 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
378 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
379 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
381 mesh->addMeshBuffer(buf);
383 m_node = smgr->addMeshSceneNode(mesh, NULL);
385 // Set it to use the materials of the meshbuffers directly.
386 // This is needed for changing the texture in the future
387 m_node->setReadOnlyMaterials(true);
391 void RatCAO::removeFromScene()
400 void RatCAO::updateLight(u8 light_at_pos)
405 u8 li = decode_light(light_at_pos);
406 video::SColor color(255,li,li,li);
407 setMeshVerticesColor(m_node->getMesh(), color);
410 v3s16 RatCAO::getLightPosition()
412 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
415 void RatCAO::updateNodePos()
420 //m_node->setPosition(m_position);
421 m_node->setPosition(pos_translator.vect_show);
423 v3f rot = m_node->getRotation();
424 rot.Y = 180.0 - m_yaw;
425 m_node->setRotation(rot);
428 void RatCAO::step(float dtime, ClientEnvironment *env)
430 pos_translator.translate(dtime);
434 void RatCAO::processMessage(const std::string &data)
436 //infostream<<"RatCAO: Got message"<<std::endl;
437 std::istringstream is(data, std::ios::binary);
443 m_position = readV3F1000(is);
444 pos_translator.update(m_position);
446 m_yaw = readF1000(is);
451 void RatCAO::initialize(const std::string &data)
453 //infostream<<"RatCAO: Got init data"<<std::endl;
456 std::istringstream is(data, std::ios::binary);
458 u8 version = readU8(is);
463 m_position = readV3F1000(is);
464 pos_translator.init(m_position);
474 #include "inventory.h"
477 Oerkki1CAO proto_Oerkki1CAO(NULL);
479 Oerkki1CAO::Oerkki1CAO(IGameDef *gamedef):
480 ClientActiveObject(0, gamedef),
481 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
483 m_position(v3f(0,10*BS,0)),
485 m_damage_visual_timer(0),
486 m_damage_texture_enabled(false)
488 ClientActiveObject::registerType(getType(), create);
491 Oerkki1CAO::~Oerkki1CAO()
495 ClientActiveObject* Oerkki1CAO::create(IGameDef *gamedef)
497 return new Oerkki1CAO(gamedef);
500 void Oerkki1CAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
505 video::IVideoDriver* driver = smgr->getVideoDriver();
507 scene::SMesh *mesh = new scene::SMesh();
508 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
509 video::SColor c(255,255,255,255);
510 video::S3DVertex vertices[4] =
512 video::S3DVertex(-BS/2-BS,0,0, 0,0,0, c, 0,1),
513 video::S3DVertex(BS/2+BS,0,0, 0,0,0, c, 1,1),
514 video::S3DVertex(BS/2+BS,BS*2,0, 0,0,0, c, 1,0),
515 video::S3DVertex(-BS/2-BS,BS*2,0, 0,0,0, c, 0,0),
517 u16 indices[] = {0,1,2,2,3,0};
518 buf->append(vertices, 4, indices, 6);
520 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
521 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
522 //buf->getMaterial().setTexture(0, NULL);
523 buf->getMaterial().setTexture
524 (0, driver->getTexture(getTexturePath("oerkki1.png").c_str()));
525 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
526 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
527 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
529 mesh->addMeshBuffer(buf);
531 m_node = smgr->addMeshSceneNode(mesh, NULL);
533 // Set it to use the materials of the meshbuffers directly.
534 // This is needed for changing the texture in the future
535 m_node->setReadOnlyMaterials(true);
539 void Oerkki1CAO::removeFromScene()
548 void Oerkki1CAO::updateLight(u8 light_at_pos)
553 if(light_at_pos <= 2)
555 m_node->setVisible(false);
559 m_node->setVisible(true);
561 u8 li = decode_light(light_at_pos);
562 video::SColor color(255,li,li,li);
563 setMeshVerticesColor(m_node->getMesh(), color);
566 v3s16 Oerkki1CAO::getLightPosition()
568 return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
571 void Oerkki1CAO::updateNodePos()
576 //m_node->setPosition(m_position);
577 m_node->setPosition(pos_translator.vect_show);
579 v3f rot = m_node->getRotation();
580 rot.Y = 180.0 - m_yaw + 90.0;
581 m_node->setRotation(rot);
584 void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
586 pos_translator.translate(dtime);
589 LocalPlayer *player = env->getLocalPlayer();
592 v3f playerpos = player->getPosition();
593 v2f playerpos_2d(playerpos.X,playerpos.Z);
594 v2f objectpos_2d(m_position.X,m_position.Z);
596 if(fabs(m_position.Y - playerpos.Y) < 1.5*BS &&
597 objectpos_2d.getDistanceFrom(playerpos_2d) < 1.5*BS)
599 if(m_attack_interval.step(dtime, 0.5))
601 env->damageLocalPlayer(2);
605 if(m_damage_visual_timer > 0)
607 if(!m_damage_texture_enabled)
609 // Enable damage texture
612 video::IVideoDriver* driver =
613 m_node->getSceneManager()->getVideoDriver();
615 scene::IMesh *mesh = m_node->getMesh();
619 u16 mc = mesh->getMeshBufferCount();
620 for(u16 j=0; j<mc; j++)
622 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
623 buf->getMaterial().setTexture(0, driver->getTexture(
624 getTexturePath("oerkki1_damaged.png").c_str()));
627 m_damage_texture_enabled = true;
629 m_damage_visual_timer -= dtime;
633 if(m_damage_texture_enabled)
635 // Disable damage texture
638 video::IVideoDriver* driver =
639 m_node->getSceneManager()->getVideoDriver();
641 scene::IMesh *mesh = m_node->getMesh();
645 u16 mc = mesh->getMeshBufferCount();
646 for(u16 j=0; j<mc; j++)
648 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
649 buf->getMaterial().setTexture(0, driver->getTexture(
650 getTexturePath("oerkki1.png").c_str()));
653 m_damage_texture_enabled = false;
658 void Oerkki1CAO::processMessage(const std::string &data)
660 //infostream<<"Oerkki1CAO: Got message"<<std::endl;
661 std::istringstream is(data, std::ios::binary);
667 m_position = readV3F1000(is);
668 pos_translator.update(m_position);
670 m_yaw = readF1000(is);
675 //u16 damage = readU8(is);
676 m_damage_visual_timer = 1.0;
680 void Oerkki1CAO::initialize(const std::string &data)
682 //infostream<<"Oerkki1CAO: Got init data"<<std::endl;
685 std::istringstream is(data, std::ios::binary);
687 u8 version = readU8(is);
692 m_position = readV3F1000(is);
693 pos_translator.init(m_position);
699 bool Oerkki1CAO::directReportPunch(const std::string &toolname, v3f dir)
701 m_damage_visual_timer = 1.0;
703 m_position += dir * BS;
704 pos_translator.sharpen();
705 pos_translator.update(m_position);
716 FireflyCAO proto_FireflyCAO(NULL);
718 FireflyCAO::FireflyCAO(IGameDef *gamedef):
719 ClientActiveObject(0, gamedef),
720 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
722 m_position(v3f(0,10*BS,0)),
725 ClientActiveObject::registerType(getType(), create);
728 FireflyCAO::~FireflyCAO()
732 ClientActiveObject* FireflyCAO::create(IGameDef *gamedef)
734 return new FireflyCAO(gamedef);
737 void FireflyCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
742 video::IVideoDriver* driver = smgr->getVideoDriver();
744 scene::SMesh *mesh = new scene::SMesh();
745 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
746 video::SColor c(255,255,255,255);
747 video::S3DVertex vertices[4] =
749 video::S3DVertex(0,0,0, 0,0,0, c, 0,1),
750 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
751 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
752 video::S3DVertex(0,BS/2,0, 0,0,0, c, 0,0),
754 u16 indices[] = {0,1,2,2,3,0};
755 buf->append(vertices, 4, indices, 6);
757 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
758 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
759 //buf->getMaterial().setTexture(0, NULL);
760 buf->getMaterial().setTexture
761 (0, driver->getTexture(getTexturePath("firefly.png").c_str()));
762 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
763 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
764 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
766 mesh->addMeshBuffer(buf);
768 m_node = smgr->addMeshSceneNode(mesh, NULL);
770 // Set it to use the materials of the meshbuffers directly.
771 // This is needed for changing the texture in the future
772 m_node->setReadOnlyMaterials(true);
776 void FireflyCAO::removeFromScene()
785 void FireflyCAO::updateLight(u8 light_at_pos)
791 video::SColor color(255,li,li,li);
792 setMeshVerticesColor(m_node->getMesh(), color);
795 v3s16 FireflyCAO::getLightPosition()
797 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
800 void FireflyCAO::updateNodePos()
805 //m_node->setPosition(m_position);
806 m_node->setPosition(pos_translator.vect_show);
808 v3f rot = m_node->getRotation();
809 rot.Y = 180.0 - m_yaw;
810 m_node->setRotation(rot);
813 void FireflyCAO::step(float dtime, ClientEnvironment *env)
815 pos_translator.translate(dtime);
819 void FireflyCAO::processMessage(const std::string &data)
821 //infostream<<"FireflyCAO: Got message"<<std::endl;
822 std::istringstream is(data, std::ios::binary);
828 m_position = readV3F1000(is);
829 pos_translator.update(m_position);
831 m_yaw = readF1000(is);
836 void FireflyCAO::initialize(const std::string &data)
838 //infostream<<"FireflyCAO: Got init data"<<std::endl;
841 std::istringstream is(data, std::ios::binary);
843 u8 version = readU8(is);
848 m_position = readV3F1000(is);
849 pos_translator.init(m_position);
860 MobV2CAO proto_MobV2CAO(NULL);
862 MobV2CAO::MobV2CAO(IGameDef *gamedef):
863 ClientActiveObject(0, gamedef),
864 m_selection_box(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS),
866 m_position(v3f(0,10*BS,0)),
869 m_walking_unset_timer(0),
872 m_damage_visual_timer(0),
875 m_shooting_unset_timer(0),
876 m_sprite_size(BS,BS),
878 m_bright_shooting(false),
879 m_lock_full_brightness(false),
880 m_player_hit_timer(0)
882 ClientActiveObject::registerType(getType(), create);
884 m_properties = new Settings;
887 MobV2CAO::~MobV2CAO()
892 ClientActiveObject* MobV2CAO::create(IGameDef *gamedef)
894 return new MobV2CAO(gamedef);
897 void MobV2CAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
902 /*infostream<<"MobV2CAO::addToScene using texture_name="<<
903 m_texture_name<<std::endl;*/
904 std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
905 texture_string += m_texture_name;
907 scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
908 smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
909 bill->setMaterialTexture(0, tsrc->getTextureRaw(texture_string));
910 bill->setMaterialFlag(video::EMF_LIGHTING, false);
911 bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
912 bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
913 bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
914 bill->setColor(video::SColor(255,0,0,0));
915 bill->setVisible(false); /* Set visible when brightness is known */
916 bill->setSize(m_sprite_size);
917 if(m_sprite_type == "humanoid_1"){
918 const float txp = 1./192;
919 const float txs = txp*32;
920 const float typ = 1./240;
921 const float tys = typ*48;
922 bill->setTCoords(0, v2f(txs*1, tys*1));
923 bill->setTCoords(1, v2f(txs*1, tys*0));
924 bill->setTCoords(2, v2f(txs*0, tys*0));
925 bill->setTCoords(3, v2f(txs*0, tys*1));
926 } else if(m_sprite_type == "simple"){
927 const float txs = 1.0;
928 const float tys = 1.0 / m_simple_anim_frames;
929 bill->setTCoords(0, v2f(txs*1, tys*1));
930 bill->setTCoords(1, v2f(txs*1, tys*0));
931 bill->setTCoords(2, v2f(txs*0, tys*0));
932 bill->setTCoords(3, v2f(txs*0, tys*1));
934 infostream<<"MobV2CAO: Unknown sprite type \""<<m_sprite_type<<"\""
943 void MobV2CAO::removeFromScene()
953 void MobV2CAO::updateLight(u8 light_at_pos)
955 if(m_lock_full_brightness)
958 m_last_light = light_at_pos;
963 if(m_damage_visual_timer > 0)
966 if(m_shooting && m_bright_shooting)
969 /*if(light_at_pos <= 2){
970 m_node->setVisible(false);
974 m_node->setVisible(true);
976 u8 li = decode_light(light_at_pos);
977 video::SColor color(255,li,li,li);
978 m_node->setColor(color);
981 v3s16 MobV2CAO::getLightPosition()
983 return floatToInt(m_position+v3f(0,0,0), BS);
986 void MobV2CAO::updateNodePos()
991 m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
994 void MobV2CAO::step(float dtime, ClientEnvironment *env)
996 scene::MyBillboardSceneNode *bill = m_node;
1000 pos_translator.translate(dtime);
1002 if(m_sprite_type == "humanoid_1"){
1003 scene::ICameraSceneNode* camera = m_node->getSceneManager()->getActiveCamera();
1006 v3f cam_to_mob = m_node->getAbsolutePosition() - camera->getAbsolutePosition();
1007 cam_to_mob.normalize();
1009 if(cam_to_mob.Y > 0.75)
1011 else if(cam_to_mob.Y < -0.75)
1014 float mob_dir = atan2(cam_to_mob.Z, cam_to_mob.X) / PI * 180.;
1015 float dir = mob_dir - m_yaw;
1016 dir = wrapDegrees_180(dir);
1017 //infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;
1018 if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
1020 else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
1022 else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
1024 else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
1033 } else if(m_walking){
1034 m_walk_timer += dtime;
1035 if(m_walk_timer >= 0.5){
1036 m_walk_frame = (m_walk_frame + 1) % 2;
1039 if(m_walk_frame == 0)
1045 const float txp = 1./192;
1046 const float txs = txp*32;
1047 const float typ = 1./240;
1048 const float tys = typ*48;
1049 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1050 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1051 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1052 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1053 } else if(m_sprite_type == "simple"){
1054 m_walk_timer += dtime;
1055 if(m_walk_timer >= m_simple_anim_frametime){
1056 m_walk_frame = (m_walk_frame + 1) % m_simple_anim_frames;
1060 int row = m_walk_frame;
1061 const float txs = 1.0;
1062 const float tys = 1.0 / m_simple_anim_frames;
1063 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1064 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1065 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1066 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1068 infostream<<"MobV2CAO::step(): Unknown sprite type \""
1069 <<m_sprite_type<<"\""<<std::endl;
1074 /* Damage local player */
1075 if(m_player_hit_damage && m_player_hit_timer <= 0.0){
1076 LocalPlayer *player = env->getLocalPlayer();
1079 v3f playerpos = player->getPosition();
1080 v2f playerpos_2d(playerpos.X,playerpos.Z);
1081 v2f objectpos_2d(m_position.X,m_position.Z);
1083 if(fabs(m_position.Y - playerpos.Y) < m_player_hit_distance*BS &&
1084 objectpos_2d.getDistanceFrom(playerpos_2d) < m_player_hit_distance*BS)
1086 env->damageLocalPlayer(m_player_hit_damage);
1087 m_player_hit_timer = m_player_hit_interval;
1093 m_player_hit_timer -= dtime;
1095 if(m_damage_visual_timer >= 0){
1096 m_damage_visual_timer -= dtime;
1097 if(m_damage_visual_timer <= 0){
1098 infostream<<"id="<<m_id<<" damage visual ended"<<std::endl;
1102 m_walking_unset_timer += dtime;
1103 if(m_walking_unset_timer >= 1.0){
1107 m_shooting_unset_timer -= dtime;
1108 if(m_shooting_unset_timer <= 0.0){
1109 if(m_bright_shooting){
1110 u8 li = decode_light(m_last_light);
1111 video::SColor color(255,li,li,li);
1112 bill->setColor(color);
1113 m_bright_shooting = false;
1120 void MobV2CAO::processMessage(const std::string &data)
1122 //infostream<<"MobV2CAO: Got message"<<std::endl;
1123 std::istringstream is(data, std::ios::binary);
1125 u8 cmd = readU8(is);
1131 m_position = readV3F1000(is);
1132 pos_translator.update(m_position);
1134 m_yaw = readF1000(is);
1137 m_walking_unset_timer = 0;
1144 //u16 damage = readU16(is);
1146 /*u8 li = decode_light(m_last_light);
1152 /*video::SColor color(255,255,0,0);
1153 m_node->setColor(color);
1155 m_damage_visual_timer = 0.2;*/
1161 m_shooting_unset_timer = readF1000(is);
1163 m_bright_shooting = readU8(is);
1164 if(m_bright_shooting){
1166 video::SColor color(255,li,li,li);
1167 m_node->setColor(color);
1174 void MobV2CAO::initialize(const std::string &data)
1176 //infostream<<"MobV2CAO: Got init data"<<std::endl;
1179 std::istringstream is(data, std::ios::binary);
1181 u8 version = readU8(is);
1184 infostream<<__FUNCTION_NAME<<": Invalid version"<<std::endl;
1188 std::ostringstream tmp_os(std::ios::binary);
1189 decompressZlib(is, tmp_os);
1190 std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
1191 m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
1193 infostream<<"MobV2CAO::initialize(): got properties:"<<std::endl;
1194 m_properties->writeLines(infostream);
1196 m_properties->setDefault("looks", "dummy_default");
1197 m_properties->setDefault("yaw", "0");
1198 m_properties->setDefault("pos", "(0,0,0)");
1199 m_properties->setDefault("player_hit_damage", "0");
1200 m_properties->setDefault("player_hit_distance", "1.5");
1201 m_properties->setDefault("player_hit_interval", "1.5");
1203 setLooks(m_properties->get("looks"));
1204 m_yaw = m_properties->getFloat("yaw");
1205 m_position = m_properties->getV3F("pos");
1206 m_player_hit_damage = m_properties->getS32("player_hit_damage");
1207 m_player_hit_distance = m_properties->getFloat("player_hit_distance");
1208 m_player_hit_interval = m_properties->getFloat("player_hit_interval");
1210 pos_translator.init(m_position);
1216 bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
1218 video::SColor color(255,255,0,0);
1219 m_node->setColor(color);
1221 m_damage_visual_timer = 0.05;
1223 m_position += dir * BS;
1224 pos_translator.sharpen();
1225 pos_translator.update(m_position);
1231 void MobV2CAO::setLooks(const std::string &looks)
1233 v2f selection_size = v2f(0.4, 0.4) * BS;
1234 float selection_y = 0 * BS;
1236 if(looks == "dungeon_master"){
1237 m_texture_name = "dungeon_master.png";
1238 m_sprite_type = "humanoid_1";
1239 m_sprite_size = v2f(2, 3) * BS;
1240 m_sprite_y = 0.85 * BS;
1241 selection_size = v2f(0.4, 2.6) * BS;
1242 selection_y = -0.4 * BS;
1244 else if(looks == "fireball"){
1245 m_texture_name = "fireball.png";
1246 m_sprite_type = "simple";
1247 m_sprite_size = v2f(1, 1) * BS;
1248 m_simple_anim_frames = 3;
1249 m_simple_anim_frametime = 0.1;
1250 m_lock_full_brightness = true;
1253 m_texture_name = "stone.png";
1254 m_sprite_type = "simple";
1255 m_sprite_size = v2f(1, 1) * BS;
1256 m_simple_anim_frames = 3;
1257 m_simple_anim_frametime = 0.333;
1258 selection_size = v2f(0.4, 0.4) * BS;
1259 selection_y = 0 * BS;
1262 m_selection_box = core::aabbox3d<f32>(
1263 -selection_size.X, selection_y, -selection_size.X,
1264 selection_size.X, selection_y+selection_size.Y,
1272 #include "luaentity_common.h"
1275 LuaEntityCAO proto_LuaEntityCAO(NULL);
1277 LuaEntityCAO::LuaEntityCAO(IGameDef *gamedef):
1278 ClientActiveObject(0, gamedef),
1279 m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.),
1282 m_position(v3f(0,10*BS,0)),
1284 m_prop(new LuaEntityProperties)
1286 ClientActiveObject::registerType(getType(), create);
1289 LuaEntityCAO::~LuaEntityCAO()
1294 ClientActiveObject* LuaEntityCAO::create(IGameDef *gamedef)
1296 return new LuaEntityCAO(gamedef);
1299 void LuaEntityCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc)
1301 if(m_meshnode != NULL || m_spritenode != NULL)
1304 //video::IVideoDriver* driver = smgr->getVideoDriver();
1306 if(m_prop->visual == "single_sprite"){
1307 infostream<<"LuaEntityCAO::addToScene(): single_sprite"<<std::endl;
1308 m_spritenode = new scene::MyBillboardSceneNode(
1309 smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
1310 std::string texturestring = "unknown_block.png";
1311 if(m_prop->textures.size() >= 1)
1312 texturestring = m_prop->textures[0];
1313 m_spritenode->setMaterialTexture(0,
1314 tsrc->getTextureRaw(texturestring));
1315 m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
1316 m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
1317 m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
1318 m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
1319 m_spritenode->setColor(video::SColor(255,0,0,0));
1320 m_spritenode->setVisible(false); /* Set visible when brightness is known */
1321 m_spritenode->setSize(v2f(1,1)*1.0*BS);
1323 const float txs = 1.0 / 1;
1324 const float tys = 1.0 / 1;
1325 m_spritenode->setTCoords(0, v2f(txs*1, tys*1));
1326 m_spritenode->setTCoords(1, v2f(txs*1, tys*0));
1327 m_spritenode->setTCoords(2, v2f(txs*0, tys*0));
1328 m_spritenode->setTCoords(3, v2f(txs*0, tys*1));
1330 } else if(m_prop->visual == "cube"){
1331 infostream<<"LuaEntityCAO::addToScene(): cube"<<std::endl;
1332 video::SColor c(255,255,255,255);
1333 video::S3DVertex vertices[24] =
1336 video::S3DVertex(-0.5,+0.5,-0.5, 0,1,0, c, 0,1),
1337 video::S3DVertex(-0.5,+0.5,+0.5, 0,1,0, c, 0,0),
1338 video::S3DVertex(+0.5,+0.5,+0.5, 0,1,0, c, 1,0),
1339 video::S3DVertex(+0.5,+0.5,-0.5, 0,1,0, c, 1,1),
1341 video::S3DVertex(-0.5,-0.5,-0.5, 0,-1,0, c, 0,0),
1342 video::S3DVertex(+0.5,-0.5,-0.5, 0,-1,0, c, 1,0),
1343 video::S3DVertex(+0.5,-0.5,+0.5, 0,-1,0, c, 1,1),
1344 video::S3DVertex(-0.5,-0.5,+0.5, 0,-1,0, c, 0,1),
1346 video::S3DVertex(+0.5,-0.5,-0.5, 1,0,0, c, 0,1),
1347 video::S3DVertex(+0.5,+0.5,-0.5, 1,0,0, c, 0,0),
1348 video::S3DVertex(+0.5,+0.5,+0.5, 1,0,0, c, 1,0),
1349 video::S3DVertex(+0.5,-0.5,+0.5, 1,0,0, c, 1,1),
1351 video::S3DVertex(-0.5,-0.5,-0.5, -1,0,0, c, 1,1),
1352 video::S3DVertex(-0.5,-0.5,+0.5, -1,0,0, c, 0,1),
1353 video::S3DVertex(-0.5,+0.5,+0.5, -1,0,0, c, 0,0),
1354 video::S3DVertex(-0.5,+0.5,-0.5, -1,0,0, c, 1,0),
1356 video::S3DVertex(-0.5,-0.5,+0.5, 0,0,1, c, 1,1),
1357 video::S3DVertex(+0.5,-0.5,+0.5, 0,0,1, c, 0,1),
1358 video::S3DVertex(+0.5,+0.5,+0.5, 0,0,1, c, 0,0),
1359 video::S3DVertex(-0.5,+0.5,+0.5, 0,0,1, c, 1,0),
1361 video::S3DVertex(-0.5,-0.5,-0.5, 0,0,-1, c, 0,1),
1362 video::S3DVertex(-0.5,+0.5,-0.5, 0,0,-1, c, 0,0),
1363 video::S3DVertex(+0.5,+0.5,-0.5, 0,0,-1, c, 1,0),
1364 video::S3DVertex(+0.5,-0.5,-0.5, 0,0,-1, c, 1,1),
1367 for(u32 i=0; i<24; ++i){
1368 vertices[i].Pos *= BS;
1371 u16 indices[6] = {0,1,2,2,3,0};
1373 scene::SMesh* mesh = new scene::SMesh();
1374 for (u32 i=0; i<6; ++i)
1376 scene::IMeshBuffer* buf = new scene::SMeshBuffer();
1377 buf->append(vertices + 4 * i, 4, indices, 6);
1378 buf->recalculateBoundingBox();
1379 mesh->addMeshBuffer(buf);
1382 mesh->recalculateBoundingBox();
1384 m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
1386 m_meshnode->setMesh(mesh);
1387 m_meshnode->setScale(v3f(1));
1388 for (u32 i = 0; i < 6; ++i)
1390 std::string texturestring = "unknown_block.png";
1391 if(m_prop->textures.size() > i)
1392 texturestring = m_prop->textures[i];
1393 AtlasPointer ap = tsrc->getTexture(texturestring);
1395 // Get the tile texture and atlas transformation
1396 video::ITexture* atlas = ap.atlas;
1400 // Set material flags and texture
1401 video::SMaterial& material = m_meshnode->getMaterial(i);
1402 material.setFlag(video::EMF_LIGHTING, false);
1403 material.setFlag(video::EMF_BILINEAR_FILTER, false);
1404 material.setTexture(0, atlas);
1405 material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
1406 material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
1408 // Will be shown when we know the brightness
1409 m_meshnode->setVisible(false);
1411 infostream<<"LuaEntityCAO::addToScene(): \""<<m_prop->visual
1412 <<"\" not supported"<<std::endl;
1417 void LuaEntityCAO::removeFromScene()
1420 m_meshnode->remove();
1424 m_spritenode->remove();
1425 m_spritenode = NULL;
1429 void LuaEntityCAO::updateLight(u8 light_at_pos)
1431 u8 li = decode_light(light_at_pos);
1432 video::SColor color(255,li,li,li);
1434 setMeshVerticesColor(m_meshnode->getMesh(), color);
1435 m_meshnode->setVisible(true);
1438 m_spritenode->setColor(color);
1439 m_spritenode->setVisible(true);
1443 v3s16 LuaEntityCAO::getLightPosition()
1445 return floatToInt(m_position, BS);
1448 void LuaEntityCAO::updateNodePos()
1451 m_meshnode->setPosition(pos_translator.vect_show);
1454 m_spritenode->setPosition(pos_translator.vect_show);
1458 void LuaEntityCAO::step(float dtime, ClientEnvironment *env)
1460 pos_translator.translate(dtime);
1464 void LuaEntityCAO::processMessage(const std::string &data)
1466 infostream<<"LuaEntityCAO: Got message"<<std::endl;
1467 std::istringstream is(data, std::ios::binary);
1469 u8 cmd = readU8(is);
1473 bool do_interpolate = readU8(is);
1475 m_position = readV3F1000(is);
1477 m_yaw = readF1000(is);
1478 // is_end_position (for interpolation)
1479 bool is_end_position = readU8(is);
1481 float update_interval = readF1000(is);
1484 pos_translator.update(m_position, is_end_position, update_interval);
1486 pos_translator.init(m_position);
1491 void LuaEntityCAO::initialize(const std::string &data)
1493 infostream<<"LuaEntityCAO: Got init data"<<std::endl;
1495 std::istringstream is(data, std::ios::binary);
1497 u8 version = readU8(is);
1502 m_position = readV3F1000(is);
1504 m_yaw = readF1000(is);
1506 std::istringstream prop_is(deSerializeLongString(is), std::ios::binary);
1507 m_prop->deSerialize(prop_is);
1509 infostream<<"m_prop: "<<m_prop->dump()<<std::endl;
1511 m_selection_box = m_prop->collisionbox;
1512 m_selection_box.MinEdge *= BS;
1513 m_selection_box.MaxEdge *= BS;
1515 pos_translator.init(m_position);