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"
23 #include "collision.h"
25 #include <ICameraSceneNode.h>
26 #include <ITextSceneNode.h>
27 #include <IBillboardSceneNode.h>
28 #include "serialization.h" // For decompressZlib
30 #include "clientobject.h"
31 #include "content_object.h"
33 #include "utility.h" // For IntervalLimiter
36 core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
42 struct SmoothTranslator
49 f32 anim_time_counter;
69 anim_time_counter = 0;
78 void update(v3f vect_new, bool is_end_position=false, float update_interval=-1)
80 aim_is_end = is_end_position;
83 if(update_interval > 0){
84 anim_time = update_interval;
86 if(anim_time < 0.001 || anim_time > 1.0)
87 anim_time = anim_time_counter;
89 anim_time = anim_time * 0.9 + anim_time_counter * 0.1;
91 anim_time_counter = 0;
95 void translate(f32 dtime)
97 anim_time_counter = anim_time_counter + dtime;
98 anim_counter = anim_counter + dtime;
99 v3f vect_move = vect_aim - vect_old;
101 if(anim_time > 0.001)
102 moveratio = anim_time_counter / anim_time;
103 // Move a bit less than should, to avoid oscillation
104 moveratio = moveratio * 0.8;
105 float move_end = 1.5;
108 if(moveratio > move_end)
109 moveratio = move_end;
110 vect_show = vect_old + vect_move * moveratio;
115 return ((anim_time_counter / anim_time) < 1.4);
124 class TestCAO : public ClientActiveObject
127 TestCAO(IGameDef *gamedef, ClientEnvironment *env);
132 return ACTIVEOBJECT_TYPE_TEST;
135 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env);
137 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
138 IrrlichtDevice *irr);
139 void removeFromScene();
140 void updateLight(u8 light_at_pos);
141 v3s16 getLightPosition();
142 void updateNodePos();
144 void step(float dtime, ClientEnvironment *env);
146 void processMessage(const std::string &data);
149 scene::IMeshSceneNode *m_node;
157 class ItemCAO : public ClientActiveObject
160 ItemCAO(IGameDef *gamedef, ClientEnvironment *env);
165 return ACTIVEOBJECT_TYPE_ITEM;
168 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env);
170 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
171 IrrlichtDevice *irr);
172 void removeFromScene();
173 void updateLight(u8 light_at_pos);
174 v3s16 getLightPosition();
175 void updateNodePos();
176 void updateInfoText();
177 void updateTexture();
179 void step(float dtime, ClientEnvironment *env);
181 void processMessage(const std::string &data);
183 void initialize(const std::string &data);
185 core::aabbox3d<f32>* getSelectionBox()
186 {return &m_selection_box;}
190 std::string infoText()
194 core::aabbox3d<f32> m_selection_box;
195 scene::IMeshSceneNode *m_node;
197 std::string m_itemstring;
198 std::string m_infotext;
205 class RatCAO : public ClientActiveObject
208 RatCAO(IGameDef *gamedef, ClientEnvironment *env);
213 return ACTIVEOBJECT_TYPE_RAT;
216 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env);
218 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
219 IrrlichtDevice *irr);
220 void removeFromScene();
221 void updateLight(u8 light_at_pos);
222 v3s16 getLightPosition();
223 void updateNodePos();
225 void step(float dtime, ClientEnvironment *env);
227 void processMessage(const std::string &data);
229 void initialize(const std::string &data);
231 core::aabbox3d<f32>* getSelectionBox()
232 {return &m_selection_box;}
234 {return pos_translator.vect_show;}
235 //{return m_position;}
238 core::aabbox3d<f32> m_selection_box;
239 scene::IMeshSceneNode *m_node;
242 SmoothTranslator pos_translator;
249 class Oerkki1CAO : public ClientActiveObject
252 Oerkki1CAO(IGameDef *gamedef, ClientEnvironment *env);
253 virtual ~Oerkki1CAO();
257 return ACTIVEOBJECT_TYPE_OERKKI1;
260 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env);
262 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
263 IrrlichtDevice *irr);
264 void removeFromScene();
265 void updateLight(u8 light_at_pos);
266 v3s16 getLightPosition();
267 void updateNodePos();
269 void step(float dtime, ClientEnvironment *env);
271 void processMessage(const std::string &data);
273 void initialize(const std::string &data);
275 core::aabbox3d<f32>* getSelectionBox()
276 {return &m_selection_box;}
278 {return pos_translator.vect_show;}
279 //{return m_position;}
281 // If returns true, punch will not be sent to the server
282 bool directReportPunch(const std::string &toolname, v3f dir);
285 IntervalLimiter m_attack_interval;
286 core::aabbox3d<f32> m_selection_box;
287 scene::IMeshSceneNode *m_node;
290 SmoothTranslator pos_translator;
291 float m_damage_visual_timer;
292 bool m_damage_texture_enabled;
299 class FireflyCAO : public ClientActiveObject
302 FireflyCAO(IGameDef *gamedef, ClientEnvironment *env);
303 virtual ~FireflyCAO();
307 return ACTIVEOBJECT_TYPE_FIREFLY;
310 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env);
312 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
313 IrrlichtDevice *irr);
314 void removeFromScene();
315 void updateLight(u8 light_at_pos);
316 v3s16 getLightPosition();
317 void updateNodePos();
319 void step(float dtime, ClientEnvironment *env);
321 void processMessage(const std::string &data);
323 void initialize(const std::string &data);
325 core::aabbox3d<f32>* getSelectionBox()
326 {return &m_selection_box;}
331 core::aabbox3d<f32> m_selection_box;
332 scene::IMeshSceneNode *m_node;
335 SmoothTranslator pos_translator;
338 static void setBillboardTextureMatrix(scene::IBillboardSceneNode *bill,
339 float txs, float tys, int col, int row)
341 video::SMaterial& material = bill->getMaterial(0);
342 core::matrix4& matrix = material.getTextureMatrix(0);
343 matrix.setTextureTranslate(txs*col, tys*row);
344 matrix.setTextureScale(txs, tys);
351 class MobV2CAO : public ClientActiveObject
354 MobV2CAO(IGameDef *gamedef, ClientEnvironment *env);
359 return ACTIVEOBJECT_TYPE_MOBV2;
362 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env);
364 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
365 IrrlichtDevice *irr);
366 void removeFromScene();
367 void updateLight(u8 light_at_pos);
368 v3s16 getLightPosition();
369 void updateNodePos();
371 void step(float dtime, ClientEnvironment *env);
373 void processMessage(const std::string &data);
375 void initialize(const std::string &data);
377 core::aabbox3d<f32>* getSelectionBox()
378 {return &m_selection_box;}
380 {return pos_translator.vect_show;}
381 //{return m_position;}
382 bool doShowSelectionBox(){return false;}
384 // If returns true, punch will not be sent to the server
385 bool directReportPunch(const std::string &toolname, v3f dir);
388 void setLooks(const std::string &looks);
390 IntervalLimiter m_attack_interval;
391 core::aabbox3d<f32> m_selection_box;
392 scene::IBillboardSceneNode *m_node;
394 std::string m_texture_name;
396 SmoothTranslator pos_translator;
398 float m_walking_unset_timer;
401 float m_damage_visual_timer;
404 float m_shooting_unset_timer;
407 bool m_bright_shooting;
408 std::string m_sprite_type;
409 int m_simple_anim_frames;
410 float m_simple_anim_frametime;
411 bool m_lock_full_brightness;
412 int m_player_hit_damage;
413 float m_player_hit_distance;
414 float m_player_hit_interval;
415 float m_player_hit_timer;
417 Settings *m_properties;
425 TestCAO proto_TestCAO(NULL, NULL);
427 TestCAO::TestCAO(IGameDef *gamedef, ClientEnvironment *env):
428 ClientActiveObject(0, gamedef, env),
430 m_position(v3f(0,10*BS,0))
432 ClientActiveObject::registerType(getType(), create);
439 ClientActiveObject* TestCAO::create(IGameDef *gamedef, ClientEnvironment *env)
441 return new TestCAO(gamedef, env);
444 void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
450 //video::IVideoDriver* driver = smgr->getVideoDriver();
452 scene::SMesh *mesh = new scene::SMesh();
453 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
454 video::SColor c(255,255,255,255);
455 video::S3DVertex vertices[4] =
457 video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
458 video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
459 video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
460 video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),
462 u16 indices[] = {0,1,2,2,3,0};
463 buf->append(vertices, 4, indices, 6);
465 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
466 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
467 buf->getMaterial().setTexture(0, tsrc->getTextureRaw("rat.png"));
468 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
469 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
470 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
472 mesh->addMeshBuffer(buf);
474 m_node = smgr->addMeshSceneNode(mesh, NULL);
479 void TestCAO::removeFromScene()
488 void TestCAO::updateLight(u8 light_at_pos)
492 v3s16 TestCAO::getLightPosition()
494 return floatToInt(m_position, BS);
497 void TestCAO::updateNodePos()
502 m_node->setPosition(m_position);
503 //m_node->setRotation(v3f(0, 45, 0));
506 void TestCAO::step(float dtime, ClientEnvironment *env)
510 v3f rot = m_node->getRotation();
511 //infostream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
512 rot.Y += dtime * 180;
513 m_node->setRotation(rot);
517 void TestCAO::processMessage(const std::string &data)
519 infostream<<"TestCAO: Got data: "<<data<<std::endl;
520 std::istringstream is(data, std::ios::binary);
538 #include "inventory.h"
541 ItemCAO proto_ItemCAO(NULL, NULL);
543 ItemCAO::ItemCAO(IGameDef *gamedef, ClientEnvironment *env):
544 ClientActiveObject(0, gamedef, env),
545 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
547 m_position(v3f(0,10*BS,0))
551 ClientActiveObject::registerType(getType(), create);
559 ClientActiveObject* ItemCAO::create(IGameDef *gamedef, ClientEnvironment *env)
561 return new ItemCAO(gamedef, env);
564 void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
570 //video::IVideoDriver* driver = smgr->getVideoDriver();
572 scene::SMesh *mesh = new scene::SMesh();
573 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
574 video::SColor c(255,255,255,255);
575 video::S3DVertex vertices[4] =
577 /*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
578 video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
579 video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
580 video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
581 video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
582 video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
583 video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
584 video::S3DVertex(BS/3.,0+BS*2./3.,0, 0,0,0, c, 0,0),
586 u16 indices[] = {0,1,2,2,3,0};
587 buf->append(vertices, 4, indices, 6);
589 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
590 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
591 // Initialize with a generated placeholder texture
592 buf->getMaterial().setTexture(0, tsrc->getTextureRaw(""));
593 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
594 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
595 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
597 mesh->addMeshBuffer(buf);
599 m_node = smgr->addMeshSceneNode(mesh, NULL);
610 void ItemCAO::removeFromScene()
619 void ItemCAO::updateLight(u8 light_at_pos)
624 u8 li = decode_light(light_at_pos);
625 video::SColor color(255,li,li,li);
626 setMeshColor(m_node->getMesh(), color);
629 v3s16 ItemCAO::getLightPosition()
631 return floatToInt(m_position, BS);
634 void ItemCAO::updateNodePos()
639 m_node->setPosition(m_position);
642 void ItemCAO::updateInfoText()
645 IItemDefManager *idef = m_gamedef->idef();
647 item.deSerialize(m_itemstring, idef);
648 if(item.isKnown(idef))
649 m_infotext = item.getDefinition(idef).description;
651 m_infotext = "Unknown item: '" + m_itemstring + "'";
653 m_infotext += " (" + itos(item.count) + ")";
655 catch(SerializationError &e)
657 m_infotext = "Unknown item: '" + m_itemstring + "'";
661 void ItemCAO::updateTexture()
666 // Create an inventory item to see what is its image
667 std::istringstream is(m_itemstring, std::ios_base::binary);
668 video::ITexture *texture = NULL;
670 IItemDefManager *idef = m_gamedef->idef();
672 item.deSerialize(is, idef);
673 texture = item.getDefinition(idef).inventory_texture;
675 catch(SerializationError &e)
677 infostream<<"WARNING: "<<__FUNCTION_NAME
678 <<": error deSerializing itemstring \""
679 <<m_itemstring<<std::endl;
682 // Set meshbuffer texture
683 m_node->getMaterial(0).setTexture(0, texture);
687 void ItemCAO::step(float dtime, ClientEnvironment *env)
691 /*v3f rot = m_node->getRotation();
692 rot.Y += dtime * 120;
693 m_node->setRotation(rot);*/
694 LocalPlayer *player = env->getLocalPlayer();
696 v3f rot = m_node->getRotation();
697 rot.Y = 180.0 - (player->getYaw());
698 m_node->setRotation(rot);
702 void ItemCAO::processMessage(const std::string &data)
704 //infostream<<"ItemCAO: Got message"<<std::endl;
705 std::istringstream is(data, std::ios::binary);
711 m_position = readV3F1000(is);
717 m_itemstring = deSerializeString(is);
723 void ItemCAO::initialize(const std::string &data)
725 infostream<<"ItemCAO: Got init data"<<std::endl;
728 std::istringstream is(data, std::ios::binary);
730 u8 version = readU8(is);
735 m_position = readV3F1000(is);
737 m_itemstring = deSerializeString(is);
748 #include "inventory.h"
751 RatCAO proto_RatCAO(NULL, NULL);
753 RatCAO::RatCAO(IGameDef *gamedef, ClientEnvironment *env):
754 ClientActiveObject(0, gamedef, env),
755 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
757 m_position(v3f(0,10*BS,0)),
760 ClientActiveObject::registerType(getType(), create);
767 ClientActiveObject* RatCAO::create(IGameDef *gamedef, ClientEnvironment *env)
769 return new RatCAO(gamedef, env);
772 void RatCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
778 //video::IVideoDriver* driver = smgr->getVideoDriver();
780 scene::SMesh *mesh = new scene::SMesh();
781 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
782 video::SColor c(255,255,255,255);
783 video::S3DVertex vertices[4] =
785 video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
786 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
787 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
788 video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
790 u16 indices[] = {0,1,2,2,3,0};
791 buf->append(vertices, 4, indices, 6);
793 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
794 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
795 //buf->getMaterial().setTexture(0, NULL);
796 buf->getMaterial().setTexture(0, tsrc->getTextureRaw("rat.png"));
797 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
798 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
799 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
801 mesh->addMeshBuffer(buf);
803 m_node = smgr->addMeshSceneNode(mesh, NULL);
805 // Set it to use the materials of the meshbuffers directly.
806 // This is needed for changing the texture in the future
807 m_node->setReadOnlyMaterials(true);
811 void RatCAO::removeFromScene()
820 void RatCAO::updateLight(u8 light_at_pos)
825 u8 li = decode_light(light_at_pos);
826 video::SColor color(255,li,li,li);
827 setMeshColor(m_node->getMesh(), color);
830 v3s16 RatCAO::getLightPosition()
832 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
835 void RatCAO::updateNodePos()
840 //m_node->setPosition(m_position);
841 m_node->setPosition(pos_translator.vect_show);
843 v3f rot = m_node->getRotation();
844 rot.Y = 180.0 - m_yaw;
845 m_node->setRotation(rot);
848 void RatCAO::step(float dtime, ClientEnvironment *env)
850 pos_translator.translate(dtime);
854 void RatCAO::processMessage(const std::string &data)
856 //infostream<<"RatCAO: Got message"<<std::endl;
857 std::istringstream is(data, std::ios::binary);
863 m_position = readV3F1000(is);
864 pos_translator.update(m_position);
866 m_yaw = readF1000(is);
871 void RatCAO::initialize(const std::string &data)
873 //infostream<<"RatCAO: Got init data"<<std::endl;
876 std::istringstream is(data, std::ios::binary);
878 u8 version = readU8(is);
883 m_position = readV3F1000(is);
884 pos_translator.init(m_position);
894 #include "inventory.h"
897 Oerkki1CAO proto_Oerkki1CAO(NULL, NULL);
899 Oerkki1CAO::Oerkki1CAO(IGameDef *gamedef, ClientEnvironment *env):
900 ClientActiveObject(0, gamedef, env),
901 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.),
903 m_position(v3f(0,10*BS,0)),
905 m_damage_visual_timer(0),
906 m_damage_texture_enabled(false)
908 ClientActiveObject::registerType(getType(), create);
911 Oerkki1CAO::~Oerkki1CAO()
915 ClientActiveObject* Oerkki1CAO::create(IGameDef *gamedef, ClientEnvironment *env)
917 return new Oerkki1CAO(gamedef, env);
920 void Oerkki1CAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
926 //video::IVideoDriver* driver = smgr->getVideoDriver();
928 scene::SMesh *mesh = new scene::SMesh();
929 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
930 video::SColor c(255,255,255,255);
931 video::S3DVertex vertices[4] =
933 video::S3DVertex(-BS/2-BS,0,0, 0,0,0, c, 0,1),
934 video::S3DVertex(BS/2+BS,0,0, 0,0,0, c, 1,1),
935 video::S3DVertex(BS/2+BS,BS*2,0, 0,0,0, c, 1,0),
936 video::S3DVertex(-BS/2-BS,BS*2,0, 0,0,0, c, 0,0),
938 u16 indices[] = {0,1,2,2,3,0};
939 buf->append(vertices, 4, indices, 6);
941 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
942 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
943 //buf->getMaterial().setTexture(0, NULL);
944 buf->getMaterial().setTexture(0, tsrc->getTextureRaw("oerkki1.png"));
945 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
946 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
947 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
949 mesh->addMeshBuffer(buf);
951 m_node = smgr->addMeshSceneNode(mesh, NULL);
953 // Set it to use the materials of the meshbuffers directly.
954 // This is needed for changing the texture in the future
955 m_node->setReadOnlyMaterials(true);
959 void Oerkki1CAO::removeFromScene()
968 void Oerkki1CAO::updateLight(u8 light_at_pos)
973 if(light_at_pos <= 2)
975 m_node->setVisible(false);
979 m_node->setVisible(true);
981 u8 li = decode_light(light_at_pos);
982 video::SColor color(255,li,li,li);
983 setMeshColor(m_node->getMesh(), color);
986 v3s16 Oerkki1CAO::getLightPosition()
988 return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
991 void Oerkki1CAO::updateNodePos()
996 //m_node->setPosition(m_position);
997 m_node->setPosition(pos_translator.vect_show);
999 v3f rot = m_node->getRotation();
1000 rot.Y = 180.0 - m_yaw + 90.0;
1001 m_node->setRotation(rot);
1004 void Oerkki1CAO::step(float dtime, ClientEnvironment *env)
1006 ITextureSource *tsrc = m_gamedef->tsrc();
1008 pos_translator.translate(dtime);
1011 LocalPlayer *player = env->getLocalPlayer();
1014 v3f playerpos = player->getPosition();
1015 v2f playerpos_2d(playerpos.X,playerpos.Z);
1016 v2f objectpos_2d(m_position.X,m_position.Z);
1018 if(fabs(m_position.Y - playerpos.Y) < 1.5*BS &&
1019 objectpos_2d.getDistanceFrom(playerpos_2d) < 1.5*BS)
1021 if(m_attack_interval.step(dtime, 0.5))
1023 env->damageLocalPlayer(2);
1027 if(m_damage_visual_timer > 0)
1029 if(!m_damage_texture_enabled)
1031 // Enable damage texture
1034 /*video::IVideoDriver* driver =
1035 m_node->getSceneManager()->getVideoDriver();*/
1037 scene::IMesh *mesh = m_node->getMesh();
1041 u16 mc = mesh->getMeshBufferCount();
1042 for(u16 j=0; j<mc; j++)
1044 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
1045 buf->getMaterial().setTexture(0,
1046 tsrc->getTextureRaw("oerkki1_damaged.png"));
1049 m_damage_texture_enabled = true;
1051 m_damage_visual_timer -= dtime;
1055 if(m_damage_texture_enabled)
1057 // Disable damage texture
1060 /*video::IVideoDriver* driver =
1061 m_node->getSceneManager()->getVideoDriver();*/
1063 scene::IMesh *mesh = m_node->getMesh();
1067 u16 mc = mesh->getMeshBufferCount();
1068 for(u16 j=0; j<mc; j++)
1070 scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
1071 buf->getMaterial().setTexture(0,
1072 tsrc->getTextureRaw("oerkki1.png"));
1075 m_damage_texture_enabled = false;
1080 void Oerkki1CAO::processMessage(const std::string &data)
1082 //infostream<<"Oerkki1CAO: Got message"<<std::endl;
1083 std::istringstream is(data, std::ios::binary);
1085 u8 cmd = readU8(is);
1089 m_position = readV3F1000(is);
1090 pos_translator.update(m_position);
1092 m_yaw = readF1000(is);
1097 //u16 damage = readU8(is);
1098 m_damage_visual_timer = 1.0;
1102 void Oerkki1CAO::initialize(const std::string &data)
1104 //infostream<<"Oerkki1CAO: Got init data"<<std::endl;
1107 std::istringstream is(data, std::ios::binary);
1109 u8 version = readU8(is);
1114 m_position = readV3F1000(is);
1115 pos_translator.init(m_position);
1121 bool Oerkki1CAO::directReportPunch(const std::string &toolname, v3f dir)
1123 m_damage_visual_timer = 1.0;
1125 m_position += dir * BS;
1126 pos_translator.sharpen();
1127 pos_translator.update(m_position);
1138 FireflyCAO proto_FireflyCAO(NULL, NULL);
1140 FireflyCAO::FireflyCAO(IGameDef *gamedef, ClientEnvironment *env):
1141 ClientActiveObject(0, gamedef, env),
1142 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.),
1144 m_position(v3f(0,10*BS,0)),
1147 ClientActiveObject::registerType(getType(), create);
1150 FireflyCAO::~FireflyCAO()
1154 ClientActiveObject* FireflyCAO::create(IGameDef *gamedef, ClientEnvironment *env)
1156 return new FireflyCAO(gamedef, env);
1159 void FireflyCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
1160 IrrlichtDevice *irr)
1165 //video::IVideoDriver* driver = smgr->getVideoDriver();
1167 scene::SMesh *mesh = new scene::SMesh();
1168 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
1169 video::SColor c(255,255,255,255);
1170 video::S3DVertex vertices[4] =
1172 video::S3DVertex(0,0,0, 0,0,0, c, 0,1),
1173 video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
1174 video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
1175 video::S3DVertex(0,BS/2,0, 0,0,0, c, 0,0),
1177 u16 indices[] = {0,1,2,2,3,0};
1178 buf->append(vertices, 4, indices, 6);
1180 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
1181 buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
1182 //buf->getMaterial().setTexture(0, NULL);
1183 buf->getMaterial().setTexture(0, tsrc->getTextureRaw("firefly.png"));
1184 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
1185 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
1186 buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
1188 mesh->addMeshBuffer(buf);
1190 m_node = smgr->addMeshSceneNode(mesh, NULL);
1192 // Set it to use the materials of the meshbuffers directly.
1193 // This is needed for changing the texture in the future
1194 m_node->setReadOnlyMaterials(true);
1198 void FireflyCAO::removeFromScene()
1207 void FireflyCAO::updateLight(u8 light_at_pos)
1213 video::SColor color(255,li,li,li);
1214 setMeshColor(m_node->getMesh(), color);
1217 v3s16 FireflyCAO::getLightPosition()
1219 return floatToInt(m_position+v3f(0,BS*0.5,0), BS);
1222 void FireflyCAO::updateNodePos()
1227 //m_node->setPosition(m_position);
1228 m_node->setPosition(pos_translator.vect_show);
1230 v3f rot = m_node->getRotation();
1231 rot.Y = 180.0 - m_yaw;
1232 m_node->setRotation(rot);
1235 void FireflyCAO::step(float dtime, ClientEnvironment *env)
1237 pos_translator.translate(dtime);
1241 void FireflyCAO::processMessage(const std::string &data)
1243 //infostream<<"FireflyCAO: Got message"<<std::endl;
1244 std::istringstream is(data, std::ios::binary);
1246 u8 cmd = readU8(is);
1250 m_position = readV3F1000(is);
1251 pos_translator.update(m_position);
1253 m_yaw = readF1000(is);
1258 void FireflyCAO::initialize(const std::string &data)
1260 //infostream<<"FireflyCAO: Got init data"<<std::endl;
1263 std::istringstream is(data, std::ios::binary);
1265 u8 version = readU8(is);
1270 m_position = readV3F1000(is);
1271 pos_translator.init(m_position);
1282 MobV2CAO proto_MobV2CAO(NULL, NULL);
1284 MobV2CAO::MobV2CAO(IGameDef *gamedef, ClientEnvironment *env):
1285 ClientActiveObject(0, gamedef, env),
1286 m_selection_box(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS),
1288 m_position(v3f(0,10*BS,0)),
1291 m_walking_unset_timer(0),
1294 m_damage_visual_timer(0),
1297 m_shooting_unset_timer(0),
1298 m_sprite_size(BS,BS),
1300 m_bright_shooting(false),
1301 m_lock_full_brightness(false),
1302 m_player_hit_timer(0)
1304 ClientActiveObject::registerType(getType(), create);
1306 m_properties = new Settings;
1309 MobV2CAO::~MobV2CAO()
1311 delete m_properties;
1314 ClientActiveObject* MobV2CAO::create(IGameDef *gamedef, ClientEnvironment *env)
1316 return new MobV2CAO(gamedef, env);
1319 void MobV2CAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
1320 IrrlichtDevice *irr)
1325 /*infostream<<"MobV2CAO::addToScene using texture_name="<<
1326 m_texture_name<<std::endl;*/
1327 std::string texture_string = m_texture_name +
1328 "^[makealpha:128,0,0^[makealpha:128,128,0";
1330 scene::IBillboardSceneNode *bill = smgr->addBillboardSceneNode(
1331 NULL, v2f(1, 1), v3f(0,0,0), -1);
1332 bill->setMaterialTexture(0, tsrc->getTextureRaw(texture_string));
1333 bill->setMaterialFlag(video::EMF_LIGHTING, false);
1334 bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
1335 bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
1336 bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
1337 bill->setColor(video::SColor(255,0,0,0));
1338 bill->setVisible(false); /* Set visible when brightness is known */
1339 bill->setSize(m_sprite_size);
1340 if(m_sprite_type == "humanoid_1"){
1341 const float txp = 1./192;
1342 const float txs = txp*32;
1343 const float typ = 1./240;
1344 const float tys = typ*48;
1345 setBillboardTextureMatrix(bill, txs, tys, 0, 0);
1346 } else if(m_sprite_type == "simple"){
1347 const float txs = 1.0;
1348 const float tys = 1.0 / m_simple_anim_frames;
1349 setBillboardTextureMatrix(bill, txs, tys, 0, 0);
1351 infostream<<"MobV2CAO: Unknown sprite type \""<<m_sprite_type<<"\""
1360 void MobV2CAO::removeFromScene()
1369 void MobV2CAO::updateLight(u8 light_at_pos)
1371 if(m_lock_full_brightness)
1374 m_last_light = light_at_pos;
1379 if(m_damage_visual_timer > 0)
1382 if(m_shooting && m_bright_shooting)
1385 /*if(light_at_pos <= 2){
1386 m_node->setVisible(false);
1390 m_node->setVisible(true);
1392 u8 li = decode_light(light_at_pos);
1393 video::SColor color(255,li,li,li);
1394 m_node->setColor(color);
1397 v3s16 MobV2CAO::getLightPosition()
1399 return floatToInt(m_position+v3f(0,0,0), BS);
1402 void MobV2CAO::updateNodePos()
1407 m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
1410 void MobV2CAO::step(float dtime, ClientEnvironment *env)
1412 scene::IBillboardSceneNode *bill = m_node;
1416 pos_translator.translate(dtime);
1418 if(m_sprite_type == "humanoid_1"){
1419 scene::ICameraSceneNode* camera = m_node->getSceneManager()->getActiveCamera();
1422 v3f cam_to_mob = m_node->getAbsolutePosition() - camera->getAbsolutePosition();
1423 cam_to_mob.normalize();
1425 if(cam_to_mob.Y > 0.75)
1427 else if(cam_to_mob.Y < -0.75)
1430 float mob_dir = atan2(cam_to_mob.Z, cam_to_mob.X) / PI * 180.;
1431 float dir = mob_dir - m_yaw;
1432 dir = wrapDegrees_180(dir);
1433 //infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;
1434 if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
1436 else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
1438 else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
1440 else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
1449 } else if(m_walking){
1450 m_walk_timer += dtime;
1451 if(m_walk_timer >= 0.5){
1452 m_walk_frame = (m_walk_frame + 1) % 2;
1455 if(m_walk_frame == 0)
1461 const float txp = 1./192;
1462 const float txs = txp*32;
1463 const float typ = 1./240;
1464 const float tys = typ*48;
1465 setBillboardTextureMatrix(bill, txs, tys, col, row);
1466 } else if(m_sprite_type == "simple"){
1467 m_walk_timer += dtime;
1468 if(m_walk_timer >= m_simple_anim_frametime){
1469 m_walk_frame = (m_walk_frame + 1) % m_simple_anim_frames;
1473 int row = m_walk_frame;
1474 const float txs = 1.0;
1475 const float tys = 1.0 / m_simple_anim_frames;
1476 setBillboardTextureMatrix(bill, txs, tys, col, row);
1478 infostream<<"MobV2CAO::step(): Unknown sprite type \""
1479 <<m_sprite_type<<"\""<<std::endl;
1484 /* Damage local player */
1485 if(m_player_hit_damage && m_player_hit_timer <= 0.0){
1486 LocalPlayer *player = env->getLocalPlayer();
1489 v3f playerpos = player->getPosition();
1490 v2f playerpos_2d(playerpos.X,playerpos.Z);
1491 v2f objectpos_2d(m_position.X,m_position.Z);
1493 if(fabs(m_position.Y - playerpos.Y) < m_player_hit_distance*BS &&
1494 objectpos_2d.getDistanceFrom(playerpos_2d) < m_player_hit_distance*BS)
1496 env->damageLocalPlayer(m_player_hit_damage);
1497 m_player_hit_timer = m_player_hit_interval;
1503 m_player_hit_timer -= dtime;
1505 if(m_damage_visual_timer >= 0){
1506 m_damage_visual_timer -= dtime;
1507 if(m_damage_visual_timer <= 0){
1508 infostream<<"id="<<m_id<<" damage visual ended"<<std::endl;
1512 m_walking_unset_timer += dtime;
1513 if(m_walking_unset_timer >= 1.0){
1517 m_shooting_unset_timer -= dtime;
1518 if(m_shooting_unset_timer <= 0.0){
1519 if(m_bright_shooting){
1520 u8 li = decode_light(m_last_light);
1521 video::SColor color(255,li,li,li);
1522 bill->setColor(color);
1523 m_bright_shooting = false;
1530 void MobV2CAO::processMessage(const std::string &data)
1532 //infostream<<"MobV2CAO: Got message"<<std::endl;
1533 std::istringstream is(data, std::ios::binary);
1535 u8 cmd = readU8(is);
1541 m_position = readV3F1000(is);
1542 pos_translator.update(m_position);
1544 m_yaw = readF1000(is);
1547 m_walking_unset_timer = 0;
1554 //u16 damage = readU16(is);
1556 /*u8 li = decode_light(m_last_light);
1562 /*video::SColor color(255,255,0,0);
1563 m_node->setColor(color);
1565 m_damage_visual_timer = 0.2;*/
1571 m_shooting_unset_timer = readF1000(is);
1573 m_bright_shooting = readU8(is);
1574 if(m_bright_shooting){
1576 video::SColor color(255,li,li,li);
1577 m_node->setColor(color);
1584 void MobV2CAO::initialize(const std::string &data)
1586 //infostream<<"MobV2CAO: Got init data"<<std::endl;
1589 std::istringstream is(data, std::ios::binary);
1591 u8 version = readU8(is);
1594 infostream<<__FUNCTION_NAME<<": Invalid version"<<std::endl;
1598 std::ostringstream tmp_os(std::ios::binary);
1599 decompressZlib(is, tmp_os);
1600 std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
1601 m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
1603 infostream<<"MobV2CAO::initialize(): got properties:"<<std::endl;
1604 m_properties->writeLines(infostream);
1606 m_properties->setDefault("looks", "dummy_default");
1607 m_properties->setDefault("yaw", "0");
1608 m_properties->setDefault("pos", "(0,0,0)");
1609 m_properties->setDefault("player_hit_damage", "0");
1610 m_properties->setDefault("player_hit_distance", "1.5");
1611 m_properties->setDefault("player_hit_interval", "1.5");
1613 setLooks(m_properties->get("looks"));
1614 m_yaw = m_properties->getFloat("yaw");
1615 m_position = m_properties->getV3F("pos");
1616 m_player_hit_damage = m_properties->getS32("player_hit_damage");
1617 m_player_hit_distance = m_properties->getFloat("player_hit_distance");
1618 m_player_hit_interval = m_properties->getFloat("player_hit_interval");
1620 pos_translator.init(m_position);
1626 bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
1628 video::SColor color(255,255,0,0);
1629 m_node->setColor(color);
1631 m_damage_visual_timer = 0.05;
1633 m_position += dir * BS;
1634 pos_translator.sharpen();
1635 pos_translator.update(m_position);
1641 void MobV2CAO::setLooks(const std::string &looks)
1643 v2f selection_size = v2f(0.4, 0.4) * BS;
1644 float selection_y = 0 * BS;
1646 if(looks == "dungeon_master"){
1647 m_texture_name = "dungeon_master.png";
1648 m_sprite_type = "humanoid_1";
1649 m_sprite_size = v2f(2, 3) * BS;
1650 m_sprite_y = 0.85 * BS;
1651 selection_size = v2f(0.4, 2.6) * BS;
1652 selection_y = -0.4 * BS;
1654 else if(looks == "fireball"){
1655 m_texture_name = "fireball.png";
1656 m_sprite_type = "simple";
1657 m_sprite_size = v2f(1, 1) * BS;
1658 m_simple_anim_frames = 3;
1659 m_simple_anim_frametime = 0.1;
1660 m_lock_full_brightness = true;
1663 m_texture_name = "stone.png";
1664 m_sprite_type = "simple";
1665 m_sprite_size = v2f(1, 1) * BS;
1666 m_simple_anim_frames = 3;
1667 m_simple_anim_frametime = 0.333;
1668 selection_size = v2f(0.4, 0.4) * BS;
1669 selection_y = 0 * BS;
1672 m_selection_box = core::aabbox3d<f32>(
1673 -selection_size.X, selection_y, -selection_size.X,
1674 selection_size.X, selection_y+selection_size.Y,
1682 #include "luaentity_common.h"
1684 class LuaEntityCAO : public ClientActiveObject
1687 core::aabbox3d<f32> m_selection_box;
1688 scene::IMeshSceneNode *m_meshnode;
1689 scene::IBillboardSceneNode *m_spritenode;
1694 struct LuaEntityProperties *m_prop;
1695 SmoothTranslator pos_translator;
1696 // Spritesheet/animation stuff
1699 bool m_tx_select_horiz_by_yawpitch;
1701 int m_anim_num_frames;
1702 float m_anim_framelength;
1706 LuaEntityCAO(IGameDef *gamedef, ClientEnvironment *env):
1707 ClientActiveObject(0, gamedef, env),
1708 m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.),
1711 m_position(v3f(0,10*BS,0)),
1712 m_velocity(v3f(0,0,0)),
1713 m_acceleration(v3f(0,0,0)),
1715 m_prop(new LuaEntityProperties),
1718 m_tx_select_horiz_by_yawpitch(false),
1720 m_anim_num_frames(1),
1721 m_anim_framelength(0.2),
1725 ClientActiveObject::registerType(getType(), create);
1728 void initialize(const std::string &data)
1730 infostream<<"LuaEntityCAO: Got init data"<<std::endl;
1732 std::istringstream is(data, std::ios::binary);
1734 u8 version = readU8(is);
1739 m_position = readV3F1000(is);
1741 m_yaw = readF1000(is);
1743 std::istringstream prop_is(deSerializeLongString(is), std::ios::binary);
1744 m_prop->deSerialize(prop_is);
1746 infostream<<"m_prop: "<<m_prop->dump()<<std::endl;
1748 m_selection_box = m_prop->collisionbox;
1749 m_selection_box.MinEdge *= BS;
1750 m_selection_box.MaxEdge *= BS;
1752 pos_translator.init(m_position);
1754 m_tx_size.X = 1.0 / m_prop->spritediv.X;
1755 m_tx_size.Y = 1.0 / m_prop->spritediv.Y;
1756 m_tx_basepos.X = m_tx_size.X * m_prop->initial_sprite_basepos.X;
1757 m_tx_basepos.Y = m_tx_size.Y * m_prop->initial_sprite_basepos.Y;
1767 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env)
1769 return new LuaEntityCAO(gamedef, env);
1774 return ACTIVEOBJECT_TYPE_LUAENTITY;
1776 core::aabbox3d<f32>* getSelectionBox()
1778 return &m_selection_box;
1782 return pos_translator.vect_show;
1785 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
1786 IrrlichtDevice *irr)
1788 if(m_meshnode != NULL || m_spritenode != NULL)
1791 //video::IVideoDriver* driver = smgr->getVideoDriver();
1793 if(m_prop->visual == "sprite"){
1794 infostream<<"LuaEntityCAO::addToScene(): single_sprite"<<std::endl;
1795 m_spritenode = smgr->addBillboardSceneNode(
1796 NULL, v2f(1, 1), v3f(0,0,0), -1);
1797 m_spritenode->setMaterialTexture(0,
1798 tsrc->getTextureRaw("unknown_block.png"));
1799 m_spritenode->setMaterialFlag(video::EMF_LIGHTING, false);
1800 m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
1801 m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
1802 m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true);
1803 m_spritenode->setColor(video::SColor(255,0,0,0));
1804 m_spritenode->setVisible(false); /* Set visible when brightness is known */
1805 m_spritenode->setSize(m_prop->visual_size*BS);
1807 const float txs = 1.0 / 1;
1808 const float tys = 1.0 / 1;
1809 setBillboardTextureMatrix(m_spritenode,
1812 } else if(m_prop->visual == "cube"){
1813 infostream<<"LuaEntityCAO::addToScene(): cube"<<std::endl;
1814 scene::IMesh *mesh = createCubeMesh(v3f(BS,BS,BS));
1815 m_meshnode = smgr->addMeshSceneNode(mesh, NULL);
1818 m_meshnode->setScale(v3f(1));
1819 // Will be shown when we know the brightness
1820 m_meshnode->setVisible(false);
1822 infostream<<"LuaEntityCAO::addToScene(): \""<<m_prop->visual
1823 <<"\" not supported"<<std::endl;
1829 void removeFromScene()
1832 m_meshnode->remove();
1836 m_spritenode->remove();
1837 m_spritenode = NULL;
1841 void updateLight(u8 light_at_pos)
1843 u8 li = decode_light(light_at_pos);
1844 video::SColor color(255,li,li,li);
1846 setMeshColor(m_meshnode->getMesh(), color);
1847 m_meshnode->setVisible(true);
1850 m_spritenode->setColor(color);
1851 m_spritenode->setVisible(true);
1855 v3s16 getLightPosition()
1857 return floatToInt(m_position, BS);
1860 void updateNodePos()
1863 m_meshnode->setPosition(pos_translator.vect_show);
1866 m_spritenode->setPosition(pos_translator.vect_show);
1870 void step(float dtime, ClientEnvironment *env)
1872 if(m_prop->physical){
1873 core::aabbox3d<f32> box = m_prop->collisionbox;
1876 collisionMoveResult moveresult;
1877 f32 pos_max_d = BS*0.25; // Distance per iteration
1878 v3f p_pos = m_position;
1879 v3f p_velocity = m_velocity;
1880 IGameDef *gamedef = env->getGameDef();
1881 moveresult = collisionMovePrecise(&env->getMap(), gamedef,
1882 pos_max_d, box, dtime, p_pos, p_velocity);
1885 m_velocity = p_velocity;
1887 bool is_end_position = moveresult.collides;
1888 pos_translator.update(m_position, is_end_position, dtime);
1889 pos_translator.translate(dtime);
1892 m_velocity += dtime * m_acceleration;
1894 m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
1895 m_velocity += dtime * m_acceleration;
1896 pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
1897 pos_translator.translate(dtime);
1901 m_anim_timer += dtime;
1902 if(m_anim_timer >= m_anim_framelength){
1903 m_anim_timer -= m_anim_framelength;
1905 if(m_anim_frame >= m_anim_num_frames)
1912 void updateTexturePos()
1915 scene::ICameraSceneNode* camera =
1916 m_spritenode->getSceneManager()->getActiveCamera();
1919 v3f cam_to_entity = m_spritenode->getAbsolutePosition()
1920 - camera->getAbsolutePosition();
1921 cam_to_entity.normalize();
1923 int row = m_tx_basepos.Y;
1924 int col = m_tx_basepos.X;
1926 if(m_tx_select_horiz_by_yawpitch)
1928 if(cam_to_entity.Y > 0.75)
1930 else if(cam_to_entity.Y < -0.75)
1933 float mob_dir = atan2(cam_to_entity.Z, cam_to_entity.X) / PI * 180.;
1934 float dir = mob_dir - m_yaw;
1935 dir = wrapDegrees_180(dir);
1936 //infostream<<"id="<<m_id<<" dir="<<dir<<std::endl;
1937 if(fabs(wrapDegrees_180(dir - 0)) <= 45.1)
1939 else if(fabs(wrapDegrees_180(dir - 90)) <= 45.1)
1941 else if(fabs(wrapDegrees_180(dir - 180)) <= 45.1)
1943 else if(fabs(wrapDegrees_180(dir + 90)) <= 45.1)
1950 // Animation goes downwards
1951 row += m_anim_frame;
1953 float txs = m_tx_size.X;
1954 float tys = m_tx_size.Y;
1955 setBillboardTextureMatrix(m_spritenode,
1956 txs, tys, col, row);
1960 void updateTextures(const std::string &mod)
1962 ITextureSource *tsrc = m_gamedef->tsrc();
1965 std::string texturestring = "unknown_block.png";
1966 if(m_prop->textures.size() >= 1)
1967 texturestring = m_prop->textures[0];
1968 texturestring += mod;
1969 m_spritenode->setMaterialTexture(0,
1970 tsrc->getTextureRaw(texturestring));
1973 for (u32 i = 0; i < 6; ++i)
1975 std::string texturestring = "unknown_block.png";
1976 if(m_prop->textures.size() > i)
1977 texturestring = m_prop->textures[i];
1978 texturestring += mod;
1979 AtlasPointer ap = tsrc->getTexture(texturestring);
1981 // Get the tile texture and atlas transformation
1982 video::ITexture* atlas = ap.atlas;
1986 // Set material flags and texture
1987 video::SMaterial& material = m_meshnode->getMaterial(i);
1988 material.setFlag(video::EMF_LIGHTING, false);
1989 material.setFlag(video::EMF_BILINEAR_FILTER, false);
1990 material.setTexture(0, atlas);
1991 material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y);
1992 material.getTextureMatrix(0).setTextureScale(size.X, size.Y);
1997 void processMessage(const std::string &data)
1999 //infostream<<"LuaEntityCAO: Got message"<<std::endl;
2000 std::istringstream is(data, std::ios::binary);
2002 u8 cmd = readU8(is);
2003 if(cmd == 0) // update position
2006 bool do_interpolate = readU8(is);
2008 m_position = readV3F1000(is);
2010 m_velocity = readV3F1000(is);
2012 m_acceleration = readV3F1000(is);
2014 m_yaw = readF1000(is);
2015 // is_end_position (for interpolation)
2016 bool is_end_position = readU8(is);
2018 float update_interval = readF1000(is);
2021 if(!m_prop->physical)
2022 pos_translator.update(m_position, is_end_position, update_interval);
2024 pos_translator.init(m_position);
2028 else if(cmd == 1) // set texture modification
2030 std::string mod = deSerializeString(is);
2031 updateTextures(mod);
2033 else if(cmd == 2) // set sprite
2035 v2s16 p = readV2S16(is);
2036 int num_frames = readU16(is);
2037 float framelength = readF1000(is);
2038 bool select_horiz_by_yawpitch = readU8(is);
2041 m_anim_num_frames = num_frames;
2042 m_anim_framelength = framelength;
2043 m_tx_select_horiz_by_yawpitch = select_horiz_by_yawpitch;
2051 LuaEntityCAO proto_LuaEntityCAO(NULL, NULL);
2057 class PlayerCAO : public ClientActiveObject
2060 core::aabbox3d<f32> m_selection_box;
2061 scene::IMeshSceneNode *m_body, *m_head, *m_leg_l, *m_leg_r, *m_arm_l, *m_arm_r;
2062 scene::ITextSceneNode* m_text;
2071 SmoothTranslator pos_translator;
2072 SmoothTranslator old_pos_translator;
2073 SmoothTranslator head_translator;
2074 bool m_is_local_player;
2075 LocalPlayer *m_local_player;
2076 float m_damage_visual_timer;
2079 PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
2080 ClientActiveObject(0, gamedef, env),
2081 m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.0,BS/3.),
2082 m_body(NULL), m_head(NULL), m_leg_l(NULL), m_leg_r(NULL), m_arm_l(NULL), m_arm_r(NULL),
2084 m_position(v3f(0,0,0)),
2085 m_old_position(v3f(0,0,0)),
2091 m_is_local_player(false),
2092 m_local_player(NULL),
2093 m_damage_visual_timer(0)
2096 ClientActiveObject::registerType(getType(), create);
2099 void initialize(const std::string &data)
2101 infostream<<"PlayerCAO: Got init data"<<std::endl;
2103 std::istringstream is(data, std::ios::binary);
2105 u8 version = readU8(is);
2110 m_name = deSerializeString(is);
2112 m_old_position = m_position; // old position
2113 m_position = readV3F1000(is);
2115 m_pitch = readF1000(is);
2116 m_pitch = updateHeadPitch(m_pitch);
2118 m_yaw = readF1000(is);
2120 pos_translator.init(m_position);
2121 old_pos_translator.init(m_old_position);
2122 head_translator.init(v3f(m_pitch, 0, 0));
2124 Player *player = m_env->getPlayer(m_name.c_str());
2125 if(player && player->isLocal()){
2126 m_is_local_player = true;
2127 m_local_player = (LocalPlayer*)player;
2147 static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env)
2149 return new PlayerCAO(gamedef, env);
2154 return ACTIVEOBJECT_TYPE_PLAYER;
2156 core::aabbox3d<f32>* getSelectionBox()
2158 if(m_is_local_player)
2160 return &m_selection_box;
2164 return pos_translator.vect_show;
2167 void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
2168 IrrlichtDevice *irr)
2170 if(m_body != NULL || m_head != NULL || m_leg_l != NULL || m_leg_r != NULL || m_arm_l != NULL || m_arm_r != NULL)
2172 if(m_is_local_player)
2175 //video::IVideoDriver* driver = smgr->getVideoDriver();
2176 gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
2179 scene::SMesh *mesh = new scene::SMesh();
2180 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
2181 video::SColor c(255,255,255,255);
2182 video::S3DVertex vertices[46] =
2184 video::S3DVertex(1.125000, 0.750000, 2.125066, 1.000000, 0.000000, -0.000000,c, 0.815385, 0.714286),
2185 video::S3DVertex(1.125001, 0.750000, 4.375066, 1.000000, 0.000000, -0.000000,c, 0.815385, 0.642857),
2186 video::S3DVertex(1.125000, -0.750000, 2.125066, 1.000000, 0.000000, -0.000000,c, 0.769231, 0.714286),
2187 video::S3DVertex(1.125001, 0.750000, 4.375066, 1.000000, -0.000001, 0.000000,c, 0.815385, 0.642857),
2188 video::S3DVertex(1.124999, -0.750001, 4.375066, 1.000000, -0.000001, 0.000000,c, 0.769231, 0.642857),
2189 video::S3DVertex(1.125000, -0.750000, 2.125066, 1.000000, -0.000001, 0.000000,c, 0.769231, 0.714286),
2190 video::S3DVertex(1.125000, -0.750000, 2.125066, 0.000000, -1.000000, -0.000000,c, 0.753846, 0.714286),
2191 video::S3DVertex(1.124999, -0.750001, 4.375066, 0.000000, -1.000000, -0.000000,c, 0.753846, 0.642857),
2192 video::S3DVertex(-1.125000, -0.750000, 2.125066, 0.000000, -1.000000, -0.000000,c, 0.692308, 0.714286),
2193 video::S3DVertex(1.124999, -0.750001, 4.375066, -0.000001, -1.000000, 0.000000,c, 0.753846, 0.642857),
2194 video::S3DVertex(-1.125001, -0.749999, 4.375066, -0.000001, -1.000000, 0.000000,c, 0.692308, 0.642857),
2195 video::S3DVertex(-1.125000, -0.750000, 2.125066, -0.000001, -1.000000, 0.000000,c, 0.692308, 0.714286),
2196 video::S3DVertex(-1.125000, -0.750000, 2.125066, -1.000000, 0.000000, -0.000000,c, 0.876923, 0.714286),
2197 video::S3DVertex(-1.125001, -0.749999, 4.375066, -1.000000, 0.000000, -0.000000,c, 0.876923, 0.642857),
2198 video::S3DVertex(-1.125000, 0.750000, 4.375066, -1.000000, 0.000000, -0.000000,c, 0.830769, 0.642857),
2199 video::S3DVertex(-1.125000, 0.750000, 2.125066, -1.000000, 0.000000, -0.000000,c, 0.830769, 0.714286),
2200 video::S3DVertex(1.125001, 0.750000, 4.375066, 0.000000, 1.000000, 0.000000,c, 0.953846, 0.714286),
2201 video::S3DVertex(1.125000, 0.750000, 2.125066, 0.000000, 1.000000, 0.000000,c, 0.953846, 0.642857),
2202 video::S3DVertex(-1.125000, 0.750000, 2.125066, 0.000000, 1.000000, 0.000000,c, 0.892308, 0.642857),
2203 video::S3DVertex(-1.125000, 0.750000, 4.375066, 0.000000, 1.000000, 0.000000,c, 0.892308, 0.714286),
2204 video::S3DVertex(3.000002, 1.124999, 2.499885, 0.000000, 1.000000, 0.000000,c, 0.353846, 0.446429),
2205 video::S3DVertex(3.000000, 1.125000, -5.000116, 0.000000, 1.000000, 0.000000,c, 0.353846, 0.714286),
2206 video::S3DVertex(-2.999999, 1.125000, -5.000116, 0.000000, 1.000000, 0.000000,c, 0.507692, 0.714286),
2207 video::S3DVertex(-3.000000, 1.124999, 2.499885, 0.000000, 1.000000, 0.000000,c, 0.507692, 0.446429),
2208 video::S3DVertex(-3.000000, -1.125000, -5.000116, -1.000000, 0.000001, -0.000000,c, 0.338462, 0.714286),
2209 video::S3DVertex(-3.000001, -1.124999, 2.499885, -1.000000, 0.000001, -0.000000,c, 0.338462, 0.446429),
2210 video::S3DVertex(-3.000000, 1.124999, 2.499885, -1.000000, 0.000001, -0.000000,c, 0.261538, 0.446429),
2211 video::S3DVertex(-2.999999, 1.125000, -5.000116, -1.000000, 0.000001, -0.000000,c, 0.261538, 0.714286),
2212 video::S3DVertex(3.000000, -1.124999, -5.000116, 0.000000, -1.000000, -0.000000,c, 0.153846, 0.714286),
2213 video::S3DVertex(2.999998, -1.125001, 2.499885, 0.000000, -1.000000, -0.000000,c, 0.153846, 0.446429),
2214 video::S3DVertex(-3.000000, -1.125000, -5.000116, 0.000000, -1.000000, -0.000000,c, 0.000000, 0.714286),
2215 video::S3DVertex(-3.000001, -1.124999, 2.499885, -0.000000, -1.000000, 0.000000,c, 0.000000, 0.446429),
2216 video::S3DVertex(3.000000, 1.125000, -5.000116, 1.000000, -0.000000, -0.000000,c, 0.246154, 0.714286),
2217 video::S3DVertex(3.000002, 1.124999, 2.499885, 1.000000, -0.000000, -0.000000,c, 0.246154, 0.446429),
2218 video::S3DVertex(3.000000, -1.124999, -5.000116, 1.000000, -0.000000, -0.000000,c, 0.169231, 0.714286),
2219 video::S3DVertex(3.000002, 1.124999, 2.499885, 1.000000, -0.000002, 0.000000,c, 0.246154, 0.446429),
2220 video::S3DVertex(2.999998, -1.125001, 2.499885, 1.000000, -0.000002, 0.000000,c, 0.169231, 0.446429),
2221 video::S3DVertex(3.000000, -1.124999, -5.000116, 1.000000, -0.000002, 0.000000,c, 0.169231, 0.714286),
2222 video::S3DVertex(3.000002, 1.124999, 2.499885, -0.000000, -0.000000, 1.000000,c, 0.676923, 0.517857),
2223 video::S3DVertex(-3.000000, 1.124999, 2.499885, -0.000000, -0.000000, 1.000000,c, 0.523077, 0.517857),
2224 video::S3DVertex(2.999998, -1.125001, 2.499885, -0.000000, -0.000000, 1.000000,c, 0.676923, 0.607143),
2225 video::S3DVertex(-3.000001, -1.124999, 2.499885, 0.000000, -0.000000, 1.000000,c, 0.523077, 0.607143),
2226 video::S3DVertex(3.000000, 1.125000, -5.000116, 0.000000, 0.000000, -1.000000,c, 0.676923, 0.714286),
2227 video::S3DVertex(3.000000, -1.124999, -5.000116, 0.000000, 0.000000, -1.000000,c, 0.676923, 0.625000),
2228 video::S3DVertex(-2.999999, 1.125000, -5.000116, 0.000000, 0.000000, -1.000000,c, 0.523077, 0.714286),
2229 video::S3DVertex(-3.000000, -1.125000, -5.000116, 0.000000, -0.000000, -1.000000,c, 0.523077, 0.625000),
2231 u16 indices[] = {0, 1, 2,
2251 buf->append(vertices, 46, indices, 60);
2253 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
2254 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
2255 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
2256 //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
2258 mesh->addMeshBuffer(buf);
2261 m_body = smgr->addMeshSceneNode(mesh, NULL);
2262 m_body->setPosition(v3f(0,0,0));
2263 m_body->setRotation(v3f(-90,0,0));
2265 // Set it to use the materials of the meshbuffers directly.
2266 // This is needed for changing the texture in the future
2267 m_body->setReadOnlyMaterials(true);
2272 scene::SMesh *mesh = new scene::SMesh();
2273 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
2274 video::SColor c(255,255,255,255);
2275 video::S3DVertex vertices[30] =
2277 video::S3DVertex(2.250001, 1.499998, 3.774997, 0.000000, 1.000000, 0.000001,c, 0.353846, 0.000000),
2278 video::S3DVertex(2.249999, 1.500000, 0.024998, 0.000000, 1.000000, 0.000001,c, 0.353846, 0.142857),
2279 video::S3DVertex(-2.250000, 1.499999, 3.774997, 0.000000, 1.000000, 0.000001,c, 0.507638, -0.000000),
2280 video::S3DVertex(2.249999, 1.500000, 0.024998, 0.000000, 1.000000, 0.000000,c, 0.353846, 0.142857),
2281 video::S3DVertex(-2.250000, 1.500001, 0.024998, 0.000000, 1.000000, 0.000000,c, 0.507638, 0.142857),
2282 video::S3DVertex(-2.250000, 1.499999, 3.774997, 0.000000, 1.000000, 0.000000,c, 0.507638, -0.000000),
2283 video::S3DVertex(-2.250000, -1.500000, 0.024998, -1.000000, -0.000000, -0.000000,c, 0.338462, 0.142857),
2284 video::S3DVertex(-2.250000, -1.499999, 3.774997, -1.000000, -0.000000, -0.000000,c, 0.338285, 0.000163),
2285 video::S3DVertex(-2.250000, 1.499999, 3.774997, -1.000000, -0.000000, -0.000000,c, 0.261538, 0.000000),
2286 video::S3DVertex(-2.250000, 1.500001, 0.024998, -1.000000, 0.000000, -0.000000,c, 0.261538, 0.142857),
2287 video::S3DVertex(2.250001, -1.499999, 0.024998, 0.000000, -1.000000, -0.000001,c, 0.153846, 0.142857),
2288 video::S3DVertex(2.249998, -1.500001, 3.774997, 0.000000, -1.000000, -0.000001,c, 0.153846, -0.000000),
2289 video::S3DVertex(-2.250000, -1.500000, 0.024998, 0.000000, -1.000000, -0.000001,c, 0.000000, 0.142857),
2290 video::S3DVertex(2.249998, -1.500001, 3.774997, -0.000001, -1.000000, 0.000000,c, 0.153846, -0.000000),
2291 video::S3DVertex(-2.250000, -1.499999, 3.774997, -0.000001, -1.000000, 0.000000,c, 0.000000, 0.000000),
2292 video::S3DVertex(-2.250000, -1.500000, 0.024998, -0.000001, -1.000000, 0.000000,c, 0.000000, 0.142857),
2293 video::S3DVertex(2.249999, 1.500000, 0.024998, 1.000000, 0.000001, -0.000000,c, 0.246154, 0.142857),
2294 video::S3DVertex(2.250001, 1.499998, 3.774997, 1.000000, 0.000001, -0.000000,c, 0.246154, 0.000000),
2295 video::S3DVertex(2.250001, -1.499999, 0.024998, 1.000000, 0.000001, -0.000000,c, 0.169231, 0.142857),
2296 video::S3DVertex(2.250001, 1.499998, 3.774997, 1.000000, -0.000001, 0.000001,c, 0.246154, 0.000000),
2297 video::S3DVertex(2.249998, -1.500001, 3.774997, 1.000000, -0.000001, 0.000001,c, 0.169231, 0.000000),
2298 video::S3DVertex(2.250001, -1.499999, 0.024998, 1.000000, -0.000001, 0.000001,c, 0.169231, 0.142857),
2299 video::S3DVertex(2.250001, 1.499998, 3.774997, -0.000000, -0.000000, 1.000000,c, 0.523077, 0.142857),
2300 video::S3DVertex(-2.250000, 1.499999, 3.774997, -0.000000, -0.000000, 1.000000,c, 0.676923, 0.142857),
2301 video::S3DVertex(-2.250000, -1.499999, 3.774997, -0.000000, -0.000000, 1.000000,c, 0.676923, 0.053571),
2302 video::S3DVertex(2.249998, -1.500001, 3.774997, 0.000000, -0.000000, 1.000000,c, 0.523077, 0.053571),
2303 video::S3DVertex(2.249999, 1.500000, 0.024998, 0.000000, 0.000000, -1.000000,c, 0.692308, 0.053571),
2304 video::S3DVertex(2.250001, -1.499999, 0.024998, 0.000000, 0.000000, -1.000000,c, 0.692308, 0.142857),
2305 video::S3DVertex(-2.250000, -1.500000, 0.024998, 0.000000, 0.000000, -1.000000,c, 0.846154, 0.142857),
2306 video::S3DVertex(-2.250000, 1.500001, 0.024998, 0.000000, 0.000000, -1.000000,c, 0.846154, 0.053571),
2308 u16 indices[] = {0, 1, 2,
2320 buf->append(vertices, 30, indices, 36);
2322 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
2323 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
2324 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
2325 //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
2327 mesh->addMeshBuffer(buf);
2330 m_head = smgr->addMeshSceneNode(mesh, NULL);
2331 m_head->setPosition(v3f(0,0,0));
2332 m_head->setRotation(v3f(-90,0,0));
2334 // Set it to use the materials of the meshbuffers directly.
2335 // This is needed for changing the texture in the future
2336 m_head->setReadOnlyMaterials(true);
2341 scene::SMesh *mesh = new scene::SMesh();
2342 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
2343 video::SColor c(255,255,255,255);
2344 video::S3DVertex vertices[28] =
2346 video::S3DVertex(-0.144449, 1.124999, 0.224998, 0.000000, 1.000000, 0.000000,c, 0.292308, 0.732143),
2347 video::S3DVertex(-0.144450, 1.125000, -8.025005, 0.000000, 1.000000, 0.000000,c, 0.292308, 1.000000),
2348 video::S3DVertex(-2.995950, 1.125000, -8.025005, 0.000000, 1.000000, 0.000000,c, 0.384615, 1.000000),
2349 video::S3DVertex(-2.995950, 1.125000, 0.224998, 0.000000, 1.000000, 0.000000,c, 0.384615, 0.732143),
2350 video::S3DVertex(-2.995950, -1.125000, -8.025005, -1.000000, 0.000000, -0.000000,c, 0.276923, 1.000000),
2351 video::S3DVertex(-2.995950, -1.124999, 0.224998, -1.000000, 0.000000, -0.000000,c, 0.276923, 0.732143),
2352 video::S3DVertex(-2.995950, 1.125000, -8.025005, -1.000000, 0.000000, -0.000000,c, 0.200000, 1.000000),
2353 video::S3DVertex(-2.995950, 1.125000, 0.224998, -1.000000, 0.000000, -0.000000,c, 0.200000, 0.732143),
2354 video::S3DVertex(-0.144450, -1.125000, -8.025005, -0.000001, -1.000000, -0.000000,c, 0.092308, 1.000000),
2355 video::S3DVertex(-0.144451, -1.125001, 0.224998, -0.000001, -1.000000, -0.000000,c, 0.092308, 0.732143),
2356 video::S3DVertex(-2.995950, -1.124999, 0.224998, -0.000001, -1.000000, -0.000000,c, 0.000000, 0.732143),
2357 video::S3DVertex(-0.144450, -1.125000, -8.025005, -0.000000, -1.000000, 0.000000,c, 0.092308, 1.000000),
2358 video::S3DVertex(-2.995950, -1.124999, 0.224998, -0.000000, -1.000000, 0.000000,c, 0.000000, 0.732143),
2359 video::S3DVertex(-2.995950, -1.125000, -8.025005, -0.000000, -1.000000, 0.000000,c, 0.000000, 1.000000),
2360 video::S3DVertex(-0.144450, 1.125000, -8.025005, 1.000000, -0.000000, -0.000000,c, 0.184615, 1.000000),
2361 video::S3DVertex(-0.144449, 1.124999, 0.224998, 1.000000, -0.000000, -0.000000,c, 0.184615, 0.732143),
2362 video::S3DVertex(-0.144450, -1.125000, -8.025005, 1.000000, -0.000000, -0.000000,c, 0.107692, 1.000000),
2363 video::S3DVertex(-0.144449, 1.124999, 0.224998, 1.000000, -0.000001, 0.000000,c, 0.184615, 0.732143),
2364 video::S3DVertex(-0.144451, -1.125001, 0.224998, 1.000000, -0.000001, 0.000000,c, 0.107692, 0.732143),
2365 video::S3DVertex(-0.144450, -1.125000, -8.025005, 1.000000, -0.000001, 0.000000,c, 0.107692, 1.000000),
2366 video::S3DVertex(-0.144449, 1.124999, 0.224998, -0.000000, 0.000000, 1.000000,c, 0.400000, 0.892857),
2367 video::S3DVertex(-2.995950, 1.125000, 0.224998, -0.000000, 0.000000, 1.000000,c, 0.492308, 0.892857),
2368 video::S3DVertex(-2.995950, -1.124999, 0.224998, -0.000000, 0.000000, 1.000000,c, 0.492308, 0.803656),
2369 video::S3DVertex(-0.144451, -1.125001, 0.224998, 0.000000, -0.000000, 1.000000,c, 0.400000, 0.803656),
2370 video::S3DVertex(-0.144450, 1.125000, -8.025005, 0.000000, 0.000000, -1.000000,c, 0.400000, 1.000000),
2371 video::S3DVertex(-0.144450, -1.125000, -8.025005, 0.000000, 0.000000, -1.000000,c, 0.492308, 1.000000),
2372 video::S3DVertex(-2.995950, -1.125000, -8.025005, 0.000000, 0.000000, -1.000000,c, 0.492308, 0.910714),
2373 video::S3DVertex(-2.995950, 1.125000, -8.025005, 0.000000, -0.000000, -1.000000,c, 0.400000, 0.910714),
2375 u16 indices[] = {0, 1, 2,
2387 buf->append(vertices, 28, indices, 36);
2389 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
2390 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
2391 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
2392 //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
2394 mesh->addMeshBuffer(buf);
2397 m_leg_l = smgr->addMeshSceneNode(mesh, NULL);
2398 m_leg_l->setPosition(v3f(0,0,0));
2399 m_leg_l->setRotation(v3f(-90,0,0));
2401 // Set it to use the materials of the meshbuffers directly.
2402 // This is needed for changing the texture in the future
2403 m_leg_l->setReadOnlyMaterials(true);
2408 scene::SMesh *mesh = new scene::SMesh();
2409 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
2410 video::SColor c(255,255,255,255);
2411 video::S3DVertex vertices[28] =
2413 video::S3DVertex(2.995751, 1.124999, 0.224998, 0.000000, 1.000000, 0.000000,c, 0.615385, 0.732143),
2414 video::S3DVertex(2.995750, 1.125000, -8.025005, 0.000000, 1.000000, 0.000000,c, 0.615385, 1.000000),
2415 video::S3DVertex(0.144250, 1.125000, -8.025005, 0.000000, 1.000000, 0.000000,c, 0.707692, 1.000000),
2416 video::S3DVertex(0.144250, 1.125000, 0.224998, 0.000000, 1.000000, 0.000000,c, 0.707692, 0.732143),
2417 video::S3DVertex(0.144249, -1.125000, -8.025005, -1.000000, 0.000000, -0.000000,c, 0.892308, 1.000000),
2418 video::S3DVertex(0.144249, -1.124999, 0.224998, -1.000000, 0.000000, -0.000000,c, 0.892308, 0.732143),
2419 video::S3DVertex(0.144250, 1.125000, -8.025005, -1.000000, 0.000000, -0.000000,c, 0.815385, 1.000000),
2420 video::S3DVertex(0.144250, 1.125000, 0.224998, -1.000000, 0.000000, -0.000000,c, 0.815385, 0.732143),
2421 video::S3DVertex(2.995750, -1.125000, -8.025005, -0.000001, -1.000000, -0.000000,c, 1.000000, 1.000000),
2422 video::S3DVertex(2.995749, -1.125001, 0.224998, -0.000001, -1.000000, -0.000000,c, 1.000000, 0.732143),
2423 video::S3DVertex(0.144249, -1.124999, 0.224998, -0.000001, -1.000000, -0.000000,c, 0.907692, 0.732143),
2424 video::S3DVertex(2.995750, -1.125000, -8.025005, -0.000000, -1.000000, 0.000000,c, 1.000000, 1.000000),
2425 video::S3DVertex(0.144249, -1.124999, 0.224998, -0.000000, -1.000000, 0.000000,c, 0.907692, 0.732143),
2426 video::S3DVertex(0.144249, -1.125000, -8.025005, -0.000000, -1.000000, 0.000000,c, 0.907692, 1.000000),
2427 video::S3DVertex(2.995750, 1.125000, -8.025005, 1.000000, 0.000000, -0.000000,c, 0.800022, 1.000000),
2428 video::S3DVertex(2.995751, 1.124999, 0.224998, 1.000000, 0.000000, -0.000000,c, 0.800000, 0.732143),
2429 video::S3DVertex(2.995750, -1.125000, -8.025005, 1.000000, 0.000000, -0.000000,c, 0.723055, 1.000000),
2430 video::S3DVertex(2.995751, 1.124999, 0.224998, 1.000000, -0.000001, 0.000000,c, 0.800000, 0.732143),
2431 video::S3DVertex(2.995749, -1.125001, 0.224998, 1.000000, -0.000001, 0.000000,c, 0.723055, 0.732143),
2432 video::S3DVertex(2.995750, -1.125000, -8.025005, 1.000000, -0.000001, 0.000000,c, 0.723055, 1.000000),
2433 video::S3DVertex(2.995751, 1.124999, 0.224998, -0.000000, 0.000000, 1.000000,c, 0.600000, 0.803571),
2434 video::S3DVertex(0.144250, 1.125000, 0.224998, -0.000000, 0.000000, 1.000000,c, 0.507692, 0.803571),
2435 video::S3DVertex(0.144249, -1.124999, 0.224998, -0.000000, 0.000000, 1.000000,c, 0.507692, 0.892857),
2436 video::S3DVertex(2.995749, -1.125001, 0.224998, 0.000000, -0.000000, 1.000000,c, 0.600000, 0.892857),
2437 video::S3DVertex(2.995750, 1.125000, -8.025005, 0.000000, 0.000000, -1.000000,c, 0.600000, 0.910714),
2438 video::S3DVertex(2.995750, -1.125000, -8.025005, 0.000000, 0.000000, -1.000000,c, 0.507659, 0.910714),
2439 video::S3DVertex(0.144249, -1.125000, -8.025005, 0.000000, 0.000000, -1.000000,c, 0.507659, 1.000000),
2440 video::S3DVertex(0.144250, 1.125000, -8.025005, 0.000000, -0.000000, -1.000000,c, 0.600000, 1.000000),
2442 u16 indices[] = {0, 1, 2,
2454 buf->append(vertices, 28, indices, 36);
2456 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
2457 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
2458 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
2459 //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
2461 mesh->addMeshBuffer(buf);
2464 m_leg_r = smgr->addMeshSceneNode(mesh, NULL);
2465 m_leg_r->setPosition(v3f(0,0,0));
2466 m_leg_r->setRotation(v3f(-90,0,0));
2468 // Set it to use the materials of the meshbuffers directly.
2469 // This is needed for changing the texture in the future
2470 m_leg_r->setReadOnlyMaterials(true);
2475 scene::SMesh *mesh = new scene::SMesh();
2476 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
2477 video::SColor c(255,255,255,255);
2478 video::S3DVertex vertices[28] =
2480 video::S3DVertex(-3.049999, 1.124999, 0.300000, 0.000000, 1.000000, 0.000000,c, 0.261538, 0.160714),
2481 video::S3DVertex(-3.049999, 1.125000, -7.200000, 0.000000, 1.000000, 0.000000,c, 0.261538, 0.428571),
2482 video::S3DVertex(-4.849999, 1.125001, -7.200000, 0.000000, 1.000000, 0.000000,c, 0.323077, 0.428644),
2483 video::S3DVertex(-3.049999, 1.124999, 0.300000, 0.000001, 1.000000, 0.000000,c, 0.261538, 0.160714),
2484 video::S3DVertex(-4.849999, 1.125001, -7.200000, 0.000001, 1.000000, 0.000000,c, 0.323077, 0.428644),
2485 video::S3DVertex(-4.849999, 1.125000, 0.300000, 0.000001, 1.000000, 0.000000,c, 0.323077, 0.160714),
2486 video::S3DVertex(-4.849999, -1.125000, -7.200000, -1.000000, 0.000000, -0.000000,c, 0.246154, 0.428571),
2487 video::S3DVertex(-4.850000, -1.124999, 0.300000, -1.000000, 0.000000, -0.000000,c, 0.246154, 0.160714),
2488 video::S3DVertex(-4.849999, 1.125001, -7.200000, -1.000000, 0.000000, -0.000000,c, 0.169231, 0.428571),
2489 video::S3DVertex(-4.849999, 1.125000, 0.300000, -1.000000, 0.000000, 0.000000,c, 0.169231, 0.160714),
2490 video::S3DVertex(-3.049999, -1.125000, -7.200000, -0.000001, -1.000000, -0.000000,c, 0.061538, 0.428571),
2491 video::S3DVertex(-3.050000, -1.125001, 0.300000, -0.000001, -1.000000, -0.000000,c, 0.061538, 0.160714),
2492 video::S3DVertex(-4.850000, -1.124999, 0.300000, -0.000001, -1.000000, -0.000000,c, 0.000000, 0.160714),
2493 video::S3DVertex(-3.049999, -1.125000, -7.200000, -0.000000, -1.000000, 0.000000,c, 0.061538, 0.428571),
2494 video::S3DVertex(-4.850000, -1.124999, 0.300000, -0.000000, -1.000000, 0.000000,c, 0.000000, 0.160714),
2495 video::S3DVertex(-4.849999, -1.125000, -7.200000, -0.000000, -1.000000, 0.000000,c, 0.000000, 0.428571),
2496 video::S3DVertex(-3.049999, 1.125000, -7.200000, 1.000000, -0.000000, 0.000000,c, 0.153846, 0.428571),
2497 video::S3DVertex(-3.049999, 1.124999, 0.300000, 1.000000, -0.000000, 0.000000,c, 0.153846, 0.160714),
2498 video::S3DVertex(-3.049999, -1.125000, -7.200000, 1.000000, -0.000000, 0.000000,c, 0.076923, 0.428571),
2499 video::S3DVertex(-3.050000, -1.125001, 0.300000, 1.000000, -0.000000, 0.000000,c, 0.076923, 0.160714),
2500 video::S3DVertex(-3.049999, 1.124999, 0.300000, -0.000000, 0.000000, 1.000000,c, 0.400000, 0.232143),
2501 video::S3DVertex(-4.849999, 1.125000, 0.300000, -0.000000, 0.000000, 1.000000,c, 0.338462, 0.232143),
2502 video::S3DVertex(-4.850000, -1.124999, 0.300000, -0.000000, 0.000000, 1.000000,c, 0.338462, 0.321429),
2503 video::S3DVertex(-3.050000, -1.125001, 0.300000, 0.000000, -0.000000, 1.000000,c, 0.400000, 0.321429),
2504 video::S3DVertex(-3.049999, 1.125000, -7.200000, 0.000000, 0.000000, -1.000000,c, 0.400000, 0.428571),
2505 video::S3DVertex(-3.049999, -1.125000, -7.200000, 0.000000, 0.000000, -1.000000,c, 0.400000, 0.339286),
2506 video::S3DVertex(-4.849999, -1.125000, -7.200000, 0.000000, 0.000000, -1.000000,c, 0.338462, 0.339286),
2507 video::S3DVertex(-4.849999, 1.125001, -7.200000, 0.000000, 0.000000, -1.000000,c, 0.338462, 0.428571),
2509 u16 indices[] = {0, 1, 2,
2521 buf->append(vertices, 28, indices, 36);
2523 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
2524 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
2525 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
2526 //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
2528 mesh->addMeshBuffer(buf);
2531 m_arm_l = smgr->addMeshSceneNode(mesh, NULL);
2532 m_arm_l->setPosition(v3f(0,0,0));
2533 m_arm_l->setRotation(v3f(-90,0,0));
2535 // Set it to use the materials of the meshbuffers directly.
2536 // This is needed for changing the texture in the future
2537 m_arm_l->setReadOnlyMaterials(true);
2542 scene::SMesh *mesh = new scene::SMesh();
2543 scene::IMeshBuffer *buf = new scene::SMeshBuffer();
2544 video::SColor c(255,255,255,255);
2545 video::S3DVertex vertices[28] =
2547 video::S3DVertex(4.850001, 1.124999, 0.300000, 0.000000, 1.000000, 0.000000,c, 0.753846, 0.160714),
2548 video::S3DVertex(4.850000, 1.125000, -7.200000, 0.000000, 1.000000, 0.000000,c, 0.753846, 0.428571),
2549 video::S3DVertex(3.050001, 1.125000, -7.200000, 0.000000, 1.000000, 0.000000,c, 0.815385, 0.428571),
2550 video::S3DVertex(4.850001, 1.124999, 0.300000, 0.000001, 1.000000, 0.000000,c, 0.753846, 0.160714),
2551 video::S3DVertex(3.050001, 1.125000, -7.200000, 0.000001, 1.000000, 0.000000,c, 0.815385, 0.428571),
2552 video::S3DVertex(3.050001, 1.125000, 0.300000, 0.000001, 1.000000, 0.000000,c, 0.815385, 0.160714),
2553 video::S3DVertex(3.050000, -1.125000, -7.200000, -1.000000, 0.000000, -0.000000,c, 0.738462, 0.428571),
2554 video::S3DVertex(3.050000, -1.124999, 0.300000, -1.000000, 0.000000, -0.000000,c, 0.738462, 0.160714),
2555 video::S3DVertex(3.050001, 1.125000, -7.200000, -1.000000, 0.000000, -0.000000,c, 0.661538, 0.428571),
2556 video::S3DVertex(3.050001, 1.125000, 0.300000, -1.000000, 0.000000, 0.000000,c, 0.661538, 0.160714),
2557 video::S3DVertex(4.850000, -1.125000, -7.200000, -0.000001, -1.000000, -0.000000,c, 0.553846, 0.428571),
2558 video::S3DVertex(4.850000, -1.125001, 0.300000, -0.000001, -1.000000, -0.000000,c, 0.553846, 0.160714),
2559 video::S3DVertex(3.050000, -1.124999, 0.300000, -0.000001, -1.000000, -0.000000,c, 0.492308, 0.160714),
2560 video::S3DVertex(4.850000, -1.125000, -7.200000, -0.000000, -1.000000, 0.000000,c, 0.553846, 0.428571),
2561 video::S3DVertex(3.050000, -1.124999, 0.300000, -0.000000, -1.000000, 0.000000,c, 0.492308, 0.160714),
2562 video::S3DVertex(3.050000, -1.125000, -7.200000, -0.000000, -1.000000, 0.000000,c, 0.492308, 0.428571),
2563 video::S3DVertex(4.850000, 1.125000, -7.200000, 1.000000, 0.000000, -0.000000,c, 0.646154, 0.428571),
2564 video::S3DVertex(4.850001, 1.124999, 0.300000, 1.000000, 0.000000, -0.000000,c, 0.646154, 0.160714),
2565 video::S3DVertex(4.850000, -1.125000, -7.200000, 1.000000, 0.000000, -0.000000,c, 0.569231, 0.428571),
2566 video::S3DVertex(4.850000, -1.125001, 0.300000, 1.000000, -0.000000, 0.000000,c, 0.569279, 0.160714),
2567 video::S3DVertex(4.850001, 1.124999, 0.300000, -0.000000, 0.000000, 1.000000,c, 0.415385, 0.321429),
2568 video::S3DVertex(3.050001, 1.125000, 0.300000, -0.000000, 0.000000, 1.000000,c, 0.476923, 0.321429),
2569 video::S3DVertex(3.050000, -1.124999, 0.300000, -0.000000, 0.000000, 1.000000,c, 0.476923, 0.232143),
2570 video::S3DVertex(4.850000, -1.125001, 0.300000, 0.000000, -0.000000, 1.000000,c, 0.415385, 0.232143),
2571 video::S3DVertex(4.850000, 1.125000, -7.200000, 0.000000, 0.000000, -1.000000,c, 0.415385, 0.339286),
2572 video::S3DVertex(4.850000, -1.125000, -7.200000, 0.000000, 0.000000, -1.000000,c, 0.415385, 0.428571),
2573 video::S3DVertex(3.050000, -1.125000, -7.200000, 0.000000, 0.000000, -1.000000,c, 0.476923, 0.428571),
2574 video::S3DVertex(3.050001, 1.125000, -7.200000, 0.000000, -0.000000, -1.000000,c, 0.476923, 0.339286),
2576 u16 indices[] = {0, 1, 2,
2588 buf->append(vertices, 28, indices, 36);
2590 buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
2591 buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
2592 buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
2593 //buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
2595 mesh->addMeshBuffer(buf);
2598 m_arm_r = smgr->addMeshSceneNode(mesh, NULL);
2599 m_arm_r->setPosition(v3f(0,0,0));
2600 m_arm_r->setRotation(v3f(-90,0,0));
2602 // Set it to use the materials of the meshbuffers directly.
2603 // This is needed for changing the texture in the future
2604 m_arm_r->setReadOnlyMaterials(true);
2608 // Add a text node for showing the name
2609 std::wstring wname = narrow_to_wide(m_name);
2610 m_text = smgr->addTextSceneNode(gui->getBuiltInFont(),
2611 wname.c_str(), video::SColor(255,255,255,255), m_head);
2612 m_text->setPosition(v3f(0, 0, 5));
2615 //updateLegRot(dtime);
2619 void removeFromScene()
2621 if (m_body != NULL) {
2625 if (m_head != NULL) {
2629 if (m_leg_l != NULL) {
2633 if (m_leg_r != NULL) {
2637 if (m_arm_l != NULL) {
2641 if (m_arm_r != NULL) {
2647 void updateLight(u8 light_at_pos)
2649 u8 li = decode_light(light_at_pos);
2650 video::SColor color(255,li,li,li);
2652 if (m_body != NULL) {
2653 m_body->setVisible(true);
2654 setMeshColor(m_body->getMesh(), color);
2657 if (m_head != NULL) {
2658 m_head->setVisible(true);
2659 setMeshColor(m_head->getMesh(), color);
2662 if (m_leg_l != NULL) {
2663 m_leg_l->setVisible(true);
2664 setMeshColor(m_leg_l->getMesh(), color);
2667 if (m_leg_r != NULL) {
2668 m_leg_r->setVisible(true);
2669 setMeshColor(m_leg_r->getMesh(), color);
2672 if (m_arm_l != NULL) {
2673 m_arm_l->setVisible(true);
2674 setMeshColor(m_arm_l->getMesh(), color);
2677 if (m_arm_r != NULL) {
2678 m_arm_r->setVisible(true);
2679 setMeshColor(m_arm_r->getMesh(), color);
2683 v3s16 getLightPosition()
2685 return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
2688 float updateHeadPitch(float pitch) {
2692 else if (pitch < -75) {
2701 void updateLegRot(float dtime) {
2702 v3f real_pos = pos_translator.vect_show;
2703 v3f real_old_pos = old_pos_translator.vect_show;
2705 m_speed = (real_pos.X-real_old_pos.X+real_pos.Z-real_old_pos.Z)/2;
2710 if (m_speed > 0.5) {
2711 m_leg_rot = sin(m_leg_rot_i)*25;
2712 m_leg_rot_i += (m_speed*2.5)*dtime;
2715 if (m_leg_rot > 0) {
2716 if (m_leg_rot-(50.0*dtime) < 0) {
2720 m_leg_rot -= 50.0*dtime;
2724 else if (m_leg_rot < 0) {
2725 if (m_leg_rot+(50.0*dtime) > 0) {
2729 m_leg_rot += 50.0*dtime;
2736 void updateNodePos()
2738 v3f real_pos = pos_translator.vect_show;
2739 v3f real_old_pos = old_pos_translator.vect_show;
2740 v3f head_pitch = head_translator.vect_show;
2742 if (m_body != NULL) {
2743 v3f rot = m_body->getRotation();
2745 m_body->setPosition(v3f(real_pos.X+0, real_pos.Y+13.3, real_pos.Z+0));
2746 m_body->setRotation(rot);
2749 if (m_head != NULL) {
2750 v3f rot = m_head->getRotation();
2752 rot.X = head_pitch.X;
2754 m_head->setPosition(v3f(real_pos.X+0, real_pos.Y+16.2, real_pos.Z+0));
2755 m_head->setRotation(rot);
2758 if (m_leg_l != NULL) {
2759 v3f rot = m_leg_l->getRotation();
2761 rot.X = m_leg_rot-90;
2763 m_leg_l->setPosition(v3f(real_pos.X+0, real_pos.Y+8.03, real_pos.Z+0));
2764 m_leg_l->setRotation(rot);
2766 if (m_leg_r != NULL) {
2767 v3f rot = m_leg_r->getRotation();
2769 rot.X = -m_leg_rot-90;
2771 m_leg_r->setPosition(v3f(real_pos.X+0, real_pos.Y+8.03, real_pos.Z+0));
2772 m_leg_r->setRotation(rot);
2775 if (m_arm_l != NULL) {
2776 v3f rot = m_arm_l->getRotation();
2778 rot.X = -m_leg_rot-90;
2780 m_arm_l->setPosition(v3f(real_pos.X+0, real_pos.Y+15.5, real_pos.Z+0));
2781 m_arm_l->setRotation(rot);
2783 if (m_arm_r != NULL) {
2784 v3f rot = m_arm_r->getRotation();
2786 rot.X = m_leg_rot-90;
2788 m_arm_r->setPosition(v3f(real_pos.X+0, real_pos.Y+15.5, real_pos.Z+0));
2789 m_arm_r->setRotation(rot);
2793 void step(float dtime, ClientEnvironment *env)
2795 pos_translator.translate(dtime);
2796 old_pos_translator.translate(dtime);
2797 head_translator.translate(dtime);
2798 updateLegRot(dtime);
2801 if(m_damage_visual_timer > 0){
2802 m_damage_visual_timer -= dtime;
2803 if(m_damage_visual_timer <= 0){
2809 void processMessage(const std::string &data)
2811 //infostream<<"PlayerCAO: Got message"<<std::endl;
2812 std::istringstream is(data, std::ios::binary);
2814 u8 cmd = readU8(is);
2815 if(cmd == 0) // update position
2818 m_old_position = m_position; //old position
2819 m_position = readV3F1000(is);
2821 m_pitch = readF1000(is);
2822 m_pitch = updateHeadPitch(m_pitch);
2824 m_yaw = readF1000(is);
2826 pos_translator.update(m_position, false);
2827 old_pos_translator.update(m_old_position);
2828 head_translator.update(v3f(m_pitch, 0, 0));
2830 //updateLegRot(dtime);
2833 else if(cmd == 1) // punched
2836 s16 damage = readS16(is);
2838 if(m_is_local_player)
2839 m_env->damageLocalPlayer(damage, false);
2841 m_damage_visual_timer = 0.5;
2842 updateTextures("^[brighten");
2846 void updateTextures(const std::string &mod)
2848 ITextureSource *tsrc = m_gamedef->tsrc();
2850 scene::IMesh *mesh = m_body->getMesh();
2853 std::string tname = "mt_player.png";
2855 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
2856 buf->getMaterial().setTexture(0,
2857 tsrc->getTextureRaw(tname));
2863 scene::IMesh *mesh = m_head->getMesh();
2866 std::string tname = "mt_player.png";
2868 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
2869 buf->getMaterial().setTexture(0,
2870 tsrc->getTextureRaw(tname));
2876 scene::IMesh *mesh = m_leg_l->getMesh();
2879 std::string tname = "mt_player.png";
2881 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
2882 buf->getMaterial().setTexture(0,
2883 tsrc->getTextureRaw(tname));
2889 scene::IMesh *mesh = m_leg_r->getMesh();
2892 std::string tname = "mt_player.png";
2894 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
2895 buf->getMaterial().setTexture(0,
2896 tsrc->getTextureRaw(tname));
2902 scene::IMesh *mesh = m_arm_l->getMesh();
2905 std::string tname = "mt_player.png";
2907 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
2908 buf->getMaterial().setTexture(0,
2909 tsrc->getTextureRaw(tname));
2915 scene::IMesh *mesh = m_arm_r->getMesh();
2918 std::string tname = "mt_player.png";
2920 scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
2921 buf->getMaterial().setTexture(0,
2922 tsrc->getTextureRaw(tname));
2930 PlayerCAO proto_PlayerCAO(NULL, NULL);