diff options
author | Ethan Jones <ethan@yasfu.net> | 2021-10-03 22:29:45 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-03 22:29:45 +0200 |
commit | afe07fe0900e5e03f439656558a953acf16f35b8 (patch) | |
tree | 1946a7980c5799bc4e028e78c6747102e4b92fba /src/Entities/ItemFrame.cpp | |
parent | Authenticator: avoid move assignments to self (#5315) (diff) | |
download | cuberite-afe07fe0900e5e03f439656558a953acf16f35b8.tar cuberite-afe07fe0900e5e03f439656558a953acf16f35b8.tar.gz cuberite-afe07fe0900e5e03f439656558a953acf16f35b8.tar.bz2 cuberite-afe07fe0900e5e03f439656558a953acf16f35b8.tar.lz cuberite-afe07fe0900e5e03f439656558a953acf16f35b8.tar.xz cuberite-afe07fe0900e5e03f439656558a953acf16f35b8.tar.zst cuberite-afe07fe0900e5e03f439656558a953acf16f35b8.zip |
Diffstat (limited to 'src/Entities/ItemFrame.cpp')
-rw-r--r-- | src/Entities/ItemFrame.cpp | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/src/Entities/ItemFrame.cpp b/src/Entities/ItemFrame.cpp index eeab06737..90d3bb049 100644 --- a/src/Entities/ItemFrame.cpp +++ b/src/Entities/ItemFrame.cpp @@ -21,6 +21,54 @@ cItemFrame::cItemFrame(eBlockFace a_BlockFace, Vector3d a_Pos): +bool cItemFrame::DoTakeDamage(TakeDamageInfo & a_TDI) +{ + // Take environmental or non-player damage normally: + if (m_Item.IsEmpty() || (a_TDI.Attacker == nullptr) || !a_TDI.Attacker->IsPlayer()) + { + return Super::DoTakeDamage(a_TDI); + } + + // Only pop out a pickup if attacked by a non-creative player: + if (!static_cast<cPlayer *>(a_TDI.Attacker)->IsGameModeCreative()) + { + // Where the pickup spawns, offset by half cPickup height to centre in the block. + const auto SpawnPosition = GetPosition().addedY(-0.125); + + // The direction the pickup travels to simulate a pop-out effect. + const auto FlyOutSpeed = AddFaceDirection(Vector3i(), ProtocolFaceToBlockFace(m_Facing)) * 2; + + // Spawn the frame's held item: + GetWorld()->SpawnItemPickup(SpawnPosition, m_Item, FlyOutSpeed); + } + + // In any case we have a held item and were hit by a player, so clear it: + m_Item.Empty(); + m_ItemRotation = 0; + a_TDI.FinalDamage = 0; + SetInvulnerableTicks(0); + GetWorld()->BroadcastEntityMetadata(*this); + return false; +} + + + + + +void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer) +{ + if (!m_Item.IsEmpty()) + { + a_Items.push_back(m_Item); + } + + a_Items.emplace_back(E_ITEM_ITEM_FRAME); +} + + + + + void cItemFrame::OnRightClicked(cPlayer & a_Player) { Super::OnRightClicked(a_Player); @@ -54,46 +102,6 @@ void cItemFrame::OnRightClicked(cPlayer & a_Player) -void cItemFrame::KilledBy(TakeDamageInfo & a_TDI) -{ - if (m_Item.IsEmpty()) - { - Super::KilledBy(a_TDI); - Destroy(); - return; - } - - if ((a_TDI.Attacker != nullptr) && a_TDI.Attacker->IsPlayer() && !static_cast<cPlayer *>(a_TDI.Attacker)->IsGameModeCreative()) - { - cItems Item; - Item.push_back(m_Item); - - GetWorld()->SpawnItemPickups(Item, GetPosX(), GetPosY(), GetPosZ()); - } - - SetHealth(GetMaxHealth()); - m_Item.Empty(); - m_ItemRotation = 0; - SetInvulnerableTicks(0); - GetWorld()->BroadcastEntityMetadata(*this); -} - - - - - -void cItemFrame::GetDrops(cItems & a_Items, cEntity * a_Killer) -{ - if ((a_Killer != nullptr) && a_Killer->IsPlayer() && !static_cast<cPlayer *>(a_Killer)->IsGameModeCreative()) - { - a_Items.emplace_back(E_ITEM_ITEM_FRAME); - } -} - - - - - void cItemFrame::SpawnOn(cClientHandle & a_ClientHandle) { Super::SpawnOn(a_ClientHandle); |