diff options
author | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-09-24 00:09:57 +0200 |
---|---|---|
committer | madmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6> | 2012-09-24 00:09:57 +0200 |
commit | ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26 (patch) | |
tree | 898e37fe747f0fdcefeb88f833557fd45db3347c /source/cPlayer.cpp | |
parent | Source files cleanup: ChunkDataSerializer is Protocol-related (diff) | |
download | cuberite-ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26.tar cuberite-ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26.tar.gz cuberite-ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26.tar.bz2 cuberite-ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26.tar.lz cuberite-ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26.tar.xz cuberite-ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26.tar.zst cuberite-ecfe6ab65bd1fc2c7f5733fe6ef4e6ddaac44a26.zip |
Diffstat (limited to 'source/cPlayer.cpp')
-rw-r--r-- | source/cPlayer.cpp | 1019 |
1 files changed, 0 insertions, 1019 deletions
diff --git a/source/cPlayer.cpp b/source/cPlayer.cpp deleted file mode 100644 index 1de9bf36a..000000000 --- a/source/cPlayer.cpp +++ /dev/null @@ -1,1019 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "cPlayer.h" -#include "cServer.h" -#include "cClientHandle.h" -#include "UI/Window.h" -#include "UI/WindowOwner.h" -#include "cWorld.h" -#include "cPickup.h" -#include "cPluginManager.h" -#include "cBlockEntity.h" -#include "cGroupManager.h" -#include "cGroup.h" -#include "cChatColor.h" -#include "cItem.h" -#include "cTracer.h" -#include "cRoot.h" -#include "OSSupport/MakeDir.h" -#include "OSSupport/Timer.h" -#include "MersenneTwister.h" - -#include "Vector3d.h" -#include "Vector3f.h" - -#include "../iniFile/iniFile.h" -#include <json/json.h> - -#define float2int(x) ((x)<0 ? ((int)(x))-1 : (int)(x)) - - - - - -CLASS_DEFINITION( cPlayer, cPawn ); - - - - - -cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) - : m_GameMode(eGameMode_NotSet) - , m_IP("") - , m_LastBlockActionTime( 0 ) - , m_LastBlockActionCnt( 0 ) - , m_bVisible( true ) - , m_LastGroundHeight( 0 ) - , m_bTouchGround( false ) - , m_Stance( 0.0 ) - , m_Inventory(*this) - , m_CurrentWindow(NULL) - , m_InventoryWindow(NULL) - , m_TimeLastPickupCheck( 0.f ) - , m_Color('-') - , m_ClientHandle( a_Client ) - , m_FoodExhaustionLevel(0.f) - , m_FoodTickTimer(0) -{ - LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", - a_PlayerName.c_str(), a_Client->GetIPString().c_str(), - this, GetUniqueID() - ); - m_EntityType = eEntityType_Player; - - m_InventoryWindow = new cInventoryWindow(*this); - m_CurrentWindow = m_InventoryWindow; - m_InventoryWindow->OpenedByPlayer(*this); - - SetMaxHealth(20); - m_MaxFoodLevel = 20; - m_MaxFoodSaturationLevel = 20.f; - - m_FoodLevel = m_MaxFoodLevel; - m_FoodSaturationLevel = 5.f; - - cTimer t1; - m_LastPlayerListTime = t1.GetNowTime(); - - m_TimeLastTeleportPacket = cWorld::GetTime(); - m_TimeLastPickupCheck = cWorld::GetTime(); - - m_PlayerName = a_PlayerName; - m_bDirtyPosition = true; // So chunks are streamed to player at spawn - - if (!LoadFromDisk()) - { - m_Inventory.Clear(); - m_Pos.x = cRoot::Get()->GetDefaultWorld()->GetSpawnX(); - m_Pos.y = cRoot::Get()->GetDefaultWorld()->GetSpawnY(); - m_Pos.z = cRoot::Get()->GetDefaultWorld()->GetSpawnZ(); - - LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", - a_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z - ); - } - m_LastGroundHeight = (float)(m_Pos.y); - m_Stance = m_Pos.y + 1.62; -} - - - - - -cPlayer::~cPlayer(void) -{ - LOG("Deleting cPlayer \"%s\" at %p, ID %d", m_PlayerName.c_str(), this, GetUniqueID()); - - SaveToDisk(); - - m_World->RemovePlayer( this ); - - m_ClientHandle = NULL; - - delete m_InventoryWindow; - - LOG("Player %p deleted", this); -} - - - - - -void cPlayer::Initialize( cWorld* a_World ) -{ - cPawn::Initialize( a_World ); - GetWorld()->AddPlayer( this ); -} - - - - - -void cPlayer::Destroyed() -{ - CloseWindow(-1); - m_ClientHandle = NULL; -} - - - - - -void cPlayer::SpawnOn(cClientHandle & a_Client) -{ - /* - LOGD("cPlayer::SpawnOn(%s) for \"%s\" at pos {%.2f, %.2f, %.2f}", - a_Client.GetUsername().c_str(), m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z - ); - */ - - if (m_bVisible) - { - a_Client.SendPlayerSpawn(*this); - } -} - - - - - -void cPlayer::Tick(float a_Dt) -{ - if (!m_ClientHandle->IsPlaying()) - { - // We're not yet in the game, ignore everything - return; - } - - cPawn::Tick(a_Dt); - - if (m_bDirtyOrientation && !m_bDirtyPosition) - { - m_World->BroadcastEntLook(*this, m_ClientHandle); - m_World->BroadcastEntHeadLook(*this, m_ClientHandle); - m_bDirtyOrientation = false; - } - else if (m_bDirtyPosition) - { - cRoot::Get()->GetPluginManager()->CallHook( cPluginManager::E_PLUGIN_PLAYER_MOVE, 1, this ); - - float DiffX = (float)(GetPosX() - m_LastPosX ); - float DiffY = (float)(GetPosY() - m_LastPosY ); - float DiffZ = (float)(GetPosZ() - m_LastPosZ ); - float SqrDist = DiffX * DiffX + DiffY * DiffY + DiffZ * DiffZ; - if ( - (SqrDist > 4 * 4) || // 4 blocks is max Relative Move - (cWorld::GetTime() - m_TimeLastTeleportPacket > 2 ) // Send an absolute position every 2 seconds - ) - { - // LOG("Teleported %f", sqrtf(SqrDist) ); - m_World->BroadcastTeleportEntity(*this, m_ClientHandle); - m_TimeLastTeleportPacket = cWorld::GetTime(); - } - else - { - // Relative move sucks balls! It's always wrong wtf! - if (m_bDirtyOrientation) - { - m_World->BroadcastEntRelMoveLook(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle); - m_bDirtyOrientation = false; - } - else - { - m_World->BroadcastEntRelMove(*this, (char)(DiffX * 32), (char)(DiffY * 32), (char)(DiffZ * 32), m_ClientHandle); - } - } - m_LastPosX = GetPosX(); - m_LastPosY = GetPosY(); - m_LastPosZ = GetPosZ(); - m_bDirtyPosition = false; - m_ClientHandle->StreamChunks(); - } - - if (m_Health > 0) // make sure player is alive - { - m_World->CollectPickupsByPlayer(this); - - //Handle Health: - m_FoodTickTimer++; - if(m_FoodTickTimer >= 80) - { - m_FoodTickTimer = 0; - - if(m_FoodLevel >= 17) - { - Heal(1); - }else if(m_FoodLevel == 0) - { - TakeDamage(1, NULL); - } - } - - // TODO: Increase Exhaustion level http://www.minecraftwiki.net/wiki/Hunger#Exhaustion_level_increase - if (m_FoodExhaustionLevel >= 4.f) - { - m_FoodExhaustionLevel -= 4.f; - - if (m_FoodSaturationLevel >= 1.f) - { - m_FoodSaturationLevel--; - } - else - { - m_FoodLevel = MAX(m_FoodLevel -1, 0); - } - - SendHealth(); - } - } - - cTimer t1; - // Send Player List (Once per m_LastPlayerListTime/1000 ms) - if (m_LastPlayerListTime + cPlayer::PLAYER_LIST_TIME_MS <= t1.GetNowTime()) - { - m_World->SendPlayerList(this); - m_LastPlayerListTime = t1.GetNowTime(); - } -} - - - - - -void cPlayer::SetTouchGround(bool a_bTouchGround) -{ - m_bTouchGround = a_bTouchGround; - - if (!m_bTouchGround) - { - cWorld* World = GetWorld(); - char BlockID = World->GetBlock( float2int(m_Pos.x), float2int(m_Pos.y), float2int(m_Pos.z) ); - if( BlockID != E_BLOCK_AIR ) - { - // LOGD("TouchGround set to true by server"); - m_bTouchGround = true; - } - if( BlockID == E_BLOCK_WATER || BlockID == E_BLOCK_STATIONARY_WATER || BlockID == E_BLOCK_LADDER || BlockID == E_BLOCK_TORCH ) - { - // LOGD("Water / Ladder / Torch"); - m_LastGroundHeight = (float)m_Pos.y; - } - } - - if (m_bTouchGround) - { - float Dist = (float)(m_LastGroundHeight - m_Pos.y); - int Damage = (int)(Dist - 4.f); - if (Damage > 0) - { - TakeDamage(Damage, 0); - } - - m_LastGroundHeight = (float)m_Pos.y; - } -} - - - - - -void cPlayer::Heal( int a_Health ) -{ - if( m_Health < GetMaxHealth() ) - { - m_Health = (short) MIN(a_Health + m_Health, GetMaxHealth()); - - - SendHealth(); - } -} - - - - - -bool cPlayer::Feed(short a_Food, float a_Saturation) -{ - if (m_FoodLevel >= GetMaxFoodLevel()) - { - return false; - } - - m_FoodLevel = MIN(a_Food + m_FoodLevel, GetMaxFoodLevel()); - m_FoodSaturationLevel = MIN(m_FoodSaturationLevel + a_Saturation, GetMaxFoodSaturationLevel()); - - SendHealth(); - return true; -} - - - - - -void cPlayer::SendHealth() -{ - if (m_ClientHandle != NULL) - { - m_ClientHandle->SendHealth(); - } -} - - - - - -void cPlayer::TakeDamage( int a_Damage, cEntity* a_Instigator ) -{ - if (m_GameMode != eGameMode_Creative) - { - cPawn::TakeDamage( a_Damage, a_Instigator ); - - AddFoodExhaustion(0.3f); - - SendHealth(); - } -} - - - - - -void cPlayer::KilledBy(cEntity * a_Killer) -{ - cPawn::KilledBy(a_Killer); - - if (m_Health > 0) - { - return; // not dead yet =] - } - - m_bVisible = false; // So new clients don't see the player - - // Puke out all the items - cItem * Items = m_Inventory.GetSlots(); - cItems Pickups; - for (unsigned int i = 1; i < m_Inventory.c_NumSlots; ++i) - { - if( !Items[i].IsEmpty() ) - { - Pickups.push_back(Items[i]); - } - Items[i].Empty(); - } - m_World->SpawnItemPickups(Pickups, m_Pos.x, m_Pos.y, m_Pos.z, 10); - SaveToDisk(); // Save it, yeah the world is a tough place ! -} - - - - - -void cPlayer::Respawn() -{ - m_Health = GetMaxHealth(); - - m_ClientHandle->SendRespawn(); - - // Set non Burning - SetMetaData(NORMAL); - - TeleportTo(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ()); - - SetVisible(true); -} - - - - - -double cPlayer::GetEyeHeight() -{ - return m_Stance; -} - -Vector3d cPlayer::GetEyePosition() -{ - return Vector3d( m_Pos.x, m_Stance, m_Pos.z ); -} - - - - - -void cPlayer::OpenWindow( cWindow* a_Window ) -{ - CloseWindow(m_CurrentWindow ? (char)m_CurrentWindow->GetWindowType() : 0); - a_Window->OpenedByPlayer(*this); - m_CurrentWindow = a_Window; -} - - - - - -void cPlayer::CloseWindow(char a_WindowType) -{ - if (m_CurrentWindow == m_InventoryWindow) - { - // The inventory window must not be closed and must not be even sent a close packet - return; - } - - if (m_CurrentWindow != NULL) - { - // TODO: This code should be in cChestWindow instead - if ((a_WindowType == 1) && (m_CurrentWindow->GetWindowType() == cWindow::Chest)) - { - int x, y, z; - m_CurrentWindow->GetOwner()->GetBlockPos(x, y, z); - m_World->BroadcastBlockAction(x, y, z, 1, 0, E_BLOCK_CHEST); - } - - m_CurrentWindow->ClosedByPlayer(*this); - } - m_CurrentWindow = m_InventoryWindow; -} - - - - - -void cPlayer::SetLastBlockActionTime() -{ - if (m_World != NULL) - { - m_LastBlockActionTime = m_World->GetTime(); - } -} - - - - - -void cPlayer::SetLastBlockActionCnt( int a_LastBlockActionCnt ) -{ - m_LastBlockActionCnt = a_LastBlockActionCnt; -} - - - - - -void cPlayer::SetGameMode(eGameMode a_GameMode) -{ - if ((a_GameMode >= 2) || (a_GameMode < 0)) - { - LOGWARNING("%s: Setting invalid gamemode: %d", GetName().c_str(), a_GameMode); - return; - } - - if (m_GameMode == a_GameMode) - { - // Gamemode already set - return; - } - - m_GameMode = a_GameMode; - m_ClientHandle->SendGameMode(a_GameMode); -} - - - - - -void cPlayer::LoginSetGameMode( eGameMode a_GameMode ) -{ - m_GameMode = a_GameMode; -} - - - - - -void cPlayer::SetIP(const AString & a_IP) -{ - m_IP = a_IP; -} - - - - - -void cPlayer::SendMessage(const AString & a_Message) -{ - m_ClientHandle->SendChat(a_Message); -} - - - - - -void cPlayer::TeleportTo(const double & a_PosX, const double & a_PosY, const double & a_PosZ) -{ - SetPosition( a_PosX, a_PosY, a_PosZ ); - - m_World->BroadcastTeleportEntity(*this, GetClientHandle()); - m_ClientHandle->SendPlayerMoveLook(); -} - - - - - -void cPlayer::MoveTo( const Vector3d & a_NewPos ) -{ - // TODO: should do some checks to see if player is not moving through terrain - // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too - - SetPosition( a_NewPos ); - SetStance(a_NewPos.y + 1.62); -} - - - - - -void cPlayer::SetVisible(bool a_bVisible) -{ - if (a_bVisible && !m_bVisible) // Make visible - { - m_bVisible = true; - m_World->BroadcastSpawn(*this); - } - if (!a_bVisible && m_bVisible) - { - m_bVisible = false; - m_World->BroadcastDestroyEntity(*this, m_ClientHandle); // Destroy on all clients - } -} - - - - - -void cPlayer::AddToGroup( const char* a_GroupName ) -{ - cGroup* Group = cRoot::Get()->GetGroupManager()->GetGroup( a_GroupName ); - m_Groups.push_back( Group ); - LOGD("Added %s to group %s", m_PlayerName.c_str(), a_GroupName ); - ResolveGroups(); - ResolvePermissions(); -} - - - - - -bool cPlayer::CanUseCommand( const char* a_Command ) -{ - for( GroupList::iterator itr = m_Groups.begin(); itr != m_Groups.end(); ++itr ) - { - if( (*itr)->HasCommand( a_Command ) ) return true; - } - return false; -} - - - - - -bool cPlayer::HasPermission( const char* a_Permission ) -{ - AStringVector Split = StringSplit( a_Permission, "." ); - PermissionMap Possibilities = m_ResolvedPermissions; - // Now search the namespaces - while( Possibilities.begin() != Possibilities.end() ) - { - PermissionMap::iterator itr = Possibilities.begin(); - if( itr->second ) - { - AStringVector OtherSplit = StringSplit( itr->first, "." ); - if( OtherSplit.size() <= Split.size() ) - { - unsigned int i; - for( i = 0; i < OtherSplit.size(); ++i ) - { - if( OtherSplit[i].compare( Split[i] ) != 0 ) - { - if( OtherSplit[i].compare("*") == 0 ) return true; // WildCard man!! WildCard! - break; - } - } - if( i == Split.size() ) return true; - } - } - Possibilities.erase( itr ); - } - - // Nothing that matched :( - return false; -} - - - - - -bool cPlayer::IsInGroup( const char* a_Group ) -{ - for( GroupList::iterator itr = m_ResolvedGroups.begin(); itr != m_ResolvedGroups.end(); ++itr ) - { - if( strcmp( a_Group, (*itr)->GetName().c_str() ) == 0 ) - return true; - } - return false; -} - - - - - -void cPlayer::ResolvePermissions() -{ - m_ResolvedPermissions.clear(); // Start with an empty map yo~ - - // Copy all player specific permissions into the resolved permissions map - for( PermissionMap::iterator itr = m_Permissions.begin(); itr != m_Permissions.end(); ++itr ) - { - m_ResolvedPermissions[ itr->first ] = itr->second; - } - - for( GroupList::iterator GroupItr = m_ResolvedGroups.begin(); GroupItr != m_ResolvedGroups.end(); ++GroupItr ) - { - const cGroup::PermissionMap & Permissions = (*GroupItr)->GetPermissions(); - for( cGroup::PermissionMap::const_iterator itr = Permissions.begin(); itr != Permissions.end(); ++itr ) - { - m_ResolvedPermissions[ itr->first ] = itr->second; - } - } -} - - - - - -void cPlayer::ResolveGroups() -{ - // Clear resolved groups first - m_ResolvedGroups.clear(); - - // Get a complete resolved list of all groups the player is in - std::map< cGroup*, bool > AllGroups; // Use a map, because it's faster than iterating through a list to find duplicates - GroupList ToIterate; - for( GroupList::iterator GroupItr = m_Groups.begin(); GroupItr != m_Groups.end(); ++GroupItr ) - { - ToIterate.push_back( *GroupItr ); - } - while( ToIterate.begin() != ToIterate.end() ) - { - cGroup* CurrentGroup = *ToIterate.begin(); - if( AllGroups.find( CurrentGroup ) != AllGroups.end() ) - { - LOGWARNING("ERROR: Player \"%s\" is in the group multiple times (\"%s\"). Please fix your settings in users.ini!", - m_PlayerName.c_str(), CurrentGroup->GetName().c_str() - ); - } - else - { - AllGroups[ CurrentGroup ] = true; - m_ResolvedGroups.push_back( CurrentGroup ); // Add group to resolved list - const cGroup::GroupList & Inherits = CurrentGroup->GetInherits(); - for( cGroup::GroupList::const_iterator itr = Inherits.begin(); itr != Inherits.end(); ++itr ) - { - if( AllGroups.find( *itr ) != AllGroups.end() ) - { - LOGERROR("ERROR: Player %s is in the same group multiple times due to inheritance (%s). FIX IT!", m_PlayerName.c_str(), (*itr)->GetName().c_str() ); - continue; - } - ToIterate.push_back( *itr ); - } - } - ToIterate.erase( ToIterate.begin() ); - } -} - - - - - -AString cPlayer::GetColor(void) const -{ - if ( m_Color != '-' ) - { - return cChatColor::MakeColor( m_Color ); - } - - if ( m_Groups.size() < 1 ) - { - return cChatColor::White; - } - - return (*m_Groups.begin())->GetColor(); -} - - - - - -void cPlayer::TossItem( - bool a_bDraggingItem, - char a_Amount /* = 1 */, - short a_CreateType /* = 0 */, - short a_CreateHealth /* = 0 */ -) -{ - cItems Drops; - if (a_CreateType) - { - // Just create item without touching the inventory (used in creative mode) - Drops.push_back(cItem(a_CreateType, a_Amount, a_CreateHealth)); - } - else - { - // Drop an item from the inventory: - if (a_bDraggingItem) - { - cItem & Item = GetDraggingItem(); - if (!Item.IsEmpty()) - { - Drops.push_back(Item); - if (Item.m_ItemCount > a_Amount) - { - Item.m_ItemCount -= (char)a_Amount; - } - else - { - Item.Empty(); - } - } - } - else - { - // Else drop equipped item - cItem DroppedItem = GetInventory().GetEquippedItem(); - if (!DroppedItem.IsEmpty()) - { - DroppedItem.m_ItemCount = 1; - if (GetInventory().RemoveItem(DroppedItem)) - { - DroppedItem.m_ItemCount = 1; // RemoveItem decreases the count, so set it to 1 again - Drops.push_back(DroppedItem); - } - } - } - } - float vX = 0, vY = 0, vZ = 0; - EulerToVector(-GetRotation(), GetPitch(), vZ, vX, vY); - vY = -vY * 2 + 1.f; - m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY() + 1.6f, GetPosZ(), vX * 2, vY * 2, vZ * 2); -} - - - - - -bool cPlayer::MoveToWorld( const char* a_WorldName ) -{ - cWorld * World = cRoot::Get()->GetWorld( a_WorldName ); - if ( World ) - { - /* Remove all links to the old world */ - m_World->RemovePlayer( this ); - m_ClientHandle->RemoveFromAllChunks(); - m_World->RemoveEntityFromChunk(this, m_ChunkX, m_ChunkY, m_ChunkZ); - - /* Add player to all the necessary parts of the new world */ - SetWorld( World ); - GetWorld()->AddPlayer( this ); - MoveToCorrectChunk(true); - GetClientHandle()->StreamChunks(); - - return true; - } - - return false; -} - - - - - -void cPlayer::LoadPermissionsFromDisk() -{ - m_Groups.clear(); - m_Permissions.clear(); - - cIniFile IniFile("users.ini"); - if( IniFile.ReadFile() ) - { - std::string Groups = IniFile.GetValue(m_PlayerName, "Groups", ""); - if( Groups.size() > 0 ) - { - AStringVector Split = StringSplit( Groups, "," ); - for( unsigned int i = 0; i < Split.size(); i++ ) - { - AddToGroup( Split[i].c_str() ); - } - } - else - { - AddToGroup("Default"); - } - - m_Color = IniFile.GetValue(m_PlayerName, "Color", "-")[0]; - } - else - { - LOGWARN("WARNING: Failed to read ini file users.ini"); - AddToGroup("Default"); - } - ResolvePermissions(); -} - - - - -bool cPlayer::LoadFromDisk() -{ - LoadPermissionsFromDisk(); - - // Log player permissions, cause it's what the cool kids do - LOGINFO("Player %s has permissions:", m_PlayerName.c_str() ); - for( PermissionMap::iterator itr = m_ResolvedPermissions.begin(); itr != m_ResolvedPermissions.end(); ++itr ) - { - if( itr->second ) LOGINFO("%s", itr->first.c_str() ); - } - - AString SourceFile; - Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); - - cFile f; - if (!f.Open(SourceFile, cFile::fmRead)) - { - return false; - } - - AString buffer; - if (f.ReadRestOfFile(buffer) != f.GetSize()) - { - LOGERROR("ERROR READING FROM FILE \"%s\"", SourceFile.c_str()); - return false; - } - f.Close(); - - Json::Value root; - Json::Reader reader; - if (!reader.parse(buffer, root, false)) - { - LOGERROR("ERROR WHILE PARSING JSON FROM FILE %s", SourceFile.c_str()); - } - - Json::Value & JSON_PlayerPosition = root["position"]; - if (JSON_PlayerPosition.size() == 3) - { - m_Pos.x = JSON_PlayerPosition[(unsigned int)0].asDouble(); - m_Pos.y = JSON_PlayerPosition[(unsigned int)1].asDouble(); - m_Pos.z = JSON_PlayerPosition[(unsigned int)2].asDouble(); - } - - Json::Value & JSON_PlayerRotation = root["rotation"]; - if (JSON_PlayerRotation.size() == 3) - { - m_Rot.x = (float)JSON_PlayerRotation[(unsigned int)0].asDouble(); - m_Rot.y = (float)JSON_PlayerRotation[(unsigned int)1].asDouble(); - m_Rot.z = (float)JSON_PlayerRotation[(unsigned int)2].asDouble(); - } - - m_Health = (short)root.get("health", 0 ).asInt(); - m_FoodLevel = (short)root.get("food", m_MaxFoodLevel ).asInt(); - m_FoodSaturationLevel = (float)root.get("foodSaturation", m_MaxFoodSaturationLevel ).asDouble(); - - m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt(); - - m_Inventory.LoadFromJson(root["inventory"]); - - m_LoadedWorldName = root.get("world", "world").asString(); - - LOGD("Player \"%s\" was read from file, spawning at {%.2f, %.2f, %.2f} in world \"%s\"", - m_PlayerName.c_str(), m_Pos.x, m_Pos.y, m_Pos.z, m_LoadedWorldName.c_str() - ); - - return true; -} - - - - - -bool cPlayer::SaveToDisk() -{ - cMakeDir::MakeDir("players"); - - // create the JSON data - Json::Value JSON_PlayerPosition; - JSON_PlayerPosition.append( Json::Value( m_Pos.x ) ); - JSON_PlayerPosition.append( Json::Value( m_Pos.y ) ); - JSON_PlayerPosition.append( Json::Value( m_Pos.z ) ); - - Json::Value JSON_PlayerRotation; - JSON_PlayerRotation.append( Json::Value( m_Rot.x ) ); - JSON_PlayerRotation.append( Json::Value( m_Rot.y ) ); - JSON_PlayerRotation.append( Json::Value( m_Rot.z ) ); - - Json::Value JSON_Inventory; - m_Inventory.SaveToJson( JSON_Inventory ); - - Json::Value root; - root["position"] = JSON_PlayerPosition; - root["rotation"] = JSON_PlayerRotation; - root["inventory"] = JSON_Inventory; - root["health"] = m_Health; - root["food"] = m_FoodLevel; - root["foodSaturation"] = m_FoodSaturationLevel; - root["world"] = GetWorld()->GetName(); - - if (m_GameMode == GetWorld()->GetGameMode()) - { - root["gamemode"] = (int) eGameMode_NotSet; - } - else - { - root["gamemode"] = (int) m_GameMode; - } - - Json::StyledWriter writer; - std::string JsonData = writer.write( root ); - - AString SourceFile; - Printf(SourceFile, "players/%s.json", m_PlayerName.c_str() ); - - cFile f; - if (!f.Open(SourceFile, cFile::fmWrite)) - { - LOGERROR("ERROR WRITING PLAYER \"%s\" TO FILE \"%s\" - cannot open file", m_PlayerName.c_str(), SourceFile.c_str()); - return false; - } - if (f.Write(JsonData.c_str(), JsonData.size()) != (int)JsonData.size()) - { - LOGERROR("ERROR WRITING PLAYER JSON TO FILE \"%s\"", SourceFile.c_str()); - return false; - } - return true; -} - - - - - -cPlayer::StringList cPlayer::GetResolvedPermissions() -{ - StringList Permissions; - - const PermissionMap& ResolvedPermissions = m_ResolvedPermissions; - for( PermissionMap::const_iterator itr = ResolvedPermissions.begin(); itr != ResolvedPermissions.end(); ++itr ) - { - if( itr->second ) Permissions.push_back( itr->first ); - } - - return Permissions; -} - - - - - -void cPlayer::UseEquippedItem() -{ - if(GetGameMode() != 1) //No damage in creative - { - if (GetInventory().GetEquippedItem().DamageItem()) - { - LOG("Player %s Broke ID: %i", GetClientHandle()->GetUsername().c_str(), GetInventory().GetEquippedItem().m_ItemID); - GetInventory().RemoveItem( GetInventory().GetEquippedItem()); - } - } -} - - - - |