summaryrefslogtreecommitdiffstats
path: root/src/Entities
diff options
context:
space:
mode:
authorTiger Wang <ziwei.tiger@hotmail.co.uk>2016-12-18 21:41:37 +0100
committerTiger Wang <ziwei.tiger@hotmail.co.uk>2016-12-18 21:41:37 +0100
commitb5b119ca750a1790848b514bb00831b050f25fac (patch)
treee7a145a856676d248da5050b57da1cee4d005815 /src/Entities
parenttest (diff)
downloadcuberite-b5b119ca750a1790848b514bb00831b050f25fac.tar
cuberite-b5b119ca750a1790848b514bb00831b050f25fac.tar.gz
cuberite-b5b119ca750a1790848b514bb00831b050f25fac.tar.bz2
cuberite-b5b119ca750a1790848b514bb00831b050f25fac.tar.lz
cuberite-b5b119ca750a1790848b514bb00831b050f25fac.tar.xz
cuberite-b5b119ca750a1790848b514bb00831b050f25fac.tar.zst
cuberite-b5b119ca750a1790848b514bb00831b050f25fac.zip
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/Entity.cpp2
-rw-r--r--src/Entities/Entity.h2
-rw-r--r--src/Entities/Pawn.cpp61
-rw-r--r--src/Entities/Pawn.h20
-rw-r--r--src/Entities/ProjectileEntity.cpp22
-rw-r--r--src/Entities/ProjectileEntity.h2
-rw-r--r--src/Entities/ThrownEnderPearlEntity.cpp2
7 files changed, 43 insertions, 68 deletions
diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp
index 489b55cf8..5693bc42b 100644
--- a/src/Entities/Entity.cpp
+++ b/src/Entities/Entity.cpp
@@ -130,7 +130,7 @@ const char * cEntity::GetParentClass(void) const
-bool cEntity::Initialize(cWorld & a_World)
+bool cEntity::Initialize(std::unique_ptr<cEntity> a_Entity, cWorld & a_EntityWorld)
{
ASSERT(a_EntityWorld.IsInTickThread());
diff --git a/src/Entities/Entity.h b/src/Entities/Entity.h
index 25f6e76bf..a8074406c 100644
--- a/src/Entities/Entity.h
+++ b/src/Entities/Entity.h
@@ -153,7 +153,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(std::unique_ptr<cEntity>a_Entity, cWorld & a_EntityWorld);
// tolua_begin
diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp
index c83e7f3cb..809c51731 100644
--- a/src/Entities/Pawn.cpp
+++ b/src/Entities/Pawn.cpp
@@ -28,9 +28,8 @@ cPawn::cPawn(eEntityType a_EntityType, double a_Width, double a_Height) :
cPawn::~cPawn()
-bool cPawn::OnPreWorldTravel(cWorld & a_NewWorld)
{
- ASSERT(m_TargetingMe.size() == 0);
+ UnsetAllTargeters();
return super::OnPreWorldTravel(a_NewWorld);
}
@@ -40,7 +39,7 @@ bool cPawn::OnPreWorldTravel(cWorld & a_NewWorld)
void cPawn::Destroyed()
{
- StopEveryoneFromTargetingMe();
+ UnsetAllTargeters();
super::Destroyed();
}
@@ -221,32 +220,37 @@ void cPawn::ClearEntityEffects()
-void cPawn::NoLongerTargetingMe(cMonster * a_Monster)
+void cPawn::UnsetAllTargeters()
{
- ASSERT(IsTicking()); // Our destroy override is supposed to clear all targets before we're destroyed.
- for (auto i = m_TargetingMe.begin(); i != m_TargetingMe.end(); ++i)
+ class Callback : public cEntityCallback
{
- cMonster * Monster = *i;
- if (Monster == a_Monster)
+ public:
+ Callback(cPawn & a_Pawn) :
+ m_Pawn(a_Pawn)
{
- ASSERT(Monster->GetTarget() != this); // The monster is notifying us it is no longer targeting us, assert if that's a lie
- m_TargetingMe.erase(i);
- return;
}
- }
- ASSERT(false); // If this happens, something is wrong. Perhaps the monster never called TargetingMe() or called NoLongerTargetingMe() twice.
-}
+ virtual bool Item(cEntity * a_Entity) override
+ {
+ if (!a_Entity->IsMob())
+ {
+ return false;
+ }
+ auto Monster = static_cast<cMonster *>(a_Entity);
+ if (Monster->GetTarget() == &m_Pawn)
+ {
+ Monster->SetTarget(nullptr);
+ }
+ return false;
+ }
+ private:
+ cPawn & m_Pawn;
+ } Callback(*this);
-void cPawn::TargetingMe(cMonster * a_Monster)
-{
- ASSERT(IsTicking());
- ASSERT(m_TargetingMe.size() < 10000);
- ASSERT(a_Monster->GetTarget() == this);
- m_TargetingMe.push_back(a_Monster);
+ GetWorld()->ForEachEntity(Callback);
}
@@ -418,20 +422,3 @@ void cPawn::HandleFalling(void)
because of the client skipping an update about the lava block. This can only be resolved by
somehow integrating these above checks into the tracer in HandlePhysics. */
}
-
-
-
-
-
-void cPawn::StopEveryoneFromTargetingMe()
-{
- std::vector<cMonster*>::iterator i = m_TargetingMe.begin();
- while (i != m_TargetingMe.end())
- {
- cMonster * Monster = *i;
- ASSERT(Monster->GetTarget() == this);
- Monster->UnsafeUnsetTarget();
- i = m_TargetingMe.erase(i);
- }
- ASSERT(m_TargetingMe.size() == 0);
-}
diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h
index 74bccc4a3..f613196e1 100644
--- a/src/Entities/Pawn.h
+++ b/src/Entities/Pawn.h
@@ -24,7 +24,6 @@ public:
cPawn(eEntityType a_EntityType, double a_Width, double a_Height);
~cPawn();
- virtual bool OnPreWorldTravel(cWorld & a_NewWorld) override;
virtual void Destroyed() override;
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
@@ -34,11 +33,6 @@ public:
virtual void HandleAir(void) override;
virtual void HandleFalling(void);
- /** Tells all pawns which are targeting us to stop targeting us. */
- void StopEveryoneFromTargetingMe();
-
-
-
// tolua_begin
/** Applies an entity effect.
@@ -59,23 +53,17 @@ public:
// tolua_end
- /** Remove the monster from the list of monsters targeting this pawn. */
- void NoLongerTargetingMe(cMonster * a_Monster);
-
- /** Add the monster to the list of monsters targeting this pawn. (Does not check if already in list!) */
- void TargetingMe(cMonster * a_Monster);
-
protected:
+ /** Resets the targeted entity of all who currently are targeting us in the current world.
+ Fulfils invariant set out in cMonster::m_Target. */
+ void UnsetAllTargeters();
+
typedef std::map<cEntityEffect::eType, cEntityEffect *> tEffectMap;
tEffectMap m_EntityEffects;
double m_LastGroundHeight;
bool m_bTouchGround;
-private:
-
- /** A list of all monsters that are targeting this pawn. */
- std::vector<cMonster*> m_TargetingMe;
} ; // tolua_export
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index c4f705668..ebfaba366 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -252,7 +252,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)
@@ -262,15 +262,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);
@@ -279,7 +279,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/ThrownEnderPearlEntity.cpp b/src/Entities/ThrownEnderPearlEntity.cpp
index 4b2e2f9ff..68022d74e 100644
--- a/src/Entities/ThrownEnderPearlEntity.cpp
+++ b/src/Entities/ThrownEnderPearlEntity.cpp
@@ -86,7 +86,7 @@ void cThrownEnderPearlEntity::TeleportCreator(const Vector3d & a_HitPos)
virtual bool Item(cPlayer * a_Entity) override
{
// Teleport the creator here, make them take 5 damage:
- a_Entity->TeleportToCoords(m_HitPos.x, m_HitPos.y + 0.2, m_HitPos.z);
+ a_Entity->TeleportToCoords(m_HitPos + Vector3d(0, 0.2, 0));
a_Entity->TakeDamage(dtEnderPearl, m_Attacker, 5, 0);
return true;
}