Entity damage system WIP; Remove C++ mobs

nephele-craftmethods
Perttu Ahola 11 years ago
parent f1cb91cd93
commit e9cdb938fe
  1. 20
      data/mods/default/init.lua
  2. 115
      src/content_abm.cpp
  3. 1611
      src/content_cao.cpp
  4. 1796
      src/content_sao.cpp
  5. 182
      src/content_sao.h
  6. 39
      src/itemgroup.h
  7. 10
      src/luaentity_common.cpp
  8. 6
      src/luaentity_common.h
  9. 53
      src/scriptapi.cpp
  10. 4
      src/scriptapi.h
  11. 15
      src/server.cpp
  12. 10
      src/serverobject.h
  13. 20
      src/serverremoteplayer.cpp
  14. 5
      src/serverremoteplayer.h

@ -202,7 +202,7 @@
-- - getpos() -> {x=num, y=num, z=num}
-- - setpos(pos); pos={x=num, y=num, z=num}
-- - moveto(pos, continuous=false): interpolated move
-- - punch(puncher, time_from_last_punch)
-- - punch(puncher, time_from_last_punch, tool_capabilities, direction)
-- ^ puncher = an another ObjectRef,
-- ^ time_from_last_punch = time since last punch action of the puncher
-- - right_click(clicker); clicker = an another ObjectRef
@ -1124,14 +1124,14 @@ minetest.register_node("default:tree", {
description = "Tree",
tile_images = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
is_ground_content = true,
groups = {snappy=2},
groups = {snappy=2,choppy=2},
})
minetest.register_node("default:jungletree", {
description = "Jungle Tree",
tile_images = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"},
is_ground_content = true,
groups = {snappy=2},
groups = {snappy=2,choppy=2},
})
minetest.register_node("default:junglegrass", {
@ -1174,7 +1174,7 @@ minetest.register_node("default:cactus", {
description = "Cactus",
tile_images = {"default_cactus_top.png", "default_cactus_top.png", "default_cactus_side.png"},
is_ground_content = true,
groups = {snappy=2},
groups = {snappy=2,choppy=3},
})
minetest.register_node("default:papyrus", {
@ -1193,7 +1193,7 @@ minetest.register_node("default:bookshelf", {
description = "Bookshelf",
tile_images = {"default_wood.png", "default_wood.png", "default_bookshelf.png"},
is_ground_content = true,
groups = {snappy=2},
groups = {snappy=2,choppy=3},
})
minetest.register_node("default:glass", {
@ -1219,7 +1219,7 @@ minetest.register_node("default:fence_wood", {
type = "fixed",
fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7},
},
groups = {snappy=2},
groups = {snappy=2,choppy=2},
})
minetest.register_node("default:rail", {
@ -1255,7 +1255,7 @@ minetest.register_node("default:ladder", {
--wall_bottom = = <default>
--wall_side = = <default>
},
groups = {snappy=2},
groups = {snappy=2,choppy=2},
legacy_wallmounted = true,
})
@ -1263,7 +1263,7 @@ minetest.register_node("default:wood", {
description = "Wood",
tile_images = {"default_wood.png"},
is_ground_content = true,
groups = {snappy=2},
groups = {snappy=2,choppy=2},
})
minetest.register_node("default:mese", {
@ -1421,7 +1421,7 @@ minetest.register_node("default:chest", {
"default_chest_side.png", "default_chest_side.png", "default_chest_front.png"},
paramtype2 = "facedir",
metadata_name = "chest",
groups = {snappy=2},
groups = {snappy=2,choppy=2},
legacy_facedir_simple = true,
})
@ -1431,7 +1431,7 @@ minetest.register_node("default:chest_locked", {
"default_chest_side.png", "default_chest_side.png", "default_chest_lock.png"},
paramtype2 = "facedir",
metadata_name = "locked_chest",
groups = {snappy=2},
groups = {snappy=2,choppy=2},
legacy_facedir_simple = true,
})

@ -88,119 +88,6 @@ public:
}
};
class SpawnRatsAroundTreesABM : public ActiveBlockModifier
{
private:
public:
virtual std::set<std::string> getTriggerContents()
{
std::set<std::string> s;
s.insert("tree");
s.insert("jungletree");
return s;
}
virtual float getTriggerInterval()
{ return 10.0; }
virtual u32 getTriggerChance()
{ return 200; }
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
u32 active_object_count, u32 active_object_count_wider)
{
if(active_object_count_wider != 0)
return;
INodeDefManager *ndef = env->getGameDef()->ndef();
ServerMap *map = &env->getServerMap();
v3s16 p1 = p + v3s16(myrand_range(-2, 2),
0, myrand_range(-2, 2));
MapNode n1 = map->getNodeNoEx(p1);
MapNode n1b = map->getNodeNoEx(p1+v3s16(0,-1,0));
if(n1b.getContent() == ndef->getId("dirt_with_grass") &&
n1.getContent() == CONTENT_AIR)
{
v3f pos = intToFloat(p1, BS);
ServerActiveObject *obj = new RatSAO(env, pos);
env->addActiveObject(obj);
}
}
};
static void getMob_dungeon_master(Settings &properties)
{
properties.set("looks", "dungeon_master");
properties.setFloat("yaw", 1.57);
properties.setFloat("hp", 30);
properties.setBool("bright_shooting", true);
properties.set("shoot_type", "fireball");
properties.set("shoot_y", "0.7");
properties.set("player_hit_damage", "1");
properties.set("player_hit_distance", "1.0");
properties.set("player_hit_interval", "0.5");
properties.setBool("mindless_rage", myrand_range(0,100)==0);
}
class SpawnInCavesABM : public ActiveBlockModifier
{
private:
public:
virtual std::set<std::string> getTriggerContents()
{
std::set<std::string> s;
s.insert("stone");
s.insert("mossycobble");
return s;
}
virtual float getTriggerInterval()
{ return 2.0; }
virtual u32 getTriggerChance()
{ return 1000; }
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
u32 active_object_count, u32 active_object_count_wider)
{
if(active_object_count_wider != 0)
return;
INodeDefManager *ndef = env->getGameDef()->ndef();
ServerMap *map = &env->getServerMap();
v3s16 p1 = p + v3s16(0,1,0);
MapNode n1a = map->getNodeNoEx(p1+v3s16(0,0,0));
if(n1a.getLightBlend(env->getDayNightRatio(), ndef) <= 3){
MapNode n1b = map->getNodeNoEx(p1+v3s16(0,1,0));
if(n1a.getContent() == CONTENT_AIR &&
n1b.getContent() == CONTENT_AIR)
{
v3f pos = intToFloat(p1, BS);
int i = myrand()%5;
if(i == 0 || i == 1){
actionstream<<"A dungeon master spawns at "
<<PP(p1)<<std::endl;
Settings properties;
getMob_dungeon_master(properties);
ServerActiveObject *obj = new MobV2SAO(
env, pos, &properties);
env->addActiveObject(obj);
} else if(i == 2 || i == 3){
actionstream<<"Rats spawn at "
<<PP(p1)<<std::endl;
for(int j=0; j<3; j++){
ServerActiveObject *obj = new RatSAO(
env, pos);
env->addActiveObject(obj);
}
} else {
actionstream<<"An oerkki spawns at "
<<PP(p1)<<std::endl;
ServerActiveObject *obj = new Oerkki1SAO(
env, pos);
env->addActiveObject(obj);
}
}
}
}
};
class MakeTreesFromSaplingsABM : public ActiveBlockModifier
{
private:
@ -261,8 +148,6 @@ void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef)
{
env->addActiveBlockModifier(new GrowGrassABM());
env->addActiveBlockModifier(new RemoveGrassABM());
env->addActiveBlockModifier(new SpawnRatsAroundTreesABM());
env->addActiveBlockModifier(new SpawnInCavesABM());
env->addActiveBlockModifier(new MakeTreesFromSaplingsABM());
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -22,173 +22,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serverobject.h"
#include "content_object.h"
#include "itemgroup.h"
class TestSAO : public ServerActiveObject
{
public:
TestSAO(ServerEnvironment *env, v3f pos);
u8 getType() const
{return ACTIVEOBJECT_TYPE_TEST;}
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
private:
float m_timer1;
float m_age;
};
class ItemSAO : public ServerActiveObject
{
public:
ItemSAO(ServerEnvironment *env, v3f pos, const std::string itemstring);
u8 getType() const
{return ACTIVEOBJECT_TYPE_ITEM;}
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
std::string getClientInitializationData();
std::string getStaticData();
ItemStack createItemStack();
void punch(ServerActiveObject *puncher, float time_from_last_punch);
float getMinimumSavedMovement(){ return 0.1*BS; }
private:
std::string m_itemstring;
bool m_itemstring_changed;
v3f m_speed_f;
v3f m_last_sent_position;
IntervalLimiter m_move_interval;
};
ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos,
const std::string itemstring);
class RatSAO : public ServerActiveObject
{
public:
RatSAO(ServerEnvironment *env, v3f pos);
u8 getType() const
{return ACTIVEOBJECT_TYPE_RAT;}
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
std::string getClientInitializationData();
std::string getStaticData();
void punch(ServerActiveObject *puncher, float time_from_last_punch);
private:
bool m_is_active;
IntervalLimiter m_inactive_interval;
v3f m_speed_f;
v3f m_oldpos;
v3f m_last_sent_position;
float m_yaw;
float m_counter1;
float m_counter2;
float m_age;
bool m_touching_ground;
};
class Oerkki1SAO : public ServerActiveObject
{
public:
Oerkki1SAO(ServerEnvironment *env, v3f pos);
u8 getType() const
{return ACTIVEOBJECT_TYPE_OERKKI1;}
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
std::string getClientInitializationData();
std::string getStaticData();
void punch(ServerActiveObject *puncher, float time_from_last_punch);
bool isPeaceful(){return false;}
private:
void doDamage(u16 d);
bool m_is_active;
IntervalLimiter m_inactive_interval;
v3f m_speed_f;
v3f m_oldpos;
v3f m_last_sent_position;
float m_yaw;
float m_counter1;
float m_counter2;
float m_age;
bool m_touching_ground;
u8 m_hp;
float m_after_jump_timer;
};
class FireflySAO : public ServerActiveObject
{
public:
FireflySAO(ServerEnvironment *env, v3f pos);
u8 getType() const
{return ACTIVEOBJECT_TYPE_FIREFLY;}
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
void step(float dtime, bool send_recommended);
std::string getClientInitializationData();
std::string getStaticData();
private:
bool m_is_active;
IntervalLimiter m_inactive_interval;
v3f m_speed_f;
v3f m_oldpos;
v3f m_last_sent_position;
float m_yaw;
float m_counter1;
float m_counter2;
float m_age;
bool m_touching_ground;
};
class Settings;
class MobV2SAO : public ServerActiveObject
{
public:
MobV2SAO(ServerEnvironment *env, v3f pos,
Settings *init_properties);
virtual ~MobV2SAO();
u8 getType() const
{return ACTIVEOBJECT_TYPE_MOBV2;}
static ServerActiveObject* create(ServerEnvironment *env, v3f pos,
const std::string &data);
std::string getStaticData();
std::string getClientInitializationData();
void step(float dtime, bool send_recommended);
void punch(ServerActiveObject *puncher, float time_from_last_punch);
bool isPeaceful();
private:
void sendPosition();
void setPropertyDefaults();
void readProperties();
void updateProperties();
void doDamage(u16 d);
std::string m_move_type;
v3f m_speed;
v3f m_last_sent_position;
v3f m_oldpos;
float m_yaw;
float m_counter1;
float m_counter2;
float m_age;
bool m_touching_ground;
int m_hp;
bool m_walk_around;
float m_walk_around_timer;
bool m_next_pos_exists;
v3s16 m_next_pos_i;
float m_shoot_reload_timer;
bool m_shooting;
float m_shooting_timer;
float m_die_age;
v2f m_size;
bool m_falling;
float m_disturb_timer;
std::string m_disturbing_player;
float m_random_disturb_timer;
float m_shoot_y;
/*
LuaEntitySAO
Settings *m_properties;
};
This is the only SAO that needs to have a bunch of it's internals exposed.
*/
struct LuaEntityProperties;
@ -206,11 +49,17 @@ public:
void step(float dtime, bool send_recommended);
std::string getClientInitializationData();
std::string getStaticData();
void punch(ServerActiveObject *puncher, float time_from_last_punch);
int punch(v3f dir,
const ToolCapabilities *toolcap=NULL,
ServerActiveObject *puncher=NULL,
float time_from_last_punch=1000000);
void rightClick(ServerActiveObject *clicker);
void setPos(v3f pos);
void moveTo(v3f pos, bool continuous);
float getMinimumSavedMovement();
std::string getDescription();
void setHP(s16 hp);
s16 getHP();
/* LuaEntitySAO-specific */
void setVelocity(v3f velocity);
v3f getVelocity();
@ -230,9 +79,12 @@ private:
bool m_registered;
struct LuaEntityProperties *m_prop;
s16 m_hp;
v3f m_velocity;
v3f m_acceleration;
float m_yaw;
ItemGroupList m_armor_groups;
float m_last_sent_yaw;
v3f m_last_sent_position;
v3f m_last_sent_velocity;

@ -0,0 +1,39 @@
/*
Minetest-c55
Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef ITEMGROUP_HEADER
#define ITEMGROUP_HEADER
#include "common_irrlicht.h"
#include <string>
#include <map>
typedef std::map<std::string, int> ItemGroupList;
static inline int itemgroup_get(const ItemGroupList &groups,
const std::string &name)
{
std::map<std::string, int>::const_iterator i = groups.find(name);
if(i == groups.end())
return 0;
return i->second;
}
#endif

@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PP2(x) "("<<(x).X<<","<<(x).Y<<")"
LuaEntityProperties::LuaEntityProperties():
hp_max(1),
physical(false),
weight(5),
collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5),
@ -39,7 +40,8 @@ LuaEntityProperties::LuaEntityProperties():
std::string LuaEntityProperties::dump()
{
std::ostringstream os(std::ios::binary);
os<<"physical="<<physical;
os<<"hp_max="<<hp_max;
os<<", physical="<<physical;
os<<", weight="<<weight;
os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge);
os<<", visual="<<visual;
@ -56,7 +58,8 @@ std::string LuaEntityProperties::dump()
void LuaEntityProperties::serialize(std::ostream &os)
{
writeU8(os, 0); // version
writeU8(os, 1); // version
writeS16(os, hp_max);
writeU8(os, physical);
writeF1000(os, weight);
writeV3F1000(os, collisionbox.MinEdge);
@ -74,8 +77,9 @@ void LuaEntityProperties::serialize(std::ostream &os)
void LuaEntityProperties::deSerialize(std::istream &is)
{
int version = readU8(is);
if(version != 0) throw SerializationError(
if(version != 1) throw SerializationError(
"unsupported LuaEntityProperties version");
hp_max = readS16(is);
physical = readU8(is);
weight = readF1000(is);
collisionbox.MinEdge = readV3F1000(is);

@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
struct LuaEntityProperties
{
// Values are BS=1
s16 hp_max;
bool physical;
float weight;
core::aabbox3d<f32> collisionbox;
@ -42,5 +43,10 @@ struct LuaEntityProperties
void deSerialize(std::istream &is);
};
#define LUAENTITY_CMD_UPDATE_POSITION 0
#define LUAENTITY_CMD_SET_TEXTURE_MOD 1
#define LUAENTITY_CMD_SET_SPRITE 2
#define LUAENTITY_CMD_PUNCHED 3
#endif

@ -2297,17 +2297,22 @@ private:
return 0;
}
// punch(self, puncher); puncher = an another ObjectRef
// punch(self, puncher, tool_capabilities, direction, time_from_last_punch)
static int l_punch(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
ObjectRef *ref2 = checkobject(L, 2);
ObjectRef *puncher_ref = checkobject(L, 2);
ServerActiveObject *co = getobject(ref);
ServerActiveObject *co2 = getobject(ref2);
ServerActiveObject *puncher = getobject(puncher_ref);
if(co == NULL) return 0;
if(co2 == NULL) return 0;
if(puncher == NULL) return 0;
ToolCapabilities toolcap = read_tool_capabilities(L, 3);
v3f dir = read_v3f(L, 4);
float time_from_last_punch = 1000000;
if(lua_isnumber(L, 5))
time_from_last_punch = lua_tonumber(L, 5);
// Do it
co->punch(co2);
puncher->punch(dir, &toolcap, puncher, time_from_last_punch);
return 0;
}
@ -2878,7 +2883,7 @@ private:
if(item.empty() || !item.isKnown(get_server(L)->idef()))
return 0;
// Do it
ServerActiveObject *obj = new ItemSAO(env, pos, item.getItemString());
ServerActiveObject *obj = createItemSAO(env, pos, item.getItemString());
int objectid = env->addActiveObject(obj);
// If failed to add, return nothing (reads as nil)
if(objectid == 0)
@ -2892,15 +2897,8 @@ private:
// pos = {x=num, y=num, z=num}
static int l_add_rat(lua_State *L)
{
infostream<<"EnvRef::l_add_rat()"<<std::endl;
EnvRef *o = checkobject(L, 1);
ServerEnvironment *env = o->m_env;
if(env == NULL) return 0;
// pos
v3f pos = checkFloatPos(L, 2);
// Do it
ServerActiveObject *obj = new RatSAO(env, pos);
env->addActiveObject(obj);
infostream<<"EnvRef::l_add_rat(): C++ mobs have been removed."
<<" Doing nothing."<<std::endl;
return 0;
}
@ -2908,15 +2906,8 @@ private:
// pos = {x=num, y=num, z=num}
static int l_add_firefly(lua_State *L)
{
infostream<<"EnvRef::l_add_firefly()"<<std::endl;
EnvRef *o = checkobject(L, 1);
ServerEnvironment *env = o->m_env;
if(env == NULL) return 0;
// pos
v3f pos = checkFloatPos(L, 2);
// Do it
ServerActiveObject *obj = new FireflySAO(env, pos);
env->addActiveObject(obj);
infostream<<"EnvRef::l_add_firefly(): C++ mobs have been removed."
<<" Doing nothing."<<std::endl;
return 0;
}
@ -4348,6 +4339,8 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
/* Read stuff */
prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
getboolfield(L, -1, "physical", prop->physical);
getfloatfield(L, -1, "weight", prop->weight);
@ -4415,9 +4408,11 @@ void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
}
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
// tool_capabilities, direction)
void scriptapi_luaentity_punch(lua_State *L, u16 id,
ServerActiveObject *puncher, float time_from_last_punch)
ServerActiveObject *puncher, float time_from_last_punch,
const ToolCapabilities *toolcap, v3f dir)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
@ -4436,8 +4431,10 @@ void scriptapi_luaentity_punch(lua_State *L, u16 id,
lua_pushvalue(L, object); // self
objectref_get_or_create(L, puncher); // Clicker reference
lua_pushnumber(L, time_from_last_punch);
// Call with 2 arguments, 0 results
if(lua_pcall(L, 3, 0, 0))
push_tool_capabilities(L, *toolcap);
push_v3f(L, dir);
// Call with 5 arguments, 0 results
if(lua_pcall(L, 5, 0, 0))
script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
}

