diff options
-rw-r--r-- | src/clientobject.h | 5 | ||||
-rw-r--r-- | src/content_cao.cpp | 33 | ||||
-rw-r--r-- | src/content_sao.cpp | 56 | ||||
-rw-r--r-- | src/game.cpp | 11 | ||||
-rw-r--r-- | src/tool.cpp | 34 | ||||
-rw-r--r-- | src/tool.h | 22 |
6 files changed, 134 insertions, 27 deletions
diff --git a/src/clientobject.h b/src/clientobject.h index 2e1b850c7..946858404 100644 --- a/src/clientobject.h +++ b/src/clientobject.h @@ -38,6 +38,8 @@ Some planning class ClientEnvironment; class ITextureSource; class IGameDef; +class LocalPlayer; +struct ItemStack; class ClientActiveObject : public ActiveObject { @@ -75,7 +77,8 @@ public: ClientEnvironment *env); // If returns true, punch will not be sent to the server - virtual bool directReportPunch(const std::string &toolname, v3f dir) + virtual bool directReportPunch(v3f dir, const ItemStack *punchitem=NULL, + float time_from_last_punch=1000000) { return false; } protected: diff --git a/src/content_cao.cpp b/src/content_cao.cpp index d6289a1b9..836f719a3 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -31,7 +31,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_object.h" #include "mesh.h" #include "utility.h" // For IntervalLimiter +#include "itemdef.h" +#include "tool.h" class Settings; +struct ToolCapabilities; core::map<u16, ClientActiveObject::Factory> ClientActiveObject::m_types; @@ -585,13 +588,41 @@ public: } else if(cmd == LUAENTITY_CMD_PUNCHED) { - s16 damage = readS16(is); + /*s16 damage =*/ readS16(is); s16 result_hp = readS16(is); m_hp = result_hp; // TODO: Execute defined fast response } } + + bool directReportPunch(v3f dir, const ItemStack *punchitem=NULL, + float time_from_last_punch=1000000) + { + // TODO: Transfer this from the server + ItemGroupList m_armor_groups; + + assert(punchitem); + const ToolCapabilities *toolcap = + &punchitem->getToolCapabilities(m_gamedef->idef()); + PunchDamageResult result = getPunchDamage( + m_armor_groups, + toolcap, + punchitem, + time_from_last_punch); + + if(result.did_punch) + { + // TODO: Decrease hp by + if(result.damage < m_hp) + m_hp -= result.damage; + else + m_hp = 0; + // TODO: Execute defined fast response + } + + return false; + } }; // Prototype diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 5c03c9053..0c105bb0f 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -531,33 +531,47 @@ 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); + actionstream<<getDescription()<<" punched by " + <<puncher->getDescription()<<", damage "<<result.damage + <<" HP"<<std::endl; + + setHP(getHP() - result.damage); + + { + 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); + } } - 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) diff --git a/src/game.cpp b/src/game.cpp index 594583fdc..d5a733c60 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2088,10 +2088,13 @@ void the_game( } if(do_punch_damage){ // Report direct punch - v3f objpos = selected_object->getPosition(); - v3f dir = (objpos - player_position).normalize(); - - bool disable_send = selected_object->directReportPunch(playeritem.name, dir); + v3f objpos = selected_object->getPosition(); + v3f dir = (objpos - player_position).normalize(); + + // TODO: Get time_from_last_punch from somewhere + float time_from_last_punch = 1000000; + bool disable_send = selected_object->directReportPunch( + dir, &playeritem, time_from_last_punch); if(!disable_send) client.interact(0, pointed); } diff --git a/src/tool.cpp b/src/tool.cpp index da7ee73dc..d6f994307 100644 --- a/src/tool.cpp +++ b/src/tool.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "utility.h" #include "itemdef.h" // For itemgroup_get() #include "log.h" +#include "inventory.h" void ToolCapabilities::serialize(std::ostream &os) const { @@ -153,3 +154,36 @@ HitParams getHitParams(const ItemGroupList &groups, return getHitParams(groups, tp, 1000000); } +PunchDamageResult getPunchDamage( + const ItemGroupList &armor_groups, + const ToolCapabilities *toolcap, + const ItemStack *punchitem, + float time_from_last_punch +){ + bool do_hit = true; + { + if(do_hit && punchitem){ + if(itemgroup_get(armor_groups, "punch_operable") && + (toolcap == NULL || punchitem->name == "")) + do_hit = false; + } + if(do_hit){ + if(itemgroup_get(armor_groups, "immortal")) + do_hit = false; + } + } + + PunchDamageResult result; + if(do_hit) + { + HitParams hitparams = getHitParams(armor_groups, toolcap, + time_from_last_punch); + result.did_punch = true; + result.wear = hitparams.wear; + result.damage = hitparams.hp; + } + + return result; +} + + diff --git a/src/tool.h b/src/tool.h index d2a9c13c8..685dfb5f2 100644 --- a/src/tool.h +++ b/src/tool.h @@ -108,5 +108,27 @@ HitParams getHitParams(const ItemGroupList &groups, HitParams getHitParams(const ItemGroupList &groups, const ToolCapabilities *tp); +struct PunchDamageResult +{ + bool did_punch; + int damage; + int wear; + + PunchDamageResult(): + did_punch(false), + damage(0), + wear(0) + {} +}; + +struct ItemStack; + +PunchDamageResult getPunchDamage( + const ItemGroupList &armor_groups, + const ToolCapabilities *toolcap, + const ItemStack *punchitem, + float time_from_last_punch +); + #endif |