aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/content_cao.cpp52
-rw-r--r--src/environment.cpp15
-rw-r--r--src/environment.h2
-rw-r--r--src/inventory.cpp1
-rw-r--r--src/player.cpp279
-rw-r--r--src/player.h79
-rw-r--r--src/server.h1
-rw-r--r--src/serverremoteplayer.cpp301
-rw-r--r--src/serverremoteplayer.h102
10 files changed, 459 insertions, 374 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2d96ddea4..3d9f49792 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -94,6 +94,7 @@ configure_file(
)
set(common_SRCS
+ serverremoteplayer.cpp
content_abm.cpp
craftdef.cpp
nameidmapping.cpp
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index 20eb3cf1b..8d1fcc24e 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -2090,6 +2090,8 @@ private:
float m_yaw;
SmoothTranslator pos_translator;
bool m_is_local_player;
+ LocalPlayer *m_local_player;
+ float m_damage_visual_timer;
public:
PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
@@ -2099,7 +2101,9 @@ public:
m_text(NULL),
m_position(v3f(0,10*BS,0)),
m_yaw(0),
- m_is_local_player(false)
+ m_is_local_player(false),
+ m_local_player(NULL),
+ m_damage_visual_timer(0)
{
if(gamedef == NULL)
ClientActiveObject::registerType(getType(), create);
@@ -2122,13 +2126,13 @@ public:
// yaw
m_yaw = readF1000(is);
- Player *player = m_env->getPlayer(m_name.c_str());
- if(player && player->isLocal())
- m_is_local_player = true;
-
pos_translator.init(m_position);
- updateNodePos();
+ Player *player = m_env->getPlayer(m_name.c_str());
+ if(player && player->isLocal()){
+ m_is_local_player = true;
+ m_local_player = (LocalPlayer*)player;
+ }
}
~PlayerCAO()
@@ -2183,7 +2187,6 @@ public:
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
- buf->getMaterial().setTexture(0, tsrc->getTextureRaw("player.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;
@@ -2205,7 +2208,6 @@ public:
buf->append(vertices, 4, indices, 6);
// Set material
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
- buf->getMaterial().setTexture(0, tsrc->getTextureRaw("player_back.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_REF;
@@ -2225,7 +2227,9 @@ public:
m_text = smgr->addTextSceneNode(gui->getBuiltInFont(),
wname.c_str(), video::SColor(255,255,255,255), m_node);
m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
-
+
+ updateTextures("");
+ updateNodePos();
}
void removeFromScene()
@@ -2296,6 +2300,36 @@ public:
updateNodePos();
}
}
+
+ void updateTextures(const std::string &mod)
+ {
+ if(!m_node)
+ return;
+ ITextureSource *tsrc = m_gamedef->tsrc();
+ scene::IMesh *mesh = m_node->getMesh();
+ if(mesh){
+ {
+ std::string tname = "player.png";
+ tname += mod;
+ scene::IMeshBuffer *buf = mesh->getMeshBuffer(0);
+ buf->getMaterial().setTexture(0,
+ tsrc->getTextureRaw(tname));
+ }
+ {
+ std::string tname = "player_back.png";
+ tname += mod;
+ scene::IMeshBuffer *buf = mesh->getMeshBuffer(1);
+ buf->getMaterial().setTexture(0,
+ tsrc->getTextureRaw(tname));
+ }
+ }
+ }
+
+ bool directReportPunch(const std::string &toolname, v3f dir)
+ {
+ updateTextures("^[brighten");
+ return false;
+ }
};
// Prototype
diff --git a/src/environment.cpp b/src/environment.cpp
index e8dfebcb3..ce81a1941 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodemetadata.h"
#include "main.h" // For g_settings, g_profiler
#include "gamedef.h"
+#include "serverremoteplayer.h"
#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
@@ -2189,15 +2190,17 @@ void ClientEnvironment::processActiveObjectMessage(u16 id,
Callbacks for activeobjects
*/
-void ClientEnvironment::damageLocalPlayer(u8 damage)
+void ClientEnvironment::damageLocalPlayer(u8 damage, bool handle_hp)
{
LocalPlayer *lplayer = getLocalPlayer();
assert(lplayer);
-
- if(lplayer->hp > damage)
- lplayer->hp -= damage;
- else
- lplayer->hp = 0;
+
+ if(handle_hp){
+ if(lplayer->hp > damage)
+ lplayer->hp -= damage;
+ else
+ lplayer->hp = 0;
+ }
ClientEnvEvent event;
event.type = CEE_PLAYER_DAMAGE;
diff --git a/src/environment.h b/src/environment.h
index fea201bb7..2cdfb4b48 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -437,7 +437,7 @@ public:
Callbacks for activeobjects
*/
- void damageLocalPlayer(u8 damage);
+ void damageLocalPlayer(u8 damage, bool handle_hp=true);
/*
Client likes to call these
diff --git a/src/inventory.cpp b/src/inventory.cpp
index 0600729c6..645e02d9c 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -37,6 +37,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "scriptapi.h"
#include "strfnd.h"
#include "nameidmapping.h" // For loading legacy MaterialItems
+#include "serverremoteplayer.h"
/*
InventoryItem
diff --git a/src/player.cpp b/src/player.cpp
index f22eddfc1..963f67c28 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -30,9 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "nodedef.h"
#include "environment.h"
#include "gamedef.h"
-#include "content_sao.h"
-#include "tooldef.h"
-#include "materials.h"
Player::Player(IGameDef *gamedef):
touching_ground(false),
@@ -178,282 +175,6 @@ void Player::deSerialize(std::istream &is)
inventory.deSerialize(is, m_gamedef);
}
-/*
- ServerRemotePlayer
-*/
-
-ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
- Player(env->getGameDef()),
- ServerActiveObject(env, v3f(0,0,0)),
- m_last_good_position(0,0,0),
- m_last_good_position_age(0),
- m_additional_items(),
- m_inventory_not_sent(false),
- m_hp_not_sent(false),
- m_respawn_active(false),
- m_is_in_environment(false),
- m_position_not_sent(false)
-{
-}
-ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
- const char *name_):
- Player(env->getGameDef()),
- ServerActiveObject(env, pos_),
- m_inventory_not_sent(false),
- m_hp_not_sent(false),
- m_is_in_environment(false),
- m_position_not_sent(false)
-{
- setPosition(pos_);
- peer_id = peer_id_;
- updateName(name_);
-}
-ServerRemotePlayer::~ServerRemotePlayer()
-{
- clearAddToInventoryLater();
-}
-
-void ServerRemotePlayer::setPosition(const v3f &position)
-{
- Player::setPosition(position);
- ServerActiveObject::setBasePosition(position);
- m_position_not_sent = true;
-}
-
-InventoryItem* ServerRemotePlayer::getWieldedItem()
-{
- InventoryList *list = inventory.getList("main");
- if (list)
- return list->getItem(m_selected_item);
- return NULL;
-}
-
-/* ServerActiveObject interface */
-
-void ServerRemotePlayer::addedToEnvironment()
-{
- assert(!m_is_in_environment);
- m_is_in_environment = true;
-}
-
-void ServerRemotePlayer::removingFromEnvironment()
-{
- assert(m_is_in_environment);
- m_is_in_environment = false;
-}
-
-bool ServerRemotePlayer::unlimitedTransferDistance() const
-{
- return true;
-}
-
-void ServerRemotePlayer::step(float dtime, bool send_recommended)
-{
- if(send_recommended == false)
- return;
-
- if(m_position_not_sent)
- {
- m_position_not_sent = false;
-
- std::ostringstream os(std::ios::binary);
- // command (0 = update position)
- writeU8(os, 0);
- // pos
- writeV3F1000(os, getPosition());
- // yaw
- writeF1000(os, getYaw());
- // create message and add to list
- ActiveObjectMessage aom(getId(), false, os.str());
- m_messages_out.push_back(aom);
- }
-}
-
-std::string ServerRemotePlayer::getClientInitializationData()
-{
- std::ostringstream os(std::ios::binary);
- // version
- writeU8(os, 0);
- // name
- os<<serializeString(getName());
- // pos
- writeV3F1000(os, getPosition());
- // yaw
- writeF1000(os, getYaw());
- return os.str();
-}
-
-std::string ServerRemotePlayer::getStaticData()
-{
- assert(0);
- return "";
-}
-
-void ServerRemotePlayer::punch(ServerActiveObject *puncher,
- float time_from_last_punch)
-{
- if(!puncher)
- return;
-
- // "Material" properties of a player
- MaterialProperties mp;
- mp.diggability = DIGGABLE_NORMAL;
- mp.crackiness = -1.0;
- mp.cuttability = 1.0;
-
- ToolDiggingProperties tp;
- puncher->getWieldDiggingProperties(&tp);
-
- HittingProperties hitprop = getHittingProperties(&mp, &tp,
- time_from_last_punch);
-
- infostream<<"1. getHP()="<<getHP()<<std::endl;
- setHP(getHP() - hitprop.hp);
- infostream<<"2. getHP()="<<getHP()<<std::endl;
- puncher->damageWieldedItem(hitprop.wear);
-}
-
-void ServerRemotePlayer::rightClick(ServerActiveObject *clicker)
-{
-}
-
-void ServerRemotePlayer::setPos(v3f pos)
-{
- setPosition(pos);
- // Movement caused by this command is always valid
- m_last_good_position = pos;
- m_last_good_position_age = 0;
-}
-void ServerRemotePlayer::moveTo(v3f pos, bool continuous)
-{
- setPosition(pos);
- // Movement caused by this command is always valid
- m_last_good_position = pos;
- m_last_good_position_age = 0;
-}
-
-void ServerRemotePlayer::getWieldDiggingProperties(ToolDiggingProperties *dst)
-{
- IGameDef *gamedef = m_env->getGameDef();
- IToolDefManager *tdef = gamedef->tdef();
-
- InventoryItem *item = getWieldedItem();
- if(item == NULL || std::string(item->getName()) != "ToolItem"){
- *dst = ToolDiggingProperties();
- return;
- }
- ToolItem *titem = (ToolItem*)item;
- *dst = tdef->getDiggingProperties(titem->getToolName());
-}
-
-void ServerRemotePlayer::damageWieldedItem(u16 amount)
-{
- infostream<<"Damaging "<<getName()<<"'s wielded item for amount="
- <<amount<<std::endl;
- InventoryList *list = inventory.getList("main");
- if(!list)
- return;
- InventoryItem *item = list->getItem(m_selected_item);
- if(item && (std::string)item->getName() == "ToolItem"){
- ToolItem *titem = (ToolItem*)item;
- bool weared_out = titem->addWear(amount);
- if(weared_out)
- list->deleteItem(m_selected_item);
- }
-}
-bool ServerRemotePlayer::addToInventory(InventoryItem *item)
-{
- infostream<<"Adding "<<item->getName()<<" into "<<getName()
- <<"'s inventory"<<std::endl;
-
- InventoryList *ilist = inventory.getList("main");
- if(ilist == NULL)
- return false;
-
- // In creative mode, just delete the item
- if(g_settings->getBool("creative_mode")){
- return false;
- }
-
- // Skip if inventory has no free space
- if(ilist->roomForItem(item) == false)
- {
- infostream<<"Player inventory has no free space"<<std::endl;
- return false;
- }
-
- // Add to inventory
- InventoryItem *leftover = ilist->addItem(item);
- assert(!leftover);
-
- m_inventory_not_sent = true;
-
- return true;
-}
-void ServerRemotePlayer::addToInventoryLater(InventoryItem *item)
-{
- infostream<<"Adding (later) "<<item->getName()<<" into "<<getName()
- <<"'s inventory"<<std::endl;
- m_additional_items.push_back(item);
-}
-void ServerRemotePlayer::clearAddToInventoryLater()
-{
- for (std::vector<InventoryItem*>::iterator
- i = m_additional_items.begin();
- i != m_additional_items.end(); i++)
- {
- delete *i;
- }
- m_additional_items.clear();
-}
-void ServerRemotePlayer::completeAddToInventoryLater(u16 preferred_index)
-{
- InventoryList *ilist = inventory.getList("main");
- if(ilist == NULL)
- {
- clearAddToInventoryLater();
- return;
- }
-
- // In creative mode, just delete the items
- if(g_settings->getBool("creative_mode"))
- {
- clearAddToInventoryLater();
- return;
- }
-
- for (std::vector<InventoryItem*>::iterator
- i = m_additional_items.begin();
- i != m_additional_items.end(); i++)
- {
- InventoryItem *item = *i;
- InventoryItem *leftover = item;
- leftover = ilist->addItem(preferred_index, leftover);
- leftover = ilist->addItem(leftover);
- delete leftover;
- }
- m_additional_items.clear();
- m_inventory_not_sent = true;
-}
-void ServerRemotePlayer::setHP(s16 hp_)
-{
- s16 oldhp = hp;
-
- // FIXME: don't hardcode maximum HP, make configurable per object
- if(hp_ < 0)
- hp_ = 0;
- else if(hp_ > 20)
- hp_ = 20;
- hp = hp_;
-
- if(hp != oldhp)
- m_hp_not_sent = true;
-}
-s16 ServerRemotePlayer::getHP()
-{
- return hp;
-}
-
#ifndef SERVER
/*
LocalPlayer
diff --git a/src/player.h b/src/player.h
index cfd59d6ca..107c829f8 100644
--- a/src/player.h
+++ b/src/player.h
@@ -174,85 +174,6 @@ public:
};
-/*
- Player on the server
-*/
-
-#include "serverobject.h"
-#include "content_object.h" // Object type IDs
-
-class PlayerSAO;
-
-class ServerRemotePlayer : public Player, public ServerActiveObject
-{
-public:
- ServerRemotePlayer(ServerEnvironment *env);
- ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
- const char *name_);
-
- virtual ~ServerRemotePlayer();
-
- virtual bool isLocal() const
- { return false; }
-
- virtual void move(f32 dtime, Map &map, f32 pos_max_d)
- {
- }
-
- virtual void setPosition(const v3f &position);
-
- // Returns a reference
- virtual InventoryItem* getWieldedItem();
-
- /* ServerActiveObject interface */
-
- u8 getType() const
- {return ACTIVEOBJECT_TYPE_PLAYER;}
-
- // Called after id has been set and has been inserted in environment
- void addedToEnvironment();
- // Called before removing from environment
- void removingFromEnvironment();
-
- bool environmentDeletes() const
- { return false; }
-
- virtual bool unlimitedTransferDistance() const;
-
- bool isStaticAllowed() const
- { return false; }
-
- void step(float dtime, bool send_recommended);
- std::string getClientInitializationData();
- std::string getStaticData();
- void punch(ServerActiveObject *puncher, float time_from_last_punch);
- void rightClick(ServerActiveObject *clicker);
- void setPos(v3f pos);
- void moveTo(v3f pos, bool continuous);
- virtual std::string getDescription(){return getName();}
-
- virtual void getWieldDiggingProperties(ToolDiggingProperties *dst);
- virtual void damageWieldedItem(u16 amount);
- // If all fits, eats item and returns true. Otherwise returns false.
- virtual bool addToInventory(InventoryItem *item);
- virtual void addToInventoryLater(InventoryItem *item);
- void clearAddToInventoryLater();
- void completeAddToInventoryLater(u16 preferred_index);
- virtual void setHP(s16 hp_);
- virtual s16 getHP();
-
- v3f m_last_good_position;
- float m_last_good_position_age;
- std::vector<InventoryItem*> m_additional_items;
- bool m_inventory_not_sent;
- bool m_hp_not_sent;
- bool m_respawn_active;
-
-private:
- bool m_is_in_environment;
- bool m_position_not_sent;
-};
-
#ifndef SERVER
struct PlayerControl
{
diff --git a/src/server.h b/src/server.h
index e91821d04..f775f3391 100644
--- a/src/server.h
+++ b/src/server.h
@@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "ban.h"
#include "gamedef.h"
#include "serialization.h" // For SER_FMT_VER_INVALID
+#include "serverremoteplayer.h"
struct LuaState;
typedef struct lua_State lua_State;
class IWritableToolDefManager;
diff --git a/src/serverremoteplayer.cpp b/src/serverremoteplayer.cpp
new file mode 100644
index 000000000..f2bb85c92
--- /dev/null
+++ b/src/serverremoteplayer.cpp
@@ -0,0 +1,301 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 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.
+*/
+
+#include "serverremoteplayer.h"
+#include "main.h" // For g_settings
+#include "settings.h"
+#include "log.h"
+#include "gamedef.h"
+#include "tooldef.h"
+#include "environment.h"
+#include "materials.h"
+
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
+ Player(env->getGameDef()),
+ ServerActiveObject(env, v3f(0,0,0)),
+ m_last_good_position(0,0,0),
+ m_last_good_position_age(0),
+ m_additional_items(),
+ m_inventory_not_sent(false),
+ m_hp_not_sent(false),
+ m_respawn_active(false),
+ m_is_in_environment(false),
+ m_position_not_sent(false)
+{
+}
+ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
+ const char *name_):
+ Player(env->getGameDef()),
+ ServerActiveObject(env, pos_),
+ m_inventory_not_sent(false),
+ m_hp_not_sent(false),
+ m_is_in_environment(false),
+ m_position_not_sent(false)
+{
+ setPosition(pos_);
+ peer_id = peer_id_;
+ updateName(name_);
+}
+ServerRemotePlayer::~ServerRemotePlayer()
+{
+ clearAddToInventoryLater();
+}
+
+void ServerRemotePlayer::setPosition(const v3f &position)
+{
+ Player::setPosition(position);
+ ServerActiveObject::setBasePosition(position);
+ m_position_not_sent = true;
+}
+
+InventoryItem* ServerRemotePlayer::getWieldedItem()
+{
+ InventoryList *list = inventory.getList("main");
+ if (list)
+ return list->getItem(m_selected_item);
+ return NULL;
+}
+
+/* ServerActiveObject interface */
+
+void ServerRemotePlayer::addedToEnvironment()
+{
+ assert(!m_is_in_environment);
+ m_is_in_environment = true;
+}
+
+void ServerRemotePlayer::removingFromEnvironment()
+{
+ assert(m_is_in_environment);
+ m_is_in_environment = false;
+}
+
+bool ServerRemotePlayer::unlimitedTransferDistance() const
+{
+ return true;
+}
+
+void ServerRemotePlayer::step(float dtime, bool send_recommended)
+{
+ if(send_recommended == false)
+ return;
+
+ if(m_position_not_sent)
+ {
+ m_position_not_sent = false;
+
+ std::ostringstream os(std::ios::binary);
+ // command (0 = update position)
+ writeU8(os, 0);
+ // pos
+ writeV3F1000(os, getPosition());
+ // yaw
+ writeF1000(os, getYaw());
+ // create message and add to list
+ ActiveObjectMessage aom(getId(), false, os.str());
+ m_messages_out.push_back(aom);
+ }
+}
+
+std::string ServerRemotePlayer::getClientInitializationData()
+{
+ std::ostringstream os(std::ios::binary);
+ // version
+ writeU8(os, 0);
+ // name
+ os<<serializeString(getName());
+ // pos
+ writeV3F1000(os, getPosition());
+ // yaw
+ writeF1000(os, getYaw());
+ return os.str();
+}
+
+std::string ServerRemotePlayer::getStaticData()
+{
+ assert(0);
+ return "";
+}
+
+void ServerRemotePlayer::punch(ServerActiveObject *puncher,
+ float time_from_last_punch)
+{
+ if(!puncher)
+ return;
+
+ // "Material" properties of a player
+ MaterialProperties mp;
+ mp.diggability = DIGGABLE_NORMAL;
+ mp.crackiness = -1.0;
+ mp.cuttability = 1.0;
+
+ ToolDiggingProperties tp;
+ puncher->getWieldDiggingProperties(&tp);
+
+ HittingProperties hitprop = getHittingProperties(&mp, &tp,
+ time_from_last_punch);
+
+ infostream<<"1. getHP()="<<getHP()<<std::endl;
+ setHP(getHP() - hitprop.hp);
+ infostream<<"2. getHP()="<<getHP()<<std::endl;
+ puncher->damageWieldedItem(hitprop.wear);
+}
+
+void ServerRemotePlayer::rightClick(ServerActiveObject *clicker)
+{
+}
+
+void ServerRemotePlayer::setPos(v3f pos)
+{
+ setPosition(pos);
+ // Movement caused by this command is always valid
+ m_last_good_position = pos;
+ m_last_good_position_age = 0;
+}
+void ServerRemotePlayer::moveTo(v3f pos, bool continuous)
+{
+ setPosition(pos);
+ // Movement caused by this command is always valid
+ m_last_good_position = pos;
+ m_last_good_position_age = 0;
+}
+
+void ServerRemotePlayer::getWieldDiggingProperties(ToolDiggingProperties *dst)
+{
+ IGameDef *gamedef = m_env->getGameDef();
+ IToolDefManager *tdef = gamedef->tdef();
+
+ InventoryItem *item = getWieldedItem();
+ if(item == NULL || std::string(item->getName()) != "ToolItem"){
+ *dst = ToolDiggingProperties();
+ return;
+ }
+ ToolItem *titem = (ToolItem*)item;
+ *dst = tdef->getDiggingProperties(titem->getToolName());
+}
+
+void ServerRemotePlayer::damageWieldedItem(u16 amount)
+{
+ infostream<<"Damaging "<<getName()<<"'s wielded item for amount="
+ <<amount<<std::endl;
+ InventoryList *list = inventory.getList("main");
+ if(!list)
+ return;
+ InventoryItem *item = list->getItem(m_selected_item);
+ if(item && (std::string)item->getName() == "ToolItem"){
+ ToolItem *titem = (ToolItem*)item;
+ bool weared_out = titem->addWear(amount);
+ if(weared_out)
+ list->deleteItem(m_selected_item);
+ }
+}
+bool ServerRemotePlayer::addToInventory(InventoryItem *item)
+{
+ infostream<<"Adding "<<item->getName()<<" into "<<getName()
+ <<"'s inventory"<<std::endl;
+
+ InventoryList *ilist = inventory.getList("main");
+ if(ilist == NULL)
+ return false;
+
+ // In creative mode, just delete the item
+ if(g_settings->getBool("creative_mode")){
+ return false;
+ }
+
+ // Skip if inventory has no free space
+ if(ilist->roomForItem(item) == false)
+ {
+ infostream<<"Player inventory has no free space"<<std::endl;
+ return false;
+ }
+
+ // Add to inventory
+ InventoryItem *leftover = ilist->addItem(item);
+ assert(!leftover);
+
+ m_inventory_not_sent = true;
+
+ return true;
+}
+void ServerRemotePlayer::addToInventoryLater(InventoryItem *item)
+{
+ infostream<<"Adding (later) "<<item->getName()<<" into "<<getName()
+ <<"'s inventory"<<std::endl;
+ m_additional_items.push_back(item);
+}
+void ServerRemotePlayer::clearAddToInventoryLater()
+{
+ for (std::vector<InventoryItem*>::iterator
+ i = m_additional_items.begin();
+ i != m_additional_items.end(); i++)
+ {
+ delete *i;
+ }
+ m_additional_items.clear();
+}
+void ServerRemotePlayer::completeAddToInventoryLater(u16 preferred_index)
+{
+ InventoryList *ilist = inventory.getList("main");
+ if(ilist == NULL)
+ {
+ clearAddToInventoryLater();
+ return;
+ }
+
+ // In creative mode, just delete the items
+ if(g_settings->getBool("creative_mode"))
+ {
+ clearAddToInventoryLater();
+ return;
+ }
+
+ for (std::vector<InventoryItem*>::iterator
+ i = m_additional_items.begin();
+ i != m_additional_items.end(); i++)
+ {
+ InventoryItem *item = *i;
+ InventoryItem *leftover = item;
+ leftover = ilist->addItem(preferred_index, leftover);
+ leftover = ilist->addItem(leftover);
+ delete leftover;
+ }
+ m_additional_items.clear();
+ m_inventory_not_sent = true;
+}
+void ServerRemotePlayer::setHP(s16 hp_)
+{
+ s16 oldhp = hp;
+
+ // FIXME: don't hardcode maximum HP, make configurable per object
+ if(hp_ < 0)
+ hp_ = 0;
+ else if(hp_ > 20)
+ hp_ = 20;
+ hp = hp_;
+
+ if(hp != oldhp)
+ m_hp_not_sent = true;
+}
+s16 ServerRemotePlayer::getHP()
+{
+ return hp;
+}
+
+
diff --git a/src/serverremoteplayer.h b/src/serverremoteplayer.h
new file mode 100644
index 000000000..1ef14ca93
--- /dev/null
+++ b/src/serverremoteplayer.h
@@ -0,0 +1,102 @@
+/*
+Minetest-c55
+Copyright (C) 2010-2011 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 SERVERREMOTEPLAYER_HEADER
+#define SERVERREMOTEPLAYER_HEADER
+
+#include "player.h"
+#include "serverobject.h"
+#include "content_object.h" // Object type IDs
+
+/*
+ Player on the server
+*/
+
+class ServerRemotePlayer : public Player, public ServerActiveObject
+{
+public:
+ ServerRemotePlayer(ServerEnvironment *env);
+ ServerRemotePlayer(ServerEnvironment *env, v3f pos_, u16 peer_id_,
+ const char *name_);
+
+ virtual ~ServerRemotePlayer();
+
+ virtual bool isLocal() const
+ { return false; }
+
+ virtual void move(f32 dtime, Map &map, f32 pos_max_d)
+ {
+ }
+
+ virtual void setPosition(const v3f &position);
+
+ // Returns a reference
+ virtual InventoryItem* getWieldedItem();
+
+ /* ServerActiveObject interface */
+
+ u8 getType() const
+ {return ACTIVEOBJECT_TYPE_PLAYER;}
+
+ // Called after id has been set and has been inserted in environment
+ void addedToEnvironment();
+ // Called before removing from environment
+ void removingFromEnvironment();
+
+ bool environmentDeletes() const
+ { return false; }
+
+ virtual bool unlimitedTransferDistance() const;
+
+ bool isStaticAllowed() const
+ { return false; }
+
+ void step(float dtime, bool send_recommended);
+ std::string getClientInitializationData();
+ std::string getStaticData();
+ void punch(ServerActiveObject *puncher, float time_from_last_punch);
+ void rightClick(ServerActiveObject *clicker);
+ void setPos(v3f pos);
+ void moveTo(v3f pos, bool continuous);
+ virtual std::string getDescription(){return getName();}
+
+ virtual void getWieldDiggingProperties(ToolDiggingProperties *dst);
+ virtual void damageWieldedItem(u16 amount);
+ // If all fits, eats item and returns true. Otherwise returns false.
+ virtual bool addToInventory(InventoryItem *item);
+ virtual void addToInventoryLater(InventoryItem *item);
+ void clearAddToInventoryLater();
+ void completeAddToInventoryLater(u16 preferred_index);
+ virtual void setHP(s16 hp_);
+ virtual s16 getHP();
+
+ v3f m_last_good_position;
+ float m_last_good_position_age;
+ std::vector<InventoryItem*> m_additional_items;
+ bool m_inventory_not_sent;
+ bool m_hp_not_sent;
+ bool m_respawn_active;
+
+private:
+ bool m_is_in_environment;
+ bool m_position_not_sent;
+};
+
+#endif
+