From 569b89b36fff058390cb90458da4285552a9c97e Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 8 Oct 2016 19:08:23 +0200 Subject: Move RemotePlayer code to its own cpp/header --- src/remoteplayer.h | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/remoteplayer.h (limited to 'src/remoteplayer.h') diff --git a/src/remoteplayer.h b/src/remoteplayer.h new file mode 100644 index 000000000..f6c70b0e9 --- /dev/null +++ b/src/remoteplayer.h @@ -0,0 +1,175 @@ +/* +Minetest +Copyright (C) 2010-2016 celeron55, Perttu Ahola +Copyright (C) 2014-2016 nerzhul, Loic Blot + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser 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 REMOTEPLAYER_HEADER +#define REMOTEPLAYER_HEADER + +#include "player.h" + +class PlayerSAO; + +enum RemotePlayerChatResult { + RPLAYER_CHATRESULT_OK, + RPLAYER_CHATRESULT_FLOODING, + RPLAYER_CHATRESULT_KICK, +}; +/* + Player on the server +*/ +class RemotePlayer : public Player +{ +public: + RemotePlayer(const char *name, IItemDefManager *idef); + virtual ~RemotePlayer() {} + + void save(std::string savedir, IGameDef *gamedef); + void deSerialize(std::istream &is, const std::string &playername); + + PlayerSAO *getPlayerSAO() { return m_sao; } + void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; } + void setPosition(const v3f &position); + + const RemotePlayerChatResult canSendChatMessage(); + + void setHotbarItemcount(s32 hotbar_itemcount) + { + hud_hotbar_itemcount = hotbar_itemcount; + } + + s32 getHotbarItemcount() const { return hud_hotbar_itemcount; } + + void overrideDayNightRatio(bool do_override, float ratio) + { + m_day_night_ratio_do_override = do_override; + m_day_night_ratio = ratio; + } + + void getDayNightRatio(bool *do_override, float *ratio) + { + *do_override = m_day_night_ratio_do_override; + *ratio = m_day_night_ratio; + } + + // Use a function, if isDead can be defined by other conditions + bool isDead() const { return hp == 0; } + + void setHotbarImage(const std::string &name) + { + hud_hotbar_image = name; + } + + std::string getHotbarImage() const + { + return hud_hotbar_image; + } + + void setHotbarSelectedImage(const std::string &name) + { + hud_hotbar_selected_image = name; + } + + const std::string &getHotbarSelectedImage() const + { + return hud_hotbar_selected_image; + } + + // Deprecated + f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } + + // Deprecated + f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; } + + void setSky(const video::SColor &bgcolor, const std::string &type, + const std::vector ¶ms) + { + m_sky_bgcolor = bgcolor; + m_sky_type = type; + m_sky_params = params; + } + + void getSky(video::SColor *bgcolor, std::string *type, + std::vector *params) + { + *bgcolor = m_sky_bgcolor; + *type = m_sky_type; + *params = m_sky_params; + } + + bool checkModified() const { return m_dirty || inventory.checkModified(); } + + void setModified(const bool x) + { + m_dirty = x; + if (!x) + inventory.setModified(x); + } + + virtual void setBreath(u16 breath) + { + if (breath != m_breath) + m_dirty = true; + Player::setBreath(breath); + } + + virtual void setPitch(f32 pitch) + { + if (pitch != m_pitch) + m_dirty = true; + Player::setPitch(pitch); + } + + virtual void setYaw(f32 yaw) + { + if (yaw != m_yaw) + m_dirty = true; + Player::setYaw(yaw); + } + + u16 protocol_version; +private: + /* + serialize() writes a bunch of text that can contain + any characters except a '\0', and such an ending that + deSerialize stops reading exactly at the right point. + */ + void serialize(std::ostream &os); + + PlayerSAO *m_sao; + bool m_dirty; + + static bool m_setting_cache_loaded; + static float m_setting_chat_message_limit_per_10sec; + static u16 m_setting_chat_message_limit_trigger_kick; + + u32 m_last_chat_message_sent; + float m_chat_message_allowance; + u16 m_message_rate_overhead; + + bool m_day_night_ratio_do_override; + float m_day_night_ratio; + std::string hud_hotbar_image; + std::string hud_hotbar_selected_image; + + std::string m_sky_type; + video::SColor m_sky_bgcolor; + std::vector m_sky_params; +}; + +#endif -- cgit v1.2.3 From 70f104be076321330a0827010704761a040d8ec7 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 8 Oct 2016 23:13:38 +0200 Subject: Environment cleanup * Move client list to ServerEnvironment and use RemotePlayer members instead of Player * ClientEnvironment only use setLocalPlayer to specify the current player * Remove ClientEnvironment dead code on player list (in fact other players are CAO not Player objects) * Drop LocalPlayer::getPlayer(xxx) functions which aren't used. * Improve a little bit performance by using const ref list for ClientEnvironment::getPlayerNames() & Client::getConnectedPlayerNames() * Drop isLocal() function from (Local)Player which is not needed anymore because of previous changes This change permits to cleanup shared client list which is very old code. ClientEnvironment doesn't use player list anymore, it only contains the local player, as addPlayer is only called from Client constructor client side. Clients are only CAO on client side, this cleanup permit to remove confusion about player list. --- src/client.cpp | 14 ++--- src/client.h | 5 +- src/content_cao.cpp | 8 +-- src/environment.cpp | 165 +++++++++++++++++++--------------------------------- src/environment.h | 32 ++++------ src/localplayer.h | 5 -- src/player.h | 16 ----- src/remoteplayer.h | 14 +++++ 8 files changed, 97 insertions(+), 162 deletions(-) (limited to 'src/remoteplayer.h') diff --git a/src/client.cpp b/src/client.cpp index cd010e592..62bd274aa 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -257,7 +257,7 @@ Client::Client( m_localdb(NULL) { // Add local player - m_env.addPlayer(new LocalPlayer(this, playername)); + m_env.setLocalPlayer(new LocalPlayer(this, playername)); m_mapper = new Mapper(device, this); m_cache_save_interval = g_settings->getU16("server_map_save_interval"); @@ -1418,8 +1418,9 @@ Inventory* Client::getInventory(const InventoryLocation &loc) break; case InventoryLocation::PLAYER: { - LocalPlayer *player = m_env.getPlayer(loc.name.c_str()); - if(!player) + // Check if we are working with local player inventory + LocalPlayer *player = m_env.getLocalPlayer(); + if (!player || strcmp(player->getName(), loc.name.c_str()) != 0) return NULL; return &player->inventory; } @@ -1500,11 +1501,6 @@ ClientActiveObject * Client::getSelectedActiveObject( return NULL; } -std::list Client::getConnectedPlayerNames() -{ - return m_env.getPlayerNames(); -} - float Client::getAnimationTime() { return m_animation_time; @@ -1664,7 +1660,7 @@ void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool ur ClientEvent Client::getClientEvent() { ClientEvent event; - if(m_client_event_queue.size() == 0) { + if (m_client_event_queue.empty()) { event.type = CE_NONE; } else { diff --git a/src/client.h b/src/client.h index 72baac2d2..6d24c0b1d 100644 --- a/src/client.h +++ b/src/client.h @@ -452,7 +452,10 @@ public: core::line3d shootline_on_map ); - std::list getConnectedPlayerNames(); + const std::list &getConnectedPlayerNames() + { + return m_env.getPlayerNames(); + } float getAnimationTime(); diff --git a/src/content_cao.cpp b/src/content_cao.cpp index a53768149..00e17f328 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -653,10 +653,10 @@ void GenericCAO::initialize(const std::string &data) pos_translator.init(m_position); updateNodePos(); - if(m_is_player) - { - LocalPlayer *player = m_env->getPlayer(m_name.c_str()); - if (player && player->isLocal()) { + if (m_is_player) { + // Check if it's the current player + LocalPlayer *player = m_env->getLocalPlayer(); + if (player && strcmp(player->getName(), m_name.c_str()) == 0) { m_is_local_player = true; m_is_visible = false; LocalPlayer* localplayer = player; diff --git a/src/environment.cpp b/src/environment.cpp index ff43ac516..ceaa01d7a 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -69,62 +69,6 @@ Environment::Environment(): Environment::~Environment() { - // Deallocate players - for(std::vector::iterator i = m_players.begin(); - i != m_players.end(); ++i) { - delete (*i); - } -} - -void Environment::addPlayer(Player *player) -{ - DSTACK(FUNCTION_NAME); - /* - Check that peer_ids are unique. - Also check that names are unique. - Exception: there can be multiple players with peer_id=0 - */ - // If peer id is non-zero, it has to be unique. - if(player->peer_id != 0) - FATAL_ERROR_IF(getPlayer(player->peer_id) != NULL, "Peer id not unique"); - // Name has to be unique. - FATAL_ERROR_IF(getPlayer(player->getName()) != NULL, "Player name not unique"); - // Add. - m_players.push_back(player); -} - -void Environment::removePlayer(Player* player) -{ - for (std::vector::iterator it = m_players.begin(); - it != m_players.end(); ++it) { - if ((*it) == player) { - delete *it; - m_players.erase(it); - return; - } - } -} - -Player *Environment::getPlayer(u16 peer_id) -{ - for (std::vector::iterator i = m_players.begin(); - i != m_players.end(); ++i) { - Player *player = *i; - if (player->peer_id == peer_id) - return player; - } - return NULL; -} - -Player *Environment::getPlayer(const char *name) -{ - for (std::vector::iterator i = m_players.begin(); - i != m_players.end(); ++i) { - Player *player = *i; - if(strcmp(player->getName(), name) == 0) - return player; - } - return NULL; } u32 Environment::getDayNightRatio() @@ -545,10 +489,16 @@ ServerEnvironment::~ServerEnvironment() m_map->drop(); // Delete ActiveBlockModifiers - for(std::vector::iterator + for (std::vector::iterator i = m_abms.begin(); i != m_abms.end(); ++i){ delete i->abm; } + + // Deallocate players + for (std::vector::iterator i = m_players.begin(); + i != m_players.end(); ++i) { + delete (*i); + } } Map & ServerEnvironment::getMap() @@ -563,12 +513,53 @@ ServerMap & ServerEnvironment::getServerMap() RemotePlayer *ServerEnvironment::getPlayer(const u16 peer_id) { - return dynamic_cast(Environment::getPlayer(peer_id)); + for (std::vector::iterator i = m_players.begin(); + i != m_players.end(); ++i) { + RemotePlayer *player = *i; + if (player->peer_id == peer_id) + return player; + } + return NULL; } RemotePlayer *ServerEnvironment::getPlayer(const char* name) { - return dynamic_cast(Environment::getPlayer(name)); + for (std::vector::iterator i = m_players.begin(); + i != m_players.end(); ++i) { + RemotePlayer *player = *i; + if (strcmp(player->getName(), name) == 0) + return player; + } + return NULL; +} + +void ServerEnvironment::addPlayer(RemotePlayer *player) +{ + DSTACK(FUNCTION_NAME); + /* + Check that peer_ids are unique. + Also check that names are unique. + Exception: there can be multiple players with peer_id=0 + */ + // If peer id is non-zero, it has to be unique. + if (player->peer_id != 0) + FATAL_ERROR_IF(getPlayer(player->peer_id) != NULL, "Peer id not unique"); + // Name has to be unique. + FATAL_ERROR_IF(getPlayer(player->getName()) != NULL, "Player name not unique"); + // Add. + m_players.push_back(player); +} + +void ServerEnvironment::removePlayer(RemotePlayer *player) +{ + for (std::vector::iterator it = m_players.begin(); + it != m_players.end(); ++it) { + if ((*it) == player) { + delete *it; + m_players.erase(it); + return; + } + } } bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16 *p) @@ -601,7 +592,7 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16 void ServerEnvironment::kickAllPlayers(AccessDeniedCode reason, const std::string &str_reason, bool reconnect) { - for (std::vector::iterator it = m_players.begin(); + for (std::vector::iterator it = m_players.begin(); it != m_players.end(); ++it) { RemotePlayer *player = dynamic_cast(*it); ((Server*)m_gamedef)->DenyAccessVerCompliant(player->peer_id, @@ -614,7 +605,7 @@ void ServerEnvironment::saveLoadedPlayers() std::string players_path = m_path_world + DIR_DELIM "players"; fs::CreateDir(players_path); - for (std::vector::iterator it = m_players.begin(); + for (std::vector::iterator it = m_players.begin(); it != m_players.end(); ++it) { RemotePlayer *player = static_cast(*it); @@ -1253,7 +1244,7 @@ void ServerEnvironment::step(float dtime) */ { ScopeProfiler sp(g_profiler, "SEnv: handle players avg", SPT_AVG); - for (std::vector::iterator i = m_players.begin(); + for (std::vector::iterator i = m_players.begin(); i != m_players.end(); ++i) { RemotePlayer *player = dynamic_cast(*i); assert(player); @@ -1276,7 +1267,7 @@ void ServerEnvironment::step(float dtime) Get player block positions */ std::vector players_blockpos; - for (std::vector::iterator i = m_players.begin(); + for (std::vector::iterator i = m_players.begin(); i != m_players.end(); ++i) { RemotePlayer *player = dynamic_cast(*i); assert(player); @@ -2255,6 +2246,7 @@ ClientEnvironment::ClientEnvironment(ClientMap *map, scene::ISceneManager *smgr, ITextureSource *texturesource, IGameDef *gamedef, IrrlichtDevice *irr): m_map(map), + m_local_player(NULL), m_smgr(smgr), m_texturesource(texturesource), m_gamedef(gamedef), @@ -2291,37 +2283,16 @@ ClientMap & ClientEnvironment::getClientMap() return *m_map; } -LocalPlayer *ClientEnvironment::getPlayer(const u16 peer_id) -{ - return dynamic_cast(Environment::getPlayer(peer_id)); -} - -LocalPlayer *ClientEnvironment::getPlayer(const char* name) -{ - return dynamic_cast(Environment::getPlayer(name)); -} - -void ClientEnvironment::addPlayer(LocalPlayer *player) +void ClientEnvironment::setLocalPlayer(LocalPlayer *player) { DSTACK(FUNCTION_NAME); /* It is a failure if already is a local player */ - FATAL_ERROR_IF(getLocalPlayer() != NULL, - "Player is local but there is already a local player"); - - Environment::addPlayer(player); -} + FATAL_ERROR_IF(m_local_player != NULL, + "Local player already allocated"); -LocalPlayer *ClientEnvironment::getLocalPlayer() -{ - for(std::vector::iterator i = m_players.begin(); - i != m_players.end(); ++i) { - Player *player = *i; - if (player->isLocal()) - return (LocalPlayer*)player; - } - return NULL; + m_local_player = player; } void ClientEnvironment::step(float dtime) @@ -2558,24 +2529,6 @@ void ClientEnvironment::step(float dtime) } } - /* - Stuff that can be done in an arbitarily large dtime - */ - for (std::vector::iterator i = m_players.begin(); - i != m_players.end(); ++i) { - Player *player = *i; - assert(player); - - /* - Handle non-local players - */ - if (!player->isLocal()) { - // Move - player->move(dtime, this, 100*BS); - - } - } - // Update lighting on local player (used for wield item) u32 day_night_ratio = getDayNightRatio(); { diff --git a/src/environment.h b/src/environment.h index f19708ad7..83ad69562 100644 --- a/src/environment.h +++ b/src/environment.h @@ -72,9 +72,6 @@ public: virtual Map & getMap() = 0; - virtual void addPlayer(Player *player); - void removePlayer(Player *player); - u32 getDayNightRatio(); // 0-23999 @@ -94,12 +91,6 @@ public: u32 m_added_objects; protected: - Player *getPlayer(u16 peer_id); - Player *getPlayer(const char *name); - - // peer_ids in here should be unique, except that there may be many 0s - std::vector m_players; - GenericAtomic m_time_of_day_speed; /* @@ -325,6 +316,8 @@ public: void saveLoadedPlayers(); void savePlayer(RemotePlayer *player); RemotePlayer *loadPlayer(const std::string &playername); + void addPlayer(RemotePlayer *player); + void removePlayer(RemotePlayer *player); /* Save and load time of day and game timer @@ -520,6 +513,9 @@ private: // Can raise to high values like 15s with eg. map generation mods. float m_max_lag_estimate; + // peer_ids in here should be unique, except that there may be many 0s + std::vector m_players; + // Particles IntervalLimiter m_particle_management_interval; UNORDERED_MAP m_particle_spawners; @@ -579,8 +575,8 @@ public: void step(f32 dtime); - virtual void addPlayer(LocalPlayer *player); - LocalPlayer * getLocalPlayer(); + virtual void setLocalPlayer(LocalPlayer *player); + LocalPlayer *getLocalPlayer() { return m_local_player; } /* ClientSimpleObjects @@ -630,21 +626,15 @@ public: u16 attachement_parent_ids[USHRT_MAX + 1]; - std::list getPlayerNames() - { return m_player_names; } - void addPlayerName(std::string name) - { m_player_names.push_back(name); } - void removePlayerName(std::string name) - { m_player_names.remove(name); } + const std::list &getPlayerNames() { return m_player_names; } + void addPlayerName(const std::string &name) { m_player_names.push_back(name); } + void removePlayerName(const std::string &name) { m_player_names.remove(name); } void updateCameraOffset(v3s16 camera_offset) { m_camera_offset = camera_offset; } v3s16 getCameraOffset() const { return m_camera_offset; } - - LocalPlayer *getPlayer(const u16 peer_id); - LocalPlayer *getPlayer(const char* name); - private: ClientMap *m_map; + LocalPlayer *m_local_player; scene::ISceneManager *m_smgr; ITextureSource *m_texturesource; IGameDef *m_gamedef; diff --git a/src/localplayer.h b/src/localplayer.h index 9d43128aa..eb727d7e3 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -38,11 +38,6 @@ public: LocalPlayer(Client *gamedef, const char *name); virtual ~LocalPlayer(); - bool isLocal() const - { - return true; - } - ClientActiveObject *parent; bool got_teleported; diff --git a/src/player.h b/src/player.h index 3c945b100..6ac5dfe65 100644 --- a/src/player.h +++ b/src/player.h @@ -183,22 +183,6 @@ public: return size; } - void setLocalAnimations(v2s32 frames[4], float frame_speed) - { - for (int i = 0; i < 4; i++) - local_animations[i] = frames[i]; - local_animation_speed = frame_speed; - } - - void getLocalAnimations(v2s32 *frames, float *frame_speed) - { - for (int i = 0; i < 4; i++) - frames[i] = local_animations[i]; - *frame_speed = local_animation_speed; - } - - virtual bool isLocal() const { return false; } - bool camera_barely_in_ceiling; v3f eye_offset_first; v3f eye_offset_third; diff --git a/src/remoteplayer.h b/src/remoteplayer.h index f6c70b0e9..1b1a90de3 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -142,6 +142,20 @@ public: Player::setYaw(yaw); } + void setLocalAnimations(v2s32 frames[4], float frame_speed) + { + for (int i = 0; i < 4; i++) + local_animations[i] = frames[i]; + local_animation_speed = frame_speed; + } + + void getLocalAnimations(v2s32 *frames, float *frame_speed) + { + for (int i = 0; i < 4; i++) + frames[i] = local_animations[i]; + *frame_speed = local_animation_speed; + } + u16 protocol_version; private: /* -- cgit v1.2.3 From 9d25242c5c1411d692254cf910345d51c9a24fa3 Mon Sep 17 00:00:00 2001 From: Ner'zhul Date: Sun, 30 Oct 2016 14:53:26 +0100 Subject: PlayerSAO/LocalPlayer refactor: (#4612) * Create UnitSAO, a common part between PlayerSAO & LuaEntitySAO * Move breath to PlayerSAO & LocalPlayer * Migrate m_yaw from (Remote)Player & LuaEntitySAO to UnitSAO * Migrate m_yaw from Player to LocalPlayer for client * Move some functions outside of player class to PlayerSAO/RemotePlayer or LocalPlayer depending on which class needs it * Move pitch to LocalPlayer & PlayerSAO * Move m_position from Player to LocalPlayer * Move camera_barely_in_ceiling to LocalPlayer as it's used only there * use PlayerSAO::m_base_position for Server side positions * remove a unused variable * ServerActiveObject::setPos now uses const ref * use ServerEnv::loadPlayer unconditionnaly as it creates RemotePlayer only if it's not already loaded * Move hp from Player to LocalPlayer * Move m_hp from LuaEntitySAO to UnitSAO * Use m_hp from PlayerSAO/UnitSAO instead of RemotePlayer --- src/clientiface.cpp | 14 ++-- src/collision.cpp | 2 +- src/content_sao.cpp | 155 +++++++++++++++++++----------------- src/content_sao.h | 62 +++++++++++---- src/environment.cpp | 35 ++++---- src/environment.h | 7 +- src/localplayer.cpp | 7 ++ src/localplayer.h | 41 ++++++++++ src/network/clientpackethandler.cpp | 1 - src/network/serverpackethandler.cpp | 55 +++++++------ src/player.cpp | 14 +--- src/player.h | 50 ------------ src/remoteplayer.cpp | 66 +++++++-------- src/remoteplayer.h | 35 +------- src/script/lua_api/l_object.cpp | 32 ++++---- src/server.cpp | 71 +++++++++-------- src/serverobject.h | 2 +- src/unittest/test_player.cpp | 39 +++++---- 18 files changed, 353 insertions(+), 335 deletions(-) (limited to 'src/remoteplayer.h') diff --git a/src/clientiface.cpp b/src/clientiface.cpp index d78cf1c53..d2e3a6da0 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "environment.h" #include "map.h" #include "emerge.h" -#include "serverobject.h" // TODO this is used for cleanup of only +#include "content_sao.h" // TODO this is used for cleanup of only #include "log.h" #include "util/srp.h" @@ -82,6 +82,10 @@ void RemoteClient::GetNextBlocks ( if (player == NULL) return; + PlayerSAO *sao = player->getPlayerSAO(); + if (sao == NULL) + return; + // Won't send anything if already sending if(m_blocks_sending.size() >= g_settings->getU16 ("max_simultaneous_block_sends_per_client")) @@ -90,7 +94,7 @@ void RemoteClient::GetNextBlocks ( return; } - v3f playerpos = player->getPosition(); + v3f playerpos = sao->getBasePosition(); v3f playerspeed = player->getSpeed(); v3f playerspeeddir(0,0,0); if(playerspeed.getLength() > 1.0*BS) @@ -103,10 +107,10 @@ void RemoteClient::GetNextBlocks ( v3s16 center = getNodeBlockPos(center_nodepos); // Camera position and direction - v3f camera_pos = player->getEyePosition(); + v3f camera_pos = sao->getEyePosition(); v3f camera_dir = v3f(0,0,1); - camera_dir.rotateYZBy(player->getPitch()); - camera_dir.rotateXZBy(player->getYaw()); + camera_dir.rotateYZBy(sao->getPitch()); + camera_dir.rotateXZBy(sao->getYaw()); /*infostream<<"camera_dir=("<(env); - if (s_env != 0) { + if (s_env != NULL) { f32 distance = speed_f->getLength(); std::vector s_objects; s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 375a43c90..23a064085 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -118,14 +118,12 @@ LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", ""); LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &name, const std::string &state): - ServerActiveObject(env, pos), + UnitSAO(env, pos), m_init_name(name), m_init_state(state), m_registered(false), - m_hp(-1), m_velocity(0,0,0), m_acceleration(0,0,0), - m_yaw(0), m_properties_sent(true), m_last_sent_yaw(0), m_last_sent_position(0,0,0), @@ -664,16 +662,6 @@ v3f LuaEntitySAO::getAcceleration() return m_acceleration; } -void LuaEntitySAO::setYaw(float yaw) -{ - m_yaw = yaw; -} - -float LuaEntitySAO::getYaw() -{ - return m_yaw; -} - void LuaEntitySAO::setTextureMod(const std::string &mod) { std::string str = gob_cmd_set_texture_mod(mod); @@ -762,10 +750,9 @@ bool LuaEntitySAO::collideWithObjects(){ // No prototype, PlayerSAO does not need to be deserialized -PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, - const std::set &privs, bool is_singleplayer): - ServerActiveObject(env_, v3f(0,0,0)), - m_player(player_), +PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer): + UnitSAO(env_, v3f(0,0,0)), + m_player(NULL), m_peer_id(peer_id_), m_inventory(NULL), m_damage(0), @@ -777,7 +764,6 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_position_not_sent(false), m_armor_groups_sent(false), m_properties_sent(true), - m_privs(privs), m_is_singleplayer(is_singleplayer), m_animation_speed(0), m_animation_blend(0), @@ -786,6 +772,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_bone_position_sent(false), m_attachment_parent_id(0), m_attachment_sent(false), + m_breath(PLAYER_MAX_BREATH), + m_pitch(0), // public m_physics_override_speed(1), m_physics_override_jump(1), @@ -794,10 +782,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_physics_override_sneak_glitch(true), m_physics_override_sent(false) { - assert(m_player); // pre-condition assert(m_peer_id != 0); // pre-condition - setBasePosition(m_player->getPosition()); - m_inventory = &m_player->inventory; m_armor_groups["fleshy"] = 100; m_prop.hp_max = PLAYER_MAX_HP; @@ -816,6 +801,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id // end of default appearance m_prop.is_visible = true; m_prop.makes_footstep_sound = true; + m_hp = PLAYER_MAX_HP; } PlayerSAO::~PlayerSAO() @@ -824,6 +810,14 @@ PlayerSAO::~PlayerSAO() delete m_inventory; } +void PlayerSAO::initialize(RemotePlayer *player, const std::set &privs) +{ + assert(player); + m_player = player; + m_privs = privs; + m_inventory = &m_player->inventory; +} + std::string PlayerSAO::getDescription() { return std::string("player ") + m_player->getName(); @@ -833,10 +827,10 @@ std::string PlayerSAO::getDescription() void PlayerSAO::addedToEnvironment(u32 dtime_s) { ServerActiveObject::addedToEnvironment(dtime_s); - ServerActiveObject::setBasePosition(m_player->getPosition()); + ServerActiveObject::setBasePosition(m_base_position); m_player->setPlayerSAO(this); m_player->peer_id = m_peer_id; - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; } // Called before removing from environment @@ -844,9 +838,9 @@ void PlayerSAO::removingFromEnvironment() { ServerActiveObject::removingFromEnvironment(); if (m_player->getPlayerSAO() == this) { - m_player->setPlayerSAO(NULL); m_player->peer_id = 0; m_env->savePlayer(m_player); + m_player->setPlayerSAO(NULL); m_env->removePlayer(m_player); for (UNORDERED_SET::iterator it = m_attached_particle_spawners.begin(); it != m_attached_particle_spawners.end(); ++it) { @@ -870,8 +864,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) os<getName()); // name writeU8(os, 1); // is_player writeS16(os, getId()); //id - writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0)); - writeF1000(os, m_player->getYaw()); + writeV3F1000(os, m_base_position + v3f(0,BS*1,0)); + writeF1000(os, m_yaw); writeS16(os, getHP()); writeU8(os, 6 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here @@ -900,8 +894,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) writeU8(os, 0); // version os<getName()); // name writeU8(os, 1); // is_player - writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0)); - writeF1000(os, m_player->getYaw()); + writeV3F1000(os, m_base_position + v3f(0,BS*1,0)); + writeF1000(os, m_yaw); writeS16(os, getHP()); writeU8(os, 2); // number of messages stuffed in here os<setPosition(m_last_good_position); + setBasePosition(m_last_good_position); ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } @@ -969,14 +963,13 @@ void PlayerSAO::step(float dtime, bool send_recommended) // Each frame, parent position is copied if the object is attached, otherwise it's calculated normally // If the object gets detached this comes into effect automatically from the last known origin - if(isAttached()) - { + if (isAttached()) { v3f pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition(); m_last_good_position = pos; - m_player->setPosition(pos); + setBasePosition(pos); } - if(send_recommended == false) + if (!send_recommended) return; // If the object is attached client-side, don't waste bandwidth sending its position to clients @@ -988,12 +981,12 @@ void PlayerSAO::step(float dtime, bool send_recommended) if(isAttached()) // Just in case we ever do send attachment position too pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition(); else - pos = m_player->getPosition() + v3f(0,BS*1,0); + pos = m_base_position + v3f(0,BS*1,0); std::string str = gob_cmd_update_position( pos, v3f(0,0,0), v3f(0,0,0), - m_player->getYaw(), + m_yaw, true, false, update_interval @@ -1003,7 +996,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_armor_groups_sent == false) { + if (!m_armor_groups_sent) { m_armor_groups_sent = true; std::string str = gob_cmd_update_armor_groups( m_armor_groups); @@ -1012,7 +1005,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_physics_override_sent == false){ + if (!m_physics_override_sent) { m_physics_override_sent = true; std::string str = gob_cmd_update_physics_override(m_physics_override_speed, m_physics_override_jump, m_physics_override_gravity, @@ -1022,7 +1015,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_animation_sent == false){ + if (!m_animation_sent) { m_animation_sent = true; std::string str = gob_cmd_update_animation( m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop); @@ -1055,16 +1048,20 @@ void PlayerSAO::step(float dtime, bool send_recommended) void PlayerSAO::setBasePosition(const v3f &position) { + if (m_player && position != m_base_position) + m_player->setDirty(true); + // This needs to be ran for attachments too ServerActiveObject::setBasePosition(position); m_position_not_sent = true; } -void PlayerSAO::setPos(v3f pos) +void PlayerSAO::setPos(const v3f &pos) { if(isAttached()) return; - m_player->setPosition(pos); + + setBasePosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); @@ -1074,22 +1071,34 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) { if(isAttached()) return; - m_player->setPosition(pos); + + setBasePosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setYaw(float yaw) +void PlayerSAO::setYaw(const float yaw, bool send_data) { - m_player->setYaw(yaw); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + if (m_player && yaw != m_yaw) + m_player->setDirty(true); + + UnitSAO::setYaw(yaw); + + // Datas should not be sent at player initialization + if (send_data) + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setPitch(float pitch) +void PlayerSAO::setPitch(const float pitch, bool send_data) { - m_player->setPitch(pitch); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + if (m_player && pitch != m_pitch) + m_player->setDirty(true); + + m_pitch = pitch; + + if (send_data) + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } int PlayerSAO::punch(v3f dir, @@ -1153,13 +1162,8 @@ int PlayerSAO::punch(v3f dir, return hitparams.wear; } -void PlayerSAO::rightClick(ServerActiveObject *clicker) -{ -} - -s16 PlayerSAO::getHP() const +void PlayerSAO::rightClick(ServerActiveObject *) { - return m_player->hp; } s16 PlayerSAO::readDamage() @@ -1169,12 +1173,16 @@ s16 PlayerSAO::readDamage() return damage; } -void PlayerSAO::setHP(s16 hp) +void PlayerSAO::setHP(s16 hp, bool direct) { - s16 oldhp = m_player->hp; + if (direct) { + m_hp = hp; + return; + } + + s16 oldhp = m_hp; - s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, - hp - oldhp); + s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - oldhp); if (hp_change == 0) return; hp = oldhp + hp_change; @@ -1184,11 +1192,11 @@ void PlayerSAO::setHP(s16 hp) else if (hp > PLAYER_MAX_HP) hp = PLAYER_MAX_HP; - if(hp < oldhp && g_settings->getBool("enable_damage") == false) { + if (hp < oldhp && !g_settings->getBool("enable_damage")) { return; } - m_player->hp = hp; + m_hp = hp; if (oldhp > hp) m_damage += (oldhp - hp); @@ -1198,14 +1206,12 @@ void PlayerSAO::setHP(s16 hp) m_properties_sent = false; } -u16 PlayerSAO::getBreath() const +void PlayerSAO::setBreath(const u16 breath) { - return m_player->getBreath(); -} + if (m_player && breath != m_breath) + m_player->setDirty(true); -void PlayerSAO::setBreath(u16 breath) -{ - m_player->setBreath(breath); + m_breath = breath; } void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups) @@ -1355,7 +1361,7 @@ bool PlayerSAO::checkMovementCheat() { if (isAttached() || m_is_singleplayer || g_settings->getBool("disable_anticheat")) { - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; return false; } @@ -1382,7 +1388,7 @@ bool PlayerSAO::checkMovementCheat() // Tolerance. The lag pool does this a bit. //player_max_speed *= 2.5; - v3f diff = (m_player->getPosition() - m_last_good_position); + v3f diff = (m_base_position - m_last_good_position); float d_vert = diff.Y; diff.Y = 0; float d_horiz = diff.getLength(); @@ -1392,27 +1398,26 @@ bool PlayerSAO::checkMovementCheat() required_time = d_vert / player_max_speed; // Moving upwards if (m_move_pool.grab(required_time)) { - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; } else { actionstream << "Player " << m_player->getName() << " moved too fast; resetting position" << std::endl; - m_player->setPosition(m_last_good_position); + setBasePosition(m_last_good_position); cheated = true; } return cheated; } -bool PlayerSAO::getCollisionBox(aabb3f *toset) { - //update collision box - *toset = m_player->getCollisionbox(); - +bool PlayerSAO::getCollisionBox(aabb3f *toset) +{ + *toset = aabb3f(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30); toset->MinEdge += m_base_position; toset->MaxEdge += m_base_position; - return true; } -bool PlayerSAO::collideWithObjects(){ +bool PlayerSAO::collideWithObjects() +{ return true; } diff --git a/src/content_sao.h b/src/content_sao.h index 76a3a37da..4ea6277ff 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -23,12 +23,35 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include "itemgroup.h" #include "object_properties.h" +#include "constants.h" + +class UnitSAO: public ServerActiveObject +{ +public: + UnitSAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_hp(-1), m_yaw(0) {} + virtual ~UnitSAO() {} + + virtual void setYaw(const float yaw) { m_yaw = yaw; } + float getYaw() const { return m_yaw; }; + f32 getRadYaw() const { return m_yaw * core::DEGTORAD; } + // Deprecated + f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; } + + s16 getHP() const { return m_hp; } + // Use a function, if isDead can be defined by other conditions + bool isDead() const { return m_hp == 0; } +protected: + s16 m_hp; + float m_yaw; +}; /* LuaEntitySAO needs some internals exposed. */ -class LuaEntitySAO : public ServerActiveObject +class LuaEntitySAO : public UnitSAO { public: LuaEntitySAO(ServerEnvironment *env, v3f pos, @@ -74,8 +97,7 @@ public: v3f getVelocity(); void setAcceleration(v3f acceleration); v3f getAcceleration(); - void setYaw(float yaw); - float getYaw(); + void setTextureMod(const std::string &mod); void setSprite(v2s16 p, int num_frames, float framelength, bool select_horiz_by_yawpitch); @@ -91,10 +113,9 @@ private: bool m_registered; struct ObjectProperties m_prop; - s16 m_hp; v3f m_velocity; v3f m_acceleration; - float m_yaw; + ItemGroupList m_armor_groups; bool m_properties_sent; @@ -158,11 +179,10 @@ public: class RemotePlayer; -class PlayerSAO : public ServerActiveObject +class PlayerSAO : public UnitSAO { public: - PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, - const std::set &privs, bool is_singleplayer); + PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer); ~PlayerSAO(); ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_PLAYER; } @@ -182,10 +202,14 @@ public: bool isAttached(); void step(float dtime, bool send_recommended); void setBasePosition(const v3f &position); - void setPos(v3f pos); + void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); - void setYaw(float); - void setPitch(float); + void setYaw(const float yaw, bool send_data = true); + void setPitch(const float pitch, bool send_data = true); + f32 getPitch() const { return m_pitch; } + f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } + // Deprecated + f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } /* Interaction interface @@ -196,11 +220,10 @@ public: ServerActiveObject *puncher, float time_from_last_punch); void rightClick(ServerActiveObject *clicker); - s16 getHP() const; - void setHP(s16 hp); + void setHP(s16 hp, bool direct = false); s16 readDamage(); - u16 getBreath() const; - void setBreath(u16 breath); + u16 getBreath() const { return m_breath; } + void setBreath(const u16 breath); void setArmorGroups(const ItemGroupList &armor_groups); ItemGroupList getArmorGroups(); void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop); @@ -283,6 +306,11 @@ public: bool getCollisionBox(aabb3f *toset); bool collideWithObjects(); + void initialize(RemotePlayer *player, const std::set &privs); + + v3f getEyePosition() const { return m_base_position + getEyeOffset(); } + v3f getEyeOffset() const { return v3f(0, BS * 1.625f, 0); } + private: std::string getPropertyPacket(); @@ -326,8 +354,8 @@ private: v3f m_attachment_position; v3f m_attachment_rotation; bool m_attachment_sent; - - + u16 m_breath; + f32 m_pitch; public: float m_physics_override_speed; float m_physics_override_jump; diff --git a/src/environment.cpp b/src/environment.cpp index ecda1b6a4..13c64b37c 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -608,9 +608,8 @@ void ServerEnvironment::saveLoadedPlayers() for (std::vector::iterator it = m_players.begin(); it != m_players.end(); ++it) { - RemotePlayer *player = static_cast(*it); - if (player->checkModified()) { - player->save(players_path, m_gamedef); + if ((*it)->checkModified()) { + (*it)->save(players_path, m_gamedef); } } } @@ -623,7 +622,7 @@ void ServerEnvironment::savePlayer(RemotePlayer *player) player->save(players_path, m_gamedef); } -RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) +RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername, PlayerSAO *sao) { bool newplayer = false; bool found = false; @@ -641,7 +640,8 @@ RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) std::ifstream is(path.c_str(), std::ios_base::binary); if (!is.good()) continue; - player->deSerialize(is, path); + + player->deSerialize(is, path, sao); is.close(); if (player->getName() == playername) { @@ -657,11 +657,13 @@ RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) << " not found" << std::endl; if (newplayer) delete player; + return NULL; } - if (newplayer) + if (newplayer) { addPlayer(player); + } player->setModified(false); return player; } @@ -1271,12 +1273,16 @@ void ServerEnvironment::step(float dtime) i != m_players.end(); ++i) { RemotePlayer *player = dynamic_cast(*i); assert(player); + // Ignore disconnected players if (player->peer_id == 0) continue; + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + v3s16 blockpos = getNodeBlockPos( - floatToInt(player->getPosition(), BS)); + floatToInt(playersao->getBasePosition(), BS)); players_blockpos.push_back(blockpos); } @@ -1584,7 +1590,7 @@ u16 ServerEnvironment::addActiveObject(ServerActiveObject *object) Finds out what new objects have been added to inside a radius around a position */ -void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, +void ServerEnvironment::getAddedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects) @@ -1594,7 +1600,6 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, if (player_radius_f < 0) player_radius_f = 0; - /* Go through the object list, - discard m_removed objects, @@ -1602,20 +1607,21 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, - discard objects that are found in current_objects. - add remaining objects to added_objects */ - for(ActiveObjectMap::iterator i = m_active_objects.begin(); + for (ActiveObjectMap::iterator i = m_active_objects.begin(); i != m_active_objects.end(); ++i) { u16 id = i->first; // Get object ServerActiveObject *object = i->second; - if(object == NULL) + if (object == NULL) continue; // Discard if removed or deactivating if(object->m_removed || object->m_pending_deactivation) continue; - f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + f32 distance_f = object->getBasePosition(). + getDistanceFrom(playersao->getBasePosition()); if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { // Discard if too far if (distance_f > player_radius_f && player_radius_f != 0) @@ -1637,7 +1643,7 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, Finds out what objects have been removed from inside a radius around a position */ -void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius, +void ServerEnvironment::getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects) @@ -1647,7 +1653,6 @@ void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius if (player_radius_f < 0) player_radius_f = 0; - /* Go through current_objects; object is removed if: - object is not found in m_active_objects (this is actually an @@ -1675,7 +1680,7 @@ void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius continue; } - f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + f32 distance_f = object->getBasePosition().getDistanceFrom(playersao->getBasePosition()); if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { if (distance_f <= player_radius_f || player_radius_f == 0) continue; diff --git a/src/environment.h b/src/environment.h index 3f3c1cf2c..4bee40e57 100644 --- a/src/environment.h +++ b/src/environment.h @@ -54,6 +54,7 @@ class ClientMap; class GameScripting; class Player; class RemotePlayer; +class PlayerSAO; class Environment { @@ -315,7 +316,7 @@ public: // Save players void saveLoadedPlayers(); void savePlayer(RemotePlayer *player); - RemotePlayer *loadPlayer(const std::string &playername); + RemotePlayer *loadPlayer(const std::string &playername, PlayerSAO *sao); void addPlayer(RemotePlayer *player); void removePlayer(RemotePlayer *player); @@ -362,7 +363,7 @@ public: Find out what new objects have been added to inside a radius around a position */ - void getAddedActiveObjects(RemotePlayer *player, s16 radius, + void getAddedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects); @@ -371,7 +372,7 @@ public: Find out what new objects have been removed from inside a radius around a position */ - void getRemovedActiveObjects(RemotePlayer *player, s16 radius, + void getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index bc242a59d..71efb2343 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., LocalPlayer::LocalPlayer(Client *gamedef, const char *name): Player(name, gamedef->idef()), parent(0), + hp(PLAYER_MAX_HP), got_teleported(false), isAttached(false), touching_ground(false), @@ -62,6 +63,7 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): light_color(255,255,255,255), hurt_tilt_timer(0.0f), hurt_tilt_strength(0.0f), + m_position(0,0,0), m_sneak_node(32767,32767,32767), m_sneak_node_exists(false), m_need_to_get_new_sneak_node(true), @@ -69,6 +71,11 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): m_old_node_below(32767,32767,32767), m_old_node_below_type("air"), m_can_jump(false), + m_breath(PLAYER_MAX_BREATH), + m_yaw(0), + m_pitch(0), + camera_barely_in_ceiling(false), + m_collisionbox(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30), m_cao(NULL), m_gamedef(gamedef) { diff --git a/src/localplayer.h b/src/localplayer.h index eb727d7e3..749f8f8ce 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -40,6 +40,7 @@ public: ClientActiveObject *parent; + u16 hp; bool got_teleported; bool isAttached; bool touching_ground; @@ -99,10 +100,45 @@ public: u32 maxHudId() const { return hud.size(); } + u16 getBreath() const { return m_breath; } + void setBreath(u16 breath) { m_breath = breath; } + + v3s16 getLightPosition() const + { + return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); + } + + void setYaw(f32 yaw) + { + m_yaw = yaw; + } + + f32 getYaw() const { return m_yaw; } + + void setPitch(f32 pitch) + { + m_pitch = pitch; + } + + f32 getPitch() const { return m_pitch; } + + void setPosition(const v3f &position) + { + m_position = position; + } + + v3f getPosition() const { return m_position; } + v3f getEyePosition() const { return m_position + getEyeOffset(); } + v3f getEyeOffset() const + { + float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f; + return v3f(0, BS * eye_height, 0); + } private: void accelerateHorizontal(const v3f &target_speed, const f32 max_increase); void accelerateVertical(const v3f &target_speed, const f32 max_increase); + v3f m_position; // This is used for determining the sneaking range v3s16 m_sneak_node; // Whether the player is allowed to sneak @@ -117,6 +153,11 @@ private: v3s16 m_old_node_below; std::string m_old_node_below_type; bool m_can_jump; + u16 m_breath; + f32 m_yaw; + f32 m_pitch; + bool camera_barely_in_ceiling; + aabb3f m_collisionbox; GenericCAO* m_cao; Client *m_gamedef; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 090741f9f..411982f69 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -634,7 +634,6 @@ void Client::handleCommand_AnnounceMedia(NetworkPacket* pkt) m_media_downloader->addFile(name, sha1_raw); } - std::vector remote_media; try { std::string str; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 554025747..5e70b4c6c 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -809,13 +809,6 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) return; } - // If player is dead we don't care of this packet - if (player->isDead()) { - verbosestream << "TOSERVER_PLAYERPOS: " << player->getName() - << " is dead. Ignoring packet"; - return; - } - PlayerSAO *playersao = player->getPlayerSAO(); if (playersao == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -825,10 +818,17 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) return; } - player->setPosition(position); + // If player is dead we don't care of this packet + if (playersao->isDead()) { + verbosestream << "TOSERVER_PLAYERPOS: " << player->getName() + << " is dead. Ignoring packet"; + return; + } + + playersao->setBasePosition(position); player->setSpeed(speed); - player->setPitch(pitch); - player->setYaw(yaw); + playersao->setPitch(pitch, false); + playersao->setYaw(yaw, false); player->keyPressed = keyPressed; player->control.up = (keyPressed & 1); player->control.down = (keyPressed & 2); @@ -1100,7 +1100,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt) if (g_settings->getBool("enable_damage")) { actionstream << player->getName() << " damaged by " - << (int)damage << " hp at " << PP(player->getPosition() / BS) + << (int)damage << " hp at " << PP(playersao->getBasePosition() / BS) << std::endl; playersao->setHP(playersao->getHP() - damage); @@ -1124,16 +1124,6 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) return; } - /* - * If player is dead, we don't need to update the breath - * He is dead ! - */ - if (player->isDead()) { - verbosestream << "TOSERVER_BREATH: " << player->getName() - << " is dead. Ignoring packet"; - return; - } - PlayerSAO *playersao = player->getPlayerSAO(); if (playersao == NULL) { @@ -1144,6 +1134,16 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) return; } + /* + * If player is dead, we don't need to update the breath + * He is dead ! + */ + if (playersao->isDead()) { + verbosestream << "TOSERVER_BREATH: " << player->getName() + << " is dead. Ignoring packet"; + return; + } + playersao->setBreath(breath); SendPlayerBreath(pkt->getPeerId()); } @@ -1264,13 +1264,16 @@ void Server::handleCommand_Respawn(NetworkPacket* pkt) return; } - if (!player->isDead()) + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + + if (!playersao->isDead()) return; RespawnPlayer(pkt->getPeerId()); actionstream << player->getName() << " respawns at " - << PP(player->getPosition()/BS) << std::endl; + << PP(playersao->getBasePosition() / BS) << std::endl; // ActiveObject is added to environment in AsyncRunStep after // the previous addition has been successfully removed @@ -1322,9 +1325,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) return; } - if (player->isDead()) { + if (playersao->isDead()) { verbosestream << "TOSERVER_INTERACT: " << player->getName() - << " is dead. Ignoring packet"; + << " is dead. Ignoring packet"; return; } @@ -1455,7 +1458,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) ToolCapabilities toolcap = punchitem.getToolCapabilities(m_itemdef); v3f dir = (pointed_object->getBasePosition() - - (player->getPosition() + player->getEyeOffset()) + (playersao->getBasePosition() + playersao->getEyeOffset()) ).normalize(); float time_from_last_punch = playersao->resetTimeFromLastPunch(); diff --git a/src/player.cpp b/src/player.cpp index fa82a79f4..9c321d571 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -30,18 +30,11 @@ with this program; if not, write to the Free Software Foundation, Inc., Player::Player(const char *name, IItemDefManager *idef): - camera_barely_in_ceiling(false), inventory(idef), - hp(PLAYER_MAX_HP), peer_id(PEER_ID_INEXISTENT), keyPressed(0), // protected - m_breath(PLAYER_MAX_BREATH), - m_pitch(0), - m_yaw(0), - m_speed(0,0,0), - m_position(0,0,0), - m_collisionbox(-BS*0.30,0.0,-BS*0.30,BS*0.30,BS*1.75,BS*0.30) + m_speed(0,0,0) { strlcpy(m_name, name, PLAYERNAME_SIZE); @@ -90,11 +83,6 @@ Player::~Player() clearHud(); } -v3s16 Player::getLightPosition() const -{ - return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); -} - u32 Player::addHud(HudElement *toadd) { MutexAutoLock lock(m_mutex); diff --git a/src/player.h b/src/player.h index 6ac5dfe65..5f9bb7ec9 100644 --- a/src/player.h +++ b/src/player.h @@ -129,49 +129,7 @@ public: m_speed = speed; } - v3f getPosition() - { - return m_position; - } - - v3s16 getLightPosition() const; - - v3f getEyeOffset() - { - float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f; - return v3f(0, BS * eye_height, 0); - } - - v3f getEyePosition() - { - return m_position + getEyeOffset(); - } - - virtual void setPosition(const v3f &position) - { - m_position = position; - } - - virtual void setPitch(f32 pitch) - { - m_pitch = pitch; - } - - virtual void setYaw(f32 yaw) - { - m_yaw = yaw; - } - - f32 getPitch() const { return m_pitch; } - f32 getYaw() const { return m_yaw; } - u16 getBreath() const { return m_breath; } - - virtual void setBreath(u16 breath) { m_breath = breath; } - - f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } - f32 getRadYaw() const { return m_yaw * core::DEGTORAD; } const char *getName() const { return m_name; } - aabb3f getCollisionbox() const { return m_collisionbox; } u32 getFreeHudID() { @@ -183,7 +141,6 @@ public: return size; } - bool camera_barely_in_ceiling; v3f eye_offset_first; v3f eye_offset_third; @@ -205,8 +162,6 @@ public: v2s32 local_animations[4]; float local_animation_speed; - u16 hp; - u16 peer_id; std::string inventory_formspec; @@ -225,12 +180,7 @@ public: s32 hud_hotbar_itemcount; protected: char m_name[PLAYERNAME_SIZE]; - u16 m_breath; - f32 m_pitch; - f32 m_yaw; v3f m_speed; - v3f m_position; - aabb3f m_collisionbox; std::vector hud; private: diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index f64d1d690..605346928 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -96,7 +96,7 @@ void RemotePlayer::save(std::string savedir, IGameDef *gamedef) infostream << "Failed to open " << path << std::endl; return; } - testplayer.deSerialize(is, path); + testplayer.deSerialize(is, path, NULL); is.close(); if (strcmp(testplayer.getName(), m_name) == 0) { // Open file and serialize @@ -115,37 +115,46 @@ void RemotePlayer::save(std::string savedir, IGameDef *gamedef) return; } -void RemotePlayer::deSerialize(std::istream &is, const std::string &playername) +void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, + PlayerSAO *sao) { Settings args; if (!args.parseConfigLines(is, "PlayerArgsEnd")) { - throw SerializationError("PlayerArgsEnd of player " + - playername + " not found!"); + throw SerializationError("PlayerArgsEnd of player " + playername + " not found!"); } m_dirty = true; //args.getS32("version"); // Version field value not used std::string name = args.get("name"); strlcpy(m_name, name.c_str(), PLAYERNAME_SIZE); - setPitch(args.getFloat("pitch")); - setYaw(args.getFloat("yaw")); - setPosition(args.getV3F("position")); - try { - hp = args.getS32("hp"); - } catch(SettingNotFoundException &e) { - hp = PLAYER_MAX_HP; - } - try { - m_breath = args.getS32("breath"); - } catch(SettingNotFoundException &e) { - m_breath = PLAYER_MAX_BREATH; + if (sao) { + try { + sao->setHP(args.getS32("hp"), true); + } catch(SettingNotFoundException &e) { + sao->setHP(PLAYER_MAX_HP, true); + } + + try { + sao->setBasePosition(args.getV3F("position")); + } catch (SettingNotFoundException &e) {} + + try { + sao->setPitch(args.getFloat("pitch"), false); + } catch (SettingNotFoundException &e) {} + try { + sao->setYaw(args.getFloat("yaw"), false); + } catch (SettingNotFoundException &e) {} + + try { + sao->setBreath(args.getS32("breath")); + } catch (SettingNotFoundException &e) {} } inventory.deSerialize(is); - if(inventory.getList("craftpreview") == NULL) { + if (inventory.getList("craftpreview") == NULL) { // Convert players without craftpreview inventory.addList("craftpreview", 1); @@ -167,11 +176,14 @@ void RemotePlayer::serialize(std::ostream &os) args.setS32("version", 1); args.set("name", m_name); //args.set("password", m_password); - args.setFloat("pitch", m_pitch); - args.setFloat("yaw", m_yaw); - args.setV3F("position", m_position); - args.setS32("hp", hp); - args.setS32("breath", m_breath); + + if (m_sao) { + args.setS32("hp", m_sao->getHP()); + args.setV3F("position", m_sao->getBasePosition()); + args.setFloat("pitch", m_sao->getPitch()); + args.setFloat("yaw", m_sao->getYaw()); + args.setS32("breath", m_sao->getBreath()); + } args.writeLines(os); @@ -180,16 +192,6 @@ void RemotePlayer::serialize(std::ostream &os) inventory.serialize(os); } -void RemotePlayer::setPosition(const v3f &position) -{ - if (position != m_position) - m_dirty = true; - - Player::setPosition(position); - if(m_sao) - m_sao->setBasePosition(position); -} - const RemotePlayerChatResult RemotePlayer::canSendChatMessage() { // Rate limit messages diff --git a/src/remoteplayer.h b/src/remoteplayer.h index 1b1a90de3..61b5a23de 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -40,11 +40,10 @@ public: virtual ~RemotePlayer() {} void save(std::string savedir, IGameDef *gamedef); - void deSerialize(std::istream &is, const std::string &playername); + void deSerialize(std::istream &is, const std::string &playername, PlayerSAO *sao); PlayerSAO *getPlayerSAO() { return m_sao; } void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; } - void setPosition(const v3f &position); const RemotePlayerChatResult canSendChatMessage(); @@ -67,9 +66,6 @@ public: *ratio = m_day_night_ratio; } - // Use a function, if isDead can be defined by other conditions - bool isDead() const { return hp == 0; } - void setHotbarImage(const std::string &name) { hud_hotbar_image = name; @@ -90,12 +86,6 @@ public: return hud_hotbar_selected_image; } - // Deprecated - f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } - - // Deprecated - f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; } - void setSky(const video::SColor &bgcolor, const std::string &type, const std::vector ¶ms) { @@ -121,27 +111,6 @@ public: inventory.setModified(x); } - virtual void setBreath(u16 breath) - { - if (breath != m_breath) - m_dirty = true; - Player::setBreath(breath); - } - - virtual void setPitch(f32 pitch) - { - if (pitch != m_pitch) - m_dirty = true; - Player::setPitch(pitch); - } - - virtual void setYaw(f32 yaw) - { - if (yaw != m_yaw) - m_dirty = true; - Player::setYaw(yaw); - } - void setLocalAnimations(v2s32 frames[4], float frame_speed) { for (int i = 0; i < 4; i++) @@ -156,6 +125,8 @@ public: *frame_speed = local_animation_speed; } + void setDirty(bool dirty) { m_dirty = true; } + u16 protocol_version; private: /* diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 23994181c..cf124f17c 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1013,11 +1013,11 @@ int ObjectRef::l_get_look_dir(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - float pitch = player->getRadPitchDep(); - float yaw = player->getRadYawDep(); + float pitch = co->getRadPitchDep(); + float yaw = co->getRadYawDep(); v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw)); push_v3f(L, v); return 1; @@ -1033,10 +1033,10 @@ int ObjectRef::l_get_look_pitch(lua_State *L) "Deprecated call to get_look_pitch, use get_look_vertical instead"); ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadPitchDep()); + lua_pushnumber(L, co->getRadPitchDep()); return 1; } @@ -1050,10 +1050,10 @@ int ObjectRef::l_get_look_yaw(lua_State *L) "Deprecated call to get_look_yaw, use get_look_horizontal instead"); ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadYawDep()); + lua_pushnumber(L, co->getRadYawDep()); return 1; } @@ -1062,10 +1062,10 @@ int ObjectRef::l_get_look_vertical(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadPitch()); + lua_pushnumber(L, co->getRadPitch()); return 1; } @@ -1074,10 +1074,10 @@ int ObjectRef::l_get_look_horizontal(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadYaw()); + lua_pushnumber(L, co->getRadYaw()); return 1; } diff --git a/src/server.cpp b/src/server.cpp index e67f37d56..cd526ad77 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -701,11 +701,15 @@ void Server::AsyncRunStep(bool initial_step) continue; } + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) + continue; + std::queue removed_objects; std::queue added_objects; - m_env->getRemovedActiveObjects(player, radius, player_radius, + m_env->getRemovedActiveObjects(playersao, radius, player_radius, client->m_known_objects, removed_objects); - m_env->getAddedActiveObjects(player, radius, player_radius, + m_env->getAddedActiveObjects(playersao, radius, player_radius, client->m_known_objects, added_objects); // Ignore if nothing happened @@ -1108,7 +1112,7 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id) SendPlayerBreath(peer_id); // Show death screen if necessary - if (player->isDead()) + if (playersao->isDead()) SendDeathscreen(peer_id, false, v3f(0,0,0)); // Note things in chat if not in simple singleplayer mode @@ -1860,18 +1864,18 @@ void Server::SendMovePlayer(u16 peer_id) DSTACK(FUNCTION_NAME); RemotePlayer *player = m_env->getPlayer(peer_id); assert(player); + PlayerSAO *sao = player->getPlayerSAO(); + assert(sao); NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id); - pkt << player->getPosition() << player->getPitch() << player->getYaw(); + pkt << sao->getBasePosition() << sao->getPitch() << sao->getYaw(); { - v3f pos = player->getPosition(); - f32 pitch = player->getPitch(); - f32 yaw = player->getYaw(); + v3f pos = sao->getBasePosition(); verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER" << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")" - << " pitch=" << pitch - << " yaw=" << yaw + << " pitch=" << sao->getPitch() + << " yaw=" << sao->getYaw() << std::endl; } @@ -1984,8 +1988,12 @@ s32 Server::playSound(const SimpleSoundSpec &spec, if (!player) continue; + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + if (pos_exists) { - if(player->getPosition().getDistanceFrom(pos) > + if(sao->getBasePosition().getDistanceFrom(pos) > params.max_hear_distance) continue; } @@ -2044,14 +2052,17 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id, pkt << p; std::vector clients = m_clients.getClientIDs(); - for(std::vector::iterator i = clients.begin(); - i != clients.end(); ++i) { + for (std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { if (far_players) { // Get player if (RemotePlayer *player = m_env->getPlayer(*i)) { + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + // If player is far away, only set modified blocks not sent - v3f player_pos = player->getPosition(); - if(player_pos.getDistanceFrom(p_f) > maxd) { + v3f player_pos = sao->getBasePosition(); + if (player_pos.getDistanceFrom(p_f) > maxd) { far_players->push_back(*i); continue; } @@ -2071,14 +2082,16 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, v3f p_f = intToFloat(p, BS); std::vector clients = m_clients.getClientIDs(); - for(std::vector::iterator i = clients.begin(); - i != clients.end(); ++i) { - - if(far_players) { + for(std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { + if (far_players) { // Get player if (RemotePlayer *player = m_env->getPlayer(*i)) { + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + // If player is far away, only set modified blocks not sent - v3f player_pos = player->getPosition(); + v3f player_pos = sao->getBasePosition(); if(player_pos.getDistanceFrom(p_f) > maxd) { far_players->push_back(*i); continue; @@ -3426,10 +3439,9 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version return NULL; } - // Load player if it isn't already loaded - if (!player) { - player = m_env->loadPlayer(name); - } + // Create a new player active object + PlayerSAO *playersao = new PlayerSAO(m_env, peer_id, isSingleplayer()); + player = m_env->loadPlayer(name, playersao); // Create player if it doesn't exist if (!player) { @@ -3438,8 +3450,7 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version // Set player position infostream<<"Server: Finding spawn place for player \"" <setPosition(pos); + playersao->setBasePosition(findSpawnPos()); // Make sure the player is saved player->setModified(true); @@ -3450,18 +3461,14 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version // If the player exists, ensure that they respawn inside legal bounds // This fixes an assert crash when the player can't be added // to the environment - if (objectpos_over_limit(player->getPosition())) { + if (objectpos_over_limit(playersao->getBasePosition())) { actionstream << "Respawn position for player \"" << name << "\" outside limits, resetting" << std::endl; - v3f pos = findSpawnPos(); - player->setPosition(pos); + playersao->setBasePosition(findSpawnPos()); } } - // Create a new player active object - PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id, - getPlayerEffectivePrivs(player->getName()), - isSingleplayer()); + playersao->initialize(player, getPlayerEffectivePrivs(player->getName())); player->protocol_version = proto_version; diff --git a/src/serverobject.h b/src/serverobject.h index 63650e3be..9884eb0a1 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -85,7 +85,7 @@ public: Some more dynamic interface */ - virtual void setPos(v3f pos) + virtual void setPos(const v3f &pos) { setBasePosition(pos); } // continuous: if true, object does not stop immediately at pos virtual void moveTo(v3f pos, bool continuous) diff --git a/src/unittest/test_player.cpp b/src/unittest/test_player.cpp index 5de9eaaf2..fba422475 100644 --- a/src/unittest/test_player.cpp +++ b/src/unittest/test_player.cpp @@ -46,11 +46,14 @@ void TestPlayer::runTests(IGameDef *gamedef) void TestPlayer::testSave(IGameDef *gamedef) { RemotePlayer rplayer("testplayer_save", gamedef->idef()); - rplayer.setBreath(10); - rplayer.hp = 8; - rplayer.setYaw(0.1f); - rplayer.setPitch(0.6f); - rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f)); + PlayerSAO sao(NULL, 1, false); + sao.initialize(&rplayer, std::set()); + rplayer.setPlayerSAO(&sao); + sao.setBreath(10); + sao.setHP(8, true); + sao.setYaw(0.1f, false); + sao.setPitch(0.6f, false); + sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_save")); } @@ -58,24 +61,28 @@ void TestPlayer::testSave(IGameDef *gamedef) void TestPlayer::testLoad(IGameDef *gamedef) { RemotePlayer rplayer("testplayer_load", gamedef->idef()); - rplayer.setBreath(10); - rplayer.hp = 8; - rplayer.setYaw(0.1f); - rplayer.setPitch(0.6f); - rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f)); + PlayerSAO sao(NULL, 1, false); + sao.initialize(&rplayer, std::set()); + rplayer.setPlayerSAO(&sao); + sao.setBreath(10); + sao.setHP(8, true); + sao.setYaw(0.1f, false); + sao.setPitch(0.6f, false); + sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_load")); RemotePlayer rplayer_load("testplayer_load", gamedef->idef()); + PlayerSAO sao_load(NULL, 2, false); std::ifstream is("testplayer_load", std::ios_base::binary); UASSERT(is.good()); - rplayer_load.deSerialize(is, "testplayer_load"); + rplayer_load.deSerialize(is, "testplayer_load", &sao_load); is.close(); UASSERT(strcmp(rplayer_load.getName(), "testplayer_load") == 0); - UASSERT(rplayer.getBreath() == 10); - UASSERT(rplayer.hp == 8); - UASSERT(rplayer.getYaw() == 0.1f); - UASSERT(rplayer.getPitch() == 0.6f); - UASSERT(rplayer.getPosition() == v3f(450.2f, -15.7f, 68.1f)); + UASSERT(sao_load.getBreath() == 10); + UASSERT(sao_load.getHP() == 8); + UASSERT(sao_load.getYaw() == 0.1f); + UASSERT(sao_load.getPitch() == 0.6f); + UASSERT(sao_load.getBasePosition() == v3f(450.2f, -15.7f, 68.1f)); } -- cgit v1.2.3