@ -33,6 +33,7 @@ struct LuaEntityProperties;
struct ItemStack;
struct PointedThing;
//class IGameDef;
struct ToolCapabilities;
void scriptapi_export(lua_State *L, Server *server);
bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
@ -82,7 +83,8 @@ void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
LuaEntityProperties *prop);
void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime);
void scriptapi_luaentity_punch(lua_State *L, u16 id,
ServerActiveObject *puncher, float time_from_last_punch);
ServerActiveObject *puncher, float time_from_last_punch,
const ToolCapabilities *toolcap, v3f dir);
void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
ServerActiveObject *clicker);

@ -47,6 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mods.h"
#include "sha1.h"
#include "base64.h"
#include "tool.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@ -1244,7 +1245,7 @@ void Server::AsyncRunStep()
explosion.
*/
player->m_last_good_position_age += dtime;
if(player->m_last_good_position_age >= 2.0){
if(player->m_last_good_position_age >= 1.0){
float age = player->m_last_good_position_age;
v3f diff = (player->getPosition() - player->m_last_good_position);
float d_vert = diff.Y;
@ -2870,7 +2871,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(action == 0 || action == 2 || action == 3)
{
float d = player_pos.getDistanceFrom(pointed_pos_under);
float max_d = BS * 10; // Just some large enough value
float max_d = BS * 14; // Just some large enough value
if(d > max_d){
actionstream<<"Player "<<player->getName()
<<" tried to access "<<pointed.dump()
@ -2933,8 +2934,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
actionstream<<player->getName()<<" punches object "
<<pointed.object_id<<std::endl;
// Do stuff
pointed_object->punch(srp, srp->m_time_from_last_punch);
ItemStack punchitem = srp->getWieldedItem();
ToolCapabilities toolcap =
punchitem.getToolCapabilities(m_itemdef);
v3f dir = (pointed_object->getBasePosition() -
(srp->getPosition() + srp->getEyeOffset())
).normalize();
pointed_object->punch(dir, &toolcap, srp,
srp->m_time_from_last_punch);
srp->m_time_from_last_punch = 0;
}

@ -44,7 +44,7 @@ Some planning
class ServerEnvironment;
struct ItemStack;
class Player;
struct ToolDiggingProperties;
struct ToolCapabilities;
class ServerActiveObject : public ActiveObject
{
@ -133,10 +133,12 @@ public:
virtual bool isStaticAllowed() const
{return true;}
// time_from_last_punch is used for lessening damage if punching fast
virtual void punch(ServerActiveObject *puncher,
// Returns tool wear
virtual int punch(v3f dir,
const ToolCapabilities *toolcap=NULL,
ServerActiveObject *puncher=NULL,
float time_from_last_punch=1000000)
{}
{ return 0; }
virtual void rightClick(ServerActiveObject *clicker)
{}
virtual void setHP(s16 hp)

@ -169,16 +169,18 @@ std::string ServerRemotePlayer::getStaticData()
return "";
}
void ServerRemotePlayer::punch(ServerActiveObject *puncher,
int ServerRemotePlayer::punch(v3f dir,
const ToolCapabilities *toolcap,
ServerActiveObject *puncher,
float time_from_last_punch)
{
if(!puncher)
return;
if(!toolcap)
return 0;
// No effect if PvP disabled
if(g_settings->getBool("enable_pvp") == false){
if(puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER)
return;
return 0;
}
// "Material" groups of the player
@ -186,19 +188,13 @@ void ServerRemotePlayer::punch(ServerActiveObject *puncher,
groups["choppy"] = 2;
groups["fleshy"] = 3;
IItemDefManager *idef = m_env->getGameDef()->idef();
ItemStack punchitem = puncher->getWieldedItem();
ToolCapabilities tp = punchitem.getToolCapabilities(idef);
HitParams hitparams = getHitParams(groups, &tp, time_from_last_punch);
HitParams hitparams = getHitParams(groups, toolcap, time_from_last_punch);
actionstream<<"Player "<<getName()<<" punched by "
<<puncher->getDescription()<<", damage "<<hitparams.hp
<<" HP"<<std::endl;
setHP(getHP() - hitparams.hp);
punchitem.addWear(hitparams.wear, idef);
puncher->setWieldedItem(punchitem);
if(hitparams.hp != 0)
{
@ -211,6 +207,8 @@ void ServerRemotePlayer::punch(ServerActiveObject *puncher,
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
}
return hitparams.wear;
}
void ServerRemotePlayer::rightClick(ServerActiveObject *clicker)

@ -67,7 +67,10 @@ public:
void step(float dtime, bool send_recommended);
std::string getClientInitializationData();
std::string getStaticData();
void punch(ServerActiveObject *puncher, float time_from_last_punch);
int punch(v3f dir,
const ToolCapabilities *toolcap,
ServerActiveObject *puncher,
float time_from_last_punch);
void rightClick(ServerActiveObject *clicker);
void setPos(v3f pos);
void moveTo(v3f pos, bool continuous);

Loading…
Cancel
Save