diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d96ddea..3d9f4979 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 20eb3cf1..8d1fcc24 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 e8dfebcb..ce81a194 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 fea201bb..2cdfb4b4 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 0600729c..645e02d9 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 f22eddfc..963f67c2 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<getWieldDiggingProperties(&tp); - - HittingProperties hitprop = getHittingProperties(&mp, &tp, - time_from_last_punch); - - infostream<<"1. getHP()="<getDiggingProperties(titem->getToolName()); -} - -void ServerRemotePlayer::damageWieldedItem(u16 amount) -{ - infostream<<"Damaging "<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 "<getName()<<" into "<getBool("creative_mode")){ - return false; - } - - // Skip if inventory has no free space - if(ilist->roomForItem(item) == false) - { - infostream<<"Player inventory has no free space"<addItem(item); - assert(!leftover); - - m_inventory_not_sent = true; - - return true; -} -void ServerRemotePlayer::addToInventoryLater(InventoryItem *item) -{ - infostream<<"Adding (later) "<getName()<<" into "<::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::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 cfd59d6c..107c829f 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 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 e91821d0..f775f339 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 00000000..f2bb85c9 --- /dev/null +++ b/src/serverremoteplayer.cpp @@ -0,0 +1,301 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +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<getWieldDiggingProperties(&tp); + + HittingProperties hitprop = getHittingProperties(&mp, &tp, + time_from_last_punch); + + infostream<<"1. getHP()="<getDiggingProperties(titem->getToolName()); +} + +void ServerRemotePlayer::damageWieldedItem(u16 amount) +{ + infostream<<"Damaging "<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 "<getName()<<" into "<getBool("creative_mode")){ + return false; + } + + // Skip if inventory has no free space + if(ilist->roomForItem(item) == false) + { + infostream<<"Player inventory has no free space"<addItem(item); + assert(!leftover); + + m_inventory_not_sent = true; + + return true; +} +void ServerRemotePlayer::addToInventoryLater(InventoryItem *item) +{ + infostream<<"Adding (later) "<getName()<<" into "<::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::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 00000000..1ef14ca9 --- /dev/null +++ b/src/serverremoteplayer.h @@ -0,0 +1,102 @@ +/* +Minetest-c55 +Copyright (C) 2010-2011 celeron55, Perttu Ahola + +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 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 +