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 //infostream<<"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 infostream<<"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);
216 // Create an inventory item to see what is its image
217 std::istringstream is(m_inventorystring, std::ios_base::binary);
218 video::ITexture *texture = NULL;
220 InventoryItem *item = NULL;
221 item = InventoryItem::deSerialize(is);
222 infostream<<__FUNCTION_NAME<<": m_inventorystring=\""
223 <<m_inventorystring<<"\" -> item="<<item
227 texture = item->getImage();
231 catch(SerializationError &e)
233 infostream<<"WARNING: "<<__FUNCTION_NAME
234 <<": error deSerializing inventorystring \""
235 <<m_inventorystring<<"\""<<std::endl;
238 // Set meshbuffer texture
239 buf->getMaterial().setTexture(0, texture);
242 void ItemCAO::removeFromScene()
251 void ItemCAO::updateLight(u8 light_at_pos)
256 u8 li = decode_light(light_at_pos);
257 video::SColor color(255,li,li,li);
258 setMeshVerticesColor(m_node->getMesh(), color);
261 v3s16 ItemCAO::getLightPosition()
263 return floatToInt(m_position, BS);
266 void ItemCAO::updateNodePos()
271 m_node->setPosition(m_position);
274 void ItemCAO::step(float dtime, ClientEnvironment *env)
278 /*v3f rot = m_node->getRotation();
279 rot.Y += dtime * 120;
280 m_node->setRotation(rot);*/
281 LocalPlayer *player = env->getLocalPlayer();
283 v3f rot = m_node->getRotation();
284 rot.Y = 180.0 - (player->getYaw());
285 m_node->setRotation(rot);
289 void ItemCAO::processMessage(const std::string &data)
291 infostream<<"ItemCAO: Got message"<<std::endl;
292 std::istringstream is(data, std::ios::binary);
298 m_position = readV3F1000(is);
303 void ItemCAO::initialize(const std::string &data)
305 infostream<<"ItemCAO: Got init data"<<std::endl;
308 std::istringstream is(data, std::ios::binary);
310 u8 version = readU8(is);
315 m_position = readV3F1000(is);
317 m_inventorystring = deSerializeString(is);
327 #include "inventory.h"
333 ClientActiveObject(0),
334 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
336 m_position(v3f(0,10*BS,0)),
339 ClientActiveObject::registerType(getType(), create);
346 ClientActiveObject* RatCAO::create()
351 void RatCAO::addToScene(scene::ISceneManager *smgr)
356 video::IVideoDriver* driver = smgr->getVideoDriver();
358 scene::SMesh *mesh = new scene::SMesh();
359 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
360 video::SColor c(255,255,255,255);
361 video::S3DVertex vertices[4] =
363 video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
364 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
365 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
366 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
368 u16 indices[] = {0,1,2,2,3,0};
369 buf->append(vertices, 4, indices, 6);
371 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
372 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
373 //buf->getMaterial().setTexture(0, NULL);
374 buf->getMaterial().setTexture
375 (0, driver->getTexture(getTexturePath("rat.png").c_str()));
376 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
377 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
378 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
380 mesh->addMeshBuffer(buf);
382 m_node = smgr->addMeshSceneNode(mesh, NULL);
384 // Set it to use the materials of the meshbuffers directly.
385 // This is needed for changing the texture in the future
386 m_node->setReadOnlyMaterials(true);
390 void RatCAO::removeFromScene()
399 void RatCAO::updateLight(u8 light_at_pos)
404 u8 li = decode_light(light_at_pos);
405 video::SColor color(255,li,li,li);
406 setMeshVerticesColor(m_node->getMesh(), color);
409 v3s16 RatCAO::getLightPosition()
411 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
414 void RatCAO::updateNodePos()
419 //m_node->setPosition(m_position);
420 m_node->setPosition(pos_translator.vect_show);
422 v3f rot = m_node->getRotation();
423 rot.Y = 180.0 - m_yaw;
424 m_node->setRotation(rot);
427 void RatCAO::step(float dtime, ClientEnvironment *env)
429 pos_translator.translate(dtime);
433 void RatCAO::processMessage(const std::string &data)
435 //infostream<<"RatCAO: Got message"<<std::endl;
436 std::istringstream is(data, std::ios::binary);
442 m_position = readV3F1000(is);
443 pos_translator.update(m_position);
445 m_yaw = readF1000(is);
450 void RatCAO::initialize(const std::string &data)
452 //infostream<<"RatCAO: Got init data"<<std::endl;
455 std::istringstream is(data, std::ios::binary);
457 u8 version = readU8(is);
462 m_position = readV3F1000(is);
463 pos_translator.init(m_position);
473 #include "inventory.h"
476 Oerkki1CAO proto_Oerkki1CAO;
478 Oerkki1CAO::Oerkki1CAO():
479 ClientActiveObject(0),
480 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
482 m_position(v3f(0,10*BS,0)),
484 m_damage_visual_timer(0),
485 m_damage_texture_enabled(false)
487 ClientActiveObject::registerType(getType(), create);
490 Oerkki1CAO::~Oerkki1CAO()
494 ClientActiveObject* Oerkki1CAO::create()
496 return new Oerkki1CAO();
499 void Oerkki1CAO::addToScene(scene::ISceneManager *smgr)
504 video::IVideoDriver* driver = smgr->getVideoDriver();
506 scene::SMesh *mesh = new scene::SMesh();
507 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
508 video::SColor c(255,255,255,255);
509 video::S3DVertex vertices[4] =
511 video::S3DVertex(-BS/2-BS,0,0, 0,0,0, c, 0,1),
512 video::S3DVertex(BS/2+BS,0,0, 0,0,0, c, 1,1),
513 video::S3DVertex(BS/2+BS,BS*2,0, 0,0,0, c, 1,0),
514 video::S3DVertex(-BS/2-BS,BS*2,0, 0,0,0, c, 0,0),
516 u16 indices[] = {0,1,2,2,3,0};
517 buf->append(vertices, 4, indices, 6);
519 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
520 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
521 //buf->getMaterial().setTexture(0, NULL);
522 buf->getMaterial().setTexture
523 (0, driver->getTexture(getTexturePath("oerkki1.png").c_str()));
524 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
525 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
526 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
528 mesh->addMeshBuffer(buf);
530 m_node = smgr->addMeshSceneNode(mesh, NULL);
532 // Set it to use the materials of the meshbuffers directly.
533 // This is needed for changing the texture in the future
534 m_node->setReadOnlyMaterials(true);
538 void Oerkki1CAO::removeFromScene()
547 void Oerkki1CAO::updateLight(u8 light_at_pos)
552 if(light_at_pos <= 2)
554 m_node->setVisible(false);
558 m_node->setVisible(true);
560 u8 li = decode_light(light_at_pos);
561 video::SColor color(255,li,li,li);
562 setMeshVerticesColor(m_node->getMesh(), color);
565 v3s16 Oerkki1CAO::getLightPosition()
567 return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
570 void Oerkki1CAO::updateNodePos()
575 //m_node->setPosition(m_position);
576 m_node->setPosition(pos_translator.vect_show);
578 v3f rot = m_node->getRotation();
579 rot.Y = 180.0 - m_yaw + 90.0;
580 m_node->setRotation(rot);
583 void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
585 pos_translator.translate(dtime);
588 LocalPlayer *player = env->getLocalPlayer();
591 v3f playerpos = player->getPosition();
592 v2f playerpos_2d(playerpos.X,playerpos.Z);
593 v2f objectpos_2d(m_position.X,m_position.Z);
595 if(fabs(m_position.Y - playerpos.Y) < 1.5*BS &&
596 objectpos_2d.getDistanceFrom(playerpos_2d) < 1.5*BS)
598 if(m_attack_interval.step(dtime, 0.5))
600 env->damageLocalPlayer(2);
604 if(m_damage_visual_timer > 0)
606 if(!m_damage_texture_enabled)
608 // Enable damage texture
611 video::IVideoDriver* driver =
612 m_node->getSceneManager()->getVideoDriver();
614 scene::IMesh *mesh = m_node->getMesh();
618 u16 mc = mesh->getMeshBufferCount();
619 for(u16 j=0; j<mc; j++)
621 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
622 buf->getMaterial().setTexture(0, driver->getTexture(
623 getTexturePath("oerkki1_damaged.png").c_str()));
626 m_damage_texture_enabled = true;
628 m_damage_visual_timer -= dtime;
632 if(m_damage_texture_enabled)
634 // Disable damage texture
637 video::IVideoDriver* driver =
638 m_node->getSceneManager()->getVideoDriver();
640 scene::IMesh *mesh = m_node->getMesh();
644 u16 mc = mesh->getMeshBufferCount();
645 for(u16 j=0; j<mc; j++)
647 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
648 buf->getMaterial().setTexture(0, driver->getTexture(
649 getTexturePath("oerkki1.png").c_str()));
652 m_damage_texture_enabled = false;
657 void Oerkki1CAO::processMessage(const std::string &data)
659 //infostream<<"Oerkki1CAO: Got message"<<std::endl;
660 std::istringstream is(data, std::ios::binary);
666 m_position = readV3F1000(is);
667 pos_translator.update(m_position);
669 m_yaw = readF1000(is);
674 //u16 damage = readU8(is);
675 m_damage_visual_timer = 1.0;
679 void Oerkki1CAO::initialize(const std::string &data)
681 //infostream<<"Oerkki1CAO: Got init data"<<std::endl;
684 std::istringstream is(data, std::ios::binary);
686 u8 version = readU8(is);
691 m_position = readV3F1000(is);
692 pos_translator.init(m_position);
698 bool Oerkki1CAO::directReportPunch(const std::string &toolname, v3f dir)
700 m_damage_visual_timer = 1.0;
702 m_position += dir * BS;
703 pos_translator.sharpen();
704 pos_translator.update(m_position);
715 FireflyCAO proto_FireflyCAO;
717 FireflyCAO::FireflyCAO():
718 ClientActiveObject(0),
719 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
721 m_position(v3f(0,10*BS,0)),
724 ClientActiveObject::registerType(getType(), create);
727 FireflyCAO::~FireflyCAO()
731 ClientActiveObject* FireflyCAO::create()
733 return new FireflyCAO();
736 void FireflyCAO::addToScene(scene::ISceneManager *smgr)
741 video::IVideoDriver* driver = smgr->getVideoDriver();
743 scene::SMesh *mesh = new scene::SMesh();
744 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
745 video::SColor c(255,255,255,255);
746 video::S3DVertex vertices[4] =
748 video::S3DVertex(0,0,0, 0,0,0, c, 0,1),
749 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
750 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
751 video::S3DVertex(0,BS/2,0, 0,0,0, c, 0,0),
753 u16 indices[] = {0,1,2,2,3,0};
754 buf->append(vertices, 4, indices, 6);
756 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
757 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
758 //buf->getMaterial().setTexture(0, NULL);
759 buf->getMaterial().setTexture
760 (0, driver->getTexture(getTexturePath("firefly.png").c_str()));
761 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
762 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
763 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
765 mesh->addMeshBuffer(buf);
767 m_node = smgr->addMeshSceneNode(mesh, NULL);
769 // Set it to use the materials of the meshbuffers directly.
770 // This is needed for changing the texture in the future
771 m_node->setReadOnlyMaterials(true);
775 void FireflyCAO::removeFromScene()
784 void FireflyCAO::updateLight(u8 light_at_pos)
790 video::SColor color(255,li,li,li);
791 setMeshVerticesColor(m_node->getMesh(), color);
794 v3s16 FireflyCAO::getLightPosition()
796 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
799 void FireflyCAO::updateNodePos()
804 //m_node->setPosition(m_position);
805 m_node->setPosition(pos_translator.vect_show);
807 v3f rot = m_node->getRotation();
808 rot.Y = 180.0 - m_yaw;
809 m_node->setRotation(rot);
812 void FireflyCAO::step(float dtime, ClientEnvironment *env)
814 pos_translator.translate(dtime);
818 void FireflyCAO::processMessage(const std::string &data)
820 //infostream<<"FireflyCAO: Got message"<<std::endl;
821 std::istringstream is(data, std::ios::binary);
827 m_position = readV3F1000(is);
828 pos_translator.update(m_position);
830 m_yaw = readF1000(is);
835 void FireflyCAO::initialize(const std::string &data)
837 //infostream<<"FireflyCAO: Got init data"<<std::endl;
840 std::istringstream is(data, std::ios::binary);
842 u8 version = readU8(is);
847 m_position = readV3F1000(is);
848 pos_translator.init(m_position);
859 MobV2CAO proto_MobV2CAO;
861 MobV2CAO::MobV2CAO():
862 ClientActiveObject(0),
863 m_selection_box(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS),
865 m_position(v3f(0,10*BS,0)),
868 m_walking_unset_timer(0),
871 m_damage_visual_timer(0),
874 m_shooting_unset_timer(0),
875 m_sprite_size(BS,BS),
877 m_bright_shooting(false),
878 m_lock_full_brightness(false),
879 m_player_hit_timer(0)
881 ClientActiveObject::registerType(getType(), create);
883 m_properties = new Settings;
886 MobV2CAO::~MobV2CAO()
891 ClientActiveObject* MobV2CAO::create()
893 return new MobV2CAO();
896 void MobV2CAO::addToScene(scene::ISceneManager *smgr)
901 /*infostream<<"MobV2CAO::addToScene using texture_name="<<
902 m_texture_name<<std::endl;*/
903 std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
904 texture_string += m_texture_name;
906 scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
907 smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
908 bill->setMaterialTexture(0, g_texturesource->getTextureRaw(texture_string));
909 bill->setMaterialFlag(video::EMF_LIGHTING, false);
910 bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
911 bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
912 bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
913 bill->setColor(video::SColor(255,0,0,0));
914 bill->setVisible(false); /* Set visible when brightness is known */
915 bill->setSize(m_sprite_size);
916 if(m_sprite_type == "humanoid_1"){
917 const float txp = 1./192;
918 const float txs = txp*32;
919 const float typ = 1./240;
920 const float tys = typ*48;
921 bill->setTCoords(0, v2f(txs*1, tys*1));
922 bill->setTCoords(1, v2f(txs*1, tys*0));
923 bill->setTCoords(2, v2f(txs*0, tys*0));
924 bill->setTCoords(3, v2f(txs*0, tys*1));
925 } else if(m_sprite_type == "simple"){
926 const float txs = 1.0;
927 const float tys = 1.0 / m_simple_anim_frames;
928 bill->setTCoords(0, v2f(txs*1, tys*1));
929 bill->setTCoords(1, v2f(txs*1, tys*0));
930 bill->setTCoords(2, v2f(txs*0, tys*0));
931 bill->setTCoords(3, v2f(txs*0, tys*1));
933 infostream<<"MobV2CAO: Unknown sprite type \""<<m_sprite_type<<"\""
942 void MobV2CAO::removeFromScene()
952 void MobV2CAO::updateLight(u8 light_at_pos)
954 if(m_lock_full_brightness)
957 m_last_light = light_at_pos;
962 if(m_damage_visual_timer > 0)
965 if(m_shooting && m_bright_shooting)
968 /*if(light_at_pos <= 2){
969 m_node->setVisible(false);
973 m_node->setVisible(true);
975 u8 li = decode_light(light_at_pos);
976 video::SColor color(255,li,li,li);
977 m_node->setColor(color);
980 v3s16 MobV2CAO::getLightPosition()
982 return floatToInt(m_position+v3f(0,0,0), BS);
985 void MobV2CAO::updateNodePos()
990 m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
993 void MobV2CAO::step(float dtime, ClientEnvironment *env)
995 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();
1005 v3f cam_to_mob = m_node->getAbsolutePosition() - camera->getAbsolutePosition();
1006 cam_to_mob.normalize();
1008 if(cam_to_mob.Y > 0.75)
1010 else if(cam_to_mob.Y < -0.75)
1013 float mob_dir = atan2(cam_to_mob.Z, cam_to_mob.X) / PI * 180.;
1014 float dir = mob_dir - m_yaw;
1015 dir = wrapDegrees_180(dir);
1016 //infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;
1017 if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
1019 else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
1021 else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
1023 else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
1032 } else if(m_walking){
1033 m_walk_timer += dtime;
1034 if(m_walk_timer >= 0.5){
1035 m_walk_frame = (m_walk_frame + 1) % 2;
1038 if(m_walk_frame == 0)
1044 const float txp = 1./192;
1045 const float txs = txp*32;
1046 const float typ = 1./240;
1047 const float tys = typ*48;
1048 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1049 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1050 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1051 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1052 } else if(m_sprite_type == "simple"){
1053 m_walk_timer += dtime;
1054 if(m_walk_timer >= m_simple_anim_frametime){
1055 m_walk_frame = (m_walk_frame + 1) % m_simple_anim_frames;
1059 int row = m_walk_frame;
1060 const float txs = 1.0;
1061 const float tys = 1.0 / m_simple_anim_frames;
1062 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1063 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1064 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1065 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1067 infostream<<"MobV2CAO::step(): Unknown sprite type \""
1068 <<m_sprite_type<<"\""<<std::endl;
1073 /* Damage local player */
1074 if(m_player_hit_damage && m_player_hit_timer <= 0.0){
1075 LocalPlayer *player = env->getLocalPlayer();
1078 v3f playerpos = player->getPosition();
1079 v2f playerpos_2d(playerpos.X,playerpos.Z);
1080 v2f objectpos_2d(m_position.X,m_position.Z);
1082 if(fabs(m_position.Y - playerpos.Y) < m_player_hit_distance*BS &&
1083 objectpos_2d.getDistanceFrom(playerpos_2d) < m_player_hit_distance*BS)
1085 env->damageLocalPlayer(m_player_hit_damage);
1086 m_player_hit_timer = m_player_hit_interval;
1092 m_player_hit_timer -= dtime;
1094 if(m_damage_visual_timer >= 0){
1095 m_damage_visual_timer -= dtime;
1096 if(m_damage_visual_timer <= 0){
1097 infostream<<"id="<<m_id<<" damage visual ended"<<std::endl;
1101 m_walking_unset_timer += dtime;
1102 if(m_walking_unset_timer >= 1.0){
1106 m_shooting_unset_timer -= dtime;
1107 if(m_shooting_unset_timer <= 0.0){
1108 if(m_bright_shooting){
1109 u8 li = decode_light(m_last_light);
1110 video::SColor color(255,li,li,li);
1111 bill->setColor(color);
1112 m_bright_shooting = false;
1119 void MobV2CAO::processMessage(const std::string &data)
1121 //infostream<<"MobV2CAO: Got message"<<std::endl;
1122 std::istringstream is(data, std::ios::binary);
1124 u8 cmd = readU8(is);
1130 m_position = readV3F1000(is);
1131 pos_translator.update(m_position);
1133 m_yaw = readF1000(is);
1136 m_walking_unset_timer = 0;
1143 //u16 damage = readU16(is);
1145 /*u8 li = decode_light(m_last_light);
1151 /*video::SColor color(255,255,0,0);
1152 m_node->setColor(color);
1154 m_damage_visual_timer = 0.2;*/
1160 m_shooting_unset_timer = readF1000(is);
1162 m_bright_shooting = readU8(is);
1163 if(m_bright_shooting){
1165 video::SColor color(255,li,li,li);
1166 m_node->setColor(color);
1173 void MobV2CAO::initialize(const std::string &data)
1175 //infostream<<"MobV2CAO: Got init data"<<std::endl;
1178 std::istringstream is(data, std::ios::binary);
1180 u8 version = readU8(is);
1183 infostream<<__FUNCTION_NAME<<": Invalid version"<<std::endl;
1187 std::ostringstream tmp_os(std::ios::binary);
1188 decompressZlib(is, tmp_os);
1189 std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
1190 m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
1192 infostream<<"MobV2CAO::initialize(): got properties:"<<std::endl;
1193 m_properties->writeLines(infostream);
1195 m_properties->setDefault("looks", "dummy_default");
1196 m_properties->setDefault("yaw", "0");
1197 m_properties->setDefault("pos", "(0,0,0)");
1198 m_properties->setDefault("player_hit_damage", "0");
1199 m_properties->setDefault("player_hit_distance", "1.5");
1200 m_properties->setDefault("player_hit_interval", "1.5");
1202 setLooks(m_properties->get("looks"));
1203 m_yaw = m_properties->getFloat("yaw");
1204 m_position = m_properties->getV3F("pos");
1205 m_player_hit_damage = m_properties->getS32("player_hit_damage");
1206 m_player_hit_distance = m_properties->getFloat("player_hit_distance");
1207 m_player_hit_interval = m_properties->getFloat("player_hit_interval");
1209 pos_translator.init(m_position);
1215 bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
1217 video::SColor color(255,255,0,0);
1218 m_node->setColor(color);
1220 m_damage_visual_timer = 0.05;
1222 m_position += dir * BS;
1223 pos_translator.sharpen();
1224 pos_translator.update(m_position);
1230 void MobV2CAO::setLooks(const std::string &looks)
1232 v2f selection_size = v2f(0.4, 0.4) * BS;
1233 float selection_y = 0 * BS;
1235 if(looks == "dungeon_master"){
1236 m_texture_name = "dungeon_master.png";
1237 m_sprite_type = "humanoid_1";
1238 m_sprite_size = v2f(2, 3) * BS;
1239 m_sprite_y = 0.85 * BS;
1240 selection_size = v2f(0.4, 2.6) * BS;
1241 selection_y = -0.4 * BS;
1243 else if(looks == "fireball"){
1244 m_texture_name = "fireball.png";
1245 m_sprite_type = "simple";
1246 m_sprite_size = v2f(1, 1) * BS;
1247 m_simple_anim_frames = 3;
1248 m_simple_anim_frametime = 0.1;
1249 m_lock_full_brightness = true;
1252 m_texture_name = "stone.png";
1253 m_sprite_type = "simple";
1254 m_sprite_size = v2f(1, 1) * BS;
1255 m_simple_anim_frames = 3;
1256 m_simple_anim_frametime = 0.333;
1257 selection_size = v2f(0.4, 0.4) * BS;
1258 selection_y = 0 * BS;
1261 m_selection_box = core::aabbox3d<f32>(
1262 -selection_size.X, selection_y, -selection_size.X,
1263 selection_size.X, selection_y+selection_size.Y,