X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcontent_cao.cpp;h=72f6145b067c25b6179e63fb902e471b58bcd0f3;hb=8f49358153637bb87f492e558a13cf9f23046e64;hp=d80804d4a0bae3b384521164ea4a324998d2179f;hpb=d2ca662569427d36642660314668e416bf68f3c8;p=dragonfireclient.git diff --git a/src/content_cao.cpp b/src/content_cao.cpp index d80804d4a..72f6145b0 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -465,7 +465,7 @@ void ItemCAO::updateTexture() } catch(SerializationError &e) { - infostream<<"WARNING: "<<__FUNCTION_NAME + warningstream< >()), m_attachment_bone(""), m_attachment_position(v3f(0,0,0)), @@ -727,6 +727,16 @@ scene::IBillboardSceneNode* GenericCAO::getSpriteSceneNode() return m_spritenode; } +void GenericCAO::setChildrenVisible(bool toset) +{ + for (std::vector::size_type i = 0; i < m_children.size(); i++) { + GenericCAO *obj = m_env->getGenericCAO(m_children[i]); + if (obj) { + obj->setVisible(toset); + } + } +} + void GenericCAO::setAttachments() { updateAttachments(); @@ -736,7 +746,7 @@ ClientActiveObject* GenericCAO::getParent() { ClientActiveObject *obj = NULL; - u16 attached_id = m_env->m_attachements[getId()]; + u16 attached_id = m_env->attachement_parent_ids[getId()]; if ((attached_id != 0) && (attached_id != getId())) { @@ -750,15 +760,14 @@ void GenericCAO::removeFromScene(bool permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals) if((m_env != NULL) && (permanent)) { - for(std::vector::iterator ci = m_children.begin(); - ci != m_children.end(); ci++) - { - if (m_env->m_attachements[*ci] == getId()) { - m_env->m_attachements[*ci] = 0; + for (std::vector::size_type i = 0; i < m_children.size(); i++) { + u16 ci = m_children[i]; + if (m_env->attachement_parent_ids[ci] == getId()) { + m_env->attachement_parent_ids[ci] = 0; } } - m_env->m_attachements[getId()] = 0; + m_env->attachement_parent_ids[getId()] = 0; LocalPlayer* player = m_env->getLocalPlayer(); if (this == player->parent) { @@ -925,10 +934,15 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, u8 li = m_last_light; setMeshColor(m_animated_meshnode->getMesh(), video::SColor(255,li,li,li)); + bool backface_culling = m_prop.backface_culling; + if (m_is_player) + backface_culling = false; + m_animated_meshnode->setMaterialFlag(video::EMF_LIGHTING, false); m_animated_meshnode->setMaterialFlag(video::EMF_BILINEAR_FILTER, false); m_animated_meshnode->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF); m_animated_meshnode->setMaterialFlag(video::EMF_FOG_ENABLE, true); + m_animated_meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, backface_culling); } else errorstream<<"GenericCAO::addToScene(): Could not load mesh "<getGUIEnvironment(); - std::wstring wname = narrow_to_wide(m_name); + std::wstring wname = utf8_to_wide(m_name); m_textnode = smgr->addTextSceneNode(gui->getSkin()->getFont(), wname.c_str(), m_nametag_color, node); m_textnode->grab(); m_textnode->setPosition(v3f(0, BS*1.1, 0)); + + // Enforce hiding nametag, + // because if freetype is enabled, a grey + // shadow can remain. + m_textnode->setVisible(m_nametag_color.getAlpha() > 0); } updateNodePos(); @@ -975,20 +994,38 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc, } void GenericCAO::updateLight(u8 light_at_pos) +{ + // Don't update light of attached one + if (getParent() != NULL) { + return; + } + + updateLightNoCheck(light_at_pos); + + // Update light of all children + for (std::vector::size_type i = 0; i < m_children.size(); i++) { + ClientActiveObject *obj = m_env->getActiveObject(m_children[i]); + if (obj) { + obj->updateLightNoCheck(light_at_pos); + } + } +} + +void GenericCAO::updateLightNoCheck(u8 light_at_pos) { u8 li = decode_light(light_at_pos); - if(li != m_last_light) - { + if (li != m_last_light) { m_last_light = li; video::SColor color(255,li,li,li); - if(m_meshnode) + if (m_meshnode) { setMeshColor(m_meshnode->getMesh(), color); - if(m_animated_meshnode) + } else if (m_animated_meshnode) { setMeshColor(m_animated_meshnode->getMesh(), color); - if(m_wield_meshnode) + } else if (m_wield_meshnode) { m_wield_meshnode->setColor(color); - if(m_spritenode) + } else if (m_spritenode) { m_spritenode->setColor(color); + } } } @@ -1100,7 +1137,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) for(std::vector::iterator ci = m_children.begin(); ci != m_children.end();) { - if (m_env->m_attachements[*ci] != getId()) { + if (m_env->attachement_parent_ids[*ci] != getId()) { ci = m_children.erase(ci); continue; } @@ -1117,11 +1154,9 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) addToScene(m_smgr, m_gamedef->tsrc(), m_irr); // Attachments, part 2: Now that the parent has been refreshed, put its attachments back - for(std::vector::iterator ci = m_children.begin(); - ci != m_children.end(); ci++) - { + for (std::vector::size_type i = 0; i < m_children.size(); i++) { // Get the object of the child - ClientActiveObject *obj = m_env->getActiveObject(*ci); + ClientActiveObject *obj = m_env->getActiveObject(m_children[i]); if (obj) obj->setAttachments(); } @@ -1459,9 +1494,18 @@ void GenericCAO::updateAnimation() { if(m_animated_meshnode == NULL) return; - m_animated_meshnode->setFrameLoop(m_animation_range.X, m_animation_range.Y); - m_animated_meshnode->setAnimationSpeed(m_animation_speed); + + if (m_animated_meshnode->getStartFrame() != m_animation_range.X || + m_animated_meshnode->getEndFrame() != m_animation_range.Y) + m_animated_meshnode->setFrameLoop(m_animation_range.X, m_animation_range.Y); + if (m_animated_meshnode->getAnimationSpeed() != m_animation_speed) + m_animated_meshnode->setAnimationSpeed(m_animation_speed); m_animated_meshnode->setTransitionTime(m_animation_blend); +// Requires Irrlicht 1.8 or greater +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR > 1 + if (m_animated_meshnode->getLoopMode() != m_animation_loop) + m_animated_meshnode->setLoopMode(m_animation_loop); +#endif } void GenericCAO::updateBonePosition() @@ -1489,16 +1533,7 @@ void GenericCAO::updateBonePosition() void GenericCAO::updateAttachments() { - // localplayer itself can't be attached to localplayer - if (!m_is_local_player) - { - m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer(); - // Objects attached to the local player should always be hidden - m_is_visible = !m_attached_to_local; - } - - if(getParent() == NULL || m_attached_to_local) // Detach or don't attach - { + if (getParent() == NULL) { // Detach or don't attach scene::ISceneNode *node = getSceneNode(); if (node) { v3f old_position = node->getAbsolutePosition(); @@ -1636,6 +1671,8 @@ void GenericCAO::processMessage(const std::string &data) m_animation_range = v2s32((s32)range.X, (s32)range.Y); m_animation_speed = readF1000(is); m_animation_blend = readF1000(is); + // these are sent inverted so we get true when the server sends nothing + m_animation_loop = !readU8(is); updateAnimation(); } else { LocalPlayer *player = m_env->getLocalPlayer(); @@ -1644,6 +1681,8 @@ void GenericCAO::processMessage(const std::string &data) m_animation_range = v2s32((s32)range.X, (s32)range.Y); m_animation_speed = readF1000(is); m_animation_blend = readF1000(is); + // these are sent inverted so we get true when the server sends nothing + m_animation_loop = !readU8(is); } // update animation only if local animations present // and received animation is unknown (except idle animation) @@ -1667,14 +1706,31 @@ void GenericCAO::processMessage(const std::string &data) m_bone_position[bone] = core::vector2d(position, rotation); updateBonePosition(); - } - else if(cmd == GENERIC_CMD_SET_ATTACHMENT) { - m_env->m_attachements[getId()] = readS16(is); - m_children.push_back(m_env->m_attachements[getId()]); + } else if (cmd == GENERIC_CMD_ATTACH_TO) { + u16 parentID = readS16(is); + u16 oldparent = m_env->attachement_parent_ids[getId()]; + if (oldparent) { + m_children.erase(std::remove(m_children.begin(), m_children.end(), + getId()), m_children.end()); + } + m_env->attachement_parent_ids[getId()] = parentID; + GenericCAO *parentobj = m_env->getGenericCAO(parentID); + + if (parentobj) { + parentobj->m_children.push_back(getId()); + } + m_attachment_bone = deSerializeString(is); m_attachment_position = readV3F1000(is); m_attachment_rotation = readV3F1000(is); + // localplayer itself can't be attached to localplayer + if (!m_is_local_player) { + m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer(); + // Objects attached to the local player should be hidden by default + m_is_visible = !m_attached_to_local; + } + updateAttachments(); } else if(cmd == GENERIC_CMD_PUNCHED) { @@ -1716,17 +1772,15 @@ void GenericCAO::processMessage(const std::string &data) m_armor_groups[name] = rating; } } else if (cmd == GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES) { - u8 version = readU8(is); // forward compatibility - if (version == 1) { - m_nametag_color = readARGB8(is); - if (m_textnode != NULL) { - m_textnode->setTextColor(m_nametag_color); - - // Enforce hiding nametag, - // because if freetype is enabled, a grey - // shadow can remain. - m_textnode->setVisible(m_nametag_color.getAlpha() > 0); - } + readU8(is); // version + m_nametag_color = readARGB8(is); + if (m_textnode != NULL) { + m_textnode->setTextColor(m_nametag_color); + + // Enforce hiding nametag, + // because if freetype is enabled, a grey + // shadow can remain. + m_textnode->setVisible(m_nametag_color.getAlpha() > 0); } } } @@ -1776,7 +1830,7 @@ std::string GenericCAO::debugInfoText() os<<"GenericCAO hp="<first<<"="<second<<", "; }