cPlayer::cPlayer(cClientHandle* a_Client, const AString & a_PlayerName) : super(etPlayer, 0.6, 1.8) , m_bVisible(true) , m_FoodLevel(MAX_FOOD_LEVEL) , m_FoodSaturationLevel(5) , m_FoodTickTimer(0) , m_FoodExhaustionLevel(0) , m_FoodPoisonedTicksRemaining(0) , m_LastJumpHeight(0) , m_LastGroundHeight(0) , m_bTouchGround(false) , m_Stance(0.0) , m_Inventory(*this) , m_CurrentWindow(NULL) , m_InventoryWindow(NULL) , m_Color('-') , m_GameMode(eGameMode_NotSet) , m_IP("") , m_ClientHandle(a_Client) , m_NormalMaxSpeed(1.0) , m_SprintingMaxSpeed(1.3) , m_FlyingMaxSpeed(1.0) , m_IsCrouched(false) , m_IsSprinting(false) , m_IsFlying(false) , m_IsSwimming(false) , m_IsSubmerged(false) , m_IsFishing(false) , m_CanFly(false) , m_EatingFinishTick(-1) , m_LifetimeTotalXp(0) , m_CurrentXp(0) , m_bDirtyExperience(false) , m_IsChargingBow(false) , m_BowCharge(0) , m_FloaterID(-1) , m_Team(NULL) { LOGD("Created a player object for \"%s\" @ \"%s\" at %p, ID %d", a_PlayerName.c_str(), a_Client->GetIPString().c_str(), this, GetUniqueID() ); m_InventoryWindow = new cInventoryWindow(*this); m_CurrentWindow = m_InventoryWindow; m_InventoryWindow->OpenedByPlayer(*this); SetMaxHealth(MAX_HEALTH); m_Health = MAX_HEALTH; cTimer t1; m_LastPlayerListTime = t1.GetNowTime(); m_PlayerName = a_PlayerName; if (!LoadFromDisk()) { m_Inventory.Clear(); cWorld * DefaultWorld = cRoot::Get()->GetDefaultWorld(); SetPosX(DefaultWorld->GetSpawnX()); SetPosY(DefaultWorld->GetSpawnY()); SetPosZ(DefaultWorld->GetSpawnZ()); LOGD("Player \"%s\" is connecting for the first time, spawning at default world spawn {%.2f, %.2f, %.2f}", a_PlayerName.c_str(), GetPosX(), GetPosY(), GetPosZ() ); } m_LastJumpHeight = (float)(GetPosY()); m_LastGroundHeight = (float)(GetPosY()); m_Stance = GetPosY() + 1.62; if (m_GameMode == gmNotSet) { cWorld * World = cRoot::Get()->GetWorld(GetLoadedWorldName()); if (World == NULL) { World = cRoot::Get()->GetDefaultWorld(); } if (World->IsGameModeCreative()) { m_CanFly = true; } } cRoot::Get()->GetServer()->PlayerCreated(this); }
bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) { // Load the data from the file: cFile f; if (!f.Open(a_FileName, cFile::fmRead)) { // This is a new player whom we haven't seen yet, bail out, let them have the defaults return false; } AString buffer; if (f.ReadRestOfFile(buffer) != f.GetSize()) { LOGWARNING("Cannot read player data from file \"%s\"", a_FileName.c_str()); return false; } f.Close(); // Parse the JSON format: Json::Value root; Json::Reader reader; if (!reader.parse(buffer, root, false)) { LOGWARNING("Cannot parse player data in file \"%s\"", a_FileName.c_str()); return false; } // Load the player data: Json::Value & JSON_PlayerPosition = root["position"]; if (JSON_PlayerPosition.size() == 3) { SetPosX(JSON_PlayerPosition[(unsigned)0].asDouble()); SetPosY(JSON_PlayerPosition[(unsigned)1].asDouble()); SetPosZ(JSON_PlayerPosition[(unsigned)2].asDouble()); m_LastPos = GetPosition(); } Json::Value & JSON_PlayerRotation = root["rotation"]; if (JSON_PlayerRotation.size() == 3) { SetYaw ((float)JSON_PlayerRotation[(unsigned)0].asDouble()); SetPitch ((float)JSON_PlayerRotation[(unsigned)1].asDouble()); SetRoll ((float)JSON_PlayerRotation[(unsigned)2].asDouble()); } m_Health = root.get("health", 0).asInt(); m_AirLevel = root.get("air", MAX_AIR_LEVEL).asInt(); m_FoodLevel = root.get("food", MAX_FOOD_LEVEL).asInt(); m_FoodSaturationLevel = root.get("foodSaturation", MAX_FOOD_LEVEL).asDouble(); m_FoodTickTimer = root.get("foodTickTimer", 0).asInt(); m_FoodExhaustionLevel = root.get("foodExhaustion", 0).asDouble(); m_LifetimeTotalXp = (short) root.get("xpTotal", 0).asInt(); m_CurrentXp = (short) root.get("xpCurrent", 0).asInt(); m_IsFlying = root.get("isflying", 0).asBool(); m_GameMode = (eGameMode) root.get("gamemode", eGameMode_NotSet).asInt(); if (m_GameMode == eGameMode_Creative) { m_CanFly = true; } m_Inventory.LoadFromJson(root["inventory"]); cEnderChestEntity::LoadFromJson(root["enderchestinventory"], m_EnderChestContents); m_LoadedWorldName = root.get("world", "world").asString(); a_World = cRoot::Get()->GetWorld(GetLoadedWorldName(), false); if (a_World == NULL) { a_World = cRoot::Get()->GetDefaultWorld(); } m_LastBedPos.x = root.get("SpawnX", a_World->GetSpawnX()).asInt(); m_LastBedPos.y = root.get("SpawnY", a_World->GetSpawnY()).asInt(); m_LastBedPos.z = root.get("SpawnZ", a_World->GetSpawnZ()).asInt(); // Load the player stats. // We use the default world name (like bukkit) because stats are shared between dimensions/worlds. cStatSerializer StatSerializer(cRoot::Get()->GetDefaultWorld()->GetName(), GetName(), &m_Stats); StatSerializer.Load(); LOGD("Player %s was read from file \"%s\", spawning at {%.2f, %.2f, %.2f} in world \"%s\"", GetName().c_str(), a_FileName.c_str(), GetPosX(), GetPosY(), GetPosZ(), a_World->GetName().c_str() ); return true; }