diff options
Diffstat (limited to '')
-rw-r--r-- | src/Entities/ArrowEntity.cpp | 51 | ||||
-rw-r--r-- | src/Entities/Entity.cpp | 5 | ||||
-rw-r--r-- | src/Entities/Pickup.cpp | 33 | ||||
-rw-r--r-- | src/Entities/Player.cpp | 10 | ||||
-rw-r--r-- | src/Entities/Player.h | 2 |
5 files changed, 79 insertions, 22 deletions
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp index 8d2569125..4727f67a9 100644 --- a/src/Entities/ArrowEntity.cpp +++ b/src/Entities/ArrowEntity.cpp @@ -3,6 +3,7 @@ #include "Player.h" #include "ArrowEntity.h" #include "../Chunk.h" +#include "FastRandom.h" @@ -24,9 +25,9 @@ cArrowEntity::cArrowEntity(cEntity * a_Creator, double a_X, double a_Y, double a SetYawFromSpeed(); SetPitchFromSpeed(); LOGD("Created arrow %d with speed {%.02f, %.02f, %.02f} and rot {%.02f, %.02f}", - m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(), - GetYaw(), GetPitch() - ); + m_UniqueID, GetSpeedX(), GetSpeedY(), GetSpeedZ(), + GetYaw(), GetPitch() + ); } @@ -44,6 +45,10 @@ cArrowEntity::cArrowEntity(cPlayer & a_Player, double a_Force) : m_bIsCollected(false), m_HitBlockPos(0, 0, 0) { + if (a_Player.IsGameModeCreative()) + { + m_PickupState = psInCreative; + } } @@ -109,7 +114,14 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, 1); // Broadcast successful hit sound - m_World->BroadcastSoundEffect("random.successful_hit", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_World->BroadcastSoundEffect( + "random.successful_hit", + (int)std::floor(GetPosX() * 8.0), + (int)std::floor(GetPosY() * 8.0), + (int)std::floor(GetPosZ() * 8.0), + 0.5f, + 0.75f + ((float)((GetUniqueID() * 23) % 32)) / 64.0f + ); Destroy(); } @@ -120,16 +132,33 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos) void cArrowEntity::CollectedBy(cPlayer * a_Dest) { - if ((m_IsInGround) && (!m_bIsCollected) && (CanPickup(*a_Dest))) + if (m_IsInGround && !m_bIsCollected && CanPickup(*a_Dest)) { - int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); - if (NumAdded > 0) // Only play effects if there was space in inventory + // Do not add the arrow to the inventory when the player is in creative: + if (!a_Dest->IsGameModeCreative()) { - m_World->BroadcastCollectPickup((const cPickup &)*this, *a_Dest); - // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;) - m_World->BroadcastSoundEffect("random.pop", (int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - m_bIsCollected = true; + int NumAdded = a_Dest->GetInventory().AddItem(E_ITEM_ARROW); + if (NumAdded == 0) + { + // No space in the inventory + return; + } } + + // TODO: BroadcastCollectPickup needs a cPickup, which we don't have + // m_World->BroadcastCollectPickup(*this, *a_Dest); + + m_bIsCollected = true; + + cFastRandom Random; + m_World->BroadcastSoundEffect( + "random.pop", + (int)std::floor(GetPosX() * 8.0), + (int)std::floor(GetPosY() * 8), + (int)std::floor(GetPosZ() * 8), + 0.2F, + ((Random.NextFloat(1.0F) - Random.NextFloat(1.0F)) * 0.7F + 1.0F) * 2.0F + ); } } diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index ee7ce06ac..2b256e766 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -1090,7 +1090,10 @@ void cEntity::HandleAir(void) if (IsSubmerged()) { - SetSpeedY(1); // Float in the water + if (!IsPlayer()) // Players control themselves + { + SetSpeedY(1); // Float in the water + } // Either reduce air level or damage player if (m_AirLevel < 1) diff --git a/src/Entities/Pickup.cpp b/src/Entities/Pickup.cpp index 0fd006485..10b6bbd5c 100644 --- a/src/Entities/Pickup.cpp +++ b/src/Entities/Pickup.cpp @@ -30,7 +30,7 @@ public: virtual bool Item(cEntity * a_Entity) override { - if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() == m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed()) + if (!a_Entity->IsPickup() || (a_Entity->GetUniqueID() <= m_Pickup->GetUniqueID()) || a_Entity->IsDestroyed()) { return false; } @@ -38,10 +38,31 @@ public: Vector3d EntityPos = a_Entity->GetPosition(); double Distance = (EntityPos - m_Position).Length(); - if ((Distance < 1.2) && ((cPickup *)a_Entity)->GetItem().IsEqual(m_Pickup->GetItem())) + cItem & Item = ((cPickup *)a_Entity)->GetItem(); + if ((Distance < 1.2) && Item.IsEqual(m_Pickup->GetItem())) { - m_Pickup->GetItem().AddCount(((cPickup *)a_Entity)->GetItem().m_ItemCount); - a_Entity->Destroy(); + short CombineCount = Item.m_ItemCount; + if ((CombineCount + m_Pickup->GetItem().m_ItemCount) > Item.GetMaxStackSize()) + { + CombineCount = Item.GetMaxStackSize() - m_Pickup->GetItem().m_ItemCount; + } + + if (CombineCount <= 0) + { + return false; + } + + m_Pickup->GetItem().AddCount((char)CombineCount); + Item.m_ItemCount -= CombineCount; + + if (Item.m_ItemCount <= 0) + { + a_Entity->Destroy(); + } + else + { + a_Entity->GetWorld()->BroadcastEntityMetadata(*a_Entity); + } m_FoundMatchingPickup = true; } return false; @@ -129,7 +150,7 @@ void cPickup::Tick(float a_Dt, cChunk & a_Chunk) } } - if (!IsDestroyed()) // Don't try to combine if someone has tried to combine me + if (!IsDestroyed() && (m_Item.m_ItemCount < m_Item.GetMaxStackSize())) // Don't combine into an already full pickup { cPickupCombiningCallback PickupCombiningCallback(GetPosition(), this); m_World->ForEachEntity(PickupCombiningCallback); // Not ForEachEntityInChunk, otherwise pickups don't combine across chunk boundaries @@ -206,7 +227,7 @@ bool cPickup::CollectedBy(cPlayer * a_Dest) m_World->BroadcastCollectPickup(*this, *a_Dest); // Also send the "pop" sound effect with a somewhat random pitch (fast-random using EntityID ;) m_World->BroadcastSoundEffect("random.pop",(int)GetPosX() * 8, (int)GetPosY() * 8, (int)GetPosZ() * 8, 0.5, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); - if (m_Item.m_ItemCount == 0) + if (m_Item.m_ItemCount <= 0) { // All of the pickup has been collected, schedule the pickup for destroying m_bCollected = true; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index e1e03fded..daf1ef2cc 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -1,4 +1,4 @@ - + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Player.h" @@ -412,6 +412,7 @@ void cPlayer::StartChargingBow(void) LOGD("Player \"%s\" started charging their bow", GetName().c_str()); m_IsChargingBow = true; m_BowCharge = 0; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle); } @@ -424,6 +425,8 @@ int cPlayer::FinishChargingBow(void) int res = m_BowCharge; m_IsChargingBow = false; m_BowCharge = 0; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle); + return res; } @@ -436,6 +439,7 @@ void cPlayer::CancelChargingBow(void) LOGD("Player \"%s\" cancelled charging their bow at a charge of %d", GetName().c_str(), m_BowCharge); m_IsChargingBow = false; m_BowCharge = 0; + m_World->BroadcastEntityMetadata(*this, m_ClientHandle); } @@ -972,7 +976,7 @@ void cPlayer::Respawn(void) m_LifetimeTotalXp = 0; // ToDo: send score to client? How? - m_ClientHandle->SendRespawn(*m_World); + m_ClientHandle->SendRespawn(*m_World, true); // Extinguish the fire: StopBurning(); @@ -1909,7 +1913,7 @@ void cPlayer::HandleFood(void) { m_FoodTickTimer = 0; - if (m_FoodLevel >= 17) + if ((m_FoodLevel > 17) && (GetHealth() < GetMaxHealth())) { // Regenerate health from food, incur 3 pts of food exhaustion: Heal(1); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index b2142a18b..2f7957f16 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -404,7 +404,7 @@ public: // cEntity overrides: virtual bool IsCrouched (void) const { return m_IsCrouched; } virtual bool IsSprinting(void) const { return m_IsSprinting; } - virtual bool IsRclking (void) const { return IsEating(); } + virtual bool IsRclking (void) const { return IsEating() || IsChargingBow(); } virtual void Detach(void); |