void cPlayer::Respawn(void) { ASSERT(m_World != NULL); m_Health = GetMaxHealth(); SetInvulnerableTicks(20); // Reset food level: m_FoodLevel = MAX_FOOD_LEVEL; m_FoodSaturationLevel = 5; // Reset Experience m_CurrentXp = 0; m_LifetimeTotalXp = 0; // ToDo: send score to client? How? m_ClientHandle->SendRespawn(*m_World); // Extinguish the fire: StopBurning(); TeleportToCoords(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ()); SetVisible(true); }
void cWolf::TickFollowPlayer() { class cCallback : public cPlayerListCallback { virtual bool Item(cPlayer * a_Player) override { OwnerPos = a_Player->GetPosition(); return false; } public: Vector3d OwnerPos; } Callback; if (m_World->DoWithPlayer(m_OwnerName, Callback)) { // The player is present in the world, follow him: double Distance = (Callback.OwnerPos - GetPosition()).Length(); if (Distance > 20) { Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); TeleportToCoords(m_World, Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); } else { MoveToPosition(Callback.OwnerPos); } } }
void cPlayer::Detach() { super::Detach(); int PosX = POSX_TOINT; int PosY = POSY_TOINT; int PosZ = POSZ_TOINT; // Search for a position within an area to teleport player after detachment // Position must be solid land, and occupied by a nonsolid block // If nothing found, player remains where they are for (int x = PosX - 2; x <= (PosX + 2); ++x) { for (int y = PosY; y <= (PosY + 3); ++y) { for (int z = PosZ - 2; z <= (PosZ + 2); ++z) { if (!cBlockInfo::IsSolid(m_World->GetBlock(x, y, z)) && cBlockInfo::IsSolid(m_World->GetBlock(x, y - 1, z))) { TeleportToCoords(x, y, z); return; } } } } }
void cWolf::TickFollowPlayer() { class cCallback : public cPlayerListCallback { virtual bool Item(cPlayer * a_Player) override { OwnerPos = a_Player->GetPosition(); return false; } public: Vector3f OwnerPos; } Callback; if (m_World->DoWithPlayer(m_OwnerName, Callback)) { // The player is present in the world, follow them: double Distance = (Callback.OwnerPos - GetPosition()).Length(); if (Distance < 3) { m_bMovingToDestination = false; } else if ((Distance > 30) && (!IsSitting())) { TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); } else { m_Destination = Callback.OwnerPos; } } }
void cPlayer::Respawn(void) { m_Health = GetMaxHealth(); // Reset food level: m_FoodLevel = MAX_FOOD_LEVEL; m_FoodSaturationLevel = 5; m_ClientHandle->SendRespawn(); // Extinguish the fire: StopBurning(); TeleportToCoords(GetWorld()->GetSpawnX(), GetWorld()->GetSpawnY(), GetWorld()->GetSpawnZ()); SetVisible(true); }
void cWolf::TickFollowPlayer() { Vector3d OwnerPos; bool OwnerFlying; auto Callback = [&](cPlayer & a_Player) { OwnerPos = a_Player.GetPosition(); OwnerFlying = a_Player.IsFlying(); return true; }; if (m_World->DoWithPlayerByUUID(m_OwnerUUID, Callback)) { // The player is present in the world, follow him: double Distance = (OwnerPos - GetPosition()).Length(); if (Distance > 20) { if (!OwnerFlying) { OwnerPos.y = FindFirstNonAirBlockPosition(OwnerPos.x, OwnerPos.z); TeleportToCoords(OwnerPos.x, OwnerPos.y, OwnerPos.z); SetTarget(nullptr); } } if (Distance < 2) { if (GetTarget() == nullptr) { StopMovingToPosition(); } } else { if (GetTarget() == nullptr) { if (!OwnerFlying) { MoveToPosition(OwnerPos); } } } } }
void cEntity::TeleportToEntity(cEntity & a_Entity) { TeleportToCoords(a_Entity.GetPosX(), a_Entity.GetPosY(), a_Entity.GetPosZ()); }
void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) { if (m_ClientHandle != NULL) { if (m_ClientHandle->IsDestroyed()) { // This should not happen, because destroying a client will remove it from the world, but just in case m_ClientHandle = NULL; return; } if (!m_ClientHandle->IsPlaying()) { // We're not yet in the game, ignore everything return; } } m_Stats.AddValue(statMinutesPlayed, 1); if (!a_Chunk.IsValid()) { // This may happen if the cPlayer is created before the chunks have the chance of being loaded / generated (#83) return; } super::Tick(a_Dt, a_Chunk); // Handle charging the bow: if (m_IsChargingBow) { m_BowCharge += 1; } // Handle updating experience if (m_bDirtyExperience) { SendExperience(); } bool CanMove = true; if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick? { // Apply food exhaustion from movement: ApplyFoodExhaustionFromMovement(); if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this, m_LastPos, GetPosition())) { CanMove = false; TeleportToCoords(m_LastPos.x, m_LastPos.y, m_LastPos.z); } m_ClientHandle->StreamChunks(); } if (CanMove) { BroadcastMovementUpdate(m_ClientHandle); } if (m_Health > 0) // make sure player is alive { m_World->CollectPickupsByPlayer(this); if ((m_EatingFinishTick >= 0) && (m_EatingFinishTick <= m_World->GetWorldAge())) { FinishEating(); } HandleFood(); } if (m_IsFishing) { HandleFloater(); } // Update items (e.g. Maps) m_Inventory.UpdateItems(); // Send Player List (Once per m_LastPlayerListTime/1000 ms) cTimer t1; if (m_LastPlayerListTime + PLAYER_LIST_TIME_MS <= t1.GetNowTime()) { m_World->BroadcastPlayerListUpdatePing(*this); m_LastPlayerListTime = t1.GetNowTime(); } if (IsFlying()) { m_LastGroundHeight = (float)GetPosY(); } if (m_TicksUntilNextSave == 0) { SaveToDisk(); m_TicksUntilNextSave = PLAYER_INVENTORY_SAVE_INTERVAL; } else { m_TicksUntilNextSave--; } }