Fix some remaining issues with attachments, now they work. Tested with object->player and player->player attachments
parent
948b5a8be7
commit
ba3fd63e29
|
@ -56,6 +56,11 @@ public:
|
||||||
virtual core::aabbox3d<f32>* getSelectionBox(){return NULL;}
|
virtual core::aabbox3d<f32>* getSelectionBox(){return NULL;}
|
||||||
virtual core::aabbox3d<f32>* getCollisionBox(){return NULL;}
|
virtual core::aabbox3d<f32>* getCollisionBox(){return NULL;}
|
||||||
virtual v3f getPosition(){return v3f(0,0,0);}
|
virtual v3f getPosition(){return v3f(0,0,0);}
|
||||||
|
virtual scene::IMeshSceneNode *getMeshSceneNode(){return NULL;}
|
||||||
|
virtual scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode(){return NULL;}
|
||||||
|
virtual scene::IBillboardSceneNode *getSpriteSceneNode(){return NULL;}
|
||||||
|
virtual bool isPlayer(){return false;}
|
||||||
|
virtual bool isLocalPlayer(){return false;}
|
||||||
virtual bool doShowSelectionBox(){return true;}
|
virtual bool doShowSelectionBox(){return true;}
|
||||||
|
|
||||||
// Step object in time
|
// Step object in time
|
||||||
|
|
|
@ -554,7 +554,7 @@ private:
|
||||||
// Only set at initialization
|
// Only set at initialization
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
bool m_is_player;
|
bool m_is_player;
|
||||||
bool m_is_local_player; // determined locally
|
bool m_is_local_player;
|
||||||
int m_id;
|
int m_id;
|
||||||
// Property-ish things
|
// Property-ish things
|
||||||
ObjectProperties m_prop;
|
ObjectProperties m_prop;
|
||||||
|
@ -594,6 +594,7 @@ private:
|
||||||
bool m_visuals_expired;
|
bool m_visuals_expired;
|
||||||
float m_step_distance_counter;
|
float m_step_distance_counter;
|
||||||
u8 m_last_light;
|
u8 m_last_light;
|
||||||
|
bool m_is_visible;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericCAO(IGameDef *gamedef, ClientEnvironment *env):
|
GenericCAO(IGameDef *gamedef, ClientEnvironment *env):
|
||||||
|
@ -634,7 +635,8 @@ public:
|
||||||
m_reset_textures_timer(-1),
|
m_reset_textures_timer(-1),
|
||||||
m_visuals_expired(false),
|
m_visuals_expired(false),
|
||||||
m_step_distance_counter(0),
|
m_step_distance_counter(0),
|
||||||
m_last_light(255)
|
m_last_light(255),
|
||||||
|
m_is_visible(false)
|
||||||
{
|
{
|
||||||
if(gamedef == NULL)
|
if(gamedef == NULL)
|
||||||
ClientActiveObject::registerType(getType(), create);
|
ClientActiveObject::registerType(getType(), create);
|
||||||
|
@ -691,7 +693,7 @@ public:
|
||||||
}
|
}
|
||||||
core::aabbox3d<f32>* getSelectionBox()
|
core::aabbox3d<f32>* getSelectionBox()
|
||||||
{
|
{
|
||||||
if(!m_prop.is_visible || m_is_local_player)
|
if(!m_prop.is_visible || !m_is_visible || m_is_local_player)
|
||||||
return NULL;
|
return NULL;
|
||||||
return &m_selection_box;
|
return &m_selection_box;
|
||||||
}
|
}
|
||||||
|
@ -700,6 +702,31 @@ public:
|
||||||
return pos_translator.vect_show;
|
return pos_translator.vect_show;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scene::IMeshSceneNode *getMeshSceneNode()
|
||||||
|
{
|
||||||
|
return m_meshnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode()
|
||||||
|
{
|
||||||
|
return m_animated_meshnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene::IBillboardSceneNode *getSpriteSceneNode()
|
||||||
|
{
|
||||||
|
return m_spritenode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPlayer()
|
||||||
|
{
|
||||||
|
return m_is_player;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLocalPlayer()
|
||||||
|
{
|
||||||
|
return m_is_local_player;
|
||||||
|
}
|
||||||
|
|
||||||
void removeFromScene()
|
void removeFromScene()
|
||||||
{
|
{
|
||||||
if(m_meshnode){
|
if(m_meshnode){
|
||||||
|
@ -891,22 +918,27 @@ public:
|
||||||
|
|
||||||
void updateLight(u8 light_at_pos)
|
void updateLight(u8 light_at_pos)
|
||||||
{
|
{
|
||||||
bool is_visible = (m_hp != 0);
|
// Objects attached to the local player should always be hidden
|
||||||
|
if(m_attachment_parent != NULL && m_attachment_parent->isLocalPlayer())
|
||||||
|
m_is_visible = false;
|
||||||
|
else
|
||||||
|
m_is_visible = (m_hp != 0);
|
||||||
u8 li = decode_light(light_at_pos);
|
u8 li = decode_light(light_at_pos);
|
||||||
|
|
||||||
if(li != m_last_light){
|
if(li != m_last_light){
|
||||||
m_last_light = li;
|
m_last_light = li;
|
||||||
video::SColor color(255,li,li,li);
|
video::SColor color(255,li,li,li);
|
||||||
if(m_meshnode){
|
if(m_meshnode){
|
||||||
setMeshColor(m_meshnode->getMesh(), color);
|
setMeshColor(m_meshnode->getMesh(), color);
|
||||||
m_meshnode->setVisible(is_visible);
|
m_meshnode->setVisible(m_is_visible);
|
||||||
}
|
}
|
||||||
if(m_animated_meshnode){
|
if(m_animated_meshnode){
|
||||||
setMeshColor(m_animated_meshnode->getMesh(), color);
|
setMeshColor(m_animated_meshnode->getMesh(), color);
|
||||||
m_animated_meshnode->setVisible(is_visible);
|
m_animated_meshnode->setVisible(m_is_visible);
|
||||||
}
|
}
|
||||||
if(m_spritenode){
|
if(m_spritenode){
|
||||||
m_spritenode->setColor(color);
|
m_spritenode->setColor(color);
|
||||||
m_spritenode->setVisible(is_visible);
|
m_spritenode->setVisible(m_is_visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -948,6 +980,7 @@ public:
|
||||||
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
|
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
|
||||||
updateAnimations();
|
updateAnimations();
|
||||||
updateBonePosRot();
|
updateBonePosRot();
|
||||||
|
updateAttachments();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_attachment_parent == NULL) // Attachments should be glued to their parent by Irrlicht
|
if(m_attachment_parent == NULL) // Attachments should be glued to their parent by Irrlicht
|
||||||
|
@ -1019,6 +1052,9 @@ public:
|
||||||
m_yaw += dtime * m_prop.automatic_rotate * 180 / M_PI;
|
m_yaw += dtime * m_prop.automatic_rotate * 180 / M_PI;
|
||||||
updateNodePos();
|
updateNodePos();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_animated_meshnode)
|
||||||
|
errorstream<<"Attachment position: "<<m_animated_meshnode->getPosition().X<<","<<m_animated_meshnode->getPosition().Y<<","<<m_animated_meshnode->getPosition().Z<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTexturePos()
|
void updateTexturePos()
|
||||||
|
@ -1241,7 +1277,120 @@ public:
|
||||||
//Useful links:
|
//Useful links:
|
||||||
// http://irrlicht.sourceforge.net/forum/viewtopic.php?t=7514
|
// http://irrlicht.sourceforge.net/forum/viewtopic.php?t=7514
|
||||||
// http://www.irrlicht3d.org/wiki/index.php?n=Main.HowToUseTheNewAnimationSystem
|
// http://www.irrlicht3d.org/wiki/index.php?n=Main.HowToUseTheNewAnimationSystem
|
||||||
|
// http://gamedev.stackexchange.com/questions/27363/finding-the-endpoint-of-a-named-bone-in-irrlicht
|
||||||
// Irrlicht documentation: http://irrlicht.sourceforge.net/docu/
|
// Irrlicht documentation: http://irrlicht.sourceforge.net/docu/
|
||||||
|
|
||||||
|
if (m_attachment_parent != NULL && !m_attachment_parent->isLocalPlayer())
|
||||||
|
{
|
||||||
|
// REMAINING ATTACHMENT ISSUES:
|
||||||
|
// The code below should cause the child to get attached, but for some reason it's not working
|
||||||
|
// A debug print confirms both position and absolute position are set accordingly, but the object still shows at origin 0,0,0
|
||||||
|
|
||||||
|
scene::IMeshSceneNode *parent_mesh = NULL;
|
||||||
|
if(m_attachment_parent->getMeshSceneNode())
|
||||||
|
parent_mesh = m_attachment_parent->getMeshSceneNode();
|
||||||
|
scene::IAnimatedMeshSceneNode *parent_animated_mesh = NULL;
|
||||||
|
if(m_attachment_parent->getAnimatedMeshSceneNode())
|
||||||
|
parent_animated_mesh = m_attachment_parent->getAnimatedMeshSceneNode();
|
||||||
|
scene::IBillboardSceneNode *parent_sprite = NULL;
|
||||||
|
if(m_attachment_parent->getSpriteSceneNode())
|
||||||
|
parent_sprite = m_attachment_parent->getSpriteSceneNode();
|
||||||
|
|
||||||
|
scene::IBoneSceneNode *parent_bone = NULL;
|
||||||
|
if(parent_animated_mesh && m_attachment_bone != "")
|
||||||
|
parent_bone = parent_animated_mesh->getJointNode(m_attachment_bone.c_str());
|
||||||
|
if(!parent_bone) // Should be false if the bone doesn't exist on the mesh
|
||||||
|
parent_bone = NULL;
|
||||||
|
|
||||||
|
// TODO: Perhaps use polymorphism here to save code duplication
|
||||||
|
if(m_meshnode){
|
||||||
|
if(parent_bone){
|
||||||
|
m_meshnode->setPosition(parent_bone->getPosition());
|
||||||
|
m_meshnode->setRotation(parent_bone->getRotation());
|
||||||
|
m_meshnode->updateAbsolutePosition();
|
||||||
|
//m_meshnode->setParent(parent_bone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(parent_mesh){
|
||||||
|
m_meshnode->setPosition(parent_mesh->getPosition());
|
||||||
|
m_meshnode->setRotation(parent_mesh->getRotation());
|
||||||
|
m_meshnode->updateAbsolutePosition();
|
||||||
|
//m_meshnode->setParent(parent_mesh);
|
||||||
|
}
|
||||||
|
else if(parent_animated_mesh){
|
||||||
|
m_meshnode->setPosition(parent_animated_mesh->getPosition());
|
||||||
|
m_meshnode->setRotation(parent_animated_mesh->getRotation());
|
||||||
|
m_meshnode->updateAbsolutePosition();
|
||||||
|
//m_meshnode->setParent(parent_animated_mesh);
|
||||||
|
}
|
||||||
|
else if(parent_sprite){
|
||||||
|
m_meshnode->setPosition(parent_sprite->getPosition());
|
||||||
|
m_meshnode->setRotation(parent_sprite->getRotation());
|
||||||
|
m_meshnode->updateAbsolutePosition();
|
||||||
|
//m_meshnode->setParent(parent_sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(m_animated_meshnode){
|
||||||
|
if(parent_bone){
|
||||||
|
m_animated_meshnode->setPosition(parent_bone->getPosition());
|
||||||
|
m_animated_meshnode->setRotation(parent_bone->getRotation());
|
||||||
|
m_animated_meshnode->updateAbsolutePosition();
|
||||||
|
//m_animated_meshnode->setParent(parent_bone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(parent_mesh){
|
||||||
|
m_animated_meshnode->setPosition(parent_mesh->getPosition());
|
||||||
|
m_animated_meshnode->setRotation(parent_mesh->getRotation());
|
||||||
|
m_animated_meshnode->updateAbsolutePosition();
|
||||||
|
//m_animated_meshnode->setParent(parent_mesh);
|
||||||
|
}
|
||||||
|
else if(parent_animated_mesh){
|
||||||
|
m_animated_meshnode->setPosition(parent_animated_mesh->getPosition());
|
||||||
|
m_animated_meshnode->setRotation(parent_animated_mesh->getRotation());
|
||||||
|
m_animated_meshnode->updateAbsolutePosition();
|
||||||
|
//m_animated_meshnode->setParent(parent_animated_mesh);
|
||||||
|
}
|
||||||
|
else if(parent_sprite){
|
||||||
|
m_animated_meshnode->setPosition(parent_sprite->getPosition());
|
||||||
|
m_animated_meshnode->setRotation(parent_sprite->getRotation());
|
||||||
|
m_animated_meshnode->updateAbsolutePosition();
|
||||||
|
//m_animated_meshnode->setParent(parent_sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(m_spritenode){
|
||||||
|
if(parent_bone){
|
||||||
|
m_spritenode->setPosition(parent_bone->getPosition());
|
||||||
|
m_spritenode->setRotation(parent_bone->getRotation());
|
||||||
|
m_spritenode->updateAbsolutePosition();
|
||||||
|
//m_spritenode->setParent(parent_bone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(parent_mesh){
|
||||||
|
m_spritenode->setPosition(parent_mesh->getPosition());
|
||||||
|
m_spritenode->setRotation(parent_mesh->getRotation());
|
||||||
|
m_spritenode->updateAbsolutePosition();
|
||||||
|
//m_spritenode->setParent(parent_mesh);
|
||||||
|
}
|
||||||
|
else if(parent_animated_mesh){
|
||||||
|
m_spritenode->setPosition(parent_animated_mesh->getPosition());
|
||||||
|
m_spritenode->setRotation(parent_animated_mesh->getRotation());
|
||||||
|
m_spritenode->updateAbsolutePosition();
|
||||||
|
//m_spritenode->setParent(parent_animated_mesh);
|
||||||
|
}
|
||||||
|
else if(parent_sprite){
|
||||||
|
m_spritenode->setPosition(parent_sprite->getPosition());
|
||||||
|
m_spritenode->setRotation(parent_sprite->getRotation());
|
||||||
|
m_spritenode->updateAbsolutePosition();
|
||||||
|
//m_spritenode->setParent(parent_sprite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void processMessage(const std::string &data)
|
void processMessage(const std::string &data)
|
||||||
|
@ -1334,11 +1483,9 @@ public:
|
||||||
}
|
}
|
||||||
else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
|
else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
|
||||||
{
|
{
|
||||||
ClientActiveObject *obj;
|
|
||||||
int parent_id = readS16(is);
|
int parent_id = readS16(is);
|
||||||
if(parent_id > 0)
|
ClientActiveObject *obj = m_env->getActiveObject(parent_id);
|
||||||
obj = m_env->getActiveObject(parent_id);
|
if(!parent_id || !obj)
|
||||||
else
|
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
m_attachment_parent = obj;
|
m_attachment_parent = obj;
|
||||||
m_attachment_bone = deSerializeString(is);
|
m_attachment_bone = deSerializeString(is);
|
||||||
|
|
|
@ -444,11 +444,12 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
|
|
||||||
m_last_sent_position_timer += dtime;
|
m_last_sent_position_timer += dtime;
|
||||||
|
|
||||||
|
// Each frame, parent position is copied if the object is attached, otherwise it's calculated normally
|
||||||
|
// If the object gets detached this comes into effect automatically from the last known origin
|
||||||
if(m_parent != NULL)
|
if(m_parent != NULL)
|
||||||
{
|
{
|
||||||
// REMAINING ATTACHMENT ISSUES:
|
v3f pos = m_parent->getBasePosition();
|
||||||
// This is causing a segmentation fault, investigate why!
|
m_base_position = pos;
|
||||||
//m_base_position = m_parent->getBasePosition();
|
|
||||||
m_velocity = v3f(0,0,0);
|
m_velocity = v3f(0,0,0);
|
||||||
m_acceleration = v3f(0,0,0);
|
m_acceleration = v3f(0,0,0);
|
||||||
}
|
}
|
||||||
|
@ -486,20 +487,23 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
||||||
|
|
||||||
if(send_recommended == false)
|
if(send_recommended == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: force send when acceleration changes enough?
|
if(m_parent != NULL)
|
||||||
float minchange = 0.2*BS;
|
{
|
||||||
if(m_last_sent_position_timer > 1.0){
|
// TODO: force send when acceleration changes enough?
|
||||||
minchange = 0.01*BS;
|
float minchange = 0.2*BS;
|
||||||
} else if(m_last_sent_position_timer > 0.2){
|
if(m_last_sent_position_timer > 1.0){
|
||||||
minchange = 0.05*BS;
|
minchange = 0.01*BS;
|
||||||
}
|
} else if(m_last_sent_position_timer > 0.2){
|
||||||
float move_d = m_base_position.getDistanceFrom(m_last_sent_position);
|
minchange = 0.05*BS;
|
||||||
move_d += m_last_sent_move_precision;
|
}
|
||||||
float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity);
|
float move_d = m_base_position.getDistanceFrom(m_last_sent_position);
|
||||||
if(move_d > minchange || vel_d > minchange ||
|
move_d += m_last_sent_move_precision;
|
||||||
fabs(m_yaw - m_last_sent_yaw) > 1.0){
|
float vel_d = m_velocity.getDistanceFrom(m_last_sent_velocity);
|
||||||
sendPosition(true, false);
|
if(move_d > minchange || vel_d > minchange ||
|
||||||
|
fabs(m_yaw - m_last_sent_yaw) > 1.0){
|
||||||
|
sendPosition(true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_armor_groups_sent == false){
|
if(m_armor_groups_sent == false){
|
||||||
|
@ -686,11 +690,11 @@ void LuaEntitySAO::setAttachment(ServerActiveObject *parent, std::string bone, v
|
||||||
{
|
{
|
||||||
// Attachments need to be handled on both the server and client.
|
// Attachments need to be handled on both the server and client.
|
||||||
// If we just attach on the server, we can only copy the position of the parent. Attachments
|
// If we just attach on the server, we can only copy the position of the parent. Attachments
|
||||||
// are still sent to clients at an interval so players would see them following the parent
|
// are still sent to clients at an interval so players might see them lagging, plus we can't
|
||||||
// instead of sticking to it, plus we can't read and attach to skeletal bones.
|
// read and attach to skeletal bones.
|
||||||
// If we just attach on the client, the server still sees the child at its original location.
|
// If we just attach on the client, the server still sees the child at its original location.
|
||||||
// This can break some things, so we also give the server the most accurate representation
|
// This breaks some things so we also give the server the most accurate representation
|
||||||
// even if players will only see the client changes since they override server-sent position.
|
// even if players only see the client changes.
|
||||||
|
|
||||||
// Server attachment:
|
// Server attachment:
|
||||||
m_parent = parent;
|
m_parent = parent;
|
||||||
|
@ -776,6 +780,7 @@ std::string LuaEntitySAO::getPropertyPacket()
|
||||||
|
|
||||||
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
|
||||||
{
|
{
|
||||||
|
// If the object is attached client-side, don't waste bandwidth sending its position to clients
|
||||||
if(m_parent != NULL)
|
if(m_parent != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -925,7 +930,7 @@ std::string PlayerSAO::getStaticData()
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerSAO::step(float dtime, bool send_recommended)
|
void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
{
|
{
|
||||||
if(!m_properties_sent)
|
if(!m_properties_sent)
|
||||||
{
|
{
|
||||||
m_properties_sent = true;
|
m_properties_sent = true;
|
||||||
|
@ -938,7 +943,16 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
m_time_from_last_punch += dtime;
|
m_time_from_last_punch += dtime;
|
||||||
m_nocheat_dig_time += dtime;
|
m_nocheat_dig_time += dtime;
|
||||||
|
|
||||||
if(m_parent == NULL)
|
// Each frame, parent position is copied if the object is attached, otherwise it's calculated normally
|
||||||
|
// If the object gets detached this comes into effect automatically from the last known origin
|
||||||
|
if(m_parent != NULL)
|
||||||
|
{
|
||||||
|
v3f pos = m_parent->getBasePosition();
|
||||||
|
m_last_good_position = pos;
|
||||||
|
m_last_good_position_age = 0;
|
||||||
|
m_player->setPosition(pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if(m_is_singleplayer || g_settings->getBool("disable_anticheat"))
|
if(m_is_singleplayer || g_settings->getBool("disable_anticheat"))
|
||||||
{
|
{
|
||||||
|
@ -999,15 +1013,13 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
if(send_recommended == false)
|
if(send_recommended == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If the object is attached client-side, don't waste bandwidth and send its position to clients
|
// If the object is attached client-side, don't waste bandwidth sending its position to clients
|
||||||
if(m_position_not_sent && m_parent == NULL)
|
if(m_position_not_sent && m_parent == NULL)
|
||||||
{
|
{
|
||||||
m_position_not_sent = false;
|
m_position_not_sent = false;
|
||||||
float update_interval = m_env->getSendRecommendedInterval();
|
float update_interval = m_env->getSendRecommendedInterval();
|
||||||
v3f pos;
|
v3f pos;
|
||||||
// REMAINING ATTACHMENT ISSUES:
|
if(m_parent != NULL) // Just in case we ever do send attachment position too
|
||||||
// This is causing a segmentation fault, investigate why!
|
|
||||||
if(m_parent != NULL)
|
|
||||||
pos = m_parent->getBasePosition();
|
pos = m_parent->getBasePosition();
|
||||||
else
|
else
|
||||||
pos = m_player->getPosition() + v3f(0,BS*1,0);
|
pos = m_player->getPosition() + v3f(0,BS*1,0);
|
||||||
|
@ -1043,8 +1055,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
||||||
|
|
||||||
void PlayerSAO::setBasePosition(const v3f &position)
|
void PlayerSAO::setBasePosition(const v3f &position)
|
||||||
{
|
{
|
||||||
if(m_parent != NULL)
|
// This needs to be ran for attachments too
|
||||||
return;
|
|
||||||
ServerActiveObject::setBasePosition(position);
|
ServerActiveObject::setBasePosition(position);
|
||||||
m_position_not_sent = true;
|
m_position_not_sent = true;
|
||||||
}
|
}
|
||||||
|
@ -1183,11 +1194,11 @@ void PlayerSAO::setAttachment(ServerActiveObject *parent, std::string bone, v3f
|
||||||
{
|
{
|
||||||
// Attachments need to be handled on both the server and client.
|
// Attachments need to be handled on both the server and client.
|
||||||
// If we just attach on the server, we can only copy the position of the parent. Attachments
|
// If we just attach on the server, we can only copy the position of the parent. Attachments
|
||||||
// are still sent to clients at an interval so players would see them following the parent
|
// are still sent to clients at an interval so players might see them lagging, plus we can't
|
||||||
// instead of sticking to it, plus we can't read and attach to skeletal bones.
|
// read and attach to skeletal bones.
|
||||||
// If we just attach on the client, the server still sees the child at its original location.
|
// If we just attach on the client, the server still sees the child at its original location.
|
||||||
// This can break some things, so we also give the server the most accurate representation
|
// This breaks some things so we also give the server the most accurate representation
|
||||||
// even if players will only see the client changes since they override server-sent position.
|
// even if players only see the client changes.
|
||||||
|
|
||||||
// Server attachment:
|
// Server attachment:
|
||||||
m_parent = parent;
|
m_parent = parent;
|
||||||
|
|
|
@ -254,6 +254,7 @@ void ContentFeatures::serialize(std::ostream &os)
|
||||||
os<<serializeString(liquid_alternative_flowing);
|
os<<serializeString(liquid_alternative_flowing);
|
||||||
os<<serializeString(liquid_alternative_source);
|
os<<serializeString(liquid_alternative_source);
|
||||||
writeU8(os, liquid_viscosity);
|
writeU8(os, liquid_viscosity);
|
||||||
|
writeU8(os, liquid_renewable);
|
||||||
writeU8(os, light_source);
|
writeU8(os, light_source);
|
||||||
writeU32(os, damage_per_second);
|
writeU32(os, damage_per_second);
|
||||||
node_box.serialize(os);
|
node_box.serialize(os);
|
||||||
|
@ -311,6 +312,7 @@ void ContentFeatures::deSerialize(std::istream &is)
|
||||||
liquid_alternative_flowing = deSerializeString(is);
|
liquid_alternative_flowing = deSerializeString(is);
|
||||||
liquid_alternative_source = deSerializeString(is);
|
liquid_alternative_source = deSerializeString(is);
|
||||||
liquid_viscosity = readU8(is);
|
liquid_viscosity = readU8(is);
|
||||||
|
liquid_renewable = readU8(is);
|
||||||
light_source = readU8(is);
|
light_source = readU8(is);
|
||||||
damage_per_second = readU32(is);
|
damage_per_second = readU32(is);
|
||||||
node_box.deSerialize(is);
|
node_box.deSerialize(is);
|
||||||
|
|
Loading…
Reference in New Issue