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 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; } + + ItemStack *punchitem = NULL; + ItemStack punchitem_static; + if(puncher){ + punchitem_static = puncher->getWieldedItem(); + punchitem = &punchitem_static; + } + + PunchDamageResult result = getPunchDamage( + m_armor_groups, + toolcap, + punchitem, + time_from_last_punch); + + if(result.did_punch) + { + actionstream<getDescription()<<", damage "<getLua(); scriptapi_luaentity_punch(L, m_id, puncher, time_from_last_punch, toolcap, dir); - HitParams hitparams = getHitParams(m_armor_groups, toolcap, - time_from_last_punch); - - actionstream<getDescription()<<", damage "<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