A bunch of fixes

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
This commit is contained in:
MirceaKitsune 2012-11-12 16:35:10 +02:00 committed by Perttu Ahola
parent fa67b46c04
commit 756db8174a
13 changed files with 144 additions and 156 deletions

@ -1103,10 +1103,10 @@ methods:
- get_wielded_item() -> ItemStack - get_wielded_item() -> ItemStack
- set_wielded_item(item): replaces the wielded item, returns true if successful - set_wielded_item(item): replaces the wielded item, returns true if successful
- set_armor_groups({group1=rating, group2=rating, ...}) - set_armor_groups({group1=rating, group2=rating, ...})
- set_animations({x=1,y=1}, frame_speed=15, frame_blend=0) - set_animation({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_attach(parent, "", {x=0,y=0,z=0}, {x=0,y=0,z=0})
- set_detachment() - set_detach()
- set_bone_posrot("", {x=0,y=0,z=0}, {x=0,y=0,z=0}) - set_bone_position("", {x=0,y=0,z=0}, {x=0,y=0,z=0})
- set_properties(object property table) - set_properties(object property table)
LuaEntitySAO-only: (no-op for other objects) LuaEntitySAO-only: (no-op for other objects)
- setvelocity({x=num, y=num, z=num}) - setvelocity({x=num, y=num, z=num})

@ -821,8 +821,8 @@ bool Client::loadMedia(const std::string &data, const std::string &filename)
name = removeStringEnd(filename, image_ext); name = removeStringEnd(filename, image_ext);
if(name != "") if(name != "")
{ {
verbosestream<<"Client: Storing image into Irrlicht: " verbosestream<<"Client: Attempting to load image "
<<"\""<<filename<<"\""<<std::endl; <<"file \""<<filename<<"\""<<std::endl;
io::IFileSystem *irrfs = m_device->getFileSystem(); io::IFileSystem *irrfs = m_device->getFileSystem();
video::IVideoDriver *vdrv = m_device->getVideoDriver(); video::IVideoDriver *vdrv = m_device->getVideoDriver();
@ -855,8 +855,8 @@ bool Client::loadMedia(const std::string &data, const std::string &filename)
name = removeStringEnd(filename, sound_ext); name = removeStringEnd(filename, sound_ext);
if(name != "") if(name != "")
{ {
verbosestream<<"Client: Storing sound into Irrlicht: " verbosestream<<"Client: Attempting to load sound "
<<"\""<<filename<<"\""<<std::endl; <<"file \""<<filename<<"\""<<std::endl;
m_sound->loadSoundData(name, data); m_sound->loadSoundData(name, data);
return true; return true;
} }

@ -61,7 +61,7 @@ public:
virtual scene::IBillboardSceneNode *getSpriteSceneNode(){return NULL;} virtual scene::IBillboardSceneNode *getSpriteSceneNode(){return NULL;}
virtual bool isPlayer(){return false;} virtual bool isPlayer(){return false;}
virtual bool isLocalPlayer(){return false;} virtual bool isLocalPlayer(){return false;}
virtual void updateParent(){} virtual void setAttachments(){}
virtual bool doShowSelectionBox(){return true;} virtual bool doShowSelectionBox(){return true;}
// Step object in time // Step object in time

@ -67,9 +67,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
TOCLIENT_DETACHED_INVENTORY TOCLIENT_DETACHED_INVENTORY
PROTOCOL_VERSION 13: PROTOCOL_VERSION 13:
InventoryList field "Width" (deserialization fails with old versions) 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 #define PROTOCOL_ID 0x4f457403

@ -52,8 +52,6 @@ struct ToolCapabilities;
core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types; core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types;
std::vector<core::vector2d<int> > attachment_list; // X is child ID, Y is parent ID
/* /*
SmoothTranslator SmoothTranslator
*/ */
@ -580,10 +578,10 @@ private:
v2s16 m_tx_basepos; v2s16 m_tx_basepos;
bool m_initial_tx_basepos_set; bool m_initial_tx_basepos_set;
bool m_tx_select_horiz_by_yawpitch; bool m_tx_select_horiz_by_yawpitch;
v2f m_frames; v2f m_animation_range;
int m_frame_speed; int m_animation_speed;
int m_frame_blend; int m_animation_blend;
std::map<std::string, core::vector2d<v3f> > m_bone_posrot; // stores position and rotation for each bone name std::map<std::string, core::vector2d<v3f> > m_bone_position; // stores position and rotation for each bone name
std::string m_attachment_bone; std::string m_attachment_bone;
v3f m_attachment_position; v3f m_attachment_position;
v3f m_attachment_rotation; v3f m_attachment_rotation;
@ -623,10 +621,10 @@ public:
m_tx_basepos(0,0), m_tx_basepos(0,0),
m_initial_tx_basepos_set(false), m_initial_tx_basepos_set(false),
m_tx_select_horiz_by_yawpitch(false), m_tx_select_horiz_by_yawpitch(false),
m_frames(v2f(0,0)), m_animation_range(v2f(0,0)),
m_frame_speed(15), m_animation_speed(15),
m_frame_blend(0), m_animation_blend(0),
m_bone_posrot(std::map<std::string, core::vector2d<v3f> >()), m_bone_position(std::map<std::string, core::vector2d<v3f> >()),
m_attachment_bone(""), m_attachment_bone(""),
m_attachment_position(v3f(0,0,0)), m_attachment_position(v3f(0,0,0)),
m_attachment_rotation(v3f(0,0,0)), m_attachment_rotation(v3f(0,0,0)),
@ -709,7 +707,7 @@ public:
return m_animated_meshnode->getAbsolutePosition(); return m_animated_meshnode->getAbsolutePosition();
if(m_spritenode) if(m_spritenode)
return m_spritenode->getAbsolutePosition(); return m_spritenode->getAbsolutePosition();
return v3f(0,0,0); // Just in case return m_position;
} }
return pos_translator.vect_show; return pos_translator.vect_show;
} }
@ -745,7 +743,7 @@ public:
return m_is_local_player; return m_is_local_player;
} }
void updateParent() void setAttachments()
{ {
updateAttachments(); updateAttachments();
} }
@ -753,9 +751,9 @@ public:
ClientActiveObject *getParent() ClientActiveObject *getParent()
{ {
ClientActiveObject *obj = NULL; 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->Y > 0){ // A parent ID exists for our child
if(cii->X != cii->Y){ // The parent and child ID are not the same if(cii->X != cii->Y){ // The parent and child ID are not the same
obj = m_env->getActiveObject(cii->Y); obj = m_env->getActiveObject(cii->Y);
@ -774,22 +772,22 @@ public:
if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals) if(permanent) // Should be true when removing the object permanently and false when refreshing (eg: updating visuals)
{ {
// Detach this object's children // 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; ii->Y = 0;
ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
if(obj) if(obj)
obj->updateParent(); obj->setAttachments();
} }
} }
// Delete this object from the attachments list // 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; break;
} }
} }
@ -983,31 +981,16 @@ public:
void updateLight(u8 light_at_pos) 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); 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(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(m_is_visible); if(m_spritenode)
}
if(m_spritenode){
m_spritenode->setColor(color); m_spritenode->setColor(color);
m_spritenode->setVisible(m_is_visible);
}
if(m_textnode){
m_textnode->setVisible(m_is_visible);
}
} }
} }
@ -1044,9 +1027,9 @@ public:
m_visuals_expired = false; m_visuals_expired = false;
// Attachments, part 1: All attached objects must be unparented first, or Irrlicht causes a segmentation fault // 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 ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
if(obj) if(obj)
@ -1066,18 +1049,18 @@ public:
removeFromScene(false); removeFromScene(false);
addToScene(m_smgr, m_gamedef->tsrc(), m_irr); addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
updateAnimations(); updateAnimation();
updateBonePosRot(); updateBonePosition();
updateAttachments(); updateAttachments();
// Attachments, part 2: Now that the parent has been refreshed, put its attachments back // 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 ClientActiveObject *obj = m_env->getActiveObject(ii->X); // Get the object of the child
if(obj) if(obj)
obj->updateParent(); obj->setAttachments();
} }
} }
} }
@ -1095,12 +1078,7 @@ public:
if(getParent() != NULL) // Attachments should be glued to their parent by Irrlicht if(getParent() != NULL) // Attachments should be glued to their parent by Irrlicht
{ {
// Set these for later // Set these for later
if(m_meshnode) m_position = getPosition();
m_position = m_meshnode->getAbsolutePosition();
if(m_animated_meshnode)
m_position = m_animated_meshnode->getAbsolutePosition();
if(m_spritenode)
m_position = m_spritenode->getAbsolutePosition();
m_velocity = v3f(0,0,0); m_velocity = v3f(0,0,0);
m_acceleration = v3f(0,0,0); m_acceleration = v3f(0,0,0);
pos_translator.vect_show = m_position; pos_translator.vect_show = m_position;
@ -1405,23 +1383,23 @@ public:
} }
} }
void updateAnimations() void updateAnimation()
{ {
if(m_animated_meshnode == NULL) if(m_animated_meshnode == NULL)
return; return;
m_animated_meshnode->setFrameLoop((int)m_frames.X, (int)m_frames.Y); m_animated_meshnode->setFrameLoop((int)m_animation_range.X, (int)m_animation_range.Y);
m_animated_meshnode->setAnimationSpeed(m_frame_speed); m_animated_meshnode->setAnimationSpeed(m_animation_speed);
m_animated_meshnode->setTransitionTime(m_frame_blend); 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; return;
m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render 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; std::string bone_name = (*ii).first;
v3f bone_pos = (*ii).second.X; v3f bone_pos = (*ii).second.X;
v3f bone_rot = (*ii).second.Y; v3f bone_rot = (*ii).second.Y;
@ -1437,6 +1415,7 @@ public:
void updateAttachments() void updateAttachments()
{ {
m_attached_to_local = getParent() != NULL && getParent()->isLocalPlayer(); 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 if(getParent() == NULL || m_attached_to_local) // Detach or don't attach
{ {
@ -1658,35 +1637,35 @@ public:
updateTexturePos(); updateTexturePos();
} }
else if(cmd == GENERIC_CMD_SET_ANIMATIONS) else if(cmd == GENERIC_CMD_SET_ANIMATION)
{ {
m_frames = readV2F1000(is); m_animation_range = readV2F1000(is);
m_frame_speed = readF1000(is); m_animation_speed = readF1000(is);
m_frame_blend = 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); std::string bone = deSerializeString(is);
v3f position = readV3F1000(is); v3f position = readV3F1000(is);
v3f rotation = 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) else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
{ {
// If an entry already exists for this object, delete it first to avoid duplicates // 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; 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_bone = deSerializeString(is);
m_attachment_position = readV3F1000(is); m_attachment_position = readV3F1000(is);
m_attachment_rotation = readV3F1000(is); m_attachment_rotation = readV3F1000(is);

@ -356,8 +356,8 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
m_last_sent_position_timer(0), m_last_sent_position_timer(0),
m_last_sent_move_precision(0), m_last_sent_move_precision(0),
m_armor_groups_sent(false), m_armor_groups_sent(false),
m_animations_sent(false), m_animation_sent(false),
m_animations_bone_sent(false), m_bone_position_sent(false),
m_attachment_sent(false) m_attachment_sent(false)
{ {
// Only register type if no environment supplied // Only register type if no environment supplied
@ -537,18 +537,18 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
m_messages_out.push_back(aom); m_messages_out.push_back(aom);
} }
if(m_animations_sent == false){ if(m_animation_sent == false){
m_animations_sent = true; m_animation_sent = true;
std::string str = gob_cmd_update_animations(m_animation_frames, m_animation_speed, m_animation_blend); std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom); m_messages_out.push_back(aom);
} }
if(m_animations_bone_sent == false){ if(m_bone_position_sent == false){
m_animations_bone_sent = true; m_bone_position_sent = true;
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_animation_bone.begin(); ii != m_animation_bone.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 str = gob_cmd_update_bone_posrot((*ii).first, (*ii).second.X, (*ii).second.Y); std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom); m_messages_out.push_back(aom);
@ -575,12 +575,12 @@ std::string LuaEntitySAO::getClientInitializationData()
writeF1000(os, m_yaw); writeF1000(os, m_yaw);
writeS16(os, m_hp); writeS16(os, m_hp);
writeU8(os, 4 + m_animation_bone.size()); // number of messages stuffed in here writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
os<<serializeLongString(getPropertyPacket()); // message 1 os<<serializeLongString(getPropertyPacket()); // message 1
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2 os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
os<<serializeLongString(gob_cmd_update_animations(m_animation_frames, m_animation_speed, m_animation_blend)); // 3 os<<serializeLongString(gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend)); // 3
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_animation_bone.begin(); ii != m_animation_bone.end(); ++ii){ for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
os<<serializeLongString(gob_cmd_update_bone_posrot((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_animation_bone.size os<<serializeLongString(gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
} }
os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4 os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
@ -728,18 +728,18 @@ void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
m_armor_groups_sent = false; m_armor_groups_sent = false;
} }
void LuaEntitySAO::setAnimations(v2f frames, float frame_speed, float frame_blend) void LuaEntitySAO::setAnimation(v2f frame_range, float frame_speed, float frame_blend)
{ {
m_animation_frames = frames; m_animation_range = frame_range;
m_animation_speed = frame_speed; m_animation_speed = frame_speed;
m_animation_blend = frame_blend; m_animation_blend = frame_blend;
m_animations_sent = false; m_animation_sent = false;
} }
void LuaEntitySAO::setBonePosRot(std::string bone, v3f position, v3f rotation) void LuaEntitySAO::setBonePosition(std::string bone, v3f position, v3f rotation)
{ {
m_animation_bone[bone] = core::vector2d<v3f>(position, rotation); m_bone_position[bone] = core::vector2d<v3f>(position, rotation);
m_animations_bone_sent = false; m_bone_position_sent = false;
} }
void LuaEntitySAO::setAttachment(int parent_id, std::string bone, v3f position, v3f rotation) void LuaEntitySAO::setAttachment(int parent_id, std::string bone, v3f position, v3f rotation)
@ -884,8 +884,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
m_properties_sent(true), m_properties_sent(true),
m_privs(privs), m_privs(privs),
m_is_singleplayer(is_singleplayer), m_is_singleplayer(is_singleplayer),
m_animations_sent(false), m_animation_sent(false),
m_animations_bone_sent(false), m_bone_position_sent(false),
m_attachment_sent(false), m_attachment_sent(false),
// public // public
m_moved(false), m_moved(false),
@ -914,7 +914,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
m_prop.colors.push_back(video::SColor(255, 255, 255, 255)); m_prop.colors.push_back(video::SColor(255, 255, 255, 255));
m_prop.spritediv = v2s16(1,1); m_prop.spritediv = v2s16(1,1);
// end of default appearance // end of default appearance
m_prop.is_visible = (getHP() != 0); // TODO: Use a death animation instead for mesh players m_prop.is_visible = true;
m_prop.makes_footstep_sound = true; m_prop.makes_footstep_sound = true;
} }
@ -973,12 +973,12 @@ std::string PlayerSAO::getClientInitializationData()
writeF1000(os, m_player->getYaw()); writeF1000(os, m_player->getYaw());
writeS16(os, getHP()); writeS16(os, getHP());
writeU8(os, 4 + m_animation_bone.size()); // number of messages stuffed in here writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here
os<<serializeLongString(getPropertyPacket()); // message 1 os<<serializeLongString(getPropertyPacket()); // message 1
os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2 os<<serializeLongString(gob_cmd_update_armor_groups(m_armor_groups)); // 2
os<<serializeLongString(gob_cmd_update_animations(m_animation_frames, m_animation_speed, m_animation_blend)); // 3 os<<serializeLongString(gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend)); // 3
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_animation_bone.begin(); ii != m_animation_bone.end(); ++ii){ for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii){
os<<serializeLongString(gob_cmd_update_bone_posrot((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_animation_bone.size os<<serializeLongString(gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y)); // m_bone_position.size
} }
os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4 os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
@ -1137,18 +1137,18 @@ void PlayerSAO::step(float dtime, bool send_recommended)
m_messages_out.push_back(aom); m_messages_out.push_back(aom);
} }
if(m_animations_sent == false){ if(m_animation_sent == false){
m_animations_sent = true; m_animation_sent = true;
std::string str = gob_cmd_update_animations(m_animation_frames, m_animation_speed, m_animation_blend); std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom); m_messages_out.push_back(aom);
} }
if(m_animations_bone_sent == false){ if(m_bone_position_sent == false){
m_animations_bone_sent = true; m_bone_position_sent = true;
for(std::map<std::string, core::vector2d<v3f> >::const_iterator ii = m_animation_bone.begin(); ii != m_animation_bone.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 str = gob_cmd_update_bone_posrot((*ii).first, (*ii).second.X, (*ii).second.Y); std::string str = gob_cmd_update_bone_position((*ii).first, (*ii).second.X, (*ii).second.Y);
// create message and add to list // create message and add to list
ActiveObjectMessage aom(getId(), true, str); ActiveObjectMessage aom(getId(), true, str);
m_messages_out.push_back(aom); m_messages_out.push_back(aom);
@ -1285,20 +1285,20 @@ void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups)
m_armor_groups_sent = false; m_armor_groups_sent = false;
} }
void PlayerSAO::setAnimations(v2f frames, float frame_speed, float frame_blend) void PlayerSAO::setAnimation(v2f frame_range, float frame_speed, float frame_blend)
{ {
// store these so they can be updated to clients // store these so they can be updated to clients
m_animation_frames = frames; m_animation_range = frame_range;
m_animation_speed = frame_speed; m_animation_speed = frame_speed;
m_animation_blend = frame_blend; m_animation_blend = frame_blend;
m_animations_sent = false; m_animation_sent = false;
} }
void PlayerSAO::setBonePosRot(std::string bone, v3f position, v3f rotation) void PlayerSAO::setBonePosition(std::string bone, v3f position, v3f rotation)
{ {
// store these so they can be updated to clients // store these so they can be updated to clients
m_animation_bone[bone] = core::vector2d<v3f>(position, rotation); m_bone_position[bone] = core::vector2d<v3f>(position, rotation);
m_animations_bone_sent = false; m_bone_position_sent = false;
} }
void PlayerSAO::setAttachment(int parent_id, std::string bone, v3f position, v3f rotation) void PlayerSAO::setAttachment(int parent_id, std::string bone, v3f position, v3f rotation)
@ -1381,7 +1381,7 @@ void PlayerSAO::disconnected()
std::string PlayerSAO::getPropertyPacket() std::string PlayerSAO::getPropertyPacket()
{ {
m_prop.is_visible = (getHP() != 0); m_prop.is_visible = (true);
return gob_cmd_set_properties(m_prop); return gob_cmd_set_properties(m_prop);
} }

@ -62,8 +62,8 @@ public:
void setHP(s16 hp); void setHP(s16 hp);
s16 getHP() const; s16 getHP() const;
void setArmorGroups(const ItemGroupList &armor_groups); void setArmorGroups(const ItemGroupList &armor_groups);
void setAnimations(v2f frames, float frame_speed, float frame_blend); void setAnimation(v2f frame_range, float frame_speed, float frame_blend);
void setBonePosRot(std::string bone, v3f position, v3f rotation); void setBonePosition(std::string bone, v3f position, v3f rotation);
void setAttachment(int parent_id, std::string bone, v3f position, v3f rotation); void setAttachment(int parent_id, std::string bone, v3f position, v3f rotation);
ObjectProperties* accessObjectProperties(); ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified(); void notifyObjectPropertiesModified();
@ -101,13 +101,13 @@ private:
float m_last_sent_move_precision; float m_last_sent_move_precision;
bool m_armor_groups_sent; bool m_armor_groups_sent;
v2f m_animation_frames; v2f m_animation_range;
float m_animation_speed; float m_animation_speed;
float m_animation_blend; float m_animation_blend;
bool m_animations_sent; bool m_animation_sent;
std::map<std::string, core::vector2d<v3f> > m_animation_bone; std::map<std::string, core::vector2d<v3f> > m_bone_position;
bool m_animations_bone_sent; bool m_bone_position_sent;
int m_attachment_parent_id; int m_attachment_parent_id;
std::string m_attachment_bone; std::string m_attachment_bone;
@ -161,8 +161,8 @@ public:
void setHP(s16 hp); void setHP(s16 hp);
void setArmorGroups(const ItemGroupList &armor_groups); void setArmorGroups(const ItemGroupList &armor_groups);
void setAnimations(v2f frames, float frame_speed, float frame_blend); void setAnimation(v2f frame_range, float frame_speed, float frame_blend);
void setBonePosRot(std::string bone, v3f position, v3f rotation); void setBonePosition(std::string bone, v3f position, v3f rotation);
void setAttachment(int parent_id, std::string bone, v3f position, v3f rotation); void setAttachment(int parent_id, std::string bone, v3f position, v3f rotation);
ObjectProperties* accessObjectProperties(); ObjectProperties* accessObjectProperties();
void notifyObjectPropertiesModified(); void notifyObjectPropertiesModified();
@ -260,13 +260,13 @@ private:
std::set<std::string> m_privs; std::set<std::string> m_privs;
bool m_is_singleplayer; bool m_is_singleplayer;
v2f m_animation_frames; v2f m_animation_range;
float m_animation_speed; float m_animation_speed;
float m_animation_blend; float m_animation_blend;
bool m_animations_sent; bool m_animation_sent;
std::map<std::string, core::vector2d<v3f> > m_animation_bone; // stores position and rotation for each bone name std::map<std::string, core::vector2d<v3f> > m_bone_position; // Stores position and rotation for each bone name
bool m_animations_bone_sent; bool m_bone_position_sent;
int m_attachment_parent_id; int m_attachment_parent_id;
std::string m_attachment_bone; std::string m_attachment_bone;

@ -464,6 +464,8 @@ public:
// Get event from queue. CEE_NONE is returned if queue is empty. // Get event from queue. CEE_NONE is returned if queue is empty.
ClientEnvEvent getClientEvent(); ClientEnvEvent getClientEvent();
std::vector<core::vector2d<int> > attachment_list; // X is child ID, Y is parent ID
private: private:
ClientMap *m_map; ClientMap *m_map;
scene::ISceneManager *m_smgr; scene::ISceneManager *m_smgr;

@ -92,11 +92,11 @@ std::string gob_cmd_set_sprite(
return os.str(); return os.str();
} }
std::string gob_cmd_update_animations(v2f frames, float frame_speed, float frame_blend) std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend)
{ {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
// command // command
writeU8(os, GENERIC_CMD_SET_ANIMATIONS); writeU8(os, GENERIC_CMD_SET_ANIMATION);
// parameters // parameters
writeV2F1000(os, frames); writeV2F1000(os, frames);
writeF1000(os, frame_speed); writeF1000(os, frame_speed);
@ -104,11 +104,11 @@ std::string gob_cmd_update_animations(v2f frames, float frame_speed, float frame
return os.str(); return os.str();
} }
std::string gob_cmd_update_bone_posrot(std::string bone, v3f position, v3f rotation) std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rotation)
{ {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
// command // command
writeU8(os, GENERIC_CMD_SET_BONE_POSROT); writeU8(os, GENERIC_CMD_SET_BONE_POSITION);
// parameters // parameters
os<<serializeString(bone); os<<serializeString(bone);
writeV3F1000(os, position); writeV3F1000(os, position);

@ -28,8 +28,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define GENERIC_CMD_UPDATE_POSITION 1 #define GENERIC_CMD_UPDATE_POSITION 1
#define GENERIC_CMD_SET_TEXTURE_MOD 2 #define GENERIC_CMD_SET_TEXTURE_MOD 2
#define GENERIC_CMD_SET_SPRITE 3 #define GENERIC_CMD_SET_SPRITE 3
#define GENERIC_CMD_SET_ANIMATIONS 4 #define GENERIC_CMD_SET_ANIMATION 4
#define GENERIC_CMD_SET_BONE_POSROT 5 #define GENERIC_CMD_SET_BONE_POSITION 5
#define GENERIC_CMD_SET_ATTACHMENT 6 #define GENERIC_CMD_SET_ATTACHMENT 6
#define GENERIC_CMD_PUNCHED 7 #define GENERIC_CMD_PUNCHED 7
#define GENERIC_CMD_UPDATE_ARMOR_GROUPS 8 #define GENERIC_CMD_UPDATE_ARMOR_GROUPS 8
@ -57,9 +57,9 @@ std::string gob_cmd_set_sprite(
bool select_horiz_by_yawpitch bool select_horiz_by_yawpitch
); );
std::string gob_cmd_update_animations(v2f frames, float frame_speed, float frame_blend); std::string gob_cmd_update_animation(v2f frames, float frame_speed, float frame_blend);
std::string gob_cmd_update_bone_posrot(std::string bone, v3f position, v3f rotation); std::string gob_cmd_update_bone_position(std::string bone, v3f position, v3f rotation);
std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f position, v3f rotation); std::string gob_cmd_update_attachment(int parent_id, std::string bone, v3f position, v3f rotation);

@ -714,6 +714,7 @@ void GUIFormSpecMenu::drawMenu()
Draw backgrounds Draw backgrounds
*/ */
for(u32 i=0; i<m_backgrounds.size(); i++) for(u32 i=0; i<m_backgrounds.size(); i++)
{
const ImageDrawSpec &spec = m_backgrounds[i]; const ImageDrawSpec &spec = m_backgrounds[i];
video::ITexture *texture = video::ITexture *texture =
m_gamedef->tsrc()->getTextureRaw(spec.name); m_gamedef->tsrc()->getTextureRaw(spec.name);
@ -727,6 +728,7 @@ void GUIFormSpecMenu::drawMenu()
core::rect<s32>(core::position2d<s32>(0,0), core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(texture->getOriginalSize())), core::dimension2di(texture->getOriginalSize())),
NULL/*&AbsoluteClippingRect*/, colors, true); NULL/*&AbsoluteClippingRect*/, colors, true);
}
/* /*
Draw images Draw images

@ -2716,8 +2716,8 @@ private:
return 0; return 0;
} }
// setanimations(self, frames, frame_speed, frame_blend) // set_animation(self, frame_range, frame_speed, frame_blend)
static int l_set_animations(lua_State *L) static int l_set_animation(lua_State *L)
{ {
ObjectRef *ref = checkobject(L, 1); ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref); ServerActiveObject *co = getobject(ref);
@ -2732,12 +2732,12 @@ private:
float frame_blend = 0; float frame_blend = 0;
if(!lua_isnil(L, 4)) if(!lua_isnil(L, 4))
frame_blend = lua_tonumber(L, 4); frame_blend = lua_tonumber(L, 4);
co->setAnimations(frames, frame_speed, frame_blend); co->setAnimation(frames, frame_speed, frame_blend);
return 0; return 0;
} }
// setboneposrot(self, std::string bone, v3f position, v3f rotation) // set_bone_position(self, std::string bone, v3f position, v3f rotation)
static int l_set_bone_posrot(lua_State *L) static int l_set_bone_position(lua_State *L)
{ {
ObjectRef *ref = checkobject(L, 1); ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref); ServerActiveObject *co = getobject(ref);
@ -2752,12 +2752,12 @@ private:
v3f rotation = v3f(0, 0, 0); v3f rotation = v3f(0, 0, 0);
if(!lua_isnil(L, 4)) if(!lua_isnil(L, 4))
rotation = read_v3f(L, 4); rotation = read_v3f(L, 4);
co->setBonePosRot(bone, position, rotation); co->setBonePosition(bone, position, rotation);
return 0; return 0;
} }
// set_attachment(self, parent, bone, position, rotation) // set_attach(self, parent, bone, position, rotation)
static int l_set_attachment(lua_State *L) static int l_set_attach(lua_State *L)
{ {
ObjectRef *ref = checkobject(L, 1); ObjectRef *ref = checkobject(L, 1);
ObjectRef *parent_ref = checkobject(L, 2); ObjectRef *parent_ref = checkobject(L, 2);
@ -2779,8 +2779,8 @@ private:
return 0; return 0;
} }
// set_detachment(self) // set_detach(self)
static int l_set_detachment(lua_State *L) static int l_set_detach(lua_State *L)
{ {
ObjectRef *ref = checkobject(L, 1); ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref); ServerActiveObject *co = getobject(ref);
@ -3104,10 +3104,10 @@ const luaL_reg ObjectRef::methods[] = {
method(ObjectRef, get_wielded_item), method(ObjectRef, get_wielded_item),
method(ObjectRef, set_wielded_item), method(ObjectRef, set_wielded_item),
method(ObjectRef, set_armor_groups), method(ObjectRef, set_armor_groups),
method(ObjectRef, set_animations), method(ObjectRef, set_animation),
method(ObjectRef, set_bone_posrot), method(ObjectRef, set_bone_position),
method(ObjectRef, set_attachment), method(ObjectRef, set_attach),
method(ObjectRef, set_detachment), method(ObjectRef, set_detach),
method(ObjectRef, set_properties), method(ObjectRef, set_properties),
// LuaEntitySAO-only // LuaEntitySAO-only
method(ObjectRef, setvelocity), method(ObjectRef, setvelocity),

@ -152,9 +152,9 @@ public:
virtual void setArmorGroups(const ItemGroupList &armor_groups) virtual void setArmorGroups(const ItemGroupList &armor_groups)
{} {}
virtual void setAnimations(v2f frames, float frame_speed, float frame_blend) virtual void setAnimation(v2f frames, float frame_speed, float frame_blend)
{} {}
virtual void setBonePosRot(std::string bone, v3f position, v3f rotation) virtual void setBonePosition(std::string bone, v3f position, v3f rotation)
{} {}
virtual void setAttachment(int parent_id, std::string bone, v3f position, v3f rotation) virtual void setAttachment(int parent_id, std::string bone, v3f position, v3f rotation)
{} {}