From f8c3743991a6897c7133bf35dc2699b8b5f9df7c Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 19 Mar 2012 03:04:16 +0100 Subject: added PlayerSAO and RemotePlayer, removed ServerRemotePlayer --- src/content_sao.cpp | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 345 insertions(+), 2 deletions(-) (limited to 'src/content_sao.cpp') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 85340981d..d01b023de 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -26,6 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serialization.h" // For compressZlib #include "tool.h" // For ToolCapabilities #include "gamedef.h" +#include "player.h" +#include "scriptapi.h" core::map ServerActiveObject::m_types; @@ -333,7 +335,6 @@ ServerActiveObject* createItemSAO(ServerEnvironment *env, v3f pos, LuaEntitySAO */ -#include "scriptapi.h" #include "luaentity_common.h" // Prototype (registers item for deserialization) @@ -610,7 +611,7 @@ void LuaEntitySAO::setHP(s16 hp) m_hp = hp; } -s16 LuaEntitySAO::getHP() +s16 LuaEntitySAO::getHP() const { return m_hp; } @@ -749,3 +750,345 @@ void LuaEntitySAO::sendPosition(bool do_interpolate, bool is_movement_end) m_messages_out.push_back(aom); } +/* + PlayerSAO +*/ + +// No prototype, PlayerSAO does not need to be deserialized + +PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_): + ServerActiveObject(env_, v3f(0,0,0)), + m_player(player_), + m_peer_id(peer_id_), + m_inventory(NULL), + m_last_good_position(0,0,0), + m_last_good_position_age(0), + m_time_from_last_punch(0), + m_wield_index(0), + m_position_not_sent(false), + m_teleported(false), + m_inventory_not_sent(false), + m_hp_not_sent(false), + m_wielded_item_not_sent(false) +{ + assert(m_player); + assert(m_peer_id != 0); + setBasePosition(m_player->getPosition()); + m_inventory = &m_player->inventory; +} + +PlayerSAO::~PlayerSAO() +{ + if(m_inventory != &m_player->inventory) + delete m_inventory; + +} + +std::string PlayerSAO::getDescription() +{ + return std::string("player ") + m_player->getName(); +} + +// Called after id has been set and has been inserted in environment +void PlayerSAO::addedToEnvironment() +{ + ServerActiveObject::addedToEnvironment(); + ServerActiveObject::setBasePosition(m_player->getPosition()); + m_player->setPlayerSAO(this); + m_player->peer_id = m_peer_id; + m_last_good_position = m_player->getPosition(); + m_last_good_position_age = 0.0; +} + +// Called before removing from environment +void PlayerSAO::removingFromEnvironment() +{ + ServerActiveObject::removingFromEnvironment(); + if(m_player->getPlayerSAO() == this) + { + m_player->setPlayerSAO(NULL); + m_player->peer_id = 0; + } +} + +bool PlayerSAO::isStaticAllowed() const +{ + return false; +} + +bool PlayerSAO::unlimitedTransferDistance() const +{ + return g_settings->getBool("unlimited_player_transfer_distance"); +} + +std::string PlayerSAO::getClientInitializationData() +{ + std::ostringstream os(std::ios::binary); + // version + writeU8(os, 0); + // name + os<getName()); + // pos + writeV3F1000(os, m_player->getPosition()); + // yaw + writeF1000(os, m_player->getYaw()); + // dead + writeU8(os, getHP() == 0); + // wielded item + os<= 1.0){ + float age = m_last_good_position_age; + v3f diff = (m_player->getPosition() - m_last_good_position); + float d_vert = diff.Y; + diff.Y = 0; + float d_horiz = diff.getLength(); + /*infostream<getName()<<"'s horizontal speed is " + <<(d_horiz/age)<getPosition(); + } else { + actionstream<<"Player "<getName() + <<" moved too fast; resetting position" + <setPosition(m_last_good_position); + m_teleported = true; + } + m_last_good_position_age = 0; + } + + 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, m_player->getPosition()); + // yaw + writeF1000(os, m_player->getYaw()); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + m_messages_out.push_back(aom); + } + + if(m_wielded_item_not_sent) + { + m_wielded_item_not_sent = false; + + std::ostringstream os(std::ios::binary); + // command (3 = wielded item) + writeU8(os, 3); + // wielded item + os<setPosition(pos); + // Movement caused by this command is always valid + m_last_good_position = pos; + m_last_good_position_age = 0; + // Force position change on client + m_teleported = true; +} + +void PlayerSAO::moveTo(v3f pos, bool continuous) +{ + m_player->setPosition(pos); + // Movement caused by this command is always valid + m_last_good_position = pos; + m_last_good_position_age = 0; + // Force position change on client + m_teleported = true; +} + +int PlayerSAO::punch(v3f dir, + const ToolCapabilities *toolcap, + ServerActiveObject *puncher, + float time_from_last_punch) +{ + if(!toolcap) + return 0; + + // No effect if PvP disabled + if(g_settings->getBool("enable_pvp") == false){ + if(puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) + return 0; + } + + // "Material" groups of the player + ItemGroupList groups; + groups["choppy"] = 2; + groups["fleshy"] = 3; + + HitParams hitparams = getHitParams(groups, toolcap, time_from_last_punch); + + actionstream<<"Player "<getName()<<" punched by " + <getDescription()<<", damage "<hp; +} + +void PlayerSAO::setHP(s16 hp) +{ + s16 oldhp = m_player->hp; + + if(hp < 0) + hp = 0; + else if(hp > PLAYER_MAX_HP) + hp = PLAYER_MAX_HP; + + if(hp < oldhp && g_settings->getBool("enable_damage") == false) + { + m_hp_not_sent = true; // fix wrong prediction on client + return; + } + + m_player->hp = hp; + + if(hp != oldhp) + m_hp_not_sent = true; + + // On death or reincarnation send an active object message + if((hp == 0) != (oldhp == 0)) + { + std::ostringstream os(std::ios::binary); + // command (2 = update death state) + writeU8(os, 2); + // dead? + writeU8(os, hp == 0); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + m_messages_out.push_back(aom); + } +} + +Inventory* PlayerSAO::getInventory() +{ + return m_inventory; +} +const Inventory* PlayerSAO::getInventory() const +{ + return m_inventory; +} + +InventoryLocation PlayerSAO::getInventoryLocation() const +{ + InventoryLocation loc; + loc.setPlayer(m_player->getName()); + return loc; +} + +void PlayerSAO::setInventoryModified() +{ + m_inventory_not_sent = true; +} + +std::string PlayerSAO::getWieldList() const +{ + return "main"; +} + +int PlayerSAO::getWieldIndex() const +{ + return m_wield_index; +} + +void PlayerSAO::setWieldIndex(int i) +{ + if(i != m_wield_index) + { + m_wield_index = i; + m_wielded_item_not_sent = true; + } +} + +void PlayerSAO::disconnected() +{ + m_peer_id = 0; + m_removed = true; + if(m_player->getPlayerSAO() == this) + { + m_player->setPlayerSAO(NULL); + m_player->peer_id = 0; + } +} + +void PlayerSAO::createCreativeInventory() +{ + if(m_inventory != &m_player->inventory) + delete m_inventory; + + m_inventory = new Inventory(m_player->inventory); + m_inventory->clearContents(); + scriptapi_get_creative_inventory(m_env->getLua(), this); +} + -- cgit v1.2.3