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) < 1.5*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);
712 bool Oerkki1CAO::directReportPunch(const std::string &toolname, v3f dir)
714 m_damage_visual_timer = 1.0;
716 m_position += dir * BS;
717 pos_translator.sharpen();
718 pos_translator.update(m_position);
729 FireflyCAO proto_FireflyCAO;
731 FireflyCAO::FireflyCAO():
732 ClientActiveObject(0),
733 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
735 m_position(v3f(0,10*BS,0)),
738 ClientActiveObject::registerType(getType(), create);
741 FireflyCAO::~FireflyCAO()
745 ClientActiveObject* FireflyCAO::create()
747 return new FireflyCAO();
750 void FireflyCAO::addToScene(scene::ISceneManager *smgr)
755 video::IVideoDriver* driver = smgr->getVideoDriver();
757 scene::SMesh *mesh = new scene::SMesh();
758 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
759 video::SColor c(255,255,255,255);
760 video::S3DVertex vertices[4] =
762 video::S3DVertex(0,0,0, 0,0,0, c, 0,1),
763 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
764 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
765 video::S3DVertex(0,BS/2,0, 0,0,0, c, 0,0),
767 u16 indices[] = {0,1,2,2,3,0};
768 buf->append(vertices, 4, indices, 6);
770 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
771 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
772 //buf->getMaterial().setTexture(0, NULL);
773 buf->getMaterial().setTexture
774 (0, driver->getTexture(getTexturePath("firefly.png").c_str()));
775 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
776 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
777 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
779 mesh->addMeshBuffer(buf);
781 m_node = smgr->addMeshSceneNode(mesh, NULL);
783 // Set it to use the materials of the meshbuffers directly.
784 // This is needed for changing the texture in the future
785 m_node->setReadOnlyMaterials(true);
789 void FireflyCAO::removeFromScene()
798 void FireflyCAO::updateLight(u8 light_at_pos)
804 video::SColor color(255,li,li,li);
805 setMeshVerticesColor(m_node->getMesh(), color);
808 v3s16 FireflyCAO::getLightPosition()
810 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
813 void FireflyCAO::updateNodePos()
818 //m_node->setPosition(m_position);
819 m_node->setPosition(pos_translator.vect_show);
821 v3f rot = m_node->getRotation();
822 rot.Y = 180.0 - m_yaw;
823 m_node->setRotation(rot);
826 void FireflyCAO::step(float dtime, ClientEnvironment *env)
828 pos_translator.translate(dtime);
832 void FireflyCAO::processMessage(const std::string &data)
834 //dstream<<"FireflyCAO: Got message"<<std::endl;
835 std::istringstream is(data, std::ios::binary);
841 m_position = readV3F1000(is);
842 pos_translator.update(m_position);
844 m_yaw = readF1000(is);
849 void FireflyCAO::initialize(const std::string &data)
851 //dstream<<"FireflyCAO: Got init data"<<std::endl;
854 std::istringstream is(data, std::ios::binary);
856 u8 version = readU8(is);
861 m_position = readV3F1000(is);
862 pos_translator.init(m_position);
873 MobV2CAO proto_MobV2CAO;
875 MobV2CAO::MobV2CAO():
876 ClientActiveObject(0),
877 m_selection_box(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS),
879 m_position(v3f(0,10*BS,0)),
882 m_walking_unset_timer(0),
885 m_damage_visual_timer(0),
888 m_shooting_unset_timer(0),
889 m_sprite_size(BS,BS),
891 m_bright_shooting(false),
892 m_lock_full_brightness(false),
893 m_player_hit_timer(0)
895 ClientActiveObject::registerType(getType(), create);
897 m_properties = new Settings;
900 MobV2CAO::~MobV2CAO()
905 ClientActiveObject* MobV2CAO::create()
907 return new MobV2CAO();
910 void MobV2CAO::addToScene(scene::ISceneManager *smgr)
915 /*dstream<<"MobV2CAO::addToScene using texture_name="<<
916 m_texture_name<<std::endl;*/
917 std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
918 texture_string += m_texture_name;
920 scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
921 smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
922 bill->setMaterialTexture(0, g_texturesource->getTextureRaw(texture_string));
923 bill->setMaterialFlag(video::EMF_LIGHTING, false);
924 bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
925 bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
926 bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
927 bill->setColor(video::SColor(255,0,0,0));
928 bill->setVisible(false); /* Set visible when brightness is known */
929 bill->setSize(m_sprite_size);
930 if(m_sprite_type == "humanoid_1"){
931 const float txp = 1./192;
932 const float txs = txp*32;
933 const float typ = 1./240;
934 const float tys = typ*48;
935 bill->setTCoords(0, v2f(txs*1, tys*1));
936 bill->setTCoords(1, v2f(txs*1, tys*0));
937 bill->setTCoords(2, v2f(txs*0, tys*0));
938 bill->setTCoords(3, v2f(txs*0, tys*1));
939 } else if(m_sprite_type == "simple"){
940 const float txs = 1.0;
941 const float tys = 1.0 / m_simple_anim_frames;
942 bill->setTCoords(0, v2f(txs*1, tys*1));
943 bill->setTCoords(1, v2f(txs*1, tys*0));
944 bill->setTCoords(2, v2f(txs*0, tys*0));
945 bill->setTCoords(3, v2f(txs*0, tys*1));
947 dstream<<"MobV2CAO: Unknown sprite type \""<<m_sprite_type<<"\""
956 void MobV2CAO::removeFromScene()
966 void MobV2CAO::updateLight(u8 light_at_pos)
968 if(m_lock_full_brightness)
971 m_last_light = light_at_pos;
976 if(m_damage_visual_timer > 0)
979 if(m_shooting && m_bright_shooting)
982 /*if(light_at_pos <= 2){
983 m_node->setVisible(false);
987 m_node->setVisible(true);
989 u8 li = decode_light(light_at_pos);
990 video::SColor color(255,li,li,li);
991 m_node->setColor(color);
994 v3s16 MobV2CAO::getLightPosition()
996 return floatToInt(m_position+v3f(0,0,0), BS);
999 void MobV2CAO::updateNodePos()
1004 m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
1007 void MobV2CAO::step(float dtime, ClientEnvironment *env)
1009 scene::MyBillboardSceneNode *bill = m_node;
1011 pos_translator.translate(dtime);
1013 if(m_sprite_type == "humanoid_1"){
1014 scene::ICameraSceneNode* camera = m_node->getSceneManager()->getActiveCamera();
1015 v3f cam_to_mob = m_node->getAbsolutePosition() - camera->getAbsolutePosition();
1016 cam_to_mob.normalize();
1018 if(cam_to_mob.Y > 0.75)
1020 else if(cam_to_mob.Y < -0.75)
1023 float mob_dir = atan2(cam_to_mob.Z, cam_to_mob.X) / M_PI * 180.;
1024 float dir = mob_dir - m_yaw;
1025 dir = wrapDegrees_180(dir);
1026 //dstream<<"id="<<m_id<<" dir="<<dir<<std::endl;
1027 if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
1029 else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
1031 else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
1033 else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
1042 } else if(m_walking){
1043 m_walk_timer += dtime;
1044 if(m_walk_timer >= 0.5){
1045 m_walk_frame = (m_walk_frame + 1) % 2;
1048 if(m_walk_frame == 0)
1054 const float txp = 1./192;
1055 const float txs = txp*32;
1056 const float typ = 1./240;
1057 const float tys = typ*48;
1058 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1059 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1060 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1061 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1062 } else if(m_sprite_type == "simple"){
1063 m_walk_timer += dtime;
1064 if(m_walk_timer >= m_simple_anim_frametime){
1065 m_walk_frame = (m_walk_frame + 1) % m_simple_anim_frames;
1069 int row = m_walk_frame;
1070 const float txs = 1.0;
1071 const float tys = 1.0 / m_simple_anim_frames;
1072 bill->setTCoords(0, v2f(txs*(1+col), tys*(1+row)));
1073 bill->setTCoords(1, v2f(txs*(1+col), tys*(0+row)));
1074 bill->setTCoords(2, v2f(txs*(0+col), tys*(0+row)));
1075 bill->setTCoords(3, v2f(txs*(0+col), tys*(1+row)));
1077 dstream<<"MobV2CAO::step(): Unknown sprite type \""
1078 <<m_sprite_type<<"\""<<std::endl;
1083 /* Damage local player */
1084 if(m_player_hit_damage && m_player_hit_timer <= 0.0){
1085 LocalPlayer *player = env->getLocalPlayer();
1088 v3f playerpos = player->getPosition();
1089 v2f playerpos_2d(playerpos.X,playerpos.Z);
1090 v2f objectpos_2d(m_position.X,m_position.Z);
1092 if(fabs(m_position.Y - playerpos.Y) < m_player_hit_distance*BS &&
1093 objectpos_2d.getDistanceFrom(playerpos_2d) < m_player_hit_distance*BS)
1095 env->damageLocalPlayer(m_player_hit_damage);
1096 m_player_hit_timer = m_player_hit_interval;
1102 m_player_hit_timer -= dtime;
1104 if(m_damage_visual_timer >= 0){
1105 m_damage_visual_timer -= dtime;
1106 if(m_damage_visual_timer <= 0){
1107 dstream<<"id="<<m_id<<" damage visual ended"<<std::endl;
1111 m_walking_unset_timer += dtime;
1112 if(m_walking_unset_timer >= 1.0){
1116 m_shooting_unset_timer -= dtime;
1117 if(m_shooting_unset_timer <= 0.0){
1118 if(m_bright_shooting){
1119 u8 li = decode_light(m_last_light);
1120 video::SColor color(255,li,li,li);
1121 bill->setColor(color);
1122 m_bright_shooting = false;
1129 void MobV2CAO::processMessage(const std::string &data)
1131 //dstream<<"MobV2CAO: Got message"<<std::endl;
1132 std::istringstream is(data, std::ios::binary);
1134 u8 cmd = readU8(is);
1140 m_position = readV3F1000(is);
1141 pos_translator.update(m_position);
1143 m_yaw = readF1000(is);
1146 m_walking_unset_timer = 0;
1153 //u16 damage = readU16(is);
1155 /*u8 li = decode_light(m_last_light);
1161 /*video::SColor color(255,255,0,0);
1162 m_node->setColor(color);
1164 m_damage_visual_timer = 0.2;*/
1170 m_shooting_unset_timer = readF1000(is);
1172 m_bright_shooting = readU8(is);
1173 if(m_bright_shooting){
1175 video::SColor color(255,li,li,li);
1176 m_node->setColor(color);
1183 void MobV2CAO::initialize(const std::string &data)
1185 //dstream<<"MobV2CAO: Got init data"<<std::endl;
1188 std::istringstream is(data, std::ios::binary);
1190 u8 version = readU8(is);
1193 dstream<<__FUNCTION_NAME<<": Invalid version"<<std::endl;
1197 std::ostringstream tmp_os(std::ios::binary);
1198 decompressZlib(is, tmp_os);
1199 std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
1200 m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
1202 dstream<<"INFO: MobV2CAO::initialize(): got properties:"<<std::endl;
1203 m_properties->writeLines(dstream);
1205 m_properties->setDefault("looks", "dummy_default");
1206 m_properties->setDefault("yaw", "0");
1207 m_properties->setDefault("pos", "(0,0,0)");
1208 m_properties->setDefault("player_hit_damage", "0");
1209 m_properties->setDefault("player_hit_distance", "1.5");
1210 m_properties->setDefault("player_hit_interval", "1.5");
1212 setLooks(m_properties->get("looks"));
1213 m_yaw = m_properties->getFloat("yaw");
1214 m_position = m_properties->getV3F("pos");
1215 m_player_hit_damage = m_properties->getS32("player_hit_damage");
1216 m_player_hit_distance = m_properties->getFloat("player_hit_distance");
1217 m_player_hit_interval = m_properties->getFloat("player_hit_interval");
1219 pos_translator.init(m_position);
1225 bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
1227 video::SColor color(255,255,0,0);
1228 m_node->setColor(color);
1230 m_damage_visual_timer = 0.05;
1232 m_position += dir * BS;
1233 pos_translator.sharpen();
1234 pos_translator.update(m_position);
1240 void MobV2CAO::setLooks(const std::string &looks)
1242 v2f selection_size = v2f(0.4, 0.4) * BS;
1243 float selection_y = 0 * BS;
1245 if(looks == "dungeon_master"){
1246 m_texture_name = "dungeon_master.png";
1247 m_sprite_type = "humanoid_1";
1248 m_sprite_size = v2f(2, 3) * BS;
1249 m_sprite_y = 0.85 * BS;
1250 selection_size = v2f(0.4, 2.6) * BS;
1251 selection_y = -0.4 * BS;
1253 else if(looks == "fireball"){
1254 m_texture_name = "fireball.png";
1255 m_sprite_type = "simple";
1256 m_sprite_size = v2f(1, 1) * BS;
1257 m_simple_anim_frames = 3;
1258 m_simple_anim_frametime = 0.1;
1259 m_lock_full_brightness = true;
1262 m_texture_name = "stone.png";
1263 m_sprite_type = "simple";
1264 m_sprite_size = v2f(1, 1) * BS;
1265 m_simple_anim_frames = 3;
1266 m_simple_anim_frametime = 0.333;
1267 selection_size = v2f(0.4, 0.4) * BS;
1268 selection_y = 0 * BS;
1271 m_selection_box = core::aabbox3d<f32>(
1272 -selection_size.X, selection_y, -selection_size.X,
1273 selection_size.X, selection_y+selection_size.Y,