Fix and tune things, add tool "recharge" animation, add dummyball

This commit is contained in:
Perttu Ahola 2012-03-09 23:53:25 +02:00
parent 6b7d6c27ee
commit 989aba1966
10 changed files with 460 additions and 50 deletions

@ -698,21 +698,6 @@ end
-- Built-in node definitions. Also defined in C. -- Built-in node definitions. Also defined in C.
-- --
minetest.register_item(":", {
type = "none",
wield_image = "wieldhand.png",
wield_scale = {x=1,y=1,z=2.5},
tool_capabilities = {
full_punch_interval = 2.0,
max_drop_level = 0,
groupcaps = {
fleshy = {times={[2]=2.00, [3]=1.00}, maxwear=0, maxlevel=1},
crumbly = {times={[3]=0.70}, maxwear=0, maxlevel=1},
snappy = {times={[3]=0.70}, maxwear=0, maxlevel=1},
}
}
})
minetest.register_item(":unknown", { minetest.register_item(":unknown", {
type = "none", type = "none",
description = "Unknown Item", description = "Unknown Item",
@ -749,6 +734,11 @@ minetest.register_node(":ignore", {
air_equivalent = true, air_equivalent = true,
}) })
-- The hand (bare definition)
minetest.register_item(":", {
type = "none",
})
-- --
-- Default material types -- Default material types
-- --

@ -445,6 +445,22 @@ default = {}
-- Tool definition -- Tool definition
-- --
-- The hand
minetest.register_item(":", {
type = "none",
wield_image = "wieldhand.png",
wield_scale = {x=1,y=1,z=2.5},
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level = 0,
groupcaps = {
fleshy = {times={[2]=2.00, [3]=1.00}, maxwear=0, maxlevel=1},
crumbly = {times={[3]=0.70}, maxwear=0, maxlevel=1},
snappy = {times={[3]=0.70}, maxwear=0, maxlevel=1},
}
}
})
minetest.register_tool("default:pick_wood", { minetest.register_tool("default:pick_wood", {
description = "Wooden Pickaxe", description = "Wooden Pickaxe",
inventory_image = "default_tool_woodpick.png", inventory_image = "default_tool_woodpick.png",
@ -554,7 +570,7 @@ minetest.register_tool("default:sword_wood", {
description = "Wooden Sword", description = "Wooden Sword",
inventory_image = "default_tool_woodsword.png", inventory_image = "default_tool_woodsword.png",
tool_capabilities = { tool_capabilities = {
full_punch_interval = 2.0, full_punch_interval = 1.0,
max_drop_level=0, max_drop_level=0,
groupcaps={ groupcaps={
fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.1, maxlevel=1}, fleshy={times={[2]=1.10, [3]=0.60}, maxwear=0.1, maxlevel=1},
@ -567,7 +583,7 @@ minetest.register_tool("default:sword_stone", {
description = "Stone Sword", description = "Stone Sword",
inventory_image = "default_tool_stonesword.png", inventory_image = "default_tool_stonesword.png",
tool_capabilities = { tool_capabilities = {
full_punch_interval = 2.0, full_punch_interval = 1.0,
max_drop_level=0, max_drop_level=0,
groupcaps={ groupcaps={
fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1}, fleshy={times={[2]=0.80, [3]=0.40}, maxwear=0.05, maxlevel=1},
@ -580,7 +596,7 @@ minetest.register_tool("default:sword_steel", {
description = "Steel Sword", description = "Steel Sword",
inventory_image = "default_tool_steelsword.png", inventory_image = "default_tool_steelsword.png",
tool_capabilities = { tool_capabilities = {
full_punch_interval = 2.0, full_punch_interval = 1.0,
max_drop_level=1, max_drop_level=1,
groupcaps={ groupcaps={
fleshy={times={[1]=1.00, [2]=0.40, [3]=0.20}, maxwear=0.1, maxlevel=2}, fleshy={times={[1]=1.00, [2]=0.40, [3]=0.20}, maxwear=0.1, maxlevel=2},

@ -374,6 +374,51 @@ minetest.register_entity("experimental:tnt", TNT)
-- Add TNT's old name also -- Add TNT's old name also
minetest.register_alias("TNT", "experimental:tnt") minetest.register_alias("TNT", "experimental:tnt")
--
-- The dummyball!
--
minetest.register_alias("dummyball", "experimental:dummyball")
minetest.register_entity("experimental:dummyball", {
-- Static definition
physical = false,
collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4},
visual = "sprite",
visual_size = {x=1, y=1},
textures = {"experimental_dummyball.png"},
spritediv = {x=1, y=3},
initial_sprite_basepos = {x=0, y=0},
-- Dynamic variables
phase = 0,
phasetimer = 0,
on_activate = function(self, staticdata)
minetest.log("Dummyball activated!")
end,
on_step = function(self, dtime)
self.phasetimer = self.phasetimer + dtime
if self.phasetimer > 2.0 then
self.phasetimer = self.phasetimer - 2.0
self.phase = self.phase + 1
if self.phase >= 3 then
self.phase = 0
end
self.object:setsprite({x=0, y=self.phase})
phasearmor = {
[0]={cracky=3},
[1]={crumbly=3},
[2]={fleshy=3}
}
self.object:set_armor_groups(phasearmor[self.phase])
end
end,
on_punch = function(self, hitter)
end,
})
-- --
-- A test entity for testing animated and yaw-modulated sprites -- A test entity for testing animated and yaw-modulated sprites
-- --

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cmath> #include <cmath>
#include "settings.h" #include "settings.h"
#include "itemdef.h" // For wield visualization #include "itemdef.h" // For wield visualization
#include "noise.h" // easeCurve
Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control): Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_smgr(smgr), m_smgr(smgr),
@ -182,7 +183,8 @@ void Camera::step(f32 dtime)
} }
} }
void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize) void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
f32 tool_reload_ratio)
{ {
// Set player node transformation // Set player node transformation
m_playernode->setPosition(player->getPosition()); m_playernode->setPosition(player->getPosition());
@ -267,8 +269,25 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize)
m_cameranode->setFOV(m_fov_y); m_cameranode->setFOV(m_fov_y);
// Position the wielded item // Position the wielded item
v3f wield_position = v3f(45, -35, 65); //v3f wield_position = v3f(45, -35, 65);
v3f wield_position = v3f(55, -35, 65);
//v3f wield_rotation = v3f(-100, 120, -100);
v3f wield_rotation = v3f(-100, 120, -100); v3f wield_rotation = v3f(-100, 120, -100);
if(m_digging_anim < 0.05 || m_digging_anim > 0.5){
f32 frac = 1.0;
if(m_digging_anim > 0.5)
frac = 2.0 * (m_digging_anim - 0.5);
// This value starts from 1 and settles to 0
f32 ratiothing = pow((1.0 - tool_reload_ratio), 0.5);
//f32 ratiothing2 = pow(ratiothing, 0.5);
f32 ratiothing2 = (easeCurve(ratiothing*0.5))*2.0;
wield_position.Y -= frac * 25.0 * pow(ratiothing2, 1.7);
//wield_position.Z += frac * 5.0 * ratiothing2;
wield_position.X -= frac * 35.0 * pow(ratiothing2, 1.1);
wield_rotation.Y += frac * 70.0 * pow(ratiothing2, 1.4);
//wield_rotation.X -= frac * 15.0 * pow(ratiothing2, 1.4);
//wield_rotation.Z += frac * 15.0 * pow(ratiothing2, 1.0);
}
if (m_digging_button != -1) if (m_digging_button != -1)
{ {
f32 digfrac = m_digging_anim; f32 digfrac = m_digging_anim;

@ -105,7 +105,8 @@ public:
// Update the camera from the local player's position. // Update the camera from the local player's position.
// frametime is used to adjust the viewing range. // frametime is used to adjust the viewing range.
void update(LocalPlayer* player, f32 frametime, v2u32 screensize); void update(LocalPlayer* player, f32 frametime, v2u32 screensize,
f32 tool_reload_ratio);
// Render distance feedback loop // Render distance feedback loop
void updateViewingRange(f32 frametime_in); void updateViewingRange(f32 frametime_in);

@ -165,6 +165,116 @@ private:
v3f m_position; v3f m_position;
}; };
// Prototype
TestCAO proto_TestCAO(NULL, NULL);
TestCAO::TestCAO(IGameDef *gamedef, ClientEnvironment *env):
ClientActiveObject(0, gamedef, env),
m_node(NULL),
m_position(v3f(0,10*BS,0))
{
ClientActiveObject::registerType(getType(), create);
}
TestCAO::~TestCAO()
{
}
ClientActiveObject* TestCAO::create(IGameDef *gamedef, ClientEnvironment *env)
{
return new TestCAO(gamedef, env);
}
void TestCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
IrrlichtDevice *irr)
{
if(m_node != NULL)
return;
//video::IVideoDriver* driver = smgr->getVideoDriver();
scene::SMesh *mesh = new scene::SMesh();
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
video::SColor c(255,255,255,255);
video::S3DVertex vertices[4] =
{
video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),
};
u16 indices[] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
buf->getMaterial().setTexture(0, tsrc->getTextureRaw("rat.png"));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
// Add to mesh
mesh->addMeshBuffer(buf);
buf->drop();
m_node = smgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
updateNodePos();
}
void TestCAO::removeFromScene()
{
if(m_node == NULL)
return;
m_node->remove();
m_node = NULL;
}
void TestCAO::updateLight(u8 light_at_pos)
{
}
v3s16 TestCAO::getLightPosition()
{
return floatToInt(m_position, BS);
}
void TestCAO::updateNodePos()
{
if(m_node == NULL)
return;
m_node->setPosition(m_position);
//m_node->setRotation(v3f(0, 45, 0));
}
void TestCAO::step(float dtime, ClientEnvironment *env)
{
if(m_node)
{
v3f rot = m_node->getRotation();
//infostream<<"dtime="<<dtime<<", rot.Y="<<rot.Y<<std::endl;
rot.Y += dtime * 180;
m_node->setRotation(rot);
}
}
void TestCAO::processMessage(const std::string &data)
{
infostream<<"TestCAO: Got data: "<<data<<std::endl;
std::istringstream is(data, std::ios::binary);
u16 cmd;
is>>cmd;
if(cmd == 0)
{
v3f newpos;
is>>newpos.X;
is>>newpos.Y;
is>>newpos.Z;
m_position = newpos;
updateNodePos();
}
}
/* /*
ItemCAO ItemCAO
*/ */
@ -213,6 +323,212 @@ private:
std::string m_infotext; std::string m_infotext;
}; };
#include "inventory.h"
// Prototype
ItemCAO proto_ItemCAO(NULL, NULL);
ItemCAO::ItemCAO(IGameDef *gamedef, ClientEnvironment *env):
ClientActiveObject(0, gamedef, env),
m_selection_box(-BS/3.,0.0,-BS/3., BS/3.,BS*2./3.,BS/3.),
m_node(NULL),
m_position(v3f(0,10*BS,0))
{
if(!gamedef && !env)
{
ClientActiveObject::registerType(getType(), create);
}
}
ItemCAO::~ItemCAO()
{
}
ClientActiveObject* ItemCAO::create(IGameDef *gamedef, ClientEnvironment *env)
{
return new ItemCAO(gamedef, env);
}
void ItemCAO::addToScene(scene::ISceneManager *smgr, ITextureSource *tsrc,
IrrlichtDevice *irr)
{
if(m_node != NULL)
return;
//video::IVideoDriver* driver = smgr->getVideoDriver();
scene::SMesh *mesh = new scene::SMesh();
scene::IMeshBuffer *buf = new scene::SMeshBuffer();
video::SColor c(255,255,255,255);
video::S3DVertex vertices[4] =
{
/*video::S3DVertex(-BS/2,-BS/4,0, 0,0,0, c, 0,1),
video::S3DVertex(BS/2,-BS/4,0, 0,0,0, c, 1,1),
video::S3DVertex(BS/2,BS/4,0, 0,0,0, c, 1,0),
video::S3DVertex(-BS/2,BS/4,0, 0,0,0, c, 0,0),*/
video::S3DVertex(BS/3.,0,0, 0,0,0, c, 0,1),
video::S3DVertex(-BS/3.,0,0, 0,0,0, c, 1,1),
video::S3DVertex(-BS/3.,0+BS*2./3.,0, 0,0,0, c, 1,0),
video::S3DVertex(BS/3.,0+BS*2./3.,0, 0,0,0, c, 0,0),
};
u16 indices[] = {0,1,2,2,3,0};
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
// Initialize with a generated placeholder texture
buf->getMaterial().setTexture(0, tsrc->getTextureRaw(""));
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
buf->getMaterial().setFlag(video::EMF_FOG_ENABLE, true);
buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
// Add to mesh
mesh->addMeshBuffer(buf);
buf->drop();
m_node = smgr->addMeshSceneNode(mesh, NULL);
mesh->drop();
updateNodePos();
/*
Update image of node
*/
updateTexture();
}
void ItemCAO::removeFromScene()
{
if(m_node == NULL)
return;
m_node->remove();
m_node = NULL;
}
void ItemCAO::updateLight(u8 light_at_pos)
{
if(m_node == NULL)
return;
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
setMeshColor(m_node->getMesh(), color);
}
v3s16 ItemCAO::getLightPosition()
{
return floatToInt(m_position + v3f(0,0.5*BS,0), BS);
}
void ItemCAO::updateNodePos()
{
if(m_node == NULL)
return;
m_node->setPosition(m_position);
}
void ItemCAO::updateInfoText()
{
try{
IItemDefManager *idef = m_gamedef->idef();
ItemStack item;
item.deSerialize(m_itemstring, idef);
if(item.isKnown(idef))
m_infotext = item.getDefinition(idef).description;
else
m_infotext = "Unknown item: '" + m_itemstring + "'";
if(item.count >= 2)
m_infotext += " (" + itos(item.count) + ")";
}
catch(SerializationError &e)
{
m_infotext = "Unknown item: '" + m_itemstring + "'";
}
}
void ItemCAO::updateTexture()
{
if(m_node == NULL)
return;
// Create an inventory item to see what is its image
std::istringstream is(m_itemstring, std::ios_base::binary);
video::ITexture *texture = NULL;
try{
IItemDefManager *idef = m_gamedef->idef();
ItemStack item;
item.deSerialize(is, idef);
texture = item.getDefinition(idef).inventory_texture;
}
catch(SerializationError &e)
{
infostream<<"WARNING: "<<__FUNCTION_NAME
<<": error deSerializing itemstring \""
<<m_itemstring<<std::endl;
}
// Set meshbuffer texture
m_node->getMaterial(0).setTexture(0, texture);
}
void ItemCAO::step(float dtime, ClientEnvironment *env)
{
if(m_node)
{
/*v3f rot = m_node->getRotation();
rot.Y += dtime * 120;
m_node->setRotation(rot);*/
LocalPlayer *player = env->getLocalPlayer();
assert(player);
v3f rot = m_node->getRotation();
rot.Y = 180.0 - (player->getYaw());
m_node->setRotation(rot);
}
}
void ItemCAO::processMessage(const std::string &data)
{
//infostream<<"ItemCAO: Got message"<<std::endl;
std::istringstream is(data, std::ios::binary);
// command
u8 cmd = readU8(is);
if(cmd == 0)
{
// pos
m_position = readV3F1000(is);
updateNodePos();
}
if(cmd == 1)
{
// itemstring
m_itemstring = deSerializeString(is);
updateInfoText();
updateTexture();
}
}
void ItemCAO::initialize(const std::string &data)
{
infostream<<"ItemCAO: Got init data"<<std::endl;
{
std::istringstream is(data, std::ios::binary);
// version
u8 version = readU8(is);
// check version
if(version != 0)
return;
// pos
m_position = readV3F1000(is);
// itemstring
m_itemstring = deSerializeString(is);
}
updateNodePos();
updateInfoText();
}
/* /*
LuaEntityCAO LuaEntityCAO
*/ */
@ -241,6 +557,7 @@ private:
float m_anim_framelength; float m_anim_framelength;
float m_anim_timer; float m_anim_timer;
ItemGroupList m_armor_groups; ItemGroupList m_armor_groups;
float m_reset_textures_timer;
public: public:
LuaEntityCAO(IGameDef *gamedef, ClientEnvironment *env): LuaEntityCAO(IGameDef *gamedef, ClientEnvironment *env):
@ -260,7 +577,8 @@ public:
m_anim_frame(0), m_anim_frame(0),
m_anim_num_frames(1), m_anim_num_frames(1),
m_anim_framelength(0.2), m_anim_framelength(0.2),
m_anim_timer(0) m_anim_timer(0),
m_reset_textures_timer(-1)
{ {
if(gamedef == NULL) if(gamedef == NULL)
ClientActiveObject::registerType(getType(), create); ClientActiveObject::registerType(getType(), create);
@ -450,6 +768,14 @@ public:
} }
updateTexturePos(); updateTexturePos();
if(m_reset_textures_timer >= 0){
m_reset_textures_timer -= dtime;
if(m_reset_textures_timer <= 0){
m_reset_textures_timer = -1;
updateTextures("");
}
}
} }
void updateTexturePos() void updateTexturePos()
@ -619,13 +945,16 @@ public:
punchitem, punchitem,
time_from_last_punch); time_from_last_punch);
if(result.did_punch) if(result.did_punch && result.damage != 0)
{ {
if(result.damage < m_hp) if(result.damage < m_hp)
m_hp -= result.damage; m_hp -= result.damage;
else else
m_hp = 0; m_hp = 0;
// TODO: Execute defined fast response // TODO: Execute defined fast response
// I guess flashing is fine as of now
updateTextures("^[brighten");
m_reset_textures_timer = 0.1;
} }
return false; return false;
@ -634,7 +963,7 @@ public:
std::string debugInfoText() std::string debugInfoText()
{ {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);
os<<"LuaEntityCAO \n"; os<<"LuaEntityCAO hp="<<m_hp<<"\n";
os<<"armor={"; os<<"armor={";
for(ItemGroupList::const_iterator i = m_armor_groups.begin(); for(ItemGroupList::const_iterator i = m_armor_groups.begin();
i != m_armor_groups.end(); i++){ i != m_armor_groups.end(); i++){

@ -563,11 +563,11 @@ int LuaEntitySAO::punch(v3f dir,
if(result.did_punch) if(result.did_punch)
{ {
setHP(getHP() - result.damage);
actionstream<<getDescription()<<" punched by " actionstream<<getDescription()<<" punched by "
<<puncher->getDescription()<<", damage "<<result.damage <<puncher->getDescription()<<", damage "<<result.damage
<<" HP"<<std::endl; <<" hp, health now "<<getHP()<<" hp"<<std::endl;
setHP(getHP() - result.damage);
{ {
std::ostringstream os(std::ios::binary); std::ostringstream os(std::ios::binary);

@ -1036,6 +1036,7 @@ void the_game(
const float object_hit_delay = 0.2; const float object_hit_delay = 0.2;
float object_hit_delay_timer = 0.0; float object_hit_delay_timer = 0.0;
float time_from_last_punch = 10;
bool invert_mouse = g_settings->getBool("invert_mouse"); bool invert_mouse = g_settings->getBool("invert_mouse");
@ -1181,6 +1182,7 @@ void the_game(
nodig_delay_timer -= dtime; nodig_delay_timer -= dtime;
if(object_hit_delay_timer >= 0) if(object_hit_delay_timer >= 0)
object_hit_delay_timer -= dtime; object_hit_delay_timer -= dtime;
time_from_last_punch += dtime;
g_profiler->add("Elapsed time", dtime); g_profiler->add("Elapsed time", dtime);
g_profiler->avg("FPS", 1./dtime); g_profiler->avg("FPS", 1./dtime);
@ -1775,23 +1777,6 @@ void the_game(
//TimeTaker //timer2("//timer2"); //TimeTaker //timer2("//timer2");
LocalPlayer* player = client.getLocalPlayer();
camera.update(player, busytime, screensize);
camera.step(dtime);
v3f player_position = player->getPosition();
v3f camera_position = camera.getPosition();
v3f camera_direction = camera.getDirection();
f32 camera_fov = camera.getFovMax();
if(!disable_camera_update){
client.updateCamera(camera_position,
camera_direction, camera_fov);
}
//timer2.stop();
//TimeTaker //timer3("//timer3");
/* /*
For interaction purposes, get info about the held item For interaction purposes, get info about the held item
- What item is it? - What item is it?
@ -1810,6 +1795,32 @@ void the_game(
playeritem_liquids_pointable = playeritem.getDefinition(itemdef).liquids_pointable; playeritem_liquids_pointable = playeritem.getDefinition(itemdef).liquids_pointable;
} }
} }
ToolCapabilities playeritem_toolcap =
playeritem.getToolCapabilities(itemdef);
/*
Update camera
*/
LocalPlayer* player = client.getLocalPlayer();
float full_punch_interval = playeritem_toolcap.full_punch_interval;
float tool_reload_ratio = time_from_last_punch / full_punch_interval;
tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0);
camera.update(player, busytime, screensize, tool_reload_ratio);
camera.step(dtime);
v3f player_position = player->getPosition();
v3f camera_position = camera.getPosition();
v3f camera_direction = camera.getDirection();
f32 camera_fov = camera.getFovMax();
if(!disable_camera_update){
client.updateCamera(camera_position,
camera_direction, camera_fov);
}
//timer2.stop();
//TimeTaker //timer3("//timer3");
/* /*
Calculate what block is the crosshair pointing to Calculate what block is the crosshair pointing to
@ -1934,9 +1945,9 @@ void the_game(
} }
MapNode n = client.getNode(nodepos); MapNode n = client.getNode(nodepos);
// Get digging properties for material and tool // Get digging parameters
ToolCapabilities tp = playeritem.getToolCapabilities(itemdef); DigParams params = getDigParams(nodedef->get(n).groups,
DigParams params = getDigParams(nodedef->get(n).groups, &tp); &playeritem_toolcap);
// If can't dig, try hand // If can't dig, try hand
if(!params.diggable){ if(!params.diggable){
const ItemDefinition &hand = itemdef->get(""); const ItemDefinition &hand = itemdef->get("");
@ -2095,10 +2106,9 @@ void the_game(
v3f objpos = selected_object->getPosition(); v3f objpos = selected_object->getPosition();
v3f dir = (objpos - player_position).normalize(); 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( bool disable_send = selected_object->directReportPunch(
dir, &playeritem, time_from_last_punch); dir, &playeritem, time_from_last_punch);
time_from_last_punch = 0;
if(!disable_send) if(!disable_send)
client.interact(0, pointed); client.interact(0, pointed);
} }

@ -56,7 +56,7 @@ struct ToolCapabilities
std::map<std::string, ToolGroupCap> groupcaps; std::map<std::string, ToolGroupCap> groupcaps;
ToolCapabilities( ToolCapabilities(
float full_punch_interval_=3.0, float full_punch_interval_=1.4,
int max_drop_level_=1, int max_drop_level_=1,
std::map<std::string, ToolGroupCap> groupcaps_ = std::map<std::string, ToolGroupCap> groupcaps_ =
std::map<std::string, ToolGroupCap>() std::map<std::string, ToolGroupCap>()