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>
26 core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
33 TestCAO proto_TestCAO;
36 ClientActiveObject(0),
38 m_position(v3f(0,10*BS,0))
40 ClientActiveObject::registerType(getType(), create);
47 ClientActiveObject* TestCAO::create()
52 void TestCAO::addToScene(scene::ISceneManager *smgr)
57 video::IVideoDriver* driver = smgr->getVideoDriver();
59 scene::SMesh *mesh = new scene::SMesh();
60 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
61 video::SColor c(255,255,255,255);
62 video::S3DVertex vertices[4] =
64 video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
65 video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
66 video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
67 video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),
69 u16 indices[] = {0,1,2,2,3,0};
70 buf->append(vertices, 4, indices, 6);
72 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
73 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
74 buf->getMaterial().setTexture
75 (0, driver->getTexture(getTexturePath("rat.png").c_str()));
76 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
77 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
78 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
80 mesh->addMeshBuffer(buf);
82 m_node = smgr->addMeshSceneNode(mesh, NULL);
87 void TestCAO::removeFromScene()
96 void TestCAO::updateLight(u8 light_at_pos)
100 v3s16 TestCAO::getLightPosition()
102 return floatToInt(m_position, BS);
105 void TestCAO::updateNodePos()
110 m_node->setPosition(m_position);
111 //m_node->setRotation(v3f(0, 45, 0));
114 void TestCAO::step(float dtime, ClientEnvironment *env)
118 v3f rot = m_node->getRotation();
119 //dstream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
120 rot.Y += dtime * 180;
121 m_node->setRotation(rot);
125 void TestCAO::processMessage(const std::string &data)
127 dstream<<"TestCAO: Got data: "<<data<<std::endl;
128 std::istringstream is(data, std::ios::binary);
146 #include "inventory.h"
149 ItemCAO proto_ItemCAO;
152 ClientActiveObject(0),
153 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
155 m_position(v3f(0,10*BS,0))
157 ClientActiveObject::registerType(getType(), create);
164 ClientActiveObject* ItemCAO::create()
166 return new ItemCAO();
169 void ItemCAO::addToScene(scene::ISceneManager *smgr)
174 video::IVideoDriver* driver = smgr->getVideoDriver();
176 scene::SMesh *mesh = new scene::SMesh();
177 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
178 video::SColor c(255,255,255,255);
179 video::S3DVertex vertices[4] =
181 /*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
182 video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
183 video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
184 video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
185 video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
186 video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
187 video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
188 video::S3DVertex(BS/3.,0+BS*2./3.,0, 0,0,0, c, 0,0),
190 u16 indices[] = {0,1,2,2,3,0};
191 buf->append(vertices, 4, indices, 6);
193 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
194 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
195 //buf->getMaterial().setTexture(0, NULL);
196 // Initialize with the stick texture
197 buf->getMaterial().setTexture
198 (0, driver->getTexture(getTexturePath("stick.png").c_str()));
199 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
200 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
201 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
203 mesh->addMeshBuffer(buf);
205 m_node = smgr->addMeshSceneNode(mesh, NULL);
207 // Set it to use the materials of the meshbuffers directly.
208 // This is needed for changing the texture in the future
209 m_node->setReadOnlyMaterials(true);
213 void ItemCAO::removeFromScene()
222 void ItemCAO::updateLight(u8 light_at_pos)
227 u8 li = decode_light(light_at_pos);
228 video::SColor color(255,li,li,li);
229 setMeshVerticesColor(m_node->getMesh(), color);
232 v3s16 ItemCAO::getLightPosition()
234 return floatToInt(m_position, BS);
237 void ItemCAO::updateNodePos()
242 m_node->setPosition(m_position);
245 void ItemCAO::step(float dtime, ClientEnvironment *env)
249 /*v3f rot = m_node->getRotation();
250 rot.Y += dtime * 120;
251 m_node->setRotation(rot);*/
252 LocalPlayer *player = env->getLocalPlayer();
254 v3f rot = m_node->getRotation();
255 rot.Y = 180.0 - (player->getYaw());
256 m_node->setRotation(rot);
260 void ItemCAO::processMessage(const std::string &data)
262 dstream<<"ItemCAO: Got message"<<std::endl;
263 std::istringstream is(data, std::ios::binary);
269 m_position = readV3F1000(is);
274 void ItemCAO::initialize(const std::string &data)
276 dstream<<"ItemCAO: Got init data"<<std::endl;
279 std::istringstream is(data, std::ios::binary);
281 u8 version = readU8(is);
286 m_position = readV3F1000(is);
288 m_inventorystring = deSerializeString(is);
300 scene::IMesh *mesh = m_node->getMesh();
305 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
310 // Create an inventory item to see what is its image
311 std::istringstream is(m_inventorystring, std::ios_base::binary);
312 video::ITexture *texture = NULL;
314 InventoryItem *item = NULL;
315 item = InventoryItem::deSerialize(is);
316 dstream<<__FUNCTION_NAME<<": m_inventorystring=\""
317 <<m_inventorystring<<"\" -> item="<<item
321 texture = item->getImage();
325 catch(SerializationError &e)
327 dstream<<"WARNING: "<<__FUNCTION_NAME
328 <<": error deSerializing inventorystring \""
329 <<m_inventorystring<<"\""<<std::endl;
332 // Set meshbuffer texture
333 buf->getMaterial().setTexture(0, texture);
341 #include "inventory.h"
347 ClientActiveObject(0),
348 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
350 m_position(v3f(0,10*BS,0)),
353 ClientActiveObject::registerType(getType(), create);
360 ClientActiveObject* RatCAO::create()
365 void RatCAO::addToScene(scene::ISceneManager *smgr)
370 video::IVideoDriver* driver = smgr->getVideoDriver();
372 scene::SMesh *mesh = new scene::SMesh();
373 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
374 video::SColor c(255,255,255,255);
375 video::S3DVertex vertices[4] =
377 video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
378 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
379 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
380 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
382 u16 indices[] = {0,1,2,2,3,0};
383 buf->append(vertices, 4, indices, 6);
385 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
386 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
387 //buf->getMaterial().setTexture(0, NULL);
388 buf->getMaterial().setTexture
389 (0, driver->getTexture(getTexturePath("rat.png").c_str()));
390 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
391 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
392 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
394 mesh->addMeshBuffer(buf);
396 m_node = smgr->addMeshSceneNode(mesh, NULL);
398 // Set it to use the materials of the meshbuffers directly.
399 // This is needed for changing the texture in the future
400 m_node->setReadOnlyMaterials(true);
404 void RatCAO::removeFromScene()
413 void RatCAO::updateLight(u8 light_at_pos)
418 u8 li = decode_light(light_at_pos);
419 video::SColor color(255,li,li,li);
420 setMeshVerticesColor(m_node->getMesh(), color);
423 v3s16 RatCAO::getLightPosition()
425 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
428 void RatCAO::updateNodePos()
433 //m_node->setPosition(m_position);
434 m_node->setPosition(pos_translator.vect_show);
436 v3f rot = m_node->getRotation();
437 rot.Y = 180.0 - m_yaw;
438 m_node->setRotation(rot);
441 void RatCAO::step(float dtime, ClientEnvironment *env)
443 pos_translator.translate(dtime);
447 void RatCAO::processMessage(const std::string &data)
449 //dstream<<"RatCAO: Got message"<<std::endl;
450 std::istringstream is(data, std::ios::binary);
456 m_position = readV3F1000(is);
457 pos_translator.update(m_position);
459 m_yaw = readF1000(is);
464 void RatCAO::initialize(const std::string &data)
466 //dstream<<"RatCAO: Got init data"<<std::endl;
469 std::istringstream is(data, std::ios::binary);
471 u8 version = readU8(is);
476 m_position = readV3F1000(is);
477 pos_translator.init(m_position);
487 #include "inventory.h"
490 Oerkki1CAO proto_Oerkki1CAO;
492 Oerkki1CAO::Oerkki1CAO():
493 ClientActiveObject(0),
494 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
496 m_position(v3f(0,10*BS,0)),
498 m_damage_visual_timer(0),
499 m_damage_texture_enabled(false)
501 ClientActiveObject::registerType(getType(), create);
504 Oerkki1CAO::~Oerkki1CAO()
508 ClientActiveObject* Oerkki1CAO::create()
510 return new Oerkki1CAO();
513 void Oerkki1CAO::addToScene(scene::ISceneManager *smgr)
518 video::IVideoDriver* driver = smgr->getVideoDriver();
520 scene::SMesh *mesh = new scene::SMesh();
521 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
522 video::SColor c(255,255,255,255);
523 video::S3DVertex vertices[4] =
525 video::S3DVertex(-BS/2-BS,0,0, 0,0,0, c, 0,1),
526 video::S3DVertex(BS/2+BS,0,0, 0,0,0, c, 1,1),
527 video::S3DVertex(BS/2+BS,BS*2,0, 0,0,0, c, 1,0),
528 video::S3DVertex(-BS/2-BS,BS*2,0, 0,0,0, c, 0,0),
530 u16 indices[] = {0,1,2,2,3,0};
531 buf->append(vertices, 4, indices, 6);
533 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
534 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
535 //buf->getMaterial().setTexture(0, NULL);
536 buf->getMaterial().setTexture
537 (0, driver->getTexture(getTexturePath("oerkki1.png").c_str()));
538 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
539 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
540 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
542 mesh->addMeshBuffer(buf);
544 m_node = smgr->addMeshSceneNode(mesh, NULL);
546 // Set it to use the materials of the meshbuffers directly.
547 // This is needed for changing the texture in the future
548 m_node->setReadOnlyMaterials(true);
552 void Oerkki1CAO::removeFromScene()
561 void Oerkki1CAO::updateLight(u8 light_at_pos)
566 if(light_at_pos <= 2)
568 m_node->setVisible(false);
572 m_node->setVisible(true);
574 u8 li = decode_light(light_at_pos);
575 video::SColor color(255,li,li,li);
576 setMeshVerticesColor(m_node->getMesh(), color);
579 v3s16 Oerkki1CAO::getLightPosition()
581 return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
584 void Oerkki1CAO::updateNodePos()
589 //m_node->setPosition(m_position);
590 m_node->setPosition(pos_translator.vect_show);
592 v3f rot = m_node->getRotation();
593 rot.Y = 180.0 - m_yaw + 90.0;
594 m_node->setRotation(rot);
597 void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
599 pos_translator.translate(dtime);
602 LocalPlayer *player = env->getLocalPlayer();
605 v3f playerpos = player->getPosition();
606 v2f playerpos_2d(playerpos.X,playerpos.Z);
607 v2f objectpos_2d(m_position.X,m_position.Z);
609 if(fabs(m_position.Y - playerpos.Y) < 3.0*BS &&
610 objectpos_2d.getDistanceFrom(playerpos_2d) < 1.5*BS)
612 if(m_attack_interval.step(dtime, 0.5))
614 env->damageLocalPlayer(2);
618 if(m_damage_visual_timer > 0)
620 if(!m_damage_texture_enabled)
622 // Enable damage texture
625 video::IVideoDriver* driver =
626 m_node->getSceneManager()->getVideoDriver();
628 scene::IMesh *mesh = m_node->getMesh();
632 u16 mc = mesh->getMeshBufferCount();
633 for(u16 j=0; j<mc; j++)
635 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
636 buf->getMaterial().setTexture(0, driver->getTexture(
637 getTexturePath("oerkki1_damaged.png").c_str()));
640 m_damage_texture_enabled = true;
642 m_damage_visual_timer -= dtime;
646 if(m_damage_texture_enabled)
648 // Disable damage texture
651 video::IVideoDriver* driver =
652 m_node->getSceneManager()->getVideoDriver();
654 scene::IMesh *mesh = m_node->getMesh();
658 u16 mc = mesh->getMeshBufferCount();
659 for(u16 j=0; j<mc; j++)
661 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
662 buf->getMaterial().setTexture(0, driver->getTexture(
663 getTexturePath("oerkki1.png").c_str()));
666 m_damage_texture_enabled = false;
671 void Oerkki1CAO::processMessage(const std::string &data)
673 //dstream<<"Oerkki1CAO: Got message"<<std::endl;
674 std::istringstream is(data, std::ios::binary);
680 m_position = readV3F1000(is);
681 pos_translator.update(m_position);
683 m_yaw = readF1000(is);
688 //u16 damage = readU8(is);
689 m_damage_visual_timer = 1.0;
693 void Oerkki1CAO::initialize(const std::string &data)
695 //dstream<<"Oerkki1CAO: Got init data"<<std::endl;
698 std::istringstream is(data, std::ios::binary);
700 u8 version = readU8(is);
705 m_position = readV3F1000(is);
706 pos_translator.init(m_position);
717 FireflyCAO proto_FireflyCAO;
719 FireflyCAO::FireflyCAO():
720 ClientActiveObject(0),
721 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
723 m_position(v3f(0,10*BS,0)),
726 ClientActiveObject::registerType(getType(), create);
729 FireflyCAO::~FireflyCAO()
733 ClientActiveObject* FireflyCAO::create()
735 return new FireflyCAO();
738 void FireflyCAO::addToScene(scene::ISceneManager *smgr)
743 video::IVideoDriver* driver = smgr->getVideoDriver();
745 scene::SMesh *mesh = new scene::SMesh();
746 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
747 video::SColor c(255,255,255,255);
748 video::S3DVertex vertices[4] =
750 video::S3DVertex(0,0,0, 0,0,0, c, 0,1),
751 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
752 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
753 video::S3DVertex(0,BS/2,0, 0,0,0, c, 0,0),
755 u16 indices[] = {0,1,2,2,3,0};
756 buf->append(vertices, 4, indices, 6);
758 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
759 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
760 //buf->getMaterial().setTexture(0, NULL);
761 buf->getMaterial().setTexture
762 (0, driver->getTexture(getTexturePath("firefly.png").c_str()));
763 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
764 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
765 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
767 mesh->addMeshBuffer(buf);
769 m_node = smgr->addMeshSceneNode(mesh, NULL);
771 // Set it to use the materials of the meshbuffers directly.
772 // This is needed for changing the texture in the future
773 m_node->setReadOnlyMaterials(true);
777 void FireflyCAO::removeFromScene()
786 void FireflyCAO::updateLight(u8 light_at_pos)
792 video::SColor color(255,li,li,li);
793 setMeshVerticesColor(m_node->getMesh(), color);
796 v3s16 FireflyCAO::getLightPosition()
798 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
801 void FireflyCAO::updateNodePos()
806 //m_node->setPosition(m_position);
807 m_node->setPosition(pos_translator.vect_show);
809 v3f rot = m_node->getRotation();
810 rot.Y = 180.0 - m_yaw;
811 m_node->setRotation(rot);
814 void FireflyCAO::step(float dtime, ClientEnvironment *env)
816 pos_translator.translate(dtime);
820 void FireflyCAO::processMessage(const std::string &data)
822 //dstream<<"FireflyCAO: Got message"<<std::endl;
823 std::istringstream is(data, std::ios::binary);
829 m_position = readV3F1000(is);
830 pos_translator.update(m_position);
832 m_yaw = readF1000(is);
837 void FireflyCAO::initialize(const std::string &data)
839 //dstream<<"FireflyCAO: Got init data"<<std::endl;
842 std::istringstream is(data, std::ios::binary);
844 u8 version = readU8(is);
849 m_position = readV3F1000(is);
850 pos_translator.init(m_position);
861 MobV2CAO proto_MobV2CAO;
863 MobV2CAO::MobV2CAO():
864 ClientActiveObject(0),
865 m_selection_box(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS),
867 m_position(v3f(0,10*BS,0)),
870 m_walking_unset_timer(0),
873 m_damage_visual_timer(0),
876 m_shooting_unset_timer(0),
877 m_sprite_size(BS,BS),
879 m_bright_shooting(false),
880 m_lock_full_brightness(false),
881 m_player_hit_timer(0)
883 ClientActiveObject::registerType(getType(), create);
885 m_properties = new Settings;
888 MobV2CAO::~MobV2CAO()
893 ClientActiveObject* MobV2CAO::create()
895 return new MobV2CAO();
898 void MobV2CAO::addToScene(scene::ISceneManager *smgr)
903 /*dstream<<"MobV2CAO::addToScene using texture_name="<<
904 m_texture_name<<std::endl;*/
905 std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
906 texture_string += m_texture_name;
908 scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
909 smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
910 bill->setMaterialTexture(0, g_texturesource->getTextureRaw(texture_string));
911 bill->setMaterialFlag(video::EMF_LIGHTING, false);
912 bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
913 bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
914 bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
915 bill->setColor(video::SColor(255,0,0,0));
916 bill->setVisible(false); /* Set visible when brightness is known */
917 bill->setSize(m_sprite_size);
918 if(m_sprite_type == "humanoid_1"){
919 const float txp = 1./192;
920 const float txs = txp*32;
921 const float typ = 1./240;
922 const float tys = typ*48;
923 bill->setTCoords(0, v2f(txs*1, tys*1));
924 bill->setTCoords(1, v2f(txs*1, tys*0));
925 bill->setTCoords(2, v2f(txs*0, tys*0));
926 bill->setTCoords(3, v2f(txs*0, tys*1));
927 } else if(m_sprite_type == "simple"){
928 const float txs = 1.0;
929 const float tys = 1.0 / m_simple_anim_frames;
930 bill->setTCoords(0, v2f(txs*1, tys*1));
931 bill->setTCoords(1, v2f(txs*1, tys*0));
932 bill->setTCoords(2, v2f(txs*0, tys*0));
933 bill->setTCoords(3, v2f(txs*0, tys*1));
935 dstream<<"MobV2CAO: Unknown sprite type \""<<m_sprite_type<<"\""
944 void MobV2CAO::removeFromScene()
954 void MobV2CAO::updateLight(u8 light_at_pos)
956 if(m_lock_full_brightness)
959 m_last_light = light_at_pos;
964 if(m_damage_visual_timer > 0)
967 if(m_shooting && m_bright_shooting)
970 /*if(light_at_pos <= 2){
971 m_node->setVisible(false);
975 m_node->setVisible(true);
977 u8 li = decode_light(light_at_pos);
978 video::SColor color(255,li,li,li);
979 m_node->setColor(color);
982 v3s16 MobV2CAO::getLightPosition()
984 return floatToInt(m_position+v3f(0,0,0), BS);
987 void MobV2CAO::updateNodePos()
992 m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
995 void MobV2CAO::step(float dtime, ClientEnvironment *env)
997 scene::MyBillboardSceneNode *bill = m_node;
999 pos_translator.translate(dtime);
1001 if(m_sprite_type == "humanoid_1"){
1002 scene::ICameraSceneNode* camera = m_node->getSceneManager()->getActiveCamera();
1003 v3f cam_to_mob = m_node->getAbsolutePosition() - camera->getAbsolutePosition();
1004 cam_to_mob.normalize();
1006 if(cam_to_mob.Y > 0.7)
1008 else if(cam_to_mob.Y < -0.7)
1011 float mob_dir = atan2(cam_to_mob.Z, cam_to_mob.X) / M_PI * 180.;
1012 float dir = mob_dir - m_yaw;
1013 dir = wrapDegrees_180(dir);
1014 //dstream<<"id="<<m_id<<" dir="<<dir<<std::endl;
1015 if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
1017 else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
1019 else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
1021 else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
1030 } else if(m_walking){
1031 m_walk_timer += dtime;
1032 if(m_walk_timer >= 0.5){
1033 m_walk_frame = (m_walk_frame + 1) % 2;
1036 if(m_walk_frame == 0)
1042 const float txp = 1./192;
1043 const float txs = txp*32;
1044 const float typ = 1./240;
1045 const float tys = typ*48;
1046 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1047 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1048 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1049 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1050 } else if(m_sprite_type == "simple"){
1051 m_walk_timer += dtime;
1052 if(m_walk_timer >= m_simple_anim_frametime){
1053 m_walk_frame = (m_walk_frame + 1) % m_simple_anim_frames;
1057 int row = m_walk_frame;
1058 const float txs = 1.0;
1059 const float tys = 1.0 / m_simple_anim_frames;
1060 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1061 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1062 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1063 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1065 dstream<<"MobV2CAO::step(): Unknown sprite type \""
1066 <<m_sprite_type<<"\""<<std::endl;
1071 /* Damage local player */
1072 if(m_player_hit_damage && m_player_hit_timer <= 0.0){
1073 LocalPlayer *player = env->getLocalPlayer();
1076 v3f playerpos = player->getPosition();
1077 v2f playerpos_2d(playerpos.X,playerpos.Z);
1078 v2f objectpos_2d(m_position.X,m_position.Z);
1080 if(fabs(m_position.Y - playerpos.Y) < m_player_hit_distance*BS &&
1081 objectpos_2d.getDistanceFrom(playerpos_2d) < m_player_hit_distance*BS)
1083 env->damageLocalPlayer(m_player_hit_damage);
1084 m_player_hit_timer = m_player_hit_interval;
1090 m_player_hit_timer -= dtime;
1092 if(m_damage_visual_timer >= 0){
1093 m_damage_visual_timer -= dtime;
1094 if(m_damage_visual_timer <= 0){
1095 dstream<<"id="<<m_id<<" damage visual ended"<<std::endl;
1099 m_walking_unset_timer += dtime;
1100 if(m_walking_unset_timer >= 1.0){
1104 m_shooting_unset_timer -= dtime;
1105 if(m_shooting_unset_timer <= 0.0){
1106 if(m_bright_shooting){
1107 u8 li = decode_light(m_last_light);
1108 video::SColor color(255,li,li,li);
1109 bill->setColor(color);
1110 m_bright_shooting = false;
1117 void MobV2CAO::processMessage(const std::string &data)
1119 //dstream<<"MobV2CAO: Got message"<<std::endl;
1120 std::istringstream is(data, std::ios::binary);
1122 u8 cmd = readU8(is);
1128 m_position = readV3F1000(is);
1129 pos_translator.update(m_position);
1131 m_yaw = readF1000(is);
1134 m_walking_unset_timer = 0;
1141 //u16 damage = readU16(is);
1143 /*u8 li = decode_light(m_last_light);
1149 /*video::SColor color(255,255,0,0);
1150 m_node->setColor(color);
1152 m_damage_visual_timer = 0.2;*/
1158 m_shooting_unset_timer = readF1000(is);
1160 m_bright_shooting = readU8(is);
1161 if(m_bright_shooting){
1163 video::SColor color(255,li,li,li);
1164 m_node->setColor(color);
1171 void MobV2CAO::initialize(const std::string &data)
1173 //dstream<<"MobV2CAO: Got init data"<<std::endl;
1176 std::istringstream is(data, std::ios::binary);
1178 u8 version = readU8(is);
1181 dstream<<__FUNCTION_NAME<<": Invalid version"<<std::endl;
1185 std::ostringstream tmp_os(std::ios::binary);
1186 decompressZlib(is, tmp_os);
1187 std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
1188 m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
1190 dstream<<"INFO: MobV2CAO::initialize(): got properties:"<<std::endl;
1191 m_properties->writeLines(dstream);
1193 m_properties->setDefault("looks", "dummy_default");
1194 m_properties->setDefault("yaw", "0");
1195 m_properties->setDefault("pos", "(0,0,0)");
1196 m_properties->setDefault("player_hit_damage", "0");
1197 m_properties->setDefault("player_hit_distance", "1.5");
1198 m_properties->setDefault("player_hit_interval", "1.5");
1200 setLooks(m_properties->get("looks"));
1201 m_yaw = m_properties->getFloat("yaw");
1202 m_position = m_properties->getV3F("pos");
1203 m_player_hit_damage = m_properties->getS32("player_hit_damage");
1204 m_player_hit_distance = m_properties->getFloat("player_hit_distance");
1205 m_player_hit_interval = m_properties->getFloat("player_hit_interval");
1207 pos_translator.init(m_position);
1213 bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
1215 video::SColor color(255,255,0,0);
1216 m_node->setColor(color);
1218 m_damage_visual_timer = 0.05;
1220 m_position += dir * BS;
1221 pos_translator.sharpen();
1222 pos_translator.update(m_position);
1228 void MobV2CAO::setLooks(const std::string &looks)
1230 v2f selection_size = v2f(0.4, 0.4) * BS;
1231 float selection_y = 0 * BS;
1233 if(looks == "dungeon_master"){
1234 m_texture_name = "dungeon_master.png";
1235 m_sprite_type = "humanoid_1";
1236 m_sprite_size = v2f(2, 3) * BS;
1237 m_sprite_y = 0.85 * BS;
1238 selection_size = v2f(0.4, 2.6) * BS;
1239 selection_y = -0.4 * BS;
1241 else if(looks == "fireball"){
1242 m_texture_name = "fireball.png";
1243 m_sprite_type = "simple";
1244 m_sprite_size = v2f(1, 1) * BS;
1245 m_simple_anim_frames = 3;
1246 m_simple_anim_frametime = 0.1;
1247 m_lock_full_brightness = true;
1250 m_texture_name = "stone.png";
1251 m_sprite_type = "simple";
1252 m_sprite_size = v2f(1, 1) * BS;
1253 m_simple_anim_frames = 3;
1254 m_simple_anim_frametime = 0.333;
1255 selection_size = v2f(0.4, 0.4) * BS;
1256 selection_y = 0 * BS;
1259 m_selection_box = core::aabbox3d<f32>(
1260 -selection_size.X, selection_y, -selection_size.X,
1261 selection_size.X, selection_y+selection_size.Y,