Fix for MSVC and move stuff around a bit in CMakeLists.txt and src/CMakeLists.txt
[oweals/minetest.git] / src / content_sao.cpp
index 5c03c90539d9db0832760d12b2db2cdc3d8613eb..85340981db7c64be614e1cbfdbd709d118e857a5 100644 (file)
@@ -354,7 +354,8 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos,
        m_last_sent_position(0,0,0),
        m_last_sent_velocity(0,0,0),
        m_last_sent_position_timer(0),
-       m_last_sent_move_precision(0)
+       m_last_sent_move_precision(0),
+       m_armor_groups_sent(false)
 {
        // Only register type if no environment supplied
        if(env == NULL){
@@ -380,42 +381,45 @@ void LuaEntitySAO::addedToEnvironment()
 {
        ServerActiveObject::addedToEnvironment();
        
-       // Create entity from name and state
+       // Create entity from name
        lua_State *L = m_env->getLua();
-       m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str(),
-                       m_init_state.c_str());
+       m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str());
        
        if(m_registered){
                // Get properties
                scriptapi_luaentity_get_properties(L, m_id, m_prop);
+               // Initialize HP from properties
+               m_hp = m_prop->hp_max;
        }
+       
+       // Activate entity, supplying serialized state
+       scriptapi_luaentity_activate(L, m_id, m_init_state.c_str());
 }
 
 ServerActiveObject* LuaEntitySAO::create(ServerEnvironment *env, v3f pos,
                const std::string &data)
 {
-       std::istringstream is(data, std::ios::binary);
-       // read version
-       u8 version = readU8(is);
        std::string name;
        std::string state;
        s16 hp = 1;
        v3f velocity;
        float yaw = 0;
-       // check if version is supported
-       if(version == 0){
-               name = deSerializeString(is);
-               state = deSerializeLongString(is);
-       }
-       else if(version == 1){
-               name = deSerializeString(is);
-               state = deSerializeLongString(is);
-               hp = readS16(is);
-               velocity = readV3F1000(is);
-               yaw = readF1000(is);
-       }
-       else{
-               return NULL;
+       if(data != ""){
+               std::istringstream is(data, std::ios::binary);
+               // read version
+               u8 version = readU8(is);
+               // check if version is supported
+               if(version == 0){
+                       name = deSerializeString(is);
+                       state = deSerializeLongString(is);
+               }
+               else if(version == 1){
+                       name = deSerializeString(is);
+                       state = deSerializeLongString(is);
+                       hp = readS16(is);
+                       velocity = readV3F1000(is);
+                       yaw = readF1000(is);
+               }
        }
        // create object
        infostream<<"LuaEntitySAO::create(name=\""<<name<<"\" state=\""
@@ -475,6 +479,21 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
                        fabs(m_yaw - m_last_sent_yaw) > 1.0){
                sendPosition(true, false);
        }
+
+       if(m_armor_groups_sent == false){
+               m_armor_groups_sent = true;
+               std::ostringstream os(std::ios::binary);
+               writeU8(os, LUAENTITY_CMD_UPDATE_ARMOR_GROUPS);
+               writeU16(os, m_armor_groups.size());
+               for(ItemGroupList::const_iterator i = m_armor_groups.begin();
+                               i != m_armor_groups.end(); i++){
+                       os<<serializeString(i->first);
+                       writeS16(os, i->second);
+               }
+               // create message and add to list
+               ActiveObjectMessage aom(getId(), true, os.str());
+               m_messages_out.push_back(aom);
+       }
 }
 
 std::string LuaEntitySAO::getClientInitializationData()
@@ -498,7 +517,7 @@ std::string LuaEntitySAO::getClientInitializationData()
 
 std::string LuaEntitySAO::getStaticData()
 {
-       infostream<<__FUNCTION_NAME<<std::endl;
+       verbosestream<<__FUNCTION_NAME<<std::endl;
        std::ostringstream os(std::ios::binary);
        // version
        writeU8(os, 1);
@@ -531,33 +550,50 @@ int LuaEntitySAO::punch(v3f dir,
                m_removed = true;
                return 0;
        }
-       lua_State *L = m_env->getLua();
-       scriptapi_luaentity_punch(L, m_id, puncher,
-                       time_from_last_punch, toolcap, dir);
+       
+       ItemStack *punchitem = NULL;
+       ItemStack punchitem_static;
+       if(puncher){
+               punchitem_static = puncher->getWieldedItem();
+               punchitem = &punchitem_static;
+       }
 
-       HitParams hitparams = getHitParams(m_armor_groups, toolcap,
+       PunchDamageResult result = getPunchDamage(
+                       m_armor_groups,
+                       toolcap,
+                       punchitem,
                        time_from_last_punch);
        
-       actionstream<<getDescription()<<" punched by "
-                       <<puncher->getDescription()<<", damage "<<hitparams.hp
-                       <<" HP"<<std::endl;
-       
-       setHP(getHP() - hitparams.hp);
-       
+       if(result.did_punch)
        {
-               std::ostringstream os(std::ios::binary);
-               // command 
-               writeU8(os, LUAENTITY_CMD_PUNCHED);
-               // damage
-               writeS16(os, hitparams.hp);
-               // result_hp
-               writeS16(os, getHP());
-               // create message and add to list
-               ActiveObjectMessage aom(getId(), true, os.str());
-               m_messages_out.push_back(aom);
+               setHP(getHP() - result.damage);
+               
+               actionstream<<getDescription()<<" punched by "
+                               <<puncher->getDescription()<<", damage "<<result.damage
+                               <<" hp, health now "<<getHP()<<" hp"<<std::endl;
+               
+               {
+                       std::ostringstream os(std::ios::binary);
+                       // command 
+                       writeU8(os, LUAENTITY_CMD_PUNCHED);
+                       // damage
+                       writeS16(os, result.damage);
+                       // result_hp
+                       writeS16(os, getHP());
+                       // create message and add to list
+                       ActiveObjectMessage aom(getId(), true, os.str());
+                       m_messages_out.push_back(aom);
+               }
+
+               if(getHP() == 0)
+                       m_removed = true;
        }
 
-       return hitparams.wear;
+       lua_State *L = m_env->getLua();
+       scriptapi_luaentity_punch(L, m_id, puncher,
+                       time_from_last_punch, toolcap, dir);
+
+       return result.wear;
 }
 
 void LuaEntitySAO::rightClick(ServerActiveObject *clicker)
@@ -605,7 +641,7 @@ std::string LuaEntitySAO::getDescription()
        os<<(m_base_position.Y/BS)<<",";
        os<<(m_base_position.Z/BS);
        os<<")";
-       return std::string("LuaEntitySAO");
+       return os.str();
 }
 
 void LuaEntitySAO::setVelocity(v3f velocity)
@@ -671,6 +707,12 @@ std::string LuaEntitySAO::getName()
        return m_init_name;
 }
 
+void LuaEntitySAO::setArmorGroups(const ItemGroupList &armor_groups)
+{
+       m_armor_groups = armor_groups;
+       m_armor_groups_sent = false;
+}
+
 void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end)
 {
        m_last_sent_move_precision = m_base_position.getDistanceFrom(