X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcontent_cao.cpp;h=cbcf66ef75d00798cdfc5c0dc44cce4a0c3ff526;hb=fd1135c7af46eb2f5b99a11f48bf9f9ae335ea9c;hp=fc1df377a7875624a56156ca2df98741f78b5f34;hpb=601d1936c9ab4787d43f55d67900ed7c46fd3452;p=minetest.git diff --git a/src/content_cao.cpp b/src/content_cao.cpp index fc1df377a..cbcf66ef7 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -3,16 +3,16 @@ Minetest-c55 Copyright (C) 2010-2011 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ @@ -36,9 +36,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_cso.h" #include "sound.h" #include "nodedef.h" +#include "localplayer.h" class Settings; struct ToolCapabilities; +#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" + core::map ClientActiveObject::m_types; /* @@ -533,28 +536,37 @@ void ItemCAO::initialize(const std::string &data) } /* - LuaEntityCAO + GenericCAO */ -#include "luaentity_common.h" +#include "genericobject.h" -class LuaEntityCAO : public ClientActiveObject +class GenericCAO : public ClientActiveObject { private: + // Only set at initialization + std::string m_name; + bool m_is_player; + bool m_is_local_player; // determined locally + // Property-ish things + ObjectProperties m_prop; + // scene::ISceneManager *m_smgr; + IrrlichtDevice *m_irr; core::aabbox3d m_selection_box; scene::IMeshSceneNode *m_meshnode; scene::IBillboardSceneNode *m_spritenode; + scene::ITextSceneNode* m_textnode; v3f m_position; v3f m_velocity; v3f m_acceleration; float m_yaw; s16 m_hp; - struct LuaEntityProperties *m_prop; SmoothTranslator pos_translator; // Spritesheet/animation stuff v2f m_tx_size; v2s16 m_tx_basepos; + bool m_initial_tx_basepos_set; bool m_tx_select_horiz_by_yawpitch; int m_anim_frame; int m_anim_num_frames; @@ -562,28 +574,40 @@ class LuaEntityCAO : public ClientActiveObject float m_anim_timer; ItemGroupList m_armor_groups; float m_reset_textures_timer; + bool m_visuals_expired; + float m_step_distance_counter; + u8 m_last_light; public: - LuaEntityCAO(IGameDef *gamedef, ClientEnvironment *env): + GenericCAO(IGameDef *gamedef, ClientEnvironment *env): ClientActiveObject(0, gamedef, env), + // + m_is_player(false), + m_is_local_player(false), + // m_smgr(NULL), + m_irr(NULL), m_selection_box(-BS/3.,-BS/3.,-BS/3., BS/3.,BS/3.,BS/3.), m_meshnode(NULL), m_spritenode(NULL), + m_textnode(NULL), m_position(v3f(0,10*BS,0)), m_velocity(v3f(0,0,0)), m_acceleration(v3f(0,0,0)), m_yaw(0), m_hp(1), - m_prop(new LuaEntityProperties), m_tx_size(1,1), m_tx_basepos(0,0), + m_initial_tx_basepos_set(false), m_tx_select_horiz_by_yawpitch(false), m_anim_frame(0), m_anim_num_frames(1), m_anim_framelength(0.2), m_anim_timer(0), - m_reset_textures_timer(-1) + m_reset_textures_timer(-1), + m_visuals_expired(false), + m_step_distance_counter(0), + m_last_light(255) { if(gamedef == NULL) ClientActiveObject::registerType(getType(), create); @@ -591,75 +615,93 @@ class LuaEntityCAO : public ClientActiveObject void initialize(const std::string &data) { - infostream<<"LuaEntityCAO: Got init data"<deSerialize(prop_is); - - infostream<<"m_prop: "<dump()<collisionbox; - m_selection_box.MinEdge *= BS; - m_selection_box.MaxEdge *= BS; - pos_translator.init(m_position); - - m_tx_size.X = 1.0 / m_prop->spritediv.X; - m_tx_size.Y = 1.0 / m_prop->spritediv.Y; - m_tx_basepos.X = m_tx_size.X * m_prop->initial_sprite_basepos.X; - m_tx_basepos.Y = m_tx_size.Y * m_prop->initial_sprite_basepos.Y; - updateNodePos(); + + if(m_is_player){ + Player *player = m_env->getPlayer(m_name.c_str()); + if(player && player->isLocal()){ + m_is_local_player = true; + } + } } - ~LuaEntityCAO() + ~GenericCAO() { - delete m_prop; } static ClientActiveObject* create(IGameDef *gamedef, ClientEnvironment *env) { - return new LuaEntityCAO(gamedef, env); + return new GenericCAO(gamedef, env); } u8 getType() const { - return ACTIVEOBJECT_TYPE_LUAENTITY; + return ACTIVEOBJECT_TYPE_GENERIC; } core::aabbox3d* getSelectionBox() { + if(!m_prop.is_visible || m_is_local_player) + return NULL; return &m_selection_box; } v3f getPosition() { return pos_translator.vect_show; } - + + void removeFromScene() + { + if(m_meshnode){ + m_meshnode->remove(); + m_meshnode = NULL; + } + if(m_spritenode){ + m_spritenode->remove(); + m_spritenode = NULL; + } + } + void addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, IrrlichtDevice *irr) { m_smgr = smgr; + m_irr = irr; if(m_meshnode != NULL || m_spritenode != NULL) return; + m_visuals_expired = false; + + if(!m_prop.is_visible || m_is_local_player) + return; + //video::IVideoDriver* driver = smgr->getVideoDriver(); - if(m_prop->visual == "sprite"){ - infostream<<"LuaEntityCAO::addToScene(): single_sprite"<addBillboardSceneNode( NULL, v2f(1, 1), v3f(0,0,0), -1); m_spritenode->setMaterialTexture(0, @@ -668,48 +710,131 @@ class LuaEntityCAO : public ClientActiveObject m_spritenode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); m_spritenode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); m_spritenode->setMaterialFlag(video::EMF_FOG_ENABLE, true); - m_spritenode->setColor(video::SColor(255,0,0,0)); - m_spritenode->setVisible(false); /* Set visible when brightness is known */ - m_spritenode->setSize(m_prop->visual_size*BS); + u8 li = m_last_light; + m_spritenode->setColor(video::SColor(255,li,li,li)); + m_spritenode->setSize(m_prop.visual_size*BS); { const float txs = 1.0 / 1; const float tys = 1.0 / 1; setBillboardTextureMatrix(m_spritenode, txs, tys, 0, 0); } - } else if(m_prop->visual == "cube"){ - infostream<<"LuaEntityCAO::addToScene(): cube"<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(); + u8 li = m_last_light; + video::SColor c(255,li,li,li); + video::S3DVertex vertices[4] = + { + video::S3DVertex(dx,-dy,0, 0,0,0, c, 1,1), + video::S3DVertex(-dx,-dy,0, 0,0,0, c, 0,1), + video::S3DVertex(-dx,dy,0, 0,0,0, c, 0,0), + video::S3DVertex(dx,dy,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_meshnode = 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_meshnode->setReadOnlyMaterials(true); + } + else if(m_prop.visual == "cube"){ + infostream<<"GenericCAO::addToScene(): cube"<addMeshSceneNode(mesh, NULL); mesh->drop(); - m_meshnode->setScale(v3f(1)); - // Will be shown when we know the brightness - m_meshnode->setVisible(false); + m_meshnode->setScale(v3f(m_prop.visual_size.X, + m_prop.visual_size.Y, + m_prop.visual_size.X)); + u8 li = m_last_light; + setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li)); + } else if(m_prop.visual == "wielditem"){ + infostream<<"GenericCAO::addToScene(): node"<= 1){ + infostream<<"textures[0]: "<idef(); + ItemStack item(m_prop.textures[0], 1, 0, "", idef); + scene::IMesh *mesh = item.getDefinition(idef).wield_mesh; + m_meshnode = smgr->addMeshSceneNode(mesh, NULL); + + m_meshnode->setScale(v3f(m_prop.visual_size.X/2, + m_prop.visual_size.Y/2, + m_prop.visual_size.X/2)); + u8 li = m_last_light; + setMeshColor(m_meshnode->getMesh(), video::SColor(255,li,li,li)); + } } else { - infostream<<"LuaEntityCAO::addToScene(): \""<visual + infostream<<"GenericCAO::addToScene(): \""<getGUIEnvironment(); + std::wstring wname = narrow_to_wide(m_name); + m_textnode = smgr->addTextSceneNode(gui->getBuiltInFont(), + wname.c_str(), video::SColor(255,255,255,255), node); + m_textnode->setPosition(v3f(0, BS*1.1, 0)); + } + updateNodePos(); } - void removeFromScene() + void expireVisuals() { - if(m_meshnode){ - m_meshnode->remove(); - m_meshnode = NULL; - } - if(m_spritenode){ - m_spritenode->remove(); - m_spritenode = NULL; - } + m_visuals_expired = true; } - + void updateLight(u8 light_at_pos) { bool is_visible = (m_hp != 0); u8 li = decode_light(light_at_pos); + m_last_light = li; video::SColor color(255,li,li,li); if(m_meshnode){ setMeshColor(m_meshnode->getMesh(), color); @@ -730,6 +855,9 @@ class LuaEntityCAO : public ClientActiveObject { if(m_meshnode){ m_meshnode->setPosition(pos_translator.vect_show); + v3f rot = m_meshnode->getRotation(); + rot.Y = -m_yaw; + m_meshnode->setRotation(rot); } if(m_spritenode){ m_spritenode->setPosition(pos_translator.vect_show); @@ -738,8 +866,16 @@ class LuaEntityCAO : public ClientActiveObject void step(float dtime, ClientEnvironment *env) { - if(m_prop->physical){ - core::aabbox3d box = m_prop->collisionbox; + v3f lastpos = pos_translator.vect_show; + + if(m_visuals_expired && m_smgr && m_irr){ + m_visuals_expired = false; + removeFromScene(); + addToScene(m_smgr, m_gamedef->tsrc(), m_irr); + } + + if(m_prop.physical){ + core::aabbox3d box = m_prop.collisionbox; box.MinEdge *= BS; box.MaxEdge *= BS; collisionMoveResult moveresult; @@ -767,6 +903,20 @@ class LuaEntityCAO : public ClientActiveObject updateNodePos(); } + float moved = lastpos.getDistanceFrom(pos_translator.vect_show); + m_step_distance_counter += moved; + if(m_step_distance_counter > 1.5*BS){ + m_step_distance_counter = 0; + if(!m_is_local_player && m_prop.makes_footstep_sound){ + INodeDefManager *ndef = m_gamedef->ndef(); + v3s16 p = floatToInt(getPosition() + v3f(0, + (m_prop.collisionbox.MinEdge.Y-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()); + } + } + m_anim_timer += dtime; if(m_anim_timer >= m_anim_framelength){ m_anim_timer -= m_anim_framelength; @@ -784,6 +934,10 @@ class LuaEntityCAO : public ClientActiveObject updateTextures(""); } } + if(fabs(m_prop.automatic_rotate) > 0.001){ + m_yaw += dtime * m_prop.automatic_rotate * 180 / PI; + updateNodePos(); + } } void updateTexturePos() @@ -838,76 +992,125 @@ class LuaEntityCAO : public ClientActiveObject { ITextureSource *tsrc = m_gamedef->tsrc(); - if(m_spritenode){ - std::string texturestring = "unknown_block.png"; - if(m_prop->textures.size() >= 1) - texturestring = m_prop->textures[0]; - texturestring += mod; - m_spritenode->setMaterialTexture(0, - tsrc->getTextureRaw(texturestring)); - } - if(m_meshnode){ - for (u32 i = 0; i < 6; ++i) + if(m_spritenode) + { + if(m_prop.visual == "sprite") { std::string texturestring = "unknown_block.png"; - if(m_prop->textures.size() > i) - texturestring = m_prop->textures[i]; + if(m_prop.textures.size() >= 1) + texturestring = m_prop.textures[0]; texturestring += mod; - AtlasPointer ap = tsrc->getTexture(texturestring); - - // Get the tile texture and atlas transformation - video::ITexture* atlas = ap.atlas; - v2f pos = ap.pos; - v2f size = ap.size; - - // Set material flags and texture - video::SMaterial& material = m_meshnode->getMaterial(i); - material.setFlag(video::EMF_LIGHTING, false); - material.setFlag(video::EMF_BILINEAR_FILTER, false); - material.setTexture(0, atlas); - material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y); - material.getTextureMatrix(0).setTextureScale(size.X, size.Y); + m_spritenode->setMaterialTexture(0, + tsrc->getTextureRaw(texturestring)); + } + } + if(m_meshnode) + { + if(m_prop.visual == "cube") + { + for (u32 i = 0; i < 6; ++i) + { + std::string texturestring = "unknown_block.png"; + if(m_prop.textures.size() > i) + texturestring = m_prop.textures[i]; + texturestring += mod; + AtlasPointer ap = tsrc->getTexture(texturestring); + + // Get the tile texture and atlas transformation + video::ITexture* atlas = ap.atlas; + v2f pos = ap.pos; + v2f size = ap.size; + + // Set material flags and texture + video::SMaterial& material = m_meshnode->getMaterial(i); + material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setTexture(0, atlas); + material.getTextureMatrix(0).setTextureTranslate(pos.X, pos.Y); + material.getTextureMatrix(0).setTextureScale(size.X, size.Y); + } + } + else if(m_prop.visual == "upright_sprite") + { + scene::IMesh *mesh = m_meshnode->getMesh(); + { + std::string tname = "unknown_object.png"; + if(m_prop.textures.size() >= 1) + tname = m_prop.textures[0]; + tname += mod; + scene::IMeshBuffer *buf = mesh->getMeshBuffer(0); + buf->getMaterial().setTexture(0, + tsrc->getTextureRaw(tname)); + } + { + std::string tname = "unknown_object.png"; + if(m_prop.textures.size() >= 2) + tname = m_prop.textures[1]; + else if(m_prop.textures.size() >= 1) + tname = m_prop.textures[0]; + tname += mod; + scene::IMeshBuffer *buf = mesh->getMeshBuffer(1); + buf->getMaterial().setTexture(0, + tsrc->getTextureRaw(tname)); + } } } } void processMessage(const std::string &data) { - //infostream<<"LuaEntityCAO: Got message"<physical) + if(!m_prop.physical) pos_translator.update(m_position, is_end_position, update_interval); } else { pos_translator.init(m_position); } updateNodePos(); } - else if(cmd == LUAENTITY_CMD_SET_TEXTURE_MOD) // set texture modification + else if(cmd == GENERIC_CMD_SET_TEXTURE_MOD) { std::string mod = deSerializeString(is); updateTextures(mod); } - else if(cmd == LUAENTITY_CMD_SET_SPRITE) // set sprite + else if(cmd == GENERIC_CMD_SET_SPRITE) { v2s16 p = readV2S16(is); int num_frames = readU16(is); @@ -921,15 +1124,14 @@ class LuaEntityCAO : public ClientActiveObject updateTexturePos(); } - else if(cmd == LUAENTITY_CMD_PUNCHED) + else if(cmd == GENERIC_CMD_PUNCHED) { /*s16 damage =*/ readS16(is); s16 result_hp = readS16(is); m_hp = result_hp; - // TODO: Execute defined fast response } - else if(cmd == LUAENTITY_CMD_UPDATE_ARMOR_GROUPS) + else if(cmd == GENERIC_CMD_UPDATE_ARMOR_GROUPS) { m_armor_groups.clear(); int armor_groups_size = readU16(is); @@ -952,7 +1154,7 @@ class LuaEntityCAO : public ClientActiveObject toolcap, punchitem, time_from_last_punch); - + if(result.did_punch && result.damage != 0) { if(result.damage < m_hp){ @@ -963,13 +1165,15 @@ class LuaEntityCAO : public ClientActiveObject // As there is no definition, make a smoke puff ClientSimpleObject *simple = createSmokePuff( m_smgr, m_env, m_position, - m_prop->visual_size * BS); + m_prop.visual_size * BS); m_env->addSimpleObject(simple); } // TODO: Execute defined fast response // Flashing shall suffice as there is no definition + m_reset_textures_timer = 0.05; + if(result.damage >= 2) + m_reset_textures_timer += 0.05 * result.damage; updateTextures("^[brighten"); - m_reset_textures_timer = 0.1; } return false; @@ -978,7 +1182,7 @@ class LuaEntityCAO : public ClientActiveObject std::string debugInfoText() { std::ostringstream os(std::ios::binary); - os<<"LuaEntityCAO hp="< 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"<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* 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"<= 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); +GenericCAO proto_GenericCAO(NULL, NULL);