class ClientEnvironment;
class ITextureSource;
class IGameDef;
+class LocalPlayer;
+struct ItemStack;
class ClientActiveObject : public ActiveObject
{
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:
#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;
}
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
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)
}
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);
}
#include "utility.h"
#include "itemdef.h" // For itemgroup_get()
#include "log.h"
+#include "inventory.h"
void ToolCapabilities::serialize(std::ostream &os) const
{
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;
+}
+
+
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