summaryrefslogtreecommitdiffstats
path: root/src/Entities/ProjectileEntity.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities/ProjectileEntity.cpp')
-rw-r--r--src/Entities/ProjectileEntity.cpp61
1 files changed, 34 insertions, 27 deletions
diff --git a/src/Entities/ProjectileEntity.cpp b/src/Entities/ProjectileEntity.cpp
index 95c494569..d45f1d212 100644
--- a/src/Entities/ProjectileEntity.cpp
+++ b/src/Entities/ProjectileEntity.cpp
@@ -67,16 +67,17 @@ protected:
if (cBlockInfo::IsSolid(a_BlockType))
{
- // The projectile hit a solid block
- // Calculate the exact hit coords:
- cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1);
- Vector3d Line1 = m_Projectile->GetPosition();
- Vector3d Line2 = Line1 + m_Projectile->GetSpeed();
- double LineCoeff = 0;
- eBlockFace Face;
- if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face))
+ // The projectile hit a solid block, calculate the exact hit coords:
+ cBoundingBox bb(a_BlockX, a_BlockX + 1, a_BlockY, a_BlockY + 1, a_BlockZ, a_BlockZ + 1); // Bounding box of the block hit
+ const Vector3d LineStart = m_Projectile->GetPosition(); // Start point for the imaginary line that goes through the block hit
+ const Vector3d LineEnd = LineStart + m_Projectile->GetSpeed(); // End point for the imaginary line that goes through the block hit
+ double LineCoeff = 0; // Used to calculate where along the line an intersection with the bounding box occurs
+ eBlockFace Face; // Face hit
+
+ if (bb.CalcLineIntersection(LineStart, LineEnd, LineCoeff, Face))
{
- Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
+ Vector3d Intersection = LineStart + m_Projectile->GetSpeed() * LineCoeff; // Point where projectile goes into the hit block
+
if (cPluginManager::Get()->CallHookProjectileHitBlock(*m_Projectile, a_BlockX, a_BlockY, a_BlockZ, Face, &Intersection))
{
return false;
@@ -161,7 +162,12 @@ public:
return false;
}
- // TODO: Some entities don't interact with the projectiles (pickups, falling blocks)
+ if (!a_Entity->IsMob() && !a_Entity->IsMinecart() && !a_Entity->IsPlayer() && !a_Entity->IsBoat())
+ {
+ // Not an entity that interacts with a projectile
+ return false;
+ }
+
if (cPluginManager::Get()->CallHookProjectileHitEntity(*m_Projectile, *a_Entity))
{
// A plugin disagreed.
@@ -316,8 +322,9 @@ AString cProjectileEntity::GetMCAClassName(void) const
void cProjectileEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
super::Tick(a_Dt, a_Chunk);
-
- if (GetProjectileKind() != pkArrow) // See cArrow::Tick
+
+ // TODO: see BroadcastMovementUpdate; RelativeMove packet jerkiness affects projectiles too (cause of sympton described in cArrowEntity::Tick())
+ if (GetProjectileKind() != pkArrow)
{
BroadcastMovementUpdate();
}
@@ -335,19 +342,10 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
return;
}
- Vector3d PerTickSpeed = GetSpeed() / 20;
- Vector3d Pos = GetPosition();
-
- // Trace the tick's worth of movement as a line:
- Vector3d NextPos = Pos + PerTickSpeed;
- cProjectileTracerCallback TracerCallback(this);
- if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
- {
- // Something has been hit, abort all other processing
- return;
- }
- // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
-
+ const Vector3d PerTickSpeed = GetSpeed() / 20;
+ const Vector3d Pos = GetPosition();
+ const Vector3d NextPos = Pos + PerTickSpeed;
+
// Test for entity collisions:
cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos);
a_Chunk.ForEachEntity(EntityCollisionCallback);
@@ -363,11 +361,20 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
EntityCollisionCallback.GetHitEntity()->GetClass(),
HitPos.x, HitPos.y, HitPos.z,
EntityCollisionCallback.GetMinCoeff()
- );
-
+ );
+
OnHitEntity(*(EntityCollisionCallback.GetHitEntity()), HitPos);
}
// TODO: Test the entities in the neighboring chunks, too
+
+ // Trace the tick's worth of movement as a line:
+ cProjectileTracerCallback TracerCallback(this);
+ if (!cLineBlockTracer::Trace(*m_World, TracerCallback, Pos, NextPos))
+ {
+ // Something has been hit, abort all other processing
+ return;
+ }
+ // The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
// Update the position:
SetPosition(NextPos);