-LuaEntityCAO proto_LuaEntityCAO(NULL, NULL);
-
-/*
- PlayerCAO
-*/
-
-class PlayerCAO : public ClientActiveObject
-{
-private:
- core::aabbox3d<f32> m_selection_box;
- scene::IMeshSceneNode *m_node;
- scene::ITextSceneNode* m_text;
- std::string m_name;
- v3f m_position;
- float m_yaw;
- SmoothTranslator pos_translator;
- bool m_is_local_player;
- LocalPlayer *m_local_player;
- float m_damage_visual_timer;
- bool m_dead;
- float m_step_distance_counter;
-
-public:
- PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
- ClientActiveObject(0, gamedef, env),
- m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2.0,BS/3.),
- m_node(NULL),
- m_text(NULL),
- m_position(v3f(0,10*BS,0)),
- m_yaw(0),
- m_is_local_player(false),
- m_local_player(NULL),
- m_damage_visual_timer(0),
- m_dead(false),
- m_step_distance_counter(0)
- {
- if(gamedef == NULL)
- ClientActiveObject::registerType(getType(), create);
- }
-
- void initialize(const std::string &data)
- {
- infostream<<"PlayerCAO: Got init data"<<std::endl;
-
- std::istringstream is(data, std::ios::binary);
- // version
- u8 version = readU8(is);
- // check version
- if(version != 0)
- return;
- // name
- m_name = deSerializeString(is);
- // pos
- m_position = readV3F1000(is);
- // yaw
- m_yaw = readF1000(is);
- // dead
- m_dead = readU8(is);
-
- pos_translator.init(m_position);
-
- Player *player = m_env->getPlayer(m_name.c_str());
- if(player && player->isLocal()){
- m_is_local_player = true;
- m_local_player = (LocalPlayer*)player;
- }
- }
-
- ~PlayerCAO()
- {
- if(m_node)
- m_node->remove();
- }
-
- static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env)
- {
- return new PlayerCAO(gamedef, env);
- }
-
- u8 getType() const
- {
- return ACTIVEOBJECT_TYPE_PLAYER;
- }
- core::aabbox3d<f32>* getSelectionBox()
- {
- if(m_is_local_player)
- return NULL;
- if(m_dead)
- return NULL;
- return &m_selection_box;
- }
- v3f getPosition()
- {
- return pos_translator.vect_show;
- }
-
- void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
- IrrlichtDevice *irr)
- {
- if(m_node != NULL)
- return;
- if(m_is_local_player)
- return;
-
- //video::IVideoDriver* driver = smgr->getVideoDriver();
- gui::IGUIEnvironment* gui = irr->getGUIEnvironment();
-
- scene::SMesh *mesh = new scene::SMesh();
- { // Front
- scene::IMeshBuffer *buf = new scene::SMeshBuffer();
- video::SColor c(255,255,255,255);
- video::S3DVertex vertices[4] =
- {
- video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
- video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
- video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
- video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
- };
- u16 indices[] = {0,1,2,2,3,0};
- buf->append(vertices, 4, indices, 6);
- // Set material
- buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
- buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
- buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
- buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
- // Add to mesh
- mesh->addMeshBuffer(buf);
- buf->drop();
- }
- { // Back
- scene::IMeshBuffer *buf = new scene::SMeshBuffer();
- video::SColor c(255,255,255,255);
- video::S3DVertex vertices[4] =
- {
- video::S3DVertex(BS/2,0,0, 0,0,0, c, 1,1),
- video::S3DVertex(-BS/2,0,0, 0,0,0, c, 0,1),
- video::S3DVertex(-BS/2,BS*2,0, 0,0,0, c, 0,0),
- video::S3DVertex(BS/2,BS*2,0, 0,0,0, c, 1,0),
- };
- u16 indices[] = {0,1,2,2,3,0};
- buf->append(vertices, 4, indices, 6);
- // Set material
- buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
- buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
- buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
- buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
- // Add to mesh
- mesh->addMeshBuffer(buf);
- buf->drop();
- }
- m_node = smgr->addMeshSceneNode(mesh, NULL);
- mesh->drop();
- // Set it to use the materials of the meshbuffers directly.
- // This is needed for changing the texture in the future
- m_node->setReadOnlyMaterials(true);
- updateNodePos();
-
- // Add a text node for showing the name
- std::wstring wname = narrow_to_wide(m_name);
- m_text = smgr->addTextSceneNode(gui->getBuiltInFont(),
- wname.c_str(), video::SColor(255,255,255,255), m_node);
- m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
-
- updateTextures("");
- updateVisibility();
- updateNodePos();
- }
-
- void removeFromScene()
- {
- if(m_node == NULL)
- return;
-
- m_node->remove();
- m_node = NULL;
- }
-
- void updateLight(u8 light_at_pos)
- {
- if(m_node == NULL)
- return;
-
- u8 li = decode_light(light_at_pos);
- video::SColor color(255,li,li,li);
- setMeshColor(m_node->getMesh(), color);
-
- updateVisibility();
- }
-
- v3s16 getLightPosition()
- {
- return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
- }
-
- void updateVisibility()
- {
- if(m_node == NULL)
- return;
-
- m_node->setVisible(!m_dead);
- }
-
- void updateNodePos()
- {
- if(m_node == NULL)
- return;
-
- m_node->setPosition(pos_translator.vect_show);
-
- v3f rot = m_node->getRotation();
- rot.Y = -m_yaw;
- m_node->setRotation(rot);
- }
-
- void step(float dtime, ClientEnvironment *env)
- {
- v3f lastpos = pos_translator.vect_show;
- pos_translator.translate(dtime);
- float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
- updateVisibility();
- updateNodePos();
-
- if(m_damage_visual_timer > 0){
- m_damage_visual_timer -= dtime;
- if(m_damage_visual_timer <= 0){
- updateTextures("");
- }
- }
-
- m_step_distance_counter += moved;
- if(m_step_distance_counter > 1.5*BS){
- m_step_distance_counter = 0;
- if(!m_is_local_player){
- INodeDefManager *ndef = m_gamedef->ndef();
- v3s16 p = floatToInt(getPosition()+v3f(0,-0.5*BS, 0), BS);
- MapNode n = m_env->getMap().getNodeNoEx(p);
- SimpleSoundSpec spec = ndef->get(n).sound_footstep;
- m_gamedef->sound()->playSoundAt(spec, false, getPosition());
- }
- }
- }
-
- void processMessage(const std::string &data)
- {
- //infostream<<"PlayerCAO: Got message"<<std::endl;
- std::istringstream is(data, std::ios::binary);
- // command
- u8 cmd = readU8(is);
- if(cmd == 0) // update position
- {
- // pos
- m_position = readV3F1000(is);
- // yaw
- m_yaw = readF1000(is);
-
- pos_translator.update(m_position, false);
-
- updateNodePos();
- }
- else if(cmd == 1) // punched
- {
- // damage
- s16 damage = readS16(is);
- m_damage_visual_timer = 0.05;
- if(damage >= 2)
- m_damage_visual_timer += 0.05 * damage;
- updateTextures("^[brighten");
- }
- else if(cmd == 2) // died or respawned
- {
- m_dead = readU8(is);
- updateVisibility();
- }
- }
-
- void updateTextures(const std::string &mod)
- {
- if(!m_node)
- return;
- ITextureSource *tsrc = m_gamedef->tsrc();
- scene::IMesh *mesh = m_node->getMesh();
- if(mesh){
- {
- std::string tname = "player.png";
- tname += mod;
- scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
- buf->getMaterial().setTexture(0,
- tsrc->getTextureRaw(tname));
- }
- {
- std::string tname = "player_back.png";
- tname += mod;
- scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
- buf->getMaterial().setTexture(0,
- tsrc->getTextureRaw(tname));
- }
- }
- }
-};
-
-// Prototype
-PlayerCAO proto_PlayerCAO(NULL, NULL);