Skip to content

Commit

Permalink
A bunch of fixes
Browse files Browse the repository at this point in the history
No longer hide players who are dead. With models, a death animation should be used instead

Some changes requested by celeron55

Rename a lot of things in the code, and use better lua api function names

Minor code corrections

Bump protocol version up, since the models / animations / attachments code creates new client<->server messages
  • Loading branch information
MirceaKitsune authored and celeron55 committed Nov 25, 2012
1 parent fa67b46 commit 756db81
Show file tree
Hide file tree
Showing 13 changed files with 144 additions and 156 deletions.
8 changes: 4 additions & 4 deletions doc/lua_api.txt
Expand Up @@ -1103,10 +1103,10 @@ methods:
- get_wielded_item() -> ItemStack
- set_wielded_item(item): replaces the wielded item, returns true if successful
- set_armor_groups({group1=rating, group2=rating, ...})
- set_animations({x=1,y=1}, frame_speed=15, frame_blend=0)
- set_attachment(parent, "", {x=0,y=0,z=0}, {x=0,y=0,z=0})
- set_detachment()
- set_bone_posrot("", {x=0,y=0,z=0}, {x=0,y=0,z=0})
- set_animation({x=1,y=1}, frame_speed=15, frame_blend=0)
- set_attach(parent, "", {x=0,y=0,z=0}, {x=0,y=0,z=0})
- set_detach()
- set_bone_position("", {x=0,y=0,z=0}, {x=0,y=0,z=0})
- set_properties(object property table)
LuaEntitySAO-only: (no-op for other objects)
- setvelocity({x=num, y=num, z=num})
Expand Down
8 changes: 4 additions & 4 deletions src/client.cpp
Expand Up @@ -821,8 +821,8 @@ bool Client::loadMedia(const std::string &data, const std::string &filename)
name = removeStringEnd(filename, image_ext);
if(name != "")
{
verbosestream<<"Client: Storing image into Irrlicht: "
<<"\""<<filename<<"\""<<std::endl;
verbosestream<<"Client: Attempting to load image "
<<"file \""<<filename<<"\""<<std::endl;

io::IFileSystem *irrfs = m_device->getFileSystem();
video::IVideoDriver *vdrv = m_device->getVideoDriver();
Expand Down Expand Up @@ -855,8 +855,8 @@ bool Client::loadMedia(const std::string &data, const std::string &filename)
name = removeStringEnd(filename, sound_ext);
if(name != "")
{
verbosestream<<"Client: Storing sound into Irrlicht: "
<<"\""<<filename<<"\""<<std::endl;
verbosestream<<"Client: Attempting to load sound "
<<"file \""<<filename<<"\""<<std::endl;
m_sound->loadSoundData(name, data);
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/clientobject.h
Expand Up @@ -61,7 +61,7 @@ class ClientActiveObject : public ActiveObject
virtual scene::IBillboardSceneNode *getSpriteSceneNode(){return NULL;}
virtual bool isPlayer(){return false;}
virtual bool isLocalPlayer(){return false;}
virtual void updateParent(){}
virtual void setAttachments(){}
virtual bool doShowSelectionBox(){return true;}

// Step object in time
Expand Down
7 changes: 6 additions & 1 deletion src/clientserver.h
Expand Up @@ -67,9 +67,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
TOCLIENT_DETACHED_INVENTORY
PROTOCOL_VERSION 13:
InventoryList field "Width" (deserialization fails with old versions)
PROTOCOL_VERSION 14:
New messages for mesh and bone animation, as well as attachments
GENERIC_CMD_SET_ANIMATION
GENERIC_CMD_SET_BONE_POSITION
GENERIC_CMD_SET_ATTACHMENT
*/

#define PROTOCOL_VERSION 13
#define PROTOCOL_VERSION 14

#define PROTOCOL_ID 0x4f457403

Expand Down
119 changes: 49 additions & 70 deletions src/content_cao.cpp
Expand Up @@ -52,8 +52,6 @@ struct ToolCapabilities;

core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;

std::vector<core::vector2d<int> > attachment_list; // X is child ID, Y is parent ID

/*
SmoothTranslator
*/
Expand Down Expand Up @@ -580,10 +578,10 @@ class GenericCAO : public ClientActiveObject
v2s16 m_tx_basepos;
bool m_initial_tx_basepos_set;
bool m_tx_select_horiz_by_yawpitch;
v2f m_frames;
int m_frame_speed;
int m_frame_blend;
std::map<std::string, core::vector2d<v3f> > m_bone_posrot; // stores position and rotation for each bone name
v2f m_animation_range;
int m_animation_speed;
int m_animation_blend;
std::map<std::string, core::vector2d<v3f> > m_bone_position; // stores position and rotation for each bone name
std::string m_attachment_bone;
v3f m_attachment_position;
v3f m_attachment_rotation;
Expand Down Expand Up @@ -623,10 +621,10 @@ class GenericCAO : public ClientActiveObject
m_tx_basepos(0,0),
m_initial_tx_basepos_set(false),
m_tx_select_horiz_by_yawpitch(false),
m_frames(v2f(0,0)),
m_frame_speed(15),
m_frame_blend(0),
m_bone_posrot(std::map<std::string, core::vector2d<v3f> >()),
m_animation_range(v2f(0,0)),
m_animation_speed(15),
m_animation_blend(0),
m_bone_position(std::map<std::string, core::vector2d<v3f> >()),
m_attachment_bone(""),
m_attachment_position(v3f(0,0,0)),
m_attachment_rotation(v3f(0,0,0)),
Expand Down Expand Up @@ -709,7 +707,7 @@ class GenericCAO : public ClientActiveObject
return m_animated_meshnode->getAbsolutePosition();
if(m_spritenode)
return m_spritenode->getAbsolutePosition();
return v3f(0,0,0); // Just in case
return m_position;
}
return pos_translator.vect_show;
}
Expand Down Expand Up @@ -745,17 +743,17 @@ class GenericCAO : public ClientActiveObject
return m_is_local_player;
}

void updateParent()
void setAttachments()
{
updateAttachments();
}

ClientActiveObject *getParent()
{
ClientActiveObject *obj = NULL;
for(std::vector<core::vector2d<int> >::const_iterator cii = attachment_list.begin(); cii != attachment_list.end(); cii++)
for(std::vector<core::vector2d<int> >::const_iterator cii = m_env->attachment_list.begin(); cii != m_env->attachment_list.end(); cii++)
{
if(cii->X == this->getId()){ // This ID is our child
if(cii->X == getId()){ // This ID is our child
if(cii->Y > 0){ // A parent ID exists for our child
if(cii->X != cii->Y){ // The parent and child ID are not the same
obj = m_env->getActiveObject(cii->Y);
Expand All @@ -774,22 +772,22 @@ class GenericCAO : public ClientActiveObject
if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals)
{
// Detach this object's children
for(std::vector<core::vector2d<int> >::iterator ii = attachment_list.begin(); ii != attachment_list.end(); ii++)
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
{
if(ii->Y == this->getId()) // Is a child of our object
if(ii->Y == getId()) // Is a child of our object
{
ii->Y = 0;
ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
if(obj)
obj->updateParent();
obj->setAttachments();
}
}
// Delete this object from the attachments list
for(std::vector<core::vector2d<int> >::iterator ii = attachment_list.begin(); ii != attachment_list.end(); ii++)
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
{
if(ii->X == this->getId()) // Is our object
if(ii->X == getId()) // Is our object
{
attachment_list.erase(ii);
m_env->attachment_list.erase(ii);
break;
}
}
Expand Down Expand Up @@ -983,31 +981,16 @@ class GenericCAO : public ClientActiveObject

void updateLight(u8 light_at_pos)
{
// Objects attached to the local player should always be hidden
if(m_attached_to_local)
m_is_visible = false;
else
m_is_visible = (m_hp != 0);
u8 li = decode_light(light_at_pos);

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);
m_meshnode->setVisible(m_is_visible);
}
if(m_animated_meshnode){
if(m_animated_meshnode)
setMeshColor(m_animated_meshnode->getMesh(), color);
m_animated_meshnode->setVisible(m_is_visible);
}
if(m_spritenode){
if(m_spritenode)
m_spritenode->setColor(color);
m_spritenode->setVisible(m_is_visible);
}
if(m_textnode){
m_textnode->setVisible(m_is_visible);
}
}
}

Expand Down Expand Up @@ -1044,9 +1027,9 @@ class GenericCAO : public ClientActiveObject
m_visuals_expired = false;

// Attachments, part 1: All attached objects must be unparented first, or Irrlicht causes a segmentation fault
for(std::vector<core::vector2d<int> >::iterator ii = attachment_list.begin(); ii != attachment_list.end(); ii++)
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
{
if(ii->Y == this->getId()) // This is a child of our parent
if(ii->Y == getId()) // This is a child of our parent
{
ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
if(obj)
Expand All @@ -1066,18 +1049,18 @@ class GenericCAO : public ClientActiveObject

removeFromScene(false);
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
updateAnimations();
updateBonePosRot();
updateAnimation();
updateBonePosition();
updateAttachments();

// Attachments, part 2: Now that the parent has been refreshed, put its attachments back
for(std::vector<core::vector2d<int> >::iterator ii = attachment_list.begin(); ii != attachment_list.end(); ii++)
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
{
if(ii->Y == this->getId()) // This is a child of our parent
if(ii->Y == getId()) // This is a child of our parent
{
ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
if(obj)
obj->updateParent();
obj->setAttachments();
}
}
}
Expand All @@ -1095,12 +1078,7 @@ class GenericCAO : public ClientActiveObject
if(getParent() != NULL) // Attachments should be glued to their parent by Irrlicht
{
// Set these for later
if(m_meshnode)
m_position = m_meshnode->getAbsolutePosition();
if(m_animated_meshnode)
m_position = m_animated_meshnode->getAbsolutePosition();
if(m_spritenode)
m_position = m_spritenode->getAbsolutePosition();
m_position = getPosition();
m_velocity = v3f(0,0,0);
m_acceleration = v3f(0,0,0);
pos_translator.vect_show = m_position;
Expand Down Expand Up @@ -1405,23 +1383,23 @@ class GenericCAO : public ClientActiveObject
}
}

void updateAnimations()
void updateAnimation()
{
if(m_animated_meshnode == NULL)
return;

m_animated_meshnode->setFrameLoop((int)m_frames.X, (int)m_frames.Y);
m_animated_meshnode->setAnimationSpeed(m_frame_speed);
m_animated_meshnode->setTransitionTime(m_frame_blend);
m_animated_meshnode->setFrameLoop((int)m_animation_range.X, (int)m_animation_range.Y);
m_animated_meshnode->setAnimationSpeed(m_animation_speed);
m_animated_meshnode->setTransitionTime(m_animation_blend);
}

void updateBonePosRot()
void updateBonePosition()
{
if(!m_bone_posrot.size() || m_animated_meshnode == NULL)
if(!m_bone_position.size() || m_animated_meshnode == NULL)
return;

m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_posrot.begin(); ii != m_bone_posrot.end(); ++ii){
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
std::string bone_name = (*ii).first;
v3f bone_pos = (*ii).second.X;
v3f bone_rot = (*ii).second.Y;
Expand All @@ -1437,6 +1415,7 @@ class GenericCAO : public ClientActiveObject
void updateAttachments()
{
m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer();
m_is_visible = !m_attached_to_local; // Objects attached to the local player should always be hidden

if(getParent() == NULL || m_attached_to_local) // Detach or don't attach
{
Expand Down Expand Up @@ -1658,35 +1637,35 @@ class GenericCAO : public ClientActiveObject

updateTexturePos();
}
else if(cmd == GENERIC_CMD_SET_ANIMATIONS)
else if(cmd == GENERIC_CMD_SET_ANIMATION)
{
m_frames = readV2F1000(is);
m_frame_speed = readF1000(is);
m_frame_blend = readF1000(is);
m_animation_range = readV2F1000(is);
m_animation_speed = readF1000(is);
m_animation_blend = readF1000(is);

updateAnimations();
updateAnimation();
}
else if(cmd == GENERIC_CMD_SET_BONE_POSROT)
else if(cmd == GENERIC_CMD_SET_BONE_POSITION)
{
std::string bone = deSerializeString(is);
v3f position = readV3F1000(is);
v3f rotation = readV3F1000(is);
m_bone_posrot[bone] = core::vector2d<v3f>(position, rotation);
m_bone_position[bone] = core::vector2d<v3f>(position, rotation);

updateBonePosRot();
updateBonePosition();
}
else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
{
// If an entry already exists for this object, delete it first to avoid duplicates
for(std::vector<core::vector2d<int> >::iterator ii = attachment_list.begin(); ii != attachment_list.end(); ii++)
for(std::vector<core::vector2d<int> >::iterator ii = m_env->attachment_list.begin(); ii != m_env->attachment_list.end(); ii++)
{
if(ii->X == this->getId()) // This is the ID of our object
if(ii->X == getId()) // This is the ID of our object
{
attachment_list.erase(ii);
m_env->attachment_list.erase(ii);
break;
}
}
attachment_list.push_back(core::vector2d<int>(this->getId(), readS16(is)));
m_env->attachment_list.push_back(core::vector2d<int>(getId(), readS16(is)));
m_attachment_bone = deSerializeString(is);
m_attachment_position = readV3F1000(is);
m_attachment_rotation = readV3F1000(is);
Expand Down

0 comments on commit 756db81

Please sign in to comment.