summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/ArrowEntity.cpp18
-rw-r--r--src/Entities/Entity.cpp51
-rw-r--r--src/Entities/Entity.h4
-rw-r--r--src/Entities/Player.cpp20
-rw-r--r--src/Entities/Player.h2
-rw-r--r--src/Entities/ProjectileEntity.cpp22
-rw-r--r--src/Entities/ProjectileEntity.h2
-rw-r--r--src/Entities/SplashPotionEntity.h4
8 files changed, 58 insertions, 65 deletions
diff --git a/src/Entities/ArrowEntity.cpp b/src/Entities/ArrowEntity.cpp
index e8430090b..6259098d8 100644
--- a/src/Entities/ArrowEntity.cpp
+++ b/src/Entities/ArrowEntity.cpp
@@ -119,23 +119,9 @@ void cArrowEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
Damage += ExtraDamage;
}
- // int KnockbackAmount = 1;
unsigned int PunchLevel = m_CreatorData.m_Enchantments.GetLevel(cEnchantments::enchPunch);
- if (PunchLevel > 0)
- {
- Vector3d LookVector = GetLookVector();
- Vector3f FinalSpeed = Vector3f(0, 0, 0);
- switch (PunchLevel)
- {
- case 1: FinalSpeed = LookVector * Vector3d(5, 0.3, 5); break;
- case 2: FinalSpeed = LookVector * Vector3d(8, 0.3, 8); break;
- default: break;
- }
- a_EntityHit.SetSpeed(FinalSpeed);
- }
-
- // a_EntityHit.TakeDamage(dtRangedAttack, this, Damage, KnockbackAmount); // TODO fix knockback.
- a_EntityHit.TakeDamage(dtRangedAttack, GetCreatorUniqueID(), Damage, 0); // Until knockback is fixed.
+ double KnockbackAmount = 11 + 10 * PunchLevel;
+ a_EntityHit.TakeDamage(dtRangedAttack, GetCreatorUniqueID(), Damage, KnockbackAmount);
if (IsOnFire() && !a_EntityHit.IsSubmerged() && !a_EntityHit.IsSwimming())
{
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index b596bc93d..a38a6552d 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -135,9 +135,9 @@ const char * cEntity::GetParentClass(void) const
-bool cEntity::Initialize(cWorld & a_World)
+bool cEntity::Initialize(OwnedEntity a_Self, cWorld & a_EntityWorld)
{
- if (cPluginManager::Get()->CallHookSpawningEntity(a_World, *this))
+ if (cPluginManager::Get()->CallHookSpawningEntity(a_EntityWorld, *this))
{
return false;
}
@@ -151,13 +151,13 @@ bool cEntity::Initialize(cWorld & a_World)
ASSERT(m_World == nullptr);
ASSERT(GetParentChunk() == nullptr);
- a_World.AddEntity(this);
+ a_EntityWorld.AddEntity(std::move(a_Self));
ASSERT(m_World != nullptr);
- cPluginManager::Get()->CallHookSpawnedEntity(a_World, *this);
+ cPluginManager::Get()->CallHookSpawnedEntity(a_EntityWorld, *this);
// Spawn the entity on the clients:
- a_World.BroadcastSpawnEntity(*this);
+ a_EntityWorld.BroadcastSpawnEntity(*this);
return true;
}
@@ -230,8 +230,10 @@ void cEntity::Destroy(bool a_ShouldBroadcast)
this->GetUniqueID(), this->GetClass(),
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
);
- ParentChunk->RemoveEntity(this);
- delete this;
+
+ // Make sure that RemoveEntity returned a valid smart pointer
+ // Also, not storing the returned pointer means automatic destruction
+ VERIFY(ParentChunk->RemoveEntity(*this));
});
Destroyed();
}
@@ -343,7 +345,7 @@ void cEntity::TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_R
Vector3d Heading(0, 0, 0);
if (a_Attacker != nullptr)
{
- Heading = a_Attacker->GetLookVector() * (a_Attacker->IsSprinting() ? 16 : 11);
+ Heading = a_Attacker->GetLookVector();
}
TDI.Knockback = Heading * a_KnockbackAmount;
@@ -532,21 +534,7 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
// Add knockback:
if ((IsMob() || IsPlayer()) && (a_TDI.Attacker != nullptr))
{
- int KnockbackLevel = static_cast<int>(a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback)); // More common enchantment
- if (KnockbackLevel < 1)
- {
- // We support punch on swords and vice versa! :)
- KnockbackLevel = static_cast<int>(a_TDI.Attacker->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchPunch));
- }
-
- Vector3d AdditionalSpeed(0, 0, 0);
- switch (KnockbackLevel)
- {
- case 1: AdditionalSpeed.Set(5, 0.3, 5); break;
- case 2: AdditionalSpeed.Set(8, 0.3, 8); break;
- default: break;
- }
- AddSpeed(a_TDI.Knockback + AdditionalSpeed);
+ AddSpeed(a_TDI.Knockback);
}
m_World->BroadcastEntityStatus(*this, esGenericHurt);
@@ -761,9 +749,19 @@ int cEntity::GetArmorCoverAgainst(const cEntity * a_Attacker, eDamageType a_Dama
double cEntity::GetKnockbackAmountAgainst(const cEntity & a_Receiver)
{
// Returns the knockback amount that the currently equipped items would cause to a_Receiver on a hit
+ double Knockback = 11;
- // TODO: Enchantments
- return 1;
+ // If we're sprinting, bump up the knockback
+ if (IsSprinting())
+ {
+ Knockback = 16;
+ }
+
+ // Check for knockback enchantments (punch only applies to shot arrows)
+ unsigned int KnockbackLevel = GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchKnockback);
+ Knockback += 10 * KnockbackLevel;
+
+ return Knockback;
}
@@ -1585,8 +1583,7 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
a_OldWorld.GetName().c_str(), a_World->GetName().c_str(),
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
);
- ParentChunk->RemoveEntity(this);
- a_World->AddEntity(this);
+ a_World->AddEntity(ParentChunk->RemoveEntity(*this));
cRoot::Get()->GetPluginManager()->CallHookEntityChangedWorld(*this, a_OldWorld);
});
return true;
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 8991b9fad..8f433b816 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -157,7 +157,7 @@ public:
/** Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed).
Adds the entity to the world. */
- virtual bool Initialize(cWorld & a_World);
+ virtual bool Initialize(OwnedEntity a_Self, cWorld & a_EntityWorld);
// tolua_begin
@@ -670,8 +670,6 @@ private:
int m_InvulnerableTicks;
} ; // tolua_export
-typedef std::list<cEntity *> cEntityList;
-
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 3bbe334fb..a1b518cbc 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -149,12 +149,12 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
-bool cPlayer::Initialize(cWorld & a_World)
+bool cPlayer::Initialize(OwnedEntity a_Self, cWorld & a_World)
{
UNUSED(a_World);
ASSERT(GetWorld() != nullptr);
ASSERT(GetParentChunk() == nullptr);
- GetWorld()->AddPlayer(this);
+ GetWorld()->AddPlayer(std::unique_ptr<cPlayer>(static_cast<cPlayer *>(a_Self.release())));
cPluginManager::Get()->CallHookSpawnedEntity(*GetWorld(), *this);
@@ -1321,10 +1321,16 @@ cTeam * cPlayer::UpdateTeam(void)
void cPlayer::OpenWindow(cWindow & a_Window)
{
+ if (cRoot::Get()->GetPluginManager()->CallHookPlayerOpeningWindow(*this, a_Window))
+ {
+ return;
+ }
+
if (&a_Window != m_CurrentWindow)
{
CloseWindow(false);
}
+
a_Window.OpenedByPlayer(*this);
m_CurrentWindow = &a_Window;
a_Window.SendWholeWindow(*GetClientHandle());
@@ -2003,7 +2009,9 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
GetWorld()->BroadcastDestroyEntity(*this);
// Remove player from world
- GetWorld()->RemovePlayer(this, false);
+ // Make sure that RemovePlayer didn't return a valid smart pointer, due to the second parameter being false
+ // We remain valid and not destructed after this call
+ VERIFY(!GetWorld()->RemovePlayer(*this, false));
// Set position to the new position
SetPosition(a_NewPosition);
@@ -2045,8 +2053,10 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d
a_OldWorld.GetName().c_str(), a_World->GetName().c_str(),
ParentChunk->GetPosX(), ParentChunk->GetPosZ()
);
- ParentChunk->RemoveEntity(this);
- a_World->AddPlayer(this, &a_OldWorld); // New world will take over and announce client at its next tick
+
+ // New world will take over and announce client at its next tick
+ auto PlayerPtr = static_cast<cPlayer *>(ParentChunk->RemoveEntity(*this).release());
+ a_World->AddPlayer(std::unique_ptr<cPlayer>(PlayerPtr), &a_OldWorld);
});
return true;
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index c00dbc7f1..8c21c25d6 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -41,7 +41,7 @@ public:
cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName);
- virtual bool Initialize(cWorld & a_World) override;
+ virtual bool Initialize(OwnedEntity a_Self, cWorld & a_World) override;
virtual ~cPlayer() override;
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index 64522acef..d1e101964 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -260,7 +260,7 @@ cProjectileEntity::cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Ve
-cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed)
+std::unique_ptr<cProjectileEntity> cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed)
{
Vector3d Speed;
if (a_Speed != nullptr)
@@ -270,15 +270,15 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator,
switch (a_Kind)
{
- case pkArrow: return new cArrowEntity (a_Creator, a_X, a_Y, a_Z, Speed);
- case pkEgg: return new cThrownEggEntity (a_Creator, a_X, a_Y, a_Z, Speed);
- case pkEnderPearl: return new cThrownEnderPearlEntity(a_Creator, a_X, a_Y, a_Z, Speed);
- case pkSnowball: return new cThrownSnowballEntity (a_Creator, a_X, a_Y, a_Z, Speed);
- case pkGhastFireball: return new cGhastFireballEntity (a_Creator, a_X, a_Y, a_Z, Speed);
- case pkFireCharge: return new cFireChargeEntity (a_Creator, a_X, a_Y, a_Z, Speed);
- case pkExpBottle: return new cExpBottleEntity (a_Creator, a_X, a_Y, a_Z, Speed);
- case pkSplashPotion: return new cSplashPotionEntity (a_Creator, a_X, a_Y, a_Z, Speed, *a_Item);
- case pkWitherSkull: return new cWitherSkullEntity (a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkArrow: return cpp14::make_unique<cArrowEntity> (a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkEgg: return cpp14::make_unique<cThrownEggEntity> (a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkEnderPearl: return cpp14::make_unique<cThrownEnderPearlEntity>(a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkSnowball: return cpp14::make_unique<cThrownSnowballEntity> (a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkGhastFireball: return cpp14::make_unique<cGhastFireballEntity> (a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkFireCharge: return cpp14::make_unique<cFireChargeEntity> (a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkExpBottle: return cpp14::make_unique<cExpBottleEntity> (a_Creator, a_X, a_Y, a_Z, Speed);
+ case pkSplashPotion: return cpp14::make_unique<cSplashPotionEntity> (a_Creator, a_X, a_Y, a_Z, Speed, *a_Item);
+ case pkWitherSkull: return cpp14::make_unique<cWitherSkullEntity> (a_Creator, a_X, a_Y, a_Z, Speed);
case pkFirework:
{
ASSERT(a_Item != nullptr);
@@ -287,7 +287,7 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator,
return nullptr;
}
- return new cFireworkEntity(a_Creator, a_X, a_Y, a_Z, *a_Item);
+ return cpp14::make_unique<cFireworkEntity>(a_Creator, a_X, a_Y, a_Z, *a_Item);
}
case pkFishingFloat: break;
}
diff --git a/src/Entities/ProjectileEntity.h b/src/Entities/ProjectileEntity.h
index b354c7cfc..da8c650f5 100644
--- a/src/Entities/ProjectileEntity.h
+++ b/src/Entities/ProjectileEntity.h
@@ -46,7 +46,7 @@ public:
cProjectileEntity(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, double a_Width, double a_Height);
cProjectileEntity(eKind a_Kind, cEntity * a_Creator, const Vector3d & a_Pos, const Vector3d & a_Speed, double a_Width, double a_Height);
- static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed = nullptr);
+ static std::unique_ptr<cProjectileEntity> Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const cItem * a_Item, const Vector3d * a_Speed = nullptr);
/** Called by the physics blocktracer when the entity hits a solid block, the hit position and the face hit (BLOCK_FACE_) is given */
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace);
diff --git a/src/Entities/SplashPotionEntity.h b/src/Entities/SplashPotionEntity.h
index 85aa5046f..baa5da725 100644
--- a/src/Entities/SplashPotionEntity.h
+++ b/src/Entities/SplashPotionEntity.h
@@ -12,10 +12,12 @@
#include "ProjectileEntity.h"
#include "EntityEffect.h"
#include "../World.h"
-#include "Entity.h"
+class cEntity;
+
+
// tolua_begin