Implemented exact block hit position.
Arrows now stick out of blocks at the exact position where they hit.
This commit is contained in:
parent
f7d5894427
commit
2c5e566fe7
@ -41,8 +41,22 @@ protected:
|
|||||||
if (g_BlockIsSolid[a_BlockType])
|
if (g_BlockIsSolid[a_BlockType])
|
||||||
{
|
{
|
||||||
// The projectile hit a solid block
|
// The projectile hit a solid block
|
||||||
m_Projectile->OnHitSolidBlock(a_BlockX, a_BlockY, a_BlockZ, a_EntryFace);
|
// Calculate the exact hit coords:
|
||||||
return true;
|
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;
|
||||||
|
char Face;
|
||||||
|
if (bb.CalcLineIntersection(Line1, Line2, LineCoeff, Face))
|
||||||
|
{
|
||||||
|
Vector3d Intersection = Line1 + m_Projectile->GetSpeed() * LineCoeff;
|
||||||
|
m_Projectile->OnHitSolidBlock(Intersection, Face);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOGD("WEIRD! block tracer reports a hit, but BBox tracer doesn't. Ignoring the hit.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convey some special effects from special blocks:
|
// Convey some special effects from special blocks:
|
||||||
@ -206,26 +220,17 @@ cProjectileEntity * cProjectileEntity::Create(eKind a_Kind, cEntity * a_Creator,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cProjectileEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
|
void cProjectileEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace)
|
||||||
{
|
{
|
||||||
// TODO: Set proper position based on what face was hit
|
// Set the position based on what face was hit:
|
||||||
switch (a_BlockFace)
|
SetPosition(a_HitPos);
|
||||||
{
|
|
||||||
case BLOCK_FACE_TOP: SetPosition(0.5 + a_BlockX, 1.0 + a_BlockY, 0.5 + a_BlockZ); break;
|
|
||||||
case BLOCK_FACE_BOTTOM: SetPosition(0.5 + a_BlockX, a_BlockY, 0.5 + a_BlockZ); break;
|
|
||||||
case BLOCK_FACE_EAST: SetPosition( a_BlockX, 0.5 + a_BlockY, 0.5 + a_BlockZ); break;
|
|
||||||
case BLOCK_FACE_WEST: SetPosition(1.0 + a_BlockX, 0.5 + a_BlockY, 0.5 + a_BlockZ); break;
|
|
||||||
case BLOCK_FACE_NORTH: SetPosition(0.5 + a_BlockX, 0.5 + a_BlockY, 1.0 + a_BlockZ); break;
|
|
||||||
case BLOCK_FACE_SOUTH: SetPosition(0.5 + a_BlockX, 0.5 + a_BlockY, a_BlockZ); break;
|
|
||||||
case BLOCK_FACE_NONE: SetPosition(0.5 + a_BlockX, 0.5 + a_BlockY, 0.5 + a_BlockZ); break;
|
|
||||||
}
|
|
||||||
SetSpeed(0, 0, 0);
|
SetSpeed(0, 0, 0);
|
||||||
|
|
||||||
// DEBUG:
|
// DEBUG:
|
||||||
LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, hit solid block at face %d",
|
LOGD("Projectile %d: pos {%.02f, %.02f, %.02f}, hit solid block at face %d",
|
||||||
m_UniqueID,
|
m_UniqueID,
|
||||||
GetPosX(), GetPosY(), GetPosZ(),
|
a_HitPos.x, a_HitPos.y, a_HitPos.z,
|
||||||
a_BlockFace
|
a_HitFace
|
||||||
);
|
);
|
||||||
|
|
||||||
m_IsInGround = true;
|
m_IsInGround = true;
|
||||||
@ -287,7 +292,7 @@ void cProjectileEntity::HandlePhysics(float a_Dt, cChunk & a_Chunk)
|
|||||||
// Something has been hit, abort all other processing
|
// Something has been hit, abort all other processing
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later
|
// The tracer also checks the blocks for slowdown blocks - water and lava - and stores it for later in its SlowdownCoeff
|
||||||
|
|
||||||
// Test for entity collisions:
|
// Test for entity collisions:
|
||||||
cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos);
|
cProjectileEntityCollisionCallback EntityCollisionCallback(this, Pos, NextPos);
|
||||||
@ -430,7 +435,7 @@ cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cThrownEggEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
|
void cThrownEggEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace)
|
||||||
{
|
{
|
||||||
// TODO: Random-spawn a chicken or four
|
// TODO: Random-spawn a chicken or four
|
||||||
|
|
||||||
@ -454,13 +459,13 @@ cThrownEnderPearlEntity::cThrownEnderPearlEntity(cEntity * a_Creator, double a_X
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cThrownEnderPearlEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
|
void cThrownEnderPearlEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace)
|
||||||
{
|
{
|
||||||
// Teleport the creator here, make them take 5 damage:
|
// Teleport the creator here, make them take 5 damage:
|
||||||
if (m_Creator != NULL)
|
if (m_Creator != NULL)
|
||||||
{
|
{
|
||||||
// TODO: The coords might need some tweaking based on the block face
|
// TODO: The coords might need some tweaking based on the block face
|
||||||
m_Creator->TeleportToCoords(a_BlockX + 0.5, a_BlockY + 1.7, a_BlockZ + 0.5);
|
m_Creator->TeleportToCoords(a_HitPos.x + 0.5, a_HitPos.y + 1.7, a_HitPos.z + 0.5);
|
||||||
m_Creator->TakeDamage(dtEnderPearl, this, 5, 0);
|
m_Creator->TakeDamage(dtEnderPearl, this, 5, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -484,7 +489,7 @@ cThrownSnowballEntity::cThrownSnowballEntity(cEntity * a_Creator, double a_X, do
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cThrownSnowballEntity::OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace)
|
void cThrownSnowballEntity::OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace)
|
||||||
{
|
{
|
||||||
// TODO: Apply damage to certain mobs (blaze etc.) and anger all mobs
|
// TODO: Apply damage to certain mobs (blaze etc.) and anger all mobs
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ public:
|
|||||||
|
|
||||||
static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d * a_Speed = NULL);
|
static cProjectileEntity * Create(eKind a_Kind, cEntity * a_Creator, double a_X, double a_Y, double a_Z, const Vector3d * a_Speed = NULL);
|
||||||
|
|
||||||
/// Called by the physics blocktracer when the entity hits a solid block, the block's coords and the face hit is given
|
/// 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(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace);
|
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace);
|
||||||
|
|
||||||
/// Called by the physics blocktracer when the entity hits another entity
|
/// Called by the physics blocktracer when the entity hits another entity
|
||||||
virtual void OnHitEntity(cEntity & a_EntityHit) {}
|
virtual void OnHitEntity(cEntity & a_EntityHit) {}
|
||||||
@ -179,7 +179,7 @@ protected:
|
|||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
// cProjectileEntity overrides:
|
// cProjectileEntity overrides:
|
||||||
virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override;
|
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override;
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ protected:
|
|||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
// cProjectileEntity overrides:
|
// cProjectileEntity overrides:
|
||||||
virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override;
|
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override;
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ protected:
|
|||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
// cProjectileEntity overrides:
|
// cProjectileEntity overrides:
|
||||||
virtual void OnHitSolidBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace) override;
|
virtual void OnHitSolidBlock(const Vector3d & a_HitPos, char a_HitFace) override;
|
||||||
|
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